一级缓存(SqlSession级别)
MyBatis的一级缓存是SqlSession级别的缓存。在操作数据库时,需要构造SqlSession对象,在对象中又一个HashMap用于存储缓存数据。不同的SqlSession之间的缓存数据区域(HashMap)是互不影响的。
一级缓存的作用域是SqlSession范围的,当同一个SqlSession中执行了两次相同的sql语句时,第一次执行完毕会将数据库查询出的数据写到缓存(内存)中,第二次从缓存中拿数据。如果执行了DML(insert,update和delete)操作,Mybatis会清空缓存。
Mybatis的缓存机制是基于id进行缓存的,也就是说,Mybatis使用HashMap缓存数据时,使用对象的id作为key,对象作为value。
一级缓存默认是开启的
二级缓存(Mapper)
多个SqlSession共用在同一个命名空间共享缓存数据。
基于注解的mybatis接口配置
对于用的角色,不经常改变,所以比较适合使用缓存【二级缓存,命名空间】。
package cn.getword.dao;
import cn.getword.dao.provider.RoleDynaSqlProvider;
import cn.getword.entity.Role;
import cn.getword.model.RolePage;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.mapping.FetchType;
import org.springframework.cache.annotation.Cacheable;
import java.util.List;
@CacheNamespace(size = 512)
public interface RoleDao {
//pure
@Select("select * from tb_role where id=#{role_id} and deleted=0")
@Options(useCache = true)
Role selectRole(@Param("role_id") int id);
@Update("update tb_role set deleted=1 where id=#{id}")
int deleteById(int id);
@Update("update tb_role set name=#{name}, order_by=#{orderBy} where id=#{id}")
// @Options(flushCache = Options.FlushCachePolicy.TRUE)
int update(Role role);
@Insert("insert into tb_role(name) values(#{name})")
int add(Role role);
}
@CacheNamespace(size = 512) : 定义在该命名空间内允许使用内置缓存,最大值为512个对象引用,读写默认是开启的,缓存内省刷新时间为默认3600000毫秒,写策略是拷贝整个对象镜像到全新堆(如同CopyOnWriteList)因此线程安全。
@SelectProvider(type = TestSqlProvider.class, method = "getSql") : 提供查询的SQL语句,如果你不用这个注解,你也可以直接使用@Select("select * from ....")注解,把查询SQL抽取到一个类里面,方便管理,同时复杂的SQL也容易操作,type = TestSqlProvider.class就是存放SQL语句的类,而method = "getSql"表示get接口方法需要到TestSqlProvider类的getSql方法中获取SQL语句。
@Options(useCache = true, flushCache = false, timeout = 10000) : 一些查询的选项开关,比如useCache = true表示本次查询结果被缓存以提高下次查询速度,flushCache = false表示下次查询时不刷新缓存,timeout = 10000表示查询结果缓存10000秒。
注意:对于更新操作,默认会自动清除命名空间的所有缓存。
end