Mybatis缓存
1.一级缓存
Mybatis一级缓存为sqlSession级别的缓存,默认开启,相同的sqlsession对象,查询相同条件的结果时,存在一级缓存只会查询一次,sqlSession关闭后缓存失效 调用cleanCache后 缓存被清除,执行过增删改后缓存会被清除,不能跨session。
<mapper namespace="lesson05.StudentMapper">
<select id="queryStudent" resultType="student">
select * from student where sid=#{0}
</select>
</mapper>
public static SqlSession getSession() throws IOException{
String resource = "lesson05/mybatis.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//工厂类
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
return sqlSessionFactory.openSession();
}
public void query() throws IOException{
SqlSession session = getSession();
StudentMapper stu=session.getMapper(StudentMapper.class);
Student s=stu.queryStudent("2");
StudentMapper stu1=session.getMapper(StudentMapper.class);
Student s1=stu1.queryStudent("2");
System.out.println(s==s1);
}
返回的结果是true,说明两次查询取到的是同一个对象,这就证明存在一级缓存只会查询一次,一级缓存是不可被更改的
2. 二级缓存
二级缓存的全局开关(mybatis.xml):
<settings>
<setting name="cacheEnabled" value="true"></setting>
</settings>
使用配置:
`<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="t`rue"> </cache>
注意事项:session必须是同一个SqlSessionFactory创建的,如果是多个session操作同一个数据,只能有一个session操作,其他都要关闭。
3.redis缓存
通过实现Cache接口,并且重写其中的方法实现
工具类
package lesson05;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import com.sun.xml.internal.messaging.saaj.util.ByteInputStream;
import com.sun.xml.internal.messaging.saaj.util.ByteOutputStream;
public class JedisUtils {
/**
* 序列化
* @throws IOException
*/
public static byte[] objectToByteArray(Object obj) throws IOException{
ByteOutputStream bos = new ByteOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(obj);
return bos.getBytes();
}
/**
* 反序列化
* @throws Exception
*/
public static Object byteArrayToObject(byte[] bt) throws Exception{
ByteInputStream bid = new ByteInputStream(bt, bt.length);
ObjectInputStream ois = new ObjectInputStream(bid);
return ois.readObject();
}
}
实现类
package lesson05;
import java.io.IOException;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.apache.ibatis.cache.Cache;
import redis.clients.jedis.Jedis;
public class RedisCache implements Cache {
Jedis jedis = new Jedis("localhost",6379);
/**
* 缓存的id
*/
private String cacheId;
public RedisCache(String cacheId){
this.cacheId=cacheId;
}
/**
* 清除redis数据库,不建议实现
*/
@Override
public void clear() {
//jedis.flushAll();
}
@Override
public String getId() {
return cacheId;
}
/**
* mybatis读取数据时 将数据库中读取的数据通过putObject设置到缓存中
*/
@Override
public void putObject(Object key, Object value) {
try {
jedis.set(JedisUtils.objectToByteArray(key), JedisUtils.objectToByteArray(value));
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* mybatis自动调用getObject检测是否有缓存
*/
@Override
public Object getObject(Object key) {
try {
byte [] bt=jedis.get(JedisUtils.objectToByteArray(key));
if(bt==null){
return null;
}
return JedisUtils.byteArrayToObject(bt);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* mybatis缓存策略删除数据
*/
@Override
public Object removeObject(Object key) {
Object obj = getObject(key);
try {
jedis.del(JedisUtils.objectToByteArray(key));
} catch (IOException e) {
e.printStackTrace();
}
return obj;
}
@Override
public int getSize() {
// TODO Auto-generated method stub
return 0;
}
/**
* 加锁
*/
@Override
public ReadWriteLock getReadWriteLock() {
return new ReentrantReadWriteLock();
}
}
配置文件
<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true" type="lesson05.RedisCache">
</cache>