謹以此做個筆記。
平時我們使用的redis無非是用作緩存以及分布式session,其他的作用就視項目需求而定了富雅。
這里主要講講redis作為緩存的作用掸驱。
使用redis做緩存,可以選擇單獨使用没佑,也可以和spring cache整合毕贼。
單獨使用redis也很方便,只是代碼耦合性高了蛤奢,所以這次試試與spring cache整合使用鬼癣。
spring cache主要是代碼級的緩存,加上redis可以使代碼解耦又可以使緩存以單純的內存級發(fā)揮作用啤贩〈海可能理解不完全對,具體的可以再去深入了解一下痹屹,這里謹以此做個筆記而已章郁。
話不多說,開始痢掠。
spring boot版本
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath/>
</parent>
1驱犹、引入redis和spring cache依賴包嘲恍,pom.xml文件如下:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
注:lombok依賴包可以自動生成getter足画、setter以及構造函數(shù)等方法,挺好用的佃牛。
2淹辞、創(chuàng)建一個簡單的POJO
@Data
public class User {
private int id;
private String name;
private int age;
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
3、因為這里用的mybatis俘侠,所以創(chuàng)建與POJO對應的mapper
@Mapper
public interface UserMapper {
@Insert("INSERT INTO users(name, age) VALUES(#{name}, #{age})")
int save(User user);
@Select("SELECT * FROM users WHERE id = #{id}")
User getById(int id);
@Delete("DELETE FROM users WHERE id = #{id}")
int deleteUser(int id);
@Update("UPDATE users SET name = #{name}, age = #{age} WHERE id = #{id}")
int updateUser(User user);
}
4象缀、創(chuàng)建UserService
public interface UserService {
User getById(int id);
int deleteUser(int id);
int updateUser(int id, User user);
void cleanCache();
}
5、配置application.yml
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/test
username: root
password: 761341
redis:
host: localhost
port: 6379
pool:
max-active: 8
max-idle: 8
max-wait: -1
min-idle: 1
management:
security:
enabled: false
redis-expires:
cache-names: redisCache
default-expiration: 3600
expires:
redisCache: 3600
6爷速、配置RedisCacheManager
@Configuration
@EnableCaching
@EnableConfigurationProperties(RedisProperties.class)
@ConfigurationProperties(prefix = "redis-expires")
public class CustomRedisCacheManager {
@Autowired
private RedisProperties redisProperties;
private List<String> cacheNames;
private long defaultExpiration;
private Map<String, Long> expires;
public List<String> getCacheNames() {
return cacheNames;
}
public void setCacheNames(List<String> cacheName) {
this.cacheNames = cacheName;
}
public long getDefaultExpiration() {
return defaultExpiration;
}
public void setDefaultExpiration(long defaultExpiration) {
this.defaultExpiration = defaultExpiration;
}
public Map<String, Long> getExpires() {
return expires;
}
public void setExpires(Map<String, Long> expires) {
this.expires = expires;
}
/**
* 重寫緩存key生成機制
* @return
*/
// @Bean
// @Primary
// public KeyGenerator keyGenerator() {
// return (target, method, params) -> {
// StringBuilder sb = new StringBuilder();
// sb.append(target.getClass().getName());
// sb.append(method.getName());
// for (Object obj : params) {
// sb.append(obj.toString());
// }
// return sb.toString();
// };
// }
@Bean("redisCacheManager")
@Primary
public CacheManager cacheManager(RedisTemplate redisTemplate) {
RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
cacheManager.setCacheNames(cacheNames);
cacheManager.setDefaultExpiration(defaultExpiration);
cacheManager.setExpires(expires); // 設置緩存過期時間
cacheManager.setUsePrefix(true); // 是否使用緩存前綴
redisTemplate.afterPropertiesSet();
return cacheManager;
}
/**
* 配置json序列化
*/
@Bean
@Primary
public RedisTemplate<Object, Object> redisTemplate(JedisConnectionFactory jedisConnectionFactory) {
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(jedisConnectionFactory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
@Bean
public JedisConnectionFactory jedisConnectionFactory() {
JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
jedisConnectionFactory.setHostName(redisProperties.getHost());
jedisConnectionFactory.setPort(redisProperties.getPort());
jedisConnectionFactory.setTimeout(redisProperties.getTimeout());
jedisConnectionFactory.setPoolConfig(jedisPoolConfig());
jedisConnectionFactory.afterPropertiesSet();
return jedisConnectionFactory;
}
private JedisPoolConfig jedisPoolConfig() {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
RedisProperties.Pool props = this.redisProperties.getPool();
jedisPoolConfig.setMaxTotal(props.getMaxActive());
jedisPoolConfig.setMaxIdle(props.getMaxIdle());
jedisPoolConfig.setMinIdle(props.getMinIdle());
jedisPoolConfig.setMaxWaitMillis(props.getMaxWait());
return jedisPoolConfig;
}
}
注:KeyGenerator可以配置緩存key的生成策略央星,如果不配置將使用SimpleKeyGenerator生成key,源碼如下惫东,但是建議還是在處理緩存的時候指定key莉给。
public static Object generateKey(Object... params) {
if (params.length == 0) {
return SimpleKey.EMPTY;
}
if (params.length == 1) {
Object param = params[0];
if (param != null && !param.getClass().isArray()) {
return param;
}
}
return new SimpleKey(params);
}
7、實現(xiàn)UserService
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
//這里指定了cacheNames = "redisCache"表示使用我們配置的默認緩存管理器也就是RedisCacheManager廉沮。debug模式可以看見第二次查詢時不會進入方法體颓遏。
@Cacheable(cacheNames = "redisCache", key = "#id")
public User getById(int id) {
return userMapper.getById(id);
}
@Override
@CacheEvict(cacheNames = "redisCache", key = "#id")
public int deleteUser(int id) {
return userMapper.deleteUser(id);
}
@Override
//更新指定緩存
@CachePut(cacheNames = "redisCache", key = "#id")
//清除指定緩存
//@CacheEvict(cacheNames = "redisCache", key = "#id")
public int updateUser(int id, User user) {
user.setId(id);
return userMapper.updateUser(user);
}
@Override
//allEntries = true:清除所有緩存
@CacheEvict(cacheNames = "redisCache", allEntries = true)
public void cleanCache() {
}
}