Spring提供了一套规范,没有实现的接口,具体缓存方案需要实现这个接口
添加依赖
配置application.properties
spring.redis.host=127.0.0.1
spring.redis.database=0
spring.redis.port=6379
spring.redis.password=123456
#给当前缓存cache命名
spring.cache.cache-names=c1
创建Entity
package org.akk.cacheredis;
import java.io.Serializable;
//需要注意的是这里需要序列化
public class User implements Serializable {
private Integer id;
private String username;
private String address;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", address='" + address + '\'' +
'}';
}
}
创建service
package org.akk.cacheredis;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
@Service
public class UserService {
@Cacheable(cacheNames = "c1")
public User getUserById(Integer id){
System.out.println("getUserById>>>" + id);
User user = new User();
user.setId(id);
return user;
}
}
需要启用缓存需要在启动类上面添加注释@EnableCaching
@SpringBootApplication
@EnableCaching
public class CacheRedisApplication {
public static void main(String[] args) {
SpringApplication.run(CacheRedisApplication.class, args);
}
}
使用测试类测试
@SpringBootTest
class CacheRedisApplicationTests {
@Autowired
UserService userService;
@Test
void contextLoads() {
User u1 = userService.getUserById(266);
User u2 = userService.getUserById(266);
System.out.println(u1);
System.out.println(u2);
}
}
只打印了一遍,第二遍就是从redis缓存中获取的
查看redis
当在如下这种情况的时候 将不会被缓存,它会将不会被认为是同一条
@Test
void contextLoads() {
User u1 = userService.getUserById(266,"aa");
User u2 = userService.getUserById(266,"bb");
System.out.println(u1);
System.out.println(u2);
}
只需要在如下指定key 那么还是会被认定是一条因为指定了key
@Service
public class UserService {
@Cacheable(cacheNames = "c1",key = "#id")
public User getUserById(Integer id,String name){
System.out.println("getUserById>>>" + id);
User user = new User();
user.setId(id);
return user;
}
}
使用方法名字来作为key (还有cache,args,target)
@Service
public class UserService {
@Cacheable(cacheNames = "c1",key = "#method.name")
public User getUserById(Integer id,String name){
System.out.println("getUserById>>>" + id);
User user = new User();
user.setId(id);
return user;
}
}
如果要定义一个复杂的key 可以自己定义一个key的生成器
@Component
public class MyKeyGenerator implements KeyGenerator {
@Override
public Object generate(Object o, Method method, Object... objects) {
//接受一个object对象 一个Method 和一个可变长度的数组
//当前对象,当前请求方法。当前方法的参数
return method.getName()+":"+ Arrays.toString(objects);
}
}
使用key生成器的返回值作为key
@Service
public class UserService {
//keyGenerator对应一个实例的名字 首字母小写
@Cacheable(cacheNames = "c1",keyGenerator = "myKeyGenerator")
public User getUserById(Integer id,String name){
System.out.println("getUserById>>>" + id);
User user = new User();
user.setId(id);
return user;
}
}
删除操作的时候
public void deleteUserById(Integer id){
System.out.println("deleteUserById>>>" + id);
}
直接删除的时候将会删除数据库中的数据,但是再次调用get方法的时候,将会调用缓存中的数据,所以在做这个操作的时候要删除redis中的数据
只用注解@CacheEvict,cacheNames是配置文件中设置的缓存名字
@CacheEvict(cacheNames = "c1")
public void deleteUserById(Integer id){
System.out.println("deleteUserById>>>" + id);
}
当update的数据的时候使用如下注释@CachePut
@CachePut(cacheNames = "c1")
public User updateUserById(User user) {
return user;
}
在每一个方法上面都需要添加缓存命名可以使用@CacheConfig注释
@Service
@CacheConfig(cacheNames = "c1")
public class UserService {
//keyGenerator对应一个实例的名字 首字母小写
@Cacheable(cacheNames = "c1",keyGenerator = "myKeyGenerator")
public User getUserById(Integer id,String name){
System.out.println("getUserById>>>" + id);
User user = new User();
user.setId(id);
return user;
}
//当使用CacheConfig参数将不用写
@CacheEvict(cacheNames = "c1")
public void deleteUserById(Integer id){
System.out.println("deleteUserById>>>" + id);
}
@CachePut(cacheNames = "c1")
public User updateUserById(User user) {
return user;
}
}
当不想用redis 可以快速切换别的缓存 代码不用动