目录
- 1.MyBatis
- 2.执行步骤
- 3.常用参数
- 4.mapper xml files
- 5.缓存机制
1.MyBatis
将编写sql的功能开放给程序员,别的类似预编译,设置参数,执行sql了,封装结果 步骤由框架自己完成。是一个半自动的轻量级的框架。
2.执行步骤
- SqlSessionFactoryBuilder,通过全局配置文件创建SqlSessionFactory
- SqlSessionFactory打开一个会话,创建SqlSession
- SqlSession操作接口的mapper,对数据库完成增删改查操作。
注意:1.sqlSession 不是线程安全的,每次使用都应该获取新的对象。
小技巧:让公共配置文件有提示:添加对应的dtd文件,在window-》preference-》xml->xml catalog 添加对应dtd文件
3.常用参数及标签
3.1 开启驼峰命名
<setting name="mapUnderscoreToCamelCase" value="true"/>
解释:可以让数据库字段column以驼峰命名规则映射到JavaBean对象的属性中。例如:dept_name ->deptName;
3.2 typeAliases
<!-- 不用别名时, resultType 需要指定权限定名-->
<select id="getEmpById" resultType="com.amarsoft.liuhx.bean.Employee">
SELECT * FROM employee WHERE id=#{id}
</select>
------------------------------------
<typeAliases>
<typeAlias type="com.amarsoft.bean.Department" alias="department"/>
<package name="所有mapper接口的全路径"/>
</typeAliases>
<select id="getEmpById" resultType="department">
SELECT * FROM employee WHERE id=#{id}
</select>
解释:1.指定别名的时候,可以在返回类型中就用简单的别名;
2.也可以通过package 为所有路径下的对象批量取别名,别名为类名,且不区分大小写,如果有类型重复的,可以通过单独的@Alias 指定特有的别名。
3.3 databaseIdProvider
<databaseIdProvider type="DB_VENDOR">
<property name="MySQL" value="mysql"/>
</databaseIdProvider>
注释:判断不同的数据库厂商,在增删改查标签中就可以指定不同的数据库厂商了。
4 mapper xml files
4.1 select 查询标签
4.41.1 主键
- useGeneratedKeys 获取自增主键值;keyProperty =“id”;封装到Java Bean中。
- oracle没有自增,可以先查询一个主键(比如序列获取主键,自定义主键生成等等),在执行插入语句。
<selectKey keyProperty ="id" order ="BEFORE">
注释:keyProperty:将查询出来的数据绑定在定义的Java Bean中。
order:语句执行时机(BEFORE、AFTER)
4.2 mapper 入参
最重要的一点就是:将所有的入参都封装成一个map集合
- 1.单个参数,参数名字没有任何要求,都可以取到值。
方法 : getDepartment(int id);
对应的mapper : SELECT * FROM employee WHERE id=#{value}
解释:此时的入参和#{}中的值无需对应 id->value 也是可以取到值
- 2.多个参数:参数会被封装成一个map,key的值为param1…paramN;即:param1…param2…paramN,在mapper中取值就为#{parm1}…
方法 : getDepartment(int id,String name);
对应的mapper : SELECT * FROM employee WHERE id=#{param1}
and name =#{param2}
解释:更加入参的顺序就可以取到值
- 3.明确指定参数名称:@Param(“name”),很明确知晓参数和参数值的对应 关系。
方法 : getDepartment(@Param("id")int id,@Param("name")String name);
对应的mapper : SELECT * FROM employee WHERE id=#{id}
and name =#{name}
注释:通过注解,明确指定参数绑定
- 4.如果参数较多,也可以直接穿入Java Bean 对象,取值是就是Bean对象的属性。或者直接传入一个自定义的map参数,取值就是map对应的key。
4.2.1 #{}和${}
- #{}用预编译形式,利用占位符
- 有更加多的配置:比如jdbcType :如果在oracle中,保存的值为null的时候,可能会报错,jdbcType Other:无效的数据类型。此时需要明确的指定jdbcType=NULL
- 取出的值直接拼接在sql中,会有安全问题
4.2.2 resultType:返回结果的单个参数。
- 1.接口定义:List ,那么返回参数resultType值为:具体的Java Bean :student 。
- 2.接口定义:Map<Integer,Student>,返回值依然是student ,需要在接口中配合@MapKey(“id”),将结果封装成map的形式。
@MapKey(value="id")//将Department的id作为封装后的map的key
public Map<Integer, Department> selectDepartmentMap();
对应的resultType="com.amarsoft.bean.Employee"
4.2.3 resultMap:自定义高级结果集映射。
- 1.级联属性封装结果。
JavaBean:
private int id ;
private String departmentName;
private List<Employee> emps;
对应的*.xml 配置
<result column="dept_name" propety="emps.deptName"/>
注释:相当于封装一个特定的JavaBean对象,JavaBean 中有一个属性是另外一个JavaBean对象。可以通过级联属性的方式赋值
- 2.association 封装单个实体
<resultMap type="com.amarsoft.liuhx.bean.Employee" id="employee_map">
<id></id>
<result />
<association property="emps"
column="id"
select="namespace+封装的方法(com.amarsoft.liuhx.mapper.EmployeeMapper.
getEmpById)">
<id/>
<result column="" property=""/>
</association>
</resultMap>
注释:association :
property :组合JavaBean的属性名字(emps)
column :上一步中查询的结果列,用于查询出封装的实体Bean(通过id查询emps)
知识点: 分步查询结合以下配置,可以实现延迟加载
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
- 3 collection对集合的封装
private int id ;
private String departmentName;
private List<Employee> emps;
对应的mapper配置信息:
<resultMap type="组合JavaBean的权限定名 " id="employeePlus">
<id column="dept_id" property="id"/>
<result/>
<!--collection对集合的封装 -->
<collection property="组合JavaBean中的JavaBean对象(emps)"
column="dept_id"
select="namespace+封装的方法
(com.amarsoft.liuhx.mapper.EmployeeMapper.getEmpList)">
<id/>
<result/>
</collection>
</resultMap>
注释:collection:封装查询出的JavaBean对象
property:组合JavaBean中的JavaBean对象属性
column:上一步数据库查询的列,作为查询条件的列名
**知识点:**1.如果关联查询的时候,需要多个值,可以将参数封装成一个map,即:column=’{key1=column1,key2= column2}’;
2.除了全局开启验证加载,单个的collection通过fetchType ="lazy/eager"控制延迟加载。
5.动态SQL
- 1.if:如果满足条件才拼接sql
<if test="id != null"></if>
- 2.where
可以去除第一个where添加后的and。
场景:拼接多个条件,如果第一个条件不满足,后面的条件满足,就会多出来一个and,可以使用where标签解决
<select id="findActiveBlogLike"
resultType="Blog">
SELECT * FROM BLOG
<where>
<if test="state != null">
state = #{state}
</if>
<if test="title != null">
AND title like #{title}
</if>
<if test="author != null and author.name != null">
AND author_name like #{author.name}
</if>
</where>
</select>
- 3.trim:
自定义截取sql串,可以按需求去除前后缀 - 4.choose
<select id="findActiveBlogLike"
resultType="Blog">
SELECT * FROM BLOG WHERE state = ‘ACTIVE’
<choose>
<when test="title != null">
AND title like #{title}
</when>
<when test="author != null and author.name != null">
AND author_name like #{author.name}
</when>
<otherwise>
AND featured = 1
</otherwise>
</choose>
</select>
注释:when :当满足’test’条件是,拼接该段的条件,如果没有符合条件的,拼接’otherwise’中的sql。
- 5.set
<update id="updateAuthorIfNecessary">
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>
注释:更新语句的时候,动态用if拼接,可能最后一个会多一个’,'我们可以利用set标签就可以解决
- 6.foreach 遍历拼接sql
<select id="selectPostIn" resultType="domain.blog.Post">
SELECT *
FROM POST P
WHERE ID in
<foreach item="item" index="index" collection="list"
open="(" separator="," close=")">
#{item}
</foreach>
</select>
注释:collection:需要遍历的集合;item:遍历出来的每一个参数对象;
open:以什么开始,close:以什么结束;separator:分隔符;index:索引
- 7.内置参数:
_databaseId :配置的厂商
_parameter:入参 - 8.bind
<select id="selectBlogsLike" resultType="Blog">
<bind name="pattern" value="'%' + _parameter.getTitle() + '%'" />
SELECT * FROM BLOG
WHERE title LIKE #{pattern}
</select>
注释:将OGNL表达式的值绑定到一个变量中,利用该标签改变传入参数的值,在拼接到sql串中。
- 9.:抽取公用的sql片段
比如多次查询的片段,抽取出来,用的地方引用就好了。
引用:
5.mybatis的缓存机制
5.1 一级缓存
是一个针对于sqlsession的缓存。因此需要是创建的同一个SQLSession。
5.1.1 一级缓存特点
- 1.SQLsession相同,需要相同的查询条件
- 2.SQLSession相同,执行了增删改查操作或者清除了缓存,缓存数据会失效
- 3.因为SQLSession在执行完之后就会关闭session,一级缓存会清空。因此一级缓存作用比域较小。
- 4.查询的数据首先放在一级缓存中,只有当会话关闭或者提交了,一级缓存的数据才会保存到二级缓存中。
5.2 二级缓存
全局缓存:基于namespace级别的缓存。
5.2.1 开启二级缓存
<setting name="cacheEnabled" value="true"/>
注释:开启全局缓存开关
<cache eviction="LRU" flushInterval="3" readOnly="false"
size="520" type=""></cache>
注释:这个标签是添加在单个mapper配置文件中的,开启单个namespace的二级缓存。
参数:
eviction:缓存回收的策略;LRU:最近最少使用;FIFO:先进先出;SOFT:软引用 ;WEAK:弱引用。
flushInterval:刷新缓存的间隔;
readOnly:是否只读;
type="" ;自定义的缓存权限定名。
知识点:如果需要自定义缓存,就需要添加想要集成的缓存包,利用上面的缓存标签的type属性,完成整合缓存框架。
集成redis作为缓存框架缓存参考
5.2.2 缓存标签属性
- 1.全局的cacheEanble=true 和每个查询标签中的usecache=“ture”,都是针对二级缓存的开关,一级缓存一直存在的
- 2.当个的增删改查标签中的flushCache=“true”,每次操作都会清空缓存,所有要让一级和二级缓存有效的话,需要设置查询标签中的flushCache=“false”,默认查询也是false
- 3.localCacheScope:可以禁用掉一级缓存(全局变量)
- 4.单个SQLSession的清除缓存方法,也会将一级缓存数据放置在二级缓存中
来源:CSDN
作者:小虾~半月劫
链接:https://blog.csdn.net/qq_38684778/article/details/104642933