博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
缓存在Springboot应用中的使用
阅读量:4045 次
发布时间:2019-05-24

本文共 5760 字,大约阅读时间需要 19 分钟。

缓存在Springboot应用中的使用

缓存

缓存(cache,又称高速缓存)是指可以高速访问的、用于临时存储的数据存储区。

缓存使用的场合

缓存一般用于在较短的时间段对相同数据频繁读取的场合,将读取频度较高的数据放入缓存,直接从缓存取数据,以提高效率。例如以下情况:

  1. MyBatis在短时间内对同一查询多次执行;
  2. Shiro等安全框架对用户的每一次访问需要获取用户权限;
  3. 用户多次执行同一个条件的查询业务。

注意:

  • 缓存数据是部分源数据的副本,需要确保源数据与缓存数据同步;
  • 对于频繁数据更新的场合,缓存并不能提高效率;
  • 在多线程访问同一缓存情况下,如果缓存数据存在更新的可能性,存在不同线程执行同一查询数据不一致的可能性。

MyBatis的缓存

MyBatis具有一级缓存和二级缓存共两级缓存。

  1. MyBatis一级缓存即SqlSession缓存,该缓存仅在一个线程内使用。
  2. MyBatis二级缓存是可选的,默认不开启,可根据需要设置开启,甚至可以使用第三方缓存。二级缓存支持多线程,如果存在数据更新,则有可能读取数据不准确,建议二级缓存在无数据更新的场合使用或单线程场合使用。

建议不要使用MyBatis的二级缓存,在业务层使用可控制的缓存(如:redis)代替更好。

Shiro缓存

Shiro自带缓存,也支持第三方缓存,可以通过配置使用。

Shiro缓存的特点:

  1. 用户登录后首次访问系统查询权限数据,以后不会每次都查询权限数据;
  2. 用户退出(正常退出或session失效退出),缓存自动清空。

配置示例:

使用starter方式实现shiro与springboot集成时,缓存配置如下:

/*1. 在shiro的配置类中,配置shiro的缓存管理器,shiro即会自动使用缓存,这里使用的是shiro提供的基于内存的缓存。2. 由于spring的缓存管理器的默认名称为cacheManager,为避免冲突,此处方法名不要使用cacheManager*/@Bean protected CacheManager shiroCacheManager() {    return new MemoryConstrainedCacheManager();}

详细信息请参阅

缓存业务查询数据

使用Springboot自动配置的简易缓存(基于内存中并发映射)

引入依赖

org.springframework.boot
spring-boot-starter-cache

在配置类上引入注解@EnableCaching开启缓存

@SpringBootApplication@EnableCachingpublic class ScgcxxApplication implements WebMvcConfigurer {        @Override    public void addViewControllers(ViewControllerRegistry registry) {        registry.addViewController("/").setViewName("redirect:/safty/login/index.html");    }        public static void main(String[] args) {        SpringApplication.run(ScgcxxApplication.class, args);    }}

在业务对象使用缓存注解

  • @CacheConfig是一个类级别的注解,允许共享缓存的名称、KeyGenerator、CacheManager 和CacheResolver。

    该操作会被方法级别注解覆盖。

  • @Cacheable是一个方法级别的注解,声明方法返回值是可缓存的,将返回值存储到缓存中以便后续使用相同参数调用时不需执行实际的方法,直接从缓存中取值。

    缓存数据的key值由@Cacheable的key属性指定。

    key属性指定可以使用spEL(Spring EL,即Spring表达式),其中几个重要内置变量名:targetClass(当前目标对象所属类名)、methodName(当前方法名称)、#P0(第0个参数)、#p1(第1个参数)、#ename(名称为ename的参数)

  • @CachePut是一个方法级别的注解,用于声明方法正常执行,并在执行后更新缓存。

    @CachePut标注的方法在执行前不会去检查缓存中是否存在之前执行过的结果,而是每次都会执行该方法,并将执行结果以键值对的形式存入指定的缓存中。

  • @CacheEvict是一个方法级别的注解,用于声明方法正常执行,并在执行后清空指定key值的缓存或全部的缓存。

    spring cache不仅支持将数据缓存,还支持将缓存数据删除。此过程经常用于从缓存中清除过期或未使用的数据。@CacheEvict可以指定删除一个key或多个key缓存数据。此外,还提供了一个额外的属性allEntries ,表示是否需要清除缓存中的所有元素。默认为false,表示不需要。当指定了allEntries为true时,Spring Cache将忽略指定的key。

缓存注解代码示例

