1.mybatis的缓存机制
1.1一级缓存:直观的理解就是某个sqlseesion的一个Map,结果用于存储一定数量的查询结果,在sqlseesion进行更新,删除操作时,mybatis会清空一级缓存,保持数据的一致性。值得注意的是mybatis与spring结合,一级缓存当sqlsession的事务提交了,spring将会关闭sqlseesion也就是将此sqlseesion的缓存清空。
1.2二级缓存:也就是某个mapper的一个Map,但是二级缓存不一定存在内存,而是多种存储介质,还可以是借助ehcache实现分布式存储。第一个sqlseesion查询了数据库之后,mybatis会进行缓存,当第二个sqlseesion 查询的时候首先会在mapper的缓存下,查询,没有再查询数据库。
2.使用
2.1一级缓存
//一级缓存一般不用管理,在你不知不觉下的就会使用了,使用代码,理解一级缓存的效果
@Controller
@RequestMapping("/order")
public class OrderController {
@Autowired
private OrderMapper ordermapper;
//事务管理
@Autowired
private DataSourceTransactionManager txManager;
//事务定义
@Autowired
private DefaultTransactionDefinition txDefinition;
@RequestMapping(value="/findorder",method=RequestMethod.GET)
public String findOrderAndOrderDetail(HttpServletRequest request)
{
//获取事务状态
TransactionStatus status = txManager.getTransaction(txDefinition);
Order order = ordermapper.findOrderAndOrderDetail();
System.out.println(order.toString()+"这是订单一");
Order order2 = ordermapper.findOrderAndOrderDetail();
System.out.println(order2.toString()+"这是订单二");
request.setAttribute("order", order);
txManager.commit(status);
return "order_detail";
}
//进行页面访问之后控制台打印
/**
DEBUG [http-bio-8080-exec-11] - ==> Preparing: SELECT orders.*, orderdetail.items_id, orderdetail.items_num FROM orders, orderdetail WHERE orderdetail.orders_id = orders.id AND orders.id=3
DEBUG [http-bio-8080-exec-11] - ==> Parameters:
DEBUG [http-bio-8080-exec-11] - <== Total: 2
DEBUG [http-bio-8080-exec-11] - Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3716e720]
com.ssm.model.Order@4fcd0175这是订单一
DEBUG [http-bio-8080-exec-11] - Fetched SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3716e720] from current transaction
DEBUG [http-bio-8080-exec-11] - Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3716e720]
com.ssm.model.Order@4fcd0175这是订单二
**/
//此时就可以看查询order1的时候,由于没有缓存数据,边进行查询数据库,但是查询order2 的时候不再向数据库发送查询语句
2.2二级缓存
2.2.1在mybatis配置文件打开二级缓存开关
2.2.2在你需要开启二级缓存的mapper 下打开二级缓存开关
<mapper namespace="com.ssm.mapping.OrderMapper">
<!-- 开启本mapper的二级缓存 -->
<cache></cache>
<!--这里还有关于二级缓存的众多选项,这里只做基础测试-->
2.2.3对pojo类进行实现序列化接口
public class Order implements Serializable
2.2.4使用
/**二级缓存是mapper级别的缓存,那么使用两次访问便可以看到效果,第一次进行查询sqlseesion关闭,mapper进行缓存,第二次查询则是另一个sqlseesion了,**/
@Controller
@RequestMapping("/order")
public class OrderController {
@Autowired
private OrderMapper ordermapper;
//事务管理
@Autowired
private DataSourceTransactionManager txManager;
//事务定义
@Autowired
private DefaultTransactionDefinition txDefinition;
@RequestMapping(value="/findorder",method=RequestMethod.GET)
public String findOrderAndOrderDetail(HttpServletRequest request)
{
//获取事务状态
TransactionStatus status = txManager.getTransaction(txDefinition);
Order order = ordermapper.findOrderAndOrderDetail();
System.out.println(order.toString()+"这是订单一");
request.setAttribute("order", order);
txManager.commit(status);
return "order_detail";
}
2.2.5结果
**<!--这是第一次查询,可以看到Cache Hit Ratio缓存命中率0.0,向数据库发送了查询语句-->**
DEBUG [http-bio-8080-exec-12] - Creating a new SqlSession
DEBUG [http-bio-8080-exec-12] - Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3a3b6630]
DEBUG [http-bio-8080-exec-12] - Cache Hit Ratio [com.ssm.mapping.OrderMapper]: 0.0
DEBUG [http-bio-8080-exec-12] - ==> Preparing: SELECT orders.*, orderdetail.items_id, orderdetail.items_num FROM orders, orderdetail WHERE orderdetail.orders_id = orders.id AND orders.id=3
DEBUG [http-bio-8080-exec-12] - ==> Parameters:
DEBUG [http-bio-8080-exec-12] - <== Total: 2
DEBUG [http-bio-8080-exec-12] - Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3a3b6630]
com.ssm.model.Order@7b49a5a9这是订单一
**<!--这是第二次查询,可以看到Cache Hit Ratio缓存命中率0.5 并没有向数据库发送查询语句-->**
DEBUG [http-bio-8080-exec-8] - Creating a new SqlSession
DEBUG [http-bio-8080-exec-8] - Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5382276e]
DEBUG [http-bio-8080-exec-8] - Cache Hit Ratio [com.ssm.mapping.OrderMapper]: 0.5
DEBUG [http-bio-8080-exec-8] - Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5382276e]
com.ssm.model.Order@64b013a这是订单一
3. 对二级缓存的总结
3.1也就是说二级缓存是mapper级别的,可以供不同的session使用,二级缓存有其的缺陷,比如说sqlseesion1向数据库查询了多次不同的数据,mybatis进行缓存多次的查询数据,sqlseesion2也如此,那么当sqlseesion1进行对一个数据的update,delete操作时,二级缓存就需要清空所有缓存保持数据一致性,那么sqlseesion2的缓存也被清除掉了,也就是二级缓存对数据的细粒度不够友好