本文共 4672 字,大约阅读时间需要 15 分钟。
一级缓存是SqlSession级别的缓存。在操作数据库时需要构造 sqlSession对象,在对象中有一个(内存区域)数据结构(HashMap)用于存储缓存数据。不同的sqlSession之间的缓存数据区域(HashMap)是互相不影响的。
二级缓存是mapper级别的缓存,多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession去操作数据库得到数据会存在二级缓存区域,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。
一级缓存的作用域是同一个SqlSession,在同一个sqlSession中两次执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写 到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。当一个sqlSession结束后该sqlSession中的一级缓存 也就不存在了。Mybatis默认开启一级缓存。
二级缓存是多个SqlSession共享的,其作用域是mapper的同一个namespace,不同的sqlSession两次执行相同 namespace下的sql语句且向sql中传递参数也相同即最终执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二 次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。Mybatis默认没有开启二级缓存需要在setting全局参数中配置开启二级缓存。
1.引入依赖
redis.clients jedis org.apache.commons commons-lang3 3.4
2.在application.yml中编写配置
server: port: 8081spring: session: store-type: redis # 指定使用redis存储session的会话信息 redis: # 指定redis服务器的相关信息 host: 192.168.174.128 port: 6379
3.实现mybatis的Cache接口,完成自定义缓存
package com.baizhi.cache;import org.apache.commons.lang3.SerializationUtils;import org.apache.ibatis.cache.Cache;import org.apache.ibatis.cache.CacheException;import redis.clients.jedis.Jedis;import java.io.Serializable;import java.util.concurrent.locks.ReadWriteLock;public class RedisCache implements Cache { private final String id; private Jedis cache = new Jedis("192.168.174.128",6379); public RedisCache(String id) { this.id = id; } @Override public String getId() { return id; } @Override //返回缓存所有键值对的数量 public int getSize() { Long dbSize = cache.dbSize(); return dbSize.intValue(); } @Override //向缓存中存入数据 public void putObject(Object key, Object value) { System.out.println("key:"+key); //将对象序列化成字节数组 引入commens-lang3工具包 byte[] keyBs = SerializationUtils.serialize((Serializable) key); byte[] valueBs = SerializationUtils.serialize((Serializable) value); cache.set(keyBs, valueBs); } @Override //从缓存中获取数据 public Object getObject(Object key) { byte[] keyBs = SerializationUtils.serialize((Serializable) key); byte[] valueBs = cache.get(keyBs); if (valueBs != null) { // 第一次到缓存找数据的时候 , 返回的是null return SerializationUtils.deserialize(valueBs); } return null; } @Override //清除缓存 public Object removeObject(Object key) { // 先获取一下删除的对象 byte[] keyBs = SerializationUtils.serialize((Serializable) key); byte[] valueBs = cache.get(keyBs); Object obj = SerializationUtils.deserialize(valueBs); cache.del(keyBs);// 执行删除操作 return obj; } @Override //清空缓存 public void clear() { cache.flushDB(); } @Override public ReadWriteLock getReadWriteLock() { return null; } @Override public boolean equals(Object o) { if (getId() == null) { throw new CacheException("Cache instances require an ID."); } if (this == o) { return true; } if (!(o instanceof Cache)) { return false; } Cache otherCache = (Cache) o; return getId().equals(otherCache.getId()); } @Override public int hashCode() { if (getId() == null) { throw new CacheException("Cache instances require an ID."); } return getId().hashCode(); }}
可以在idea中ctrl+t将PrepetualCache类中的方法粘过来修改一下
4.在mybatis中使用自定义缓存
5.在springboot项目中开启mybatis的二级缓存
mybatis: mapper-locations: classpath:com/xxxx/mapper/*Mapper.xml type-aliases-package: com.xxxx.entity configuration: # 开启mybatis的二级缓存 cache-enabled: true
6.编写好dao service controller层之后,开启测试
package com.baizhi.controller;import com.baizhi.entity.User;import com.baizhi.service.UserService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpSession;import java.util.List;@RestController@RequestMapping("user")public class UserController { @Autowired private UserService userService; @RequestMapping("findAll") public ListfindAll(){ List users = userService.findAll(); return users; }}
key:514810625:3350643160:com.xxxx.dao.UserDAO.findAll:0:2147483647:select * from t_user:SqlSessionFactoryBean
访问一次之后,再次访问就会从缓存中获取数据,就会变得很快,数据量大的时候就比较明显了。
注意:实体类一定要实现Serializable接口
转载地址:http://fggo.baihongyu.com/