spring-boot-note6---redis
SpringBoot整合Redis,本文采用RedisTemplate操作redis和配置CacheMannager使用快取註解的二個方式。
一、配置相關
1、新增pom依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId>
</dependency>
2、application.properties
#redis配置
spring.redis.database=0
#Redis伺服器地址
spring.redis.host=127.0.0.1
#Redis伺服器連線埠
spring.redis.port=6379
#Redis伺服器連線密碼(預設為空)
spring.redis.password=123456
#連線超時時間
spring.redis.timeout=2000
#連線池最大連線數(使用負值表示沒有限制)
spring.redis.pool.max-active=500
#連線池最大阻塞等待時間(使用負值表示沒有限制)
spring.redis.pool.max-wait=10000
#連線池中的最大空閒連線
spring.redis.pool.max-idle=50
#連線池中的最小空閒連線
spring.redis.pool.min-idle=0
包結構:
配置類詳細:(1、配置redisTemplate可直接操作redis,2、配置CacheManager+@EnableCaching可以使用快取註解)
@Configuration
@EnableCaching // 開啟註解的方式
public class RedisConfig {
/**
* 1、設定CacheManager實現為redisCacheMannager,並且開啟EnableCaching,可以使用快取註解。
*/
@Bean
public CacheManager cacheManager(RedisTemplate<?, ?> redisTemplate) {
RedisCacheManager rcm = new RedisCacheManager(redisTemplate);
rcm.setUsePrefix(true);
rcm.setCacheNames(Arrays.asList("myCache"));
rcm.setDefaultExpiration(600);
return rcm;
}
/**
* 2、redisTemplate配置完成可以直接使用redis
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
//使用Jackson2JsonRedisSerializer來序列化和反序列化redis的value值(預設使用JDK的序列化方式)
Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, Visibility.ANY);
mapper.enableDefaultTyping(DefaultTyping.NON_FINAL);
serializer.setObjectMapper(mapper);
//使用StringRedisSerializer來序列化和反序列化redis的key值
template.setValueSerializer(serializer);
template.setKeySerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(serializer);
template.afterPropertiesSet();
return template;
}
二、使用redistemplate操作redis
1、pojo、dao等。
public class Person implements Serializable{
private static final long serialVersionUID = -3189329947019478591L;
private Integer id;
public String name;
@Component
public class PersonDao {
private static Map<Integer, Person> map = new HashMap<>();
static {
Person p;
for (int i = 0; i < 10; i++) {
p = new Person();
p.setId(i);
p.setName("name" + i);
map.put(i, p);
}
}
public void deleteById(Integer id) {
map.remove(id);
}
public Person findById(Integer id) {
return map.get(id);
}
public void updateOne(Person person) {
Person old = map.get(person.getId());
old.setName(person.getName());
}
public void saveOne(Person person) {
map.put(person.getId(), person);
}
public List<Person> findList() {
return new ArrayList<>(map.values());
}
2、redisTemplate操作redis的service類
/**
* 使用redisTemplate操作快取。
*/
@Service
public class PersonService {
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private PersonDao personDao;
@Resource
private RedisTemplate<String, Person> redisTemplate;
/**
* 查詢person
* 快取存在從快取中取,不存在,查詢出放入快取。
*/
public Person getById(int id) {
logger.info("獲取使用者start...");
String key = "person_" + id;
ValueOperations<String, Person> operations = redisTemplate.opsForValue();
boolean hasKey = redisTemplate.hasKey(key);
if (hasKey) {
Person user = operations.get(key);
logger.info("從快取中獲取了 id = " + id);
return user;
}
Person person = personDao.findById(id);
operations.set(key, person, 10, TimeUnit.SECONDS);
return person;
}
/**
* 更新使用者
* 如果快取存在,刪除
* 如果快取不存在,不操作
*/
public void updateUser(Person person) {
logger.info("更新使用者start...");
personDao.updateOne(person);
String key = "person_" + person.getId();
boolean hasKey = redisTemplate.hasKey(key);
if (hasKey) {
redisTemplate.delete(key);
logger.info("更新時,刪除快取id= " + person.getId());
}
}
/**
* 刪除使用者
* 如果快取中存在,刪除
*/
public void deleteById(int id) {
logger.info("刪除使用者start...");
personDao.deleteById(id);
String key = "person_" + id;
boolean hasKey = redisTemplate.hasKey(key);
if (hasKey) {
redisTemplate.delete(key);
logger.info("刪除時,從快取中刪除id=>> " + id);
}
}
}
3、測試使用。
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
public class TestPersonService {
@Autowired
private PersonService personService;
/**
* redis快取使用redisTemplate操作的演示
*/
@Test
public void testCache() {
int id = 1;
Person person = personService.getById(id); // 第1次查詢 //獲取使用者start...
Person person2 = personService.getById(id); // 第2次查詢 //獲取使用者start...
//從快取中獲取了 id = 1
person2.setName("update_name");
personService.updateUser(person2); // 第1次更新 //更新使用者start...
//更新時,刪除快取id= 1
Person person3 = personService.getById(id); // 第3次查詢 //獲取使用者start...
System.out.println(person3.getName()); // update_name
personService.deleteById(id); // 第1次刪除 // 刪除使用者start...
// 刪除時,從快取中刪除id=>> 1
assertNull(personService.getById(id));
}
}
三、使用快取註解的方式。
@Service
public class PersonCacheService {
@Autowired
private PersonDao personDao;
/**
* 查詢一個Person
*/
@Cacheable(value = "myCache", key = "'Persons_'+#id")
public Person findPerson(Integer id) {
Person person = this.personDao.findById(id);
System.out.println("資料庫查一條記錄:id=" + id);
return person;
}
/**
* 更新一個Person,每次都會執行。
*/
@CachePut(value="myCache", key="'Persons_'+#id")
public Person updatePerson(Person person,Integer id) {
this.personDao.updateOne(person);
System.out.println("資料庫更新一條記錄:id=" + id);
return person;
}
/**
* 刪除一個Person
*/
@CacheEvict(value = "myCache", key = "'Persons_'+#id", condition = "#id!=99")
public void delPerson(Integer id) {
System.out.println("資料庫刪除一條記錄:id=" + id);
this.personDao.deleteById(id);
}
}
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
public class TestPersonCacheService {
@Autowired
private PersonCacheService personCacheService;
@Test
public void test1() {
Person person1 = personCacheService.findPerson(1); // 資料庫查一條記錄:id=1
Person person2 = personCacheService.findPerson(1);
person2.setName("update_name");
personCacheService.updatePerson(person2, 1); //資料庫更新一條記錄:id=1
Person person3 = personCacheService.findPerson(1); // 不查詢,@CachePut每次都會執行,並把結果放入快取。
System.out.println(person3.getName()); //update_name
personCacheService.delPerson(1); // 資料庫刪除一條記錄:id=1
}
}