ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

MyBatis缓存

2020-09-22 03:01:12  阅读:171  来源: 互联网

标签:缓存 System class println MyBatis id out


一级缓存
  • 一级缓存也叫本地缓存,SqlSession开启到关闭之间缓存查询结果
  • 缓存select结果,指的是查询相同的数据
  • 通过==可以看出,两次查询返回的是同一个对象
  • insert,update,delete会刷新缓存,无论是否更新查询的数据,都会刷新缓存
  • 一级缓存默认开启

连续查询两次相同数据

SqlSession sqlSession = MyBatisUtil.getSqlSession();
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);

System.out.println("第一次查询");
Employee employee = mapper.selectById(1);
System.out.println(employee);

System.out.println("第二次查询");
Employee employee2 = mapper.selectById(1);
System.out.println(employee2);

sqlSession.close();

运行结果

  • 可以看出第一次查询执行了sql,第二次查询并没有执行sql
  • 这个时候employee和employee2实际上是同一个对象
第一次查询
Opening JDBC Connection
Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.
Created connection 436532993.
==>  Preparing: select id, name, age, gender, birthday, phone, dept_id from employee where id = ?
==> Parameters: 1(Integer)
<==    Columns: id, name, age, gender, birthday, phone, dept_id
<==        Row: 1, 张三二, 80, 男, 2020-09-01, 13323332331, 2
<==      Total: 1
Employee{id=1, name='张三二', age=80, gender='男', birthday=Tue Sep 01 00:00:00 CST 2020, phone='13323332331', deptId=2}
第二次查询
Employee{id=1, name='张三二', age=80, gender='男', birthday=Tue Sep 01 00:00:00 CST 2020, phone='13323332331', deptId=2}
Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@1a04f701]
Returned connection 436532993 to pool.

两次查询之间执行更新语句

SqlSession sqlSession = MyBatisUtil.getSqlSession();
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);

System.out.println("第一次查询");
Employee employee = mapper.selectById(1);
System.out.println(employee);

System.out.println("更新数据");
mapper.update(2, "13399887766");

System.out.println("第二次查询");
Employee employee2 = mapper.selectById(1);
System.out.println(employee2);

sqlSession.close();

运行结果

  • 更新的是与查询无关的数据,但是也刷新了缓存
第一次查询
Opening JDBC Connection
Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.
Created connection 436532993.
==>  Preparing: select id, name, age, gender, birthday, phone, dept_id from employee where id = ?;
==> Parameters: 1(Integer)
<==    Columns: id, name, age, gender, birthday, phone, dept_id
<==        Row: 1, 张三二, 80, 男, 2020-09-01, 13323332331, 2
<==      Total: 1
Employee{id=1, name='张三二', age=80, gender='男', birthday=Tue Sep 01 00:00:00 CST 2020, phone='13323332331', deptId=2}
更新数据
==>  Preparing: update employee set phone = ? where id = ?;
==> Parameters: 13399887766(String), 2(Integer)
<==    Updates: 1
第二次查询
==>  Preparing: select id, name, age, gender, birthday, phone, dept_id from employee where id = ?;
==> Parameters: 1(Integer)
<==    Columns: id, name, age, gender, birthday, phone, dept_id
<==        Row: 1, 张三二, 80, 男, 2020-09-01, 13323332331, 2
<==      Total: 1
Employee{id=1, name='张三二', age=80, gender='男', birthday=Tue Sep 01 00:00:00 CST 2020, phone='13323332331', deptId=2}
Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@1a04f701]
Returned connection 436532993 to pool.

手动关闭缓存

SqlSession sqlSession = MyBatisUtil.getSqlSession();
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);

System.out.println("第一次查询");
Employee employee = mapper.selectById(1);
System.out.println(employee);

System.out.println("清理缓存");
sqlSession.clearCache();

System.out.println("第二次查询");
Employee employee2 = mapper.selectById(1);
System.out.println(employee2);

sqlSession.close();

运行结果

  • 手动清理完缓存,查询相同数据又一次执行了sql
