一、添加依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</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-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.1.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
</dependencies>
二、项目的目录结构:
三、一个ssm_book表格
四、配置文件application.yml
server:
servlet:
context-path: /redis
port: 8080
spring:
redis:
host: 127.0.0.1
port: 6379
jedis:
pool:
max-active: 8
max-wait: -1
max-idle: 8
min-idle: 0
timeout: 1200
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mvc?serverTimezone=UTC
username: root
password: 123456
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
五、配置redistemplate序列化
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
/*
选择redis作为默认缓存工具
*/
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofHours(1));//设置缓存有效期1小时
return RedisCacheManager
.builder(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory))
.cacheDefaults(redisCacheConfiguration).build();
}
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);//配置连接工厂
//使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值(默认使用JDK的序列化方式)
Jackson2JsonRedisSerializer jsonSerial = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
//指定要序列化的域、field、get和set,以及修饰符范围,ANY是都有(包括private和public)
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
//指定序列化输入的类型,类必须是非final修饰的,final修饰符的(比如String、Integer等会抛出异常)
om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
jsonSerial.setObjectMapper(om);
//值采用json序列化
template.setValueSerializer(jsonSerial);
//使用StringRedisSerializer来序列化和反序列化redis的key值
template.setKeySerializer(new StringRedisSerializer());
//设置hash、key和value序列化模式
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(jsonSerial);
template.afterPropertiesSet();
return template;
}
//对hash类型的数据操作
@Bean
public HashOperations<String, String, Object> hashOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForHash();
}
//对redis字符串类型数据操作
@Bean
public ValueOperations<String, Object> valueOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForValue();
}
//对链表类型的数据操作
@Bean
public ListOperations<String, Object> listOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForList();
}
//对无序集合类型的数据操作
@Bean
public SetOperations<String, Object> setOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForSet();
}
//对有序集合类型的数据操作
@Bean
public ZSetOperations<String, Object> zSetOperations(RedisTemplate redisTemplate) {
return redisTemplate.opsForZSet();
}
}
六、创建实体类Book
@Data
@ToString
@TableName(value = "ssm_book")
public class Book implements Serializable {
@TableId(value = "book_id",type = IdType.AUTO)
private Integer bookId;
@TableField(value = "book_name")
private String bookName;
@TableField(value = "book_author")
private String bookAuthor;
@TableField(value = "book_date")
private Date bookDate;
@TableField(value = "book_price")
private Double bookPrice;
}
七、创建BookMapper
@Mapper
public interface BookMapper extends BaseMapper<Book> { }
八、创建BookService
@Service
public class BookService {
@Autowired
private BookMapper bookMapper;
@Autowired
private RedisTemplate redisTemplate;
public List<Book> findAll(){
while(redisTemplate.opsForList().size("books")>0){
redisTemplate.opsForList().leftPop("books");
}
redisTemplate.opsForList().rightPushAll("books",bookMapper.selectList(null));
return bookMapper.selectList(null);
}
//获取book策略:先从缓存中获取book,没有则在数据库中获取,再将数据写入缓存
public Book findBookById(int id){
String key = "book_"+id;
ValueOperations<String,Book> operations = redisTemplate.opsForValue();
//判断redis中是否有键为key的缓存
boolean hasKey = redisTemplate.hasKey(key);
if(hasKey){
Book book = operations.get(key);
System.out.println("从缓存中获得数据:"+book.getBookName());
System.out.println("-----------------------------------");
return book;
}else{
Book book = bookMapper.selectById(id);
System.out.println("从数据库中获得数据:"+book.getBookName());
System.out.println("-----------------------------------");
//写入缓存
operations.set(key,book,5, TimeUnit.HOURS);
return book;
}
}
//更新图书策略:先更新数据表,成功之后,删除原来的缓存,再更新缓存
public int updateBook(Book book){
ValueOperations<String,Object> operations = redisTemplate.opsForValue();
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.eq("book_id",book.getBookId());
int result = bookMapper.update(book,queryWrapper);
if(result !=0 ){
String key = "book_"+book.getBookId();
boolean haskey = redisTemplate.hasKey(key);
if(haskey){
redisTemplate.delete(key);
System.out.println("删除缓存中的key------------> "+key);
}
//再将更新后的数据加入缓存
Book newbook = bookMapper.selectById(book.getBookId());
if(newbook != null){
operations.set(key,newbook,3,TimeUnit.HOURS);
}
}
return result;
}
//删除图书策略:删除数据表中的数据,然后删除缓存
public int deleteBookById(int id){
int result = bookMapper.deleteById(id); //删除数据库中记录
String key = "book_"+id;
if(result != 0){
boolean hasKey = redisTemplate.hasKey(key); //查询缓存是否存在对应的id
if(hasKey){
redisTemplate.delete(key);//删除缓存中的数据
System.out.println("删除了缓存中的key:"+key);
}
}
return result;
}
}
九、测试
@SpringBootTest
class RedisdemoApplicationTests {
@Autowired
private BookService bookService;
@Autowired
private RedisTemplate redisTemplate;
@Test
public void all(){
List<Book> bookList = redisTemplate.opsForList().range("books",0,-1);
System.out.println("缓存中数据:"+bookList.size());
if(bookList.size()==0){
System.out.println("=========缓存中没有数据,直接到数据库中查询==========");
bookList = bookService.findAll();
}else{
System.out.println("==============缓存中有数据了==============");
bookList.forEach(book -> System.out.println(book));
}
}
@Test
public void selectById(){
Book book = bookService.findBookById(52);
System.out.println(book);
}
@Test
public void update(){
Book book = bookService.findBookById(57);
book.setBookName("读城记");
book.setBookAuthor("易中天");
book.setBookDate(new Date());
book.setBookPrice(889.5);
bookService.updateBook(book);
}
@Test
public void del(){
bookService.deleteBookById(13);
}
}