版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/cd420928908/article/details/78360308
·
MyBatis
起步:
(1)MyBatis 是一个优秀的数据库持久化框架
(2)可以解决java中进行JDBC操作时的繁杂步骤
- 将对象作为SQL的参数传入
- 将查询的结果转换为Java对象
(3)不会自动生成SQL,需要开发人员提供
(4)历史上名为IBatis ,隶属于apache 独立后发布MyBatis3.x 改名为MyBatis
(5)官网:
https://github.com/mybatis/
(6)核心对象
1.SqlSessionFactory 工厂模式
2.SqlSession 执行SQL
配置:
- 创建工程
- 添加Maven依赖
- junit
- MySQL
- MyBatis
- 创建MyBatis配置文件
- <?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--配置数据库环境-->
<environments default="dev">
<environment id="dev">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///mydb"/>
<property name="username" value="root"/>
<property name="password" value="rootroot"/>
</dataSource>
</environment>
</environments>
<!--配置Mapper文件-->
<mappers>
<!--classpath中的路径-->
<mapper resource="mapper/ProductMapper.xml"/>
</mappers>
</configuration>
- 创建Mapper配置文件
- <?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.kaishengit.mapper.ProductMapper">
<insert id="save" parameterType="com.kaishengit.entity.Product">
insert into product(product_name,product_inventory)
values(#{productName},#{productInventory})
</insert>
</mapper>
- 其他配置
- settings
- 将数据库中的下划线风格的命名映射为java中的驼峰命名风格;
- <setting name="mapUnderscoreToCamelCase" value="true"/>
- 别名:给java类的完全限定名创建别名:
- 包中所有类都有一个类名首字母小写的别名
- settings
<package name="com.kaishengit.entity"/>
包中所有类都有一个类名首字母小写的别名
<typeAlias type="com.kaishengit.entity.Product" alias="Product"/>
使用sqlSessiopn api 进行CRUD
- 添加insert()
- 查看结果为selectList()
- 查看结果单条记录selectOne()
- 修改update
- 删除 delete
使用Mapper接口进行CURD
- 创建接口:
- 接口的完全限定名和Maooer.xml 文件中的namespach相同
- 接口的方法名和xml文件中的id属性相同
- 接口中的参数和返回值的类型和xml文件中的参数和返回值相同
- 通过SqlSession对象的getMapper()方法动态创建接口的实现类(动态代码模式)
- 通过接口指向实现类的方法来调用接口中定义的方法;
技巧:
一.对于insert,update,delete三种操作,MaBatis会自动返回int类型的 受影响行数;
二. 获取自动增长的主键值:
<insert id="save" parameterType="product"
useGeneratedKeys="true" keyProperty="id">
insert into product(product_name,product_inventory)
values(#{productName},#{productInventory})
</insert>
useGenrateKeys="true" 使用自动增长的主键值
keyPropery=“id” 将主键赋值给parameter对应的对象的属性上
三.多个方法参数
①将多个参数封装到一个对象里,将该对象传到方法里;
② 将多个参数封装到一个Map集合里,key值为参数的名称,value值为参数的值;
③将多个参数传入到方法里:
- xml中不能写参数类型
- 参数名称
- 第一个参数为arg0,第二个参数为arg1
- 第一个参数为param1.第二个参数为param2
- 使用@param注解来给参数命名
四.一对一,多对一
①使用resultMap节点
<
resultMap id="userMap" type="user">
<id column="id" property="id"/>
<result column="user_name" property="userName"/>
<result column="address" property="address"/>
<result column="password" property="password"/>
<result column="dept_id" property="deptId"/>
<
association property="dept"
javaType="com.kaishengit.entity.Dept">
<id column="dept_id" property="id"/>
<result column="dept_name" property="deptName"/>
</association>
</resultMap>
②使用OGNL(对象图导航语言)
SELECT
t_user.id,
user_name,
address,
PASSWORD,
dept_id,
t_dept.id as 'dept.id',
dept_name as 'dept.deptName'
FROM
t_user
LEFT JOIN t_dept ON t_user.dept_id = t_dept.id
WHERE
t_user.id = #{userId}
③注意N+1问题:
缓存不健全,依赖的外键非常的分散请况下,性能很低。
通过设置别名来获取,dept(关联表)id...(关联表中的属性,别名和dept表中的属性名相同)
五.多对多,一对多
只能使用resultMap节点
<
resultMap id="userWithTagMap" type="com.kaishengit.entity.User" extends="baseMap">
<collection property="tagList"
ofType="com.kaishengit.entity.Tag">
<id column="tag_id" property="id"/>
<result column="tag_name" property="tagName"/>
</collection>
</resultMap>
查询一个是使用<association>标签 属性 javaType=“关联表的完全限定名”
查询多个时使用<collection>标签 属性 ofType=“关联表的完全限定名”
六.动态Sql
if
choose(when,otherwise)
trim(where,set)
foreach
①if
做判断,查找符合条件的语句:
eg:
<
select
id
="find"
resultType
="com.kaishengit.entity.Article"
>
SELECT
*
from t_article
<
if
test
="title !=null and title!= ''"
>
WHERE title like #{title}
</
if
>
</
select
>
更具条件判断
②WHERE
拼接sql语句中有where and| on 开头时
通过<WHERE> 可以将拼接SQL中的And on 等抹掉
eg:
<
select
id
="findByParam"
resultType
="com.kaishengit.entity.Article"
>
SELECT
*
from t_article
<
where
>
<
if
test
="title != null and title != ''"
>
WHERE title LIKE #{title}
</
if
>
<
if
test
="simplecontent !=null and simplecontent!= ''"
>
AND simplecontent LIKE #{simplecontent}
</
if
>
</
where
>
</
select
>
③choose...when
有多个限制语句时,使用choose...when
④trim
where的增强版,可以设置属性
prefix="where"
prefixOverrides="and|or"
通过设置 可以抹去sql语句中后面的and | or 等
eg:
<trim
prefix="where"
prefixOverrides
="and|or">
<if test="username != null and username != ''">
username = #{username}
</if>
<choose>
<when test="password != null and password != ''">and password = # {password}
</when>
<when test="email != null and email != ''">
and email = #{email}
</when>
</choose>
</trim>
⑤set
修改多个属性的时候,set判断是否为空,抹去SQL语句后的,
eg:
<update id="updateAuthorIfNecessary" parameterType="domain.blog.Author"update Author
<set>
<if test="username != null">username=#{username},</if>
<if test="password != null">password=#{password},</if>
<if test="email != null">email=#{email},</if>
<if test="bio != null">bio=#{bio}</if>
</set>
where id=#{id}
</update>
⑥foreach
可以循环查询多条语句,
eg:
<
select
id
="findByIdList"
resultType
="com.kaishengit.entity.Article"
>
SELECT
*
from t_article
WHERE id IN
<
foreach
collection
="collection"
item
="id"
separator
=","
open
="("
close
=")"
>
#{id}
</
foreach
>
</
select
>
注:sepatator:分隔符
open:左括号
close:右括号
⑦批量添加
一条insert语句插入多条内容
eg:
<
insert
id
="batchSave"
>
INSERT INTO mybatis (NAME, age, cls_id)
VALUES
<
foreach
collection
="UserList"
item
="User"
separator
=","
>
(#{User.name},#{User.age},#{User.clsId})
</
foreach
>
</
insert
>
缓存:
一级缓存:
在
同一个Sqlsession
中,查询
同一个对象
多次,只有第一次会真正的 去 数据库中去查询,其他的查询都在一级缓存中获得
默认开启
二级缓存:
默认关闭
在同一个
SqlSessionFactory
中产生的
多个Sqlsession
之间共享;
开启二级缓存:
1.将被缓存的对象进行序列化(实现序列化接口)
2.在Mapper.xml文件中添加
<cache/>
节点,
- 映射语句文件中所有的select语句将被缓存
- select节点的userCache属性为false时表示不使用缓存
- 映射语句文件中的insert,update,delete语句会刷新缓存
- flushCache属性为false时表示不刷新缓存
- 缓存会使用lset recently used(LRU 最进很少使用 的) 算法来回收
- 根据时间的间隔来刷新缓存,默认不刷新
- 缓存会存储列集合或对象的1024个引用;
- 缓存被视为read/writh的缓存
基于注解的配置:
一。在MyBatis中注解不能完全替代XML,常以注解加xml或只使用xml的形式;
二。如果只使用注解,则在Mabatis配置文件中配置接口,如果是注解+xml或这是xml 时。则在MyBatis的主配置文件中配置XMl,不能时接口
三。常见的注解:
- @insert
- @update
- @select
- @delete
- Options
- 使用自动增长的主键
- 刷新缓存
- 不适用缓存
- 结果集映射
- @Results
- @Result
- @One
- @Many
- CaCheNamespace
- 二级缓存开启
- 如果是注解+xml时,二级缓存在XML中进行
查看代码:https://github.com/Deerlinh/MyBatis_1