最近看了下我们内部2B的项目,发现很多数据都是直接从mysql中查询的,几乎页面上所有的展示数据都是从mysql中去动态查询,此时的情况下,部分统计界面等不常展示的数据恰是可以做个缓存即可,不用每次都从数据库查,费时费力。所以这里的话,其实我们要很好的利用起来缓存。
在传统的编码逻辑中,我们同时使用缓存和数据库结合的时候,我们经常会这么来操作,下面给一部分伪代码:
User user = redis.get(id); if(user == null){ user = userdao.getUserById(id) } return user;
上面我们使用伪代码演示了一下在实际业务中的编码逻辑,其实对于我们来说,还有更简单的方法,就是不需要我们手动去redis中查询信息,而是由框架完成了。这里的话,我们介绍一个多级缓存框架-jetcache。这是一个阿里巴巴开源的基于java的缓存框架,他同时支持多种缓存类型:
1、本地缓存 2、分布式缓存 3、多级缓存
下面我们来介绍下这个jetcache框架的使用。主要以案例的形式来给大家展示。
1)准备一个springboot web项目
这里我们准备一个springboot web项目,编写几个增删改查的接口,这里我们已准备好了,如下图:
这个项目我们已经准备好了,然后再这个代码里面,每一个controller都打印一行日志出来。
2)向数据库插入数据
这里我们在数据库里面插入一些记录,如下图:方便我们一会来获取数据:
3)添加jetcache依赖
这里的话我们进入到springboot web项目里面,在pom.xml里面添加上jetcache注解,具体添加如下:
<dependency> <groupId>com.alicp.jetcache</groupId> <artifactId>jetcache-starter-redis</artifactId> <version>2.7.3</version> </dependency> <!--jetcache2.7.x版本需要额外添加该依赖--> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>4.3.1</version> </dependency>
这里jetcache的话,会添加两个注解,分别是jetcache-start-redis和redis的依赖。因为一般情况下我们都是把缓存放在redis里面的,所以一定要添加这两个注解。
4)添加配置文件
这里的jetcache我们需要在application.yml文件中进行配置,相关的配置模板固定为如下:
jetcache: ## 统计间隔,0表示不统计,开启后定期在控制台输出缓存信息 statIntervalMinutes: 15 ## 是否把cacheName作为远程缓存key前缀 areaInCacheName: false ## 本地缓存配置 local: default: ## default表示全部生效,也可以指定某个cacheName ## 本地缓存类型,其他可选:caffeine/linkedhashmap type: linkedhashmap keyConvertor: fastjson ## 远程缓存配置 remote: default: ## default表示全部生效,也可以指定某个cacheName type: redis ## key转换器方式n keyConvertor: fastjson broadcastChannel: jetcache-demo ## redis序列化方式 valueEncoder: java valueDecoder: java ## redis线程池 poolConfig: minIdle: 5 maxIdle: 20 maxTotal: 50 ## redis地址与端口 host: 192.168.31.30 port: 6379 password: 3c0bef8420ca0961a74ff1fbe8c66ef4 database: 15
这里有两种地方配置,一种local,一种是remote,我们根据实际情况进行选择即可,如果是2b这种单体项目的话,我们一般用local即可,如果是2C场景的话,由于我们需要部署多个,因此这里我们就需要配置remote。
5)添加查询注解缓存
这里再添加注解之前,我们首先需要启动jetcache,也就是在Application启动类的时候添加上如下的注解:
@EnableMethodCache(basePackages = "com.jetcache.demo.controller") @EnableCreateCacheAnnotation
这里的扫描包是专门带有后面cached相关注解的包,一定要添加进去,不然的话会不生效,这里我们的示例图如下:
接着我们去想要缓存的地方添加注解实践。这里我们在查询的时候添加下注解缓存,固定的格式如下:
@Cached(name="userCache:", key = "#userId", expire = 3600, timeUnit = TimeUnit.SECONDS, cacheType = CacheType.REMOTE)
这里我们涉及到的cached信息是:
name: 这是给缓存添加一个keyname,注意不同的cache的话,我们应该使用不同的cachename。 key:就是name+key组成一个完整的cachename,这里的key是动态的,也就是在传递的方法里面的某个函数里面取值。 expire:所有的缓存我们都要给一个缓存时间,到了缓存期之后,会通过lru算法给淘汰掉,这里我们根据实际情况选择时间即可。 timeUnit:这是缓存过期时间的单位,配合expire使用。 cacheType:这里的cacheType,主要是3种,分别是:CacheType.REMOTE 把数据缓存到redis中去,CacheType.LOCAL把数据缓存到本地,CacheType.BOTH把数据同时缓存到redis和本地。
这里我们在演示代码的时候,我们接口对应的方法是:
@Cached(name="userCache:", key = "#userId", expire = 3600, timeUnit = TimeUnit.SECONDS, cacheType = CacheType.REMOTE) @RequestMapping("/getUserById") public UserPoJo getUserById(@RequestParam("userId")Integer userId) { log.info("根据userid获取用户:{}",userId); QueryWrapper<UserPoJo> q = new QueryWrapper<UserPoJo>(); q.eq("id", userId); return userDao.selectOne(q); }
此时我们可以看到在代码里面,我们通过用户id来获取完整的用户信息,然后把数据缓存到redis中去。此时我们用postman测试下效果:
第一次获取用户id为1的用户:
我们从http结果里面已经看到是获取到了用户的数据,此时我们看看服务器的日志:
可以看到我们在日志中打印的根据userid获取用户:${userid}给打印出来了,说明的是从缓存中没有获取到对应的数据,所以打印了日志,然后使用sql去查询了结果,然后我们看看redis中是否有缓存数据了:
可以看到在redis中当前用户的数据已经缓存到redis中了,那么按照我们的常理,如果下一次获取的话就应该直接从redis中获取数据了,然后不再取mysql中查询了,那么我们再试试第二次获取数据:
可以看到http正常的返回了数据,然后我们去看服务器日志:
此时我们可以看到日志只有刚才打印的那一条日志,没有其他日志,也就是这个框架自动帮我们返回了数据,不再执行我们方法里面编写的从mysql中获取数据。此时缓存就是生效的,这就是jetcache的基本使用,是不是很方便?
备注:
1、如果要使用缓存,切记在application启动类里面添加:
@EnableMethodCache(basePackages = "com.jetcache.demo.controller") @EnableCreateCacheAnnotation
这两个注解。
2、如果要使用缓存,对应的model必须要实现Serializable序列化。
最后按照惯例,我们附上本次演示的代码,登录后即可下载。
还没有评论,来说两句吧...