文章目录
mybatis官网:https://mybatis.org/mybatis-3/zh/configuration.html
1. mybatis特性
- Mybatis是支持定制化SQL,存储过程以及高级映射的优秀的持久层框架
- Mybatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集
- Mybatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO映射成数据库中的记录
- Mybatis是一个半自动的ORM(Object Relation Mapping)框架
-
Hibernate和JPA
操作简单,开发效率高。
程序中的长难复杂SQL需要绕过框架。
内部自动生产的SQL,不容易做特殊优化。
基于全映射的全自动框架,大量字段的pojo进行部分映射时比较困难。
反射操作太多,导致数据库性能下降。
-
MyBatis
轻量级,性能出色
SQL和Java编码分开,功能边界清晰。Java代码专注业务,SQL语句专注数据。
开发效率稍逊于Hibernate,但完全能接受。
2. mybatis配置属性
<environment id="development">
<!--
transactionManager: 设置事务管理方式
属性:JDBC:表示当前环境中,执行SQL时,使用的是JDBC中原生的事务管理方式
MANAGED:被管理,例如spring
-->
<transactionManager type="JDBC" />
<!--
dataSource:配置数据源
-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
3. 分布查询
优点:可以实现延迟加载,但是必须在核心配置文件中设置全局配置信息:lazyLoadingEnable:延迟加载的全局开关,当开启时,所有关联对象都会延迟加载
aggressiveLazyLoading:当开启时,任何方法的调用都会加载该对象的所有属性。否则,每个属性会按需要加载。
此时就可以实现按需加载,获取的数据是什么,就只会执行相应的sql。此时通过association和collection中的fetchType属性设置当前的分布查询是否使用延迟加载,fetchType=“lazy(延迟加载) | eager(立即加载)”
<settings>
<!-- 将自动映射为驼峰 -->
<setting name="mapUpderscoreToCamelCase" value="true"/>
<!-- 开启延迟加载 -->
<setting name="lazyLoadingEnabled" value="true" />
</settings>
Mapper配置类中:
<resultMap id="deptAndEmpResultMap" type="Dept">
<!--
select:设置分布查询的sql的唯一标识(namespace.SQLId或mapper接口的全类名,方法名)
column:设置分布查询的条件
fetchType:当开启全局的延迟加载之后,可通过此属性手动控制延迟加载的效果
-->
<association property="dept"
select="com.vector.mapper.DeptMapper.getEmpAndDeptMapper"
column="did"
fetchType="eager"></association>
</resultMap>
// 在一对多的返回属性中用ofType="", 用collection
//一对一用javaType=""
4.多条件查询
Where标签
<!-- where标签只能去掉其中内容内容前的and或or -->
<select id="getEmpByCondition" resultType="Emp">
select * from t_emp
<where>
<if test="empName != null and empName != ''">
emp_name = #{empName}
</if>
<if test="age != null and empName != ''">
and age = #{age}
</if>
<if test="sex != null and empName != ''">
or sex = #{sex}
</if>
</where>
</select>
trim标签
// trim:
// 若标签中有内容
prefix | suffix: 将trim标签中内容前面或后面添加指定内容
suffixOverrides | prefixOverrides: 将trim标签中内容前面或后面去掉指定内容
// 若标签中没有内容时,trim标签也没有任何效果
<select id="getEmpByCondition" resultType="Emp">
select * from t_emp
<trim prefix="where" suffixOverrides="and | or">
<if test="empName != null and empName != ''">
emp_name = #{empName}
</if>
<if test="age != null and empName != ''">
and age = #{age}
</if>
<if test="sex != null and empName != ''">
or sex = #{sex}
</if>
</trim>
</select>
choose, when, otherwise
相当于if…else if …else
循环删除foreach
<!--加括号的方法 -->
<delete id="deleteMoreByArray">
delete from t_emp where eid in
(
<foreach collection="传过来的数组 eids" item="属性eid" separator=",">
#{eid}
</foreach>
)
</delete>
<!--不加加括号的方法 -->
<delete id="deleteMoreByArray">
delete from t_emp where eid in
<foreach collection="传过来的数组 eids" item="属性eid" separator="," open="(" close=")">
#{eid}
</foreach>
</delete>
<!--or的方法 -->
<delete id="deleteMoreByArray">
delete from t_emp where
<foreach collection="传过来的数组 eids" item="属性eid" separator="or>
eid = #{eid}
</foreach>
</delete>
sql标签
设置SQl片段 <sql id="empColumns">eid, emp_name, age, sex, email</sql>
引用片段: <include refid="empColumns"></include>
5.mybatis一级缓存
一级缓存的是SqlSession级别的,通过同一个SqlSession查询的数据会被缓存,下次查询相同的数据,就会从缓存中直接获取,不会从数据库重新访问了
使一级缓存失效的四种情况:
(1)不同的SqlSession对应不同的一级缓存
(2)同一个SqlSession但是查询条件不同
(3)同一个SqlSession两次查询期间执行了任何一次增删改操作
(4)同一个SqlSession两次查询期间手动清空了缓存
6.MyBatis的二级缓存
二级缓存升是SqlSessionFactory级别,通过同一个SqlSessionFactory创建的SqlSession查询结果会被缓存;此后若再次执行相同的查询语句,结果就会从缓存中获取
二级缓存开启的条件:
(1)在核心配置文件中,设置全局配置属性cacheEnabled=“true”, 默认为true,不需要设置
(2)在映射文件中设置标签
(3)二级缓存必须在SqlSession关闭或提交之后有效
(4)查询的数据所转换的实体类类型必须实现序列化的接口
使二级缓存失效的情况:
两次查询之间执行任意增删改,会使一级和二级缓存同时失效
7.二级缓存的相关配置
在mapper配置文件中添加的cache标签可以设置一些属性:
-
eviction 属性:缓存回收策略
LRU(Lesst Recently Used) -最近最少使用
FIFO(First in First out) - 先进先出
SOFT- 软引用 :移除基于垃圾回收器状态和软引用规则的对象
WEAK - 弱引用:更积极地移除基于垃圾回收器状态和弱引用规则的对象。
默认是LRU。
- flushInterval属性:刷新间隔,单位毫秒
默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用用语句时刷新
-
size属性:引用数目,正整数
代表缓存最多可以存储多少个对象,太大容易导致内存溢出
-
readOnly属性:只读,true/false
true:只读缓存,会给所有调用者返回缓存对象的相同实例。因此这些对象不能被修改。这提供了很重要的性能优势。
false:读写缓存;会返回缓存对象的拷贝(通过序列化)。这会慢一些,但是安全,因此默认是false.
8.Mybatis缓存查询的顺序
- 先查询二级缓存,因为二级缓存中可能会有其他程序查出来的数据,可以拿来直接使用。
- 如果二级缓存没有命中,在查询一级缓存
- 如果一级缓存也没有命中,则查询数据库
- SqlSession关闭后,一级缓存中的数据会写入到二级缓存