第一次查询
Opening JDBC Connection
Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.
Created connection 436532993.
==>  Preparing: select id, name, age, gender, birthday, phone, dept_id from employee where id = ?;
==> Parameters: 1(Integer)
<==    Columns: id, name, age, gender, birthday, phone, dept_id
<==        Row: 1, 张三二, 80, 男, 2020-09-01, 13323332331, 2
<==      Total: 1
Employee{id=1, name='张三二', age=80, gender='男', birthday=Tue Sep 01 00:00:00 CST 2020, phone='13323332331', deptId=2}
清理缓存
第二次查询
==>  Preparing: select id, name, age, gender, birthday, phone, dept_id from employee where id = ?;
==> Parameters: 1(Integer)
<==    Columns: id, name, age, gender, birthday, phone, dept_id
<==        Row: 1, 张三二, 80, 男, 2020-09-01, 13323332331, 2
<==      Total: 1
Employee{id=1, name='张三二', age=80, gender='男', birthday=Tue Sep 01 00:00:00 CST 2020, phone='13323332331', deptId=2}
Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@1a04f701]
Returned connection 436532993 to pool.
二级缓存
  • 会话关闭时,会把一级缓存中的数据保存到二级缓存中
  • 再次开启会话时,会读取二级缓存中的数据

核心配置文件

  • cacheEnabled默认值是true
<setting name="cacheEnabled" value="true"/>

mapper中设置

  • eviction清除策略,默认LRU
    • LRU 最近最少使用,移除最长时间不被使用的对象
    • FIFO 先进先出,按照对象进入缓存的顺序来移除
    • SOFI 软引用
    • WEAK 弱引用
  • flushInterval刷新时间ms,默认不刷新
  • size缓存引用(对象或列表)的最大值,默认1024
  • readOnly只读,默认读写缓存。如果readOnly为false,实体类必须序列号。如果该值为true,返回的是同一个引用;如果该值为false,返回的是对象的拷贝,不是同一个引用。
<mapper namespace="com.example.mapper.EmployeeMapper">
    <cache
        eviction="FIFO"
        flushInterval="60000"
        size="512"
        readOnly="true"/>
</mapper>

测试代码

System.out.println("开启会话1");
SqlSession sqlSession = MyBatisUtil.getSqlSession();
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);

System.out.println("第一次查询");
Employee employee = mapper.selectById(1);
System.out.println(employee);

System.out.println("关闭会话1");
sqlSession.close();

System.out.println("开启会话2");
SqlSession sqlSession2 = MyBatisUtil.getSqlSession();
EmployeeMapper mapper2 = sqlSession2.getMapper(EmployeeMapper.class);

System.out.println("第二次查询");
Employee employee2 = mapper2.selectById(1);
System.out.println(employee2);

System.out.println("关闭会话");
sqlSession2.close();

运行结果

  • 可以看出虽然使用的不是同一个会话连接,但是也只执行了一次sql
开启会话1
第一次查询
Cache Hit Ratio [com.example.mapper.EmployeeMapper]: 0.0
Opening JDBC Connection
Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.
Created connection 2085002312.
==>  Preparing: select id, name, age, gender, birthday, phone, dept_id from employee where id = ?;
==> Parameters: 1(Integer)
<==    Columns: id, name, age, gender, birthday, phone, dept_id
<==        Row: 1, 张三二, 80, 男, 2020-09-01, 13323332331, 2
<==      Total: 1
Employee{id=1, name='张三二', age=80, gender='男', birthday=Tue Sep 01 00:00:00 CST 2020, phone='13323332331', deptId=2}
关闭会话1
Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@7c469c48]
Returned connection 2085002312 to pool.
开启会话2
第二次查询
Cache Hit Ratio [com.example.mapper.EmployeeMapper]: 0.5
Employee{id=1, name='张三二', age=80, gender='男', birthday=Tue Sep 01 00:00:00 CST 2020, phone='13323332331', deptId=2}
关闭会话

标签:缓存,System,class,println,MyBatis,id,out
来源: https://www.cnblogs.com/qixioa/p/13709729.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有