= = = =MyBatis整理= = = =
篇一.MyBatis环境搭建与增删改查
篇二.MyBatis查询与特殊SQL
篇三.自定义映射resultMap和动态SQL
篇四.MyBatis缓存和逆向工程
缓存,即将当前查询出来的数据做一个记录,等下一次查询相同数据的时候,直接在缓存中拿数据,而不用重新去数据库。
一级缓存是SqlSession级别的,通过同一个SqlSession查询的数据会被缓存,下次查询相同的数据,就会从缓存中直接获取,不会从数据库重新访问
一级缓存失效的四种情况:
不同的sqlSession,缓存失效,两次查询,执行两次SQL:
调用sqlSession对象的clearCache()
方法,缓存被清空,执行两次SQL:
二级缓存是SqlSessionFactory级别
,通过同一个SqlSessionFactory创建的SqlSession查询的结果会被缓存。此后若再次执行相同的查询语句,结果就会从缓存中获取。
二级缓存开启的条件:
以上条件没有全部满足的时候,二级缓存开启失败:
二级缓存失效的情况:
两次查询之间执行了任意的增删改,会使一级和二级缓存同时失效
//注意
sqlSession.clearCache()方法,是SqlSession对象的方法
这个级别对应一级缓存,它清空不了二级缓存
二级缓存的相关配置:
二级缓存的一些配置,通过cache标签的各个属性来修改:
eviction属性:缓存回收策略
。 LRU(Least Recently Used) – 最近最少使用的:移除最长时间不被使用的对象,默认的是 LRU
。 FIFO(First in First out) – 先进先出:按对象进入缓存的顺序来移除它们
。 SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象
。 WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象
flushInterval属性:刷新间隔,单位毫秒
。默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句(增删改)时刷新
size属性:引用数目,正整数
。 代表缓存最多可以存储多少个对象,太大容易导致内存溢出
readOnly属性:只读,true/false
。 true:只读缓存;会给所有调用者返回缓存对象的相同实例。因此这些对象不能被修改。这提供了很重要的性能优势。
。 false:读写缓存;会返回缓存对象的拷贝(通过序列化)。这会慢一些,但是安全,因此默认是false
STEP1:先添加相关的依赖:
org.mybatis.caches mybatis-ehcache 1.2.1
ch.qos.logback logback-classic 1.2.3
STEP2:resources目录下创建EHCache的配置文件ehcache.xml
STEP3:设置二级缓存的类型
STEP4:加入logback日志
//存在SLF4J时,作为简易日志的log4j将失
//此时需要借助SLF4J的具体实现logback来打印日志
//创建logback的配置文件logback.xml,名字固定
[%d{HH:mm:ss.SSS}] [%-5level] [%thread] [%logger] [%msg]%n
STEP1:添加相关的依赖和插件
org.mybatis mybatis 3.5.9 junit junit 4.13.2 test mysql mysql-connector-java 8.0.27 log4j log4j 1.2.17
org.mybatis.generator mybatis-generator-maven-plugin 1.3.0 org.mybatis.generator mybatis-generator-core 1.3.2 com.mchange c3p0 0.9.2 mysql mysql-connector-java 8.0.27
STEP2:新建mybatis核心配置文件(这一步无关逆向工程,只是为了写数据库信息,方便后面测试增删改查)
STEP3:创建逆向工程的配置文件,文件名固定
generatorConfig.xml
STEP4:双击generator插件
构建成功:
建议直接构建奢华尊享版MyBatis,增删改查。按条件、动态拼接这些都已经封装成了方法供调用,很方便:
部分方法使用举例:
/*** @author llg* @date 2023/3/10*/
public class testMBGTest {@Testpublic void testMBG(){try {InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);SqlSession sqlSession = sqlSessionFactory.openSession(true);EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);/*** 查询所有数据*/List empList = empMapper.selectByExample(null);empList.forEach(emp -> System.out.println(emp));/*** 根据条件查询*/EmpExample example = new EmpExample();example.createCriteria().andEmpNameEqualTo("甲").andAgeGreaterThan("16");example.or().andDidIsNotNull();List empList = empMapper.selectByExample(example);empList.forEach(emp -> System.out.println(emp));/*** 选择性修改* 即当某个属性为null的时候,该字段不会被更改* 以下即执行 update t_emp SET age = ? where eid = ? */empMapper.updateByPrimaryKeySelective(new Emp(1,null,"23",null,null,null));} catch (IOException e) {e.printStackTrace();}}
}
selectByExample
:按条件查询,需要传入一个example对象或者null;如果传入一个null,则表示没有条件,也就是查询所有数据example.createCriteria().xxx
:创建条件对象,通过andXXX方法为SQL添加查询添加,每个条件之间是and关系example.or().xxx
:将之前添加的条件通过or拼接其他条件updateByPrimaryKey
:通过主键进行数据修改,如果某一个值为null,也会将对应的字段改为nulupdateByPrimaryKeySelective()
:通过主键进行选择性数据修改,如果某个值为null,则不修改这个字段STEP1:添加依赖
com.github.pagehelper pagehelper 5.2.0
STEP2:配置分页插件
在MyBatis核心配置文件mybatis-config.xml中添加:
开启分页功能:
在查询功能之前使用PageHelper.startPage(int pageNum, int pageSize)
开启分页功能
@Test
public void testPageHelper() throws IOException {InputStream is = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);SqlSession sqlSession = sqlSessionFactory.openSession(true);EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);//访问第2页,每页四条数据PageHelper.startPage(2,4);List emps = mapper.selectByExample(null);emps.forEach(emp -> System.out.println(emp));
}
Page对象
startPage方法返回的是一个Page对象,可以接收一下,并从中查看分页相关的数据:
Page
输出分页相关数据:
Page{count=true, pageNum=1, pageSize=4, startRow=0, endRow=4, total=8, pages=2, reasonable=false, pageSizeZero=false}[Emp{eid=1, empName='admin', age=22, sex='男', email='456@qq.com', did=3}, Emp{eid=2, empName='admin2', age=22, sex='男', email='456@qq.com', did=3}, Emp{eid=3, empName='王五', age=12, sex='女', email='123@qq.com', did=3}, Emp{eid=4, empName='赵六', age=32, sex='男', email='123@qq.com', did=1}]
PageInfo对象
在查询获取list集合之后,使用PageInfo pageInfo = new PageInfo<>(List list, intnavigatePages)获取分页相关数据
@Test
public void testPageHelper() throws IOException {InputStream is = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);SqlSession sqlSession = sqlSessionFactory.openSession(true);EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);PageHelper.startPage(1, 4);List emps = mapper.selectByExample(null);PageInfo page = new PageInfo<>(emps,5);System.out.println(page);
}
返回数据:
PageInfo{
pageNum=1, pageSize=4, size=4, startRow=1, endRow=4, total=8, pages=2,
list=Page{count=true, pageNum=1, pageSize=4, startRow=0, endRow=4, total=8, pages=2, reasonable=false, pageSizeZero=false}[Emp{eid=1, empName='admin', age=22, sex='男', email='456@qq.com', did=3}, Emp{eid=2, empName='admin2', age=22, sex='男', email='456@qq.com', did=3}, Emp{eid=3, empName='王五', age=12, sex='女', email='123@qq.com', did=3}, Emp{eid=4, empName='赵六', age=32, sex='男', email='123@qq.com', did=1}],
prePage=0, nextPage=2, isFirstPage=true, isLastPage=false, hasPreviousPage=false, hasNextPage=true, navigatePages=5, navigateFirstPage=1, navigateLastPage=2, navigatepageNums=[1, 2]}
字段含义说明: