主要内容:基本原理概念;单表CURD操作;多表关联操作;查询缓存
一、MyBatis前言
1.1 MyBatis概述
MyBatis本是Apache的开源项目iBatis,2010年迁移到Google并改名为MyBatis,2013年迁移到Github。MyBatis内部封装了JDBC,开发者只需要关注SQL语言本身,它通过xml或注解的方式配置各种statement。(常用xml方式)
1.2 工作原理
1.3 MyBatis与Hibernate
Hibernate框架属于全自动的ORM(对象关系映射),它实现了Java对象和数据库表之间的映射,以及SQL的自动生成和执行;相比之下,MyBatis就是半自动的ORM了,它着力于Java对象与SQL语言之间的映射,并不会自动生成SQL语言。
相比于Hibernate,它有如下特点:(1)在XML文件中配置SQL语句,实现了SQL与代码的分离,给程序维护带来了方便。(2)SQL语句需要自己编写,从而能有更高的查询效率,可完成更复杂的查询。
1.4 完整的MyBatis程序步骤
(1)导入Jar包
(2)定义实体类
(3)在DB中建表
(4)定义Dao接口
(5)定义映射文件mapper.xml
(6)定义主配置文件mybatis.xml
(7)定义Dao实现类
(8)定义测试类
1.5 主配置文件与映射文件的编写
略
二、单表的CURD操作
CURD操作,即增(Create )、改(Update)、查(Read)、删(Delete)。操作的实现方法有两种:自定义Dao接口实现类和Mapper动态代理。(主要使用Mapper动态代理)
2.1 自定义Dao接口实现类操作过程
(1)修改Dao接口,接口中写入需要进行的操作方法
(2)修改Dao实现类,对接口中的方法重写,重写步骤包括session操作
(3)修改映射文件
=================================================================
以下内容(2.2小节)仅做了解
=================================================================
2.2 自定义Dao接口实现类之查询操作
2.2.1 查询所有对象-返回List 【session.selectList()】
(1)主配置文件
(2)映射文件
2.2.2 查询所有对象返回Map 【session.selectMap()】
(1)映射文件与List相同
(2)Dao实现类
2.2.3 查询单个对象 【 session.selectOne()】
映射文件
2.2.4 模糊查询 【session.selectList()】
映射文件
2.2.5 根据Map查询 【session.selectOne()】
(1)测试类
(2)映射文件
2.2.6 属性名与查询字段名不相同
当属性名与数据表中字段名称不一致时,有两种方法解决。
(1)查询字段使用别名
可以为查询结果的字段名称赋予别名,让别名与实体Bean的属性名相同。如下图。
(2)使用结果映射resultMap
通过resultMap完成由字段到属性的映射,达到将查询结果封装为对象的目的。
==================================================================
2.3 Mapper动态代理
Mapper动态代理方式无需程序员实现Dao接口,接口是由MyBatis结合映射文件自动生成的动态代理完成。
(1)修改映射文件的namespace属性值:将映射文件中标签的namespace属性改为Dao接口的全类名。
(2)修改Dao接口方法名:接口中的方法名要与映射文件中SQL标签的id值相同。
(3)Dao对象的获取:只需要调用SqlSession的getMapper()方法,即可获得指定接口的实现类对象。
(4)测试类使用Dao
三、关联关系查询
当查询内容涉及到具有关联关系的多个表时,就需要用到关联查询。关联查询最主要的不同是在映射文件。
3.1 一对多关联查询
举例:一个国家有多个部长。现有国家表和部长表,部长表中每个部长有所属某国家的字段。现在想通过国家编号查询出该国家的所有部长。
(1)定义实体类
在定义实体时,若定义的实体是双向关联的,即双方的属性中均有对方对象作为域属性出现,那么他们在定义各自的toString()方法时,只能让某一方可以输出另一方,不要让双方的toString()方法均可输出对方,以防避免形成递归调用。
(2)定义映射文件
3.2 多对一关联查询
(1)定义实体类
(2)定义映射文件
3.3 自关联查询
自关联简单来讲就是表中有外键指向本表。例如下表:
处理方式有两种:一对多方式处理和多对一方式处理
(具体实现略)
3.4 多对多关联查询
多对多关联关系最常用的例子是一个学生可以选多门课程,而一门课程也只能被多个学生选。多对多关系需要中间表来储存对应关系。
(1)定义实体
(2)定义映射文件
四、延迟加载
概念:MyBatis中的延迟加载是指在进行关联查询时按照设置延迟规则推迟关联对象的select查询。
作用:延迟加载可以有效减少数据库压力。
PS:MyBatis的延迟加载只是对关联对象的查询有延迟设置,对于主加载对象都是直接查询。
关联对象加载时机分类:直接加载、侵入式延迟加载、深度延迟加载
4.1 侵入式延迟加载
执行完对主加载对象的查询时,不会执行对关联对象查询,但当要访问主加载对象的详情时,就会马上执行关联对象的select查询。
主配置文件修改:
4.2 深度延迟加载
只有当真正访问关联对象详情时,才会执行对关联对象的select查询。
主配置文件修改:
五、查询缓存
查询缓存是将用户对同一数据的重复性查询过程简化,不再每次均从数据库中查询,主要是为了提高查询访问的速度。
5.1 一级查询缓存
原理:MyBatis一级查询缓存是基于org.apache.ibatis.cache.impl.PerpetualCache类的HashMap本地缓存,其作用域是SqlSession。
过程:在同一个SqlSession中两次执行相同的sql查询语句,第一次执行完毕后会将查询结果写入到缓存中,第二次就不再到数据库中查询,而是直接从缓存中直接获取数据。
特点一:MyBatis默认一级缓存是开启状态,且不能关闭。
特点二:一级缓存存的是相同Sql映射id的查询结果,而非相同Sql语句的查询结果。
特点三:增、删、改操作,无论是否进行提交SqlSession.commit(),均会清空一级缓存。
5.2 内置二级查询缓存
原理:MyBatis内置的二级缓存也是基于org.apache.ibatis.cache.impl.PerpetualCache类,其作用域是整个应用。
使用过程:
(一)实体序列化
要求查询结果所涉及到的实体类要实现java.Serializable接口,若该实体类存在父类,或其具有域属性,则父类和域属性也要实现序列化接口。
(二)mapper映射文件中添加<cache/>标签
cache中属性值的设置都有相应的规定。
二级缓存的关闭:
二级缓存默认为开启状态。若要将其关闭,则需要在配置文件中进行相关设置。根据关闭的范围大小可以分为全局关闭和局部关闭。
(一)全局关闭
(二)局部关闭
特点一:二级缓存的生命周期会与整个应用同步,与SqlSession是否关闭无关。
特点二:在默认情况下,增删改操作均会清空一级、二级查询缓存;但也可以设置不清空。
5.3 ehCache二级查询缓存
ehCache是第三方缓存产品。在使用ehCache时,实体类无需实现序列化接口。
使用过程:
(1)导入Jar包
(2)添加ehcache.xml文件:文件包含<diskStore/>标签和<defaultCache/>标签
(3)启用ehcache缓存机制