什么是MyBatis?
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生类型、接口和 Java 的 POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
总结:持久层框架,SQL定制,省去JDBC操作,JavaBean与数据库记录的对应转换;
Batis,估计是作者的一只宠物鸟;
关于Mapper.xml 文件的位置
1、放在 java 目录下:站在开发角度,方便查找文件,便于开发(我比较喜欢);
2、放在resources 目录下:站在软件工程角度,xml确实是资源文件;
修改配置属性
mybatis:
mapper-locations: classpath:com/example/mybatis/dev/dao/mapper/*Mapper.xml
type-aliases-package: com.example.mybatis.dev.model
修改pom.xml文件
<build> <resources> <!-- mapper.xml文件在java目录下 --> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> <!-- mapper.xml文件在resources目录下--> <resource> <directory>src/main/resources</directory> </resource> </resources> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
resultType、resultMap的区别
resultType:将SQL得返回映射出 POJO,当SQL列和POJO属性不对应时,无法成功映射
resultMap:先通过<resultmap/>标签将POJO于SQL返回绑定,然后通过resultMap返回,类似对SQL于POJO之间做了格式化、二次加工;
简单情况下,无区别,复杂情况下resultMap更强大;
二级缓存
一级缓存
生命周期:
a.伴随着SqlSession的创建而创建,伴随着sqlSession的销毁而销毁;
b.SqlSession 调用了 clearCache() 时,缓存对象中的数据会清空,缓存对象还存在;
b.SqlSession 调用了 update()、insert()、delete() 时,缓存对象中的数据会清空,缓存对象还存在;
二级缓存
生命周期
a.应用的启动缓存创建,应用的停止,缓存销毁(此观点不是很正确)
b.同 namespace 下,调用<select> 缓存会被创建
c.当到达 <cache flushInterval="1000"/> 的flushInterval 时间限制后(单位毫秒),缓存会被刷新;
d.同 namespace 下,调用<update> <insert> <delete> 缓存会被清除
作用域 namespace
二级缓存的开启
mybatis:
mapper-locations: classpath:com/example/mybatis/dev/dao/mapper/*Mapper.xml
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
cache-enabled: true #k开启二级缓存
<mapper namespace="com.example.mybatis.dev.dao.DevDataDao"> <!--二级缓存开启--> <cache /> <select id="queryByCode" resultType="com.example.mybatis.dev.model.DevData" > …… </select> <insert id="createData"> …… </insert> </mapper>
二级缓存的潜在危害
a.二级缓存是作用域是 namespace,当同一张表在不同的 namespace 中操作时,会导致缓存不刷新,未知风险非常大;
b. insert、update、delete 操作会清空所在namespace下的全部缓存,操作颗粒比较大;
c. 多表操作根本不能用二级缓存( user_role 用户角色表 ,不管在哪个 namespace 下 做二级缓存都是有问题的 )
二级缓存的挽救
当考虑到上一节中的危害,MyBatis给出的解决方案是:使用 <cache-ref /> 共用一个缓存空间,其实是再次增大了操作颗粒,一旦控制不好还是比较有风险的;
<cache-ref namespace="com.someone.application.data.SomeMapper"/>
一对多、多对一、多对多
一对多
JavaBean : 在one端 建立many的集合属性;
*Mapper.xml
<!--第1种 不适用 collection 的 select --> <resultMap id="user" type="com.example.mybatis.dev.model.User"><collection property="deviceList" ofType="com.example.mybatis.dev.model.Device" column="loginName"> </resultMap> <!--第2种 适用 collection 的 select--> <resultMap id="user" type="com.example.mybatis.dev.model.User"><collection property="deviceList" column="loginName" select="com.example.mybatis.dev.dao.DeviceDao.queryByUser"> </collection> </resultMap>
两种比较:
第一种:效率略高一点,进行了1次访问数据库,<select> 标签需要写多表关联,耦合高一点,面向对象好一差;
第二种:效率略差一点,进行了N次访问数据库,<select> 标签不需要写多表关联,耦合低一点,面向对象好一点;
总结:性能更要,建议第一种,第二种数据库压力越大呀( <select> 标签内语句写的耦合度高,表示很不喜欢 ,但是处于性能考虑,表示没办法);
多对一
JavaBean : 在many端 建立one的属性;
*Mapper.xml
使用 <association/> 标签 与 <collection /> 类似
多对多
JavaBean : 在任意端 建立另一端的集合属性;
*Mapper.xml
使用 <collection />