2.3 SpringCache注解详解
2.3.1 @Cacheable注解
==如果缓存中没有:查询数据库,存储缓存,返回结果,==
==如果缓存中有:直接返回结果==
作用:可以用来进行缓存的写入,将结果存储在缓存中,以便于在后续调用的时候可以直接返回缓存中的值,而不必再执行实际的方法。 最简单的使用方式,注解名称=缓存名称,使用例子如下:
示例代码:
public class RoleServiceImpl implements IRoleService {
@Autowired
private RoleMapper roleMapper;
/**
* <p>
* 几个属性:
* a)cacheNames/value:指定缓存组件的名字
* cacheNames = {"role"}可以使用多个参数,是数组的形式,可以指定多个缓存
* b)key:缓存数据使用的key,可以用他来指定。默认是使用方法参数的值
* 编写SpEl: #id #a0,#po,#argrs[0] "0"代表参数的索引
* #result 方法执行后的返回值
* #root.methodName 方法名
* key = "#root.methodName+'['+#id+']'"
* e)condition:指定符合缓存的条件
* condition = "#id>0 and #root.methodName eq 'aaa'" 可以多条件判断
* f)unless: 否定缓存,当unless的条件为true,方法结果不会被缓存,可以获取结果进行判断
* unless = "#result==null",结果为null,就不缓存
*/
// findById()方法的返回值Role作为 key = "#id"的value在缓存中保存,无需配置
@Cacheable(cacheNames = "role", key = "#id")//#id表示引用findById(Integer id)中id的值
@Override
public Role findById(Integer id) {
return roleMapper.selectByPrimaryKey(id);
}
}
测试代码
package com.itheima.cache;
import com.itheima.cache.model.Role;
import com.itheima.cache.service.IRoleService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class MyTest {
@Autowired
private IRoleService roleService;
/**
* @Description 缓存测试
*/
@Test
public void test1(){
Role role = roleService.findById(8);
System.out.println("role:"+role);
}
}
控制台打印
JDBC Connection [HikariProxyConnection@256089615 wrapping com.mysql.cj.jdbc.ConnectionImpl@62410e1f] will not be managed by Spring
==> Preparing: select id,roleName,roleCode, introduce from role where id = ?
==> Parameters: 8(Integer)
<== Columns: id, roleName, roleCode, introduce
<== Row: 8, 0088Role, 0088, 00888Introduce
<== Total: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@dd9de63]
role:Role(id=8, rolename=0088Role, rolecode=0088, introduce=00888Introduce)
redis中
再次执行测试方法,控制台打印
2024-01-16 17:48:54.933 INFO 5556 --- [ main] com.itheima.cache.MyTest : Started MyTest in 5.959 seconds (JVM running for 7.641)
role:Role(id=8, rolename=0088Role, rolecode=0088, introduce=00888Introduce)
2024-01-16 17:48:56.374 INFO 5556 --- [extShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor'
没有打印sql,说明没有查询mysql,直接从redis中查询的数据
缓存mysql中所有的数据
//root代表当前findAllRole()方法所在的类,methodName代表当前方法名
@Cacheable(cacheNames = "role", key = "#root.methodName")
@Override
public R findAllRole() {
List<Role> roleList = roleMapper.findAll();
return R.ok(roleList);
}
测试代码
@Test
public void test2(){
R allRole = roleService.findAllRole();
System.out.println(allRole);
}
执行完查看控制台
JDBC Connection [HikariProxyConnection@94166581 wrapping com.mysql.cj.jdbc.ConnectionImpl@43de9fc9] will not be managed by Spring
==> Preparing: select id,roleName,roleCode, introduce from role
==> Parameters:
<== Columns: id, roleName, roleCode, introduce
<== Row: 1, Richeldis, i, nt in culpa qui officia deserunt mollit an
<== Row: 4, Hester, unt in culpa qui officia deserunt mollit anim id est laborum.Lorem, amco l
<== Row: 5, Jaime, de, it, sed do eiusmod tempor incididunt ut l
<== Row: 6, 006Role, 006, 006Introduce
<== Row: 7, Jason, t nulla pariatur. Excepteur sint occaecat , t. Duis aute irure dolor in reprehenderit in voluptate velit esse cill
<== Row: 8, 0088Role, 0088, 00888Introduce
<== Row: 9, Drew, cididunt ut labore et dolore magna ali, fugiat nulla pariatur. Excepteur sint oc
<== Row: 10, Anne, it a, um.Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed
<== Total: 8
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@56f61d74]
com.itheima.cache.common.R@757c685d
查看redis
可以把 @CacheConfig(cacheNames = "role")加在类上,那么每个缓存都会生成role的前缀
@Service
@CacheConfig(cacheNames = "role")
public class RoleServiceImpl implements IRoleService {
@Autowired
private RoleMapper roleMapper;
// findById()方法的返回值Role作为 key = "#id"的value在缓存中保存,无需配置
@Cacheable(key = "#id")//#id表示引用findById(Integer id)中id的值
@Override
public Role findById(Integer id) {
return roleMapper.selectByPrimaryKey(id);
}
@Cacheable(key = "#root.methodName")
@Override
public R findAllRole() {
List<Role> roleList = roleMapper.findAll();
return R.ok(roleList);
}
}
清空缓存,再分别执行test1和test2方法
查看redis