@Service @Transactional @CacheConfig(cacheNames="customer")public class CustomerServiceImpl implements CustomerService {    @Autowired    private CustomerDao customerDao;        //Customer应当是可序列化类    @Cacheable(key="targetClass +'.'+ methodName+'()'")    @Override    public List
getAllCustomers() { return customerDao.findAllCustomers(); } //Customer应当是可序列化类 @Cacheable(key="targetClass +'.'+ methodName+'(' + #p0 +')'") @Override public PageInfo
getCustomersPage(PageParam pageParam) { return PageCreater.createPageInfo( ()->{return customerDao.findCustomersPage(pageParam);}, pageParam ); } //Customer应当是可序列化类 @Cacheable(key="targetClass +'.'+ methodName+'(' + #cus_id +')'") @Override public Customer getCustomer(Integer cus_id) { return customerDao.findCustomerbyId(cus_id); } @CacheEvict(allEntries=true) @Override public boolean addCustomer(CustomerDto dto) { dto.setCus_status(DataStatusEnum.未确定.getCode()); int cnt = customerDao.insertCustomer(dto); return cnt>0; } @CacheEvict(allEntries=true) @Override public boolean updateCustomer(CustomerDto dto) { int cnt = customerDao.updateCustomer(dto); return cnt>0; } @CacheEvict(allEntries=true) @Override public boolean deleteCustomer(Integer... cus_ids) { if(cus_ids==null || cus_ids.length==0) { return false; } int cnt = customerDao.deleteCustomerByIds(cus_ids); return cnt>0; } @CacheEvict(allEntries=true) @Override public boolean updateCustomersStatus(String status, Integer[] cus_ids) { if(cus_ids==null || cus_ids.length==0) { return false; } int cnt = customerDao.updateCustomerStatusByIds(status,cus_ids); return cnt>0; } }

进行测试

在application.yaml文件中配置缓存日志,启动运行观察日志信息。

logging:  level:   	......    org.springframework.cache: trace    ......

使用第三方缓存Redis

redis是什么?

Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。

redis在JavaEE应用中的作用

redis本身是一个内存数据库,在应用中可以充当缓存,提高系统数据查询性能。

redis的安装并测试

Window 环境

  1. 下载地址:
  2. 下载zip版本或者安装版(建议zip版)
  3. 解压
  4. 打开一个 cmd 窗口 使用cd命令切换目录到 redis解压目录, 运行 redis-server redis.windows.conf,启动redis服务
  5. 另打开一个cmd窗口,切换到redis目录下运行 redis-cli -h 127.0.0.1 -p 6379
  6. 输入 set key value 存储一个键值对
  7. 输入 get key 根据键获取值
  8. 若一切顺利,则安装成功。

ubuntu/deepin 环境

  1. 在终端执行命令 sudo apt-get update ,更新软件列表
  2. 在终端执行命令 sudo apt-get install redis-server 安装redis
  3. 启动redis服务器
    前台方式启动:在终端执行命令 redis-server
    后台方式启动:在终端执行命令 /etc/init.d/redis-server start
  4. 在终端执行命令 redis-cli 进入redis客户端命令行模式
  5. 输入 set key value 存储一个键值对
  6. 输入 get key 根据键获取值
  7. 关闭redis服务器
    前台启动方式的关闭:在终端执行 redis-cli shutdown
    后台启动方式的关闭:在终端执行 /etc/init.d/redis-server stop
  8. 若一切顺利,则安装成功。

引入依赖

org.springframework.boot
spring-boot-starter-cache
org.springframework.boot
spring-boot-starter-data-redis

在配置文件application.properties中添加如下配置:

# Redis数据库索引(默认为0)spring.redis.database=1# Redis服务器地址spring.redis.host=127.0.0.1# Redis服务器连接端口spring.redis.port=6379# Redis服务器连接密码(默认为空)#spring.redis.password=# 连接池最大连接数(使用负值表示没有限制)连接池中的最大空闲连接spring.redis.jedis.pool.max-idle=100# 连接池最大阻塞等待时间(使用负值表示没有限制)spring.redis.jedis.pool.max-wait=-1# 连接池中的最小空闲连接spring.redis.jedis.pool.min-idle=2# 连接超时时间(毫秒)spring.redis.timeout=15000spring.cache.type=redisspring.cache.redis.time-to-live=6000000

在配置类上引入注解@EnableCaching开启缓存

同上述 使用Springboot自动配置的简易缓存

在业务对象使用缓存注解

同上述 使用Springboot自动配置的简易缓存

进行测试

转载地址:http://unhdi.baihongyu.com/

你可能感兴趣的文章
Redis 越来越慢?常见延迟问题定位与分析
查看>>
枚举用法详解
查看>>
枚举用法详解
查看>>
设计模式常见面试题
查看>>
curl
查看>>
hibernateTemplate常用方法
查看>>
windows下查看端口监听情况
查看>>
windows下mongodb安装
查看>>
win7下安装mongodb
查看>>
mongodb使用笔记
查看>>
ZeroMQ研究与应用分析
查看>>
mongodb--nodejs
查看>>
linux vi 操作笔记
查看>>
使用TortoiseGit对Git版本进行分支操作
查看>>
Linux tcpdump命令详解
查看>>
mysql日期格式化
查看>>
MySQL数据库中的Date,DateTime,TimeStamp和Time类型
查看>>
MySQL索引
查看>>
mongodb 的重启
查看>>
Mongoose - 让NodeJS更容易操作Mongodb数据库
查看>>