整合SpringBoot+JPA+Mysql+Redis实现缓存机制的一个Demo

  公司的项目中用到了Redis,最近一直在学习这一块。从开始学习到现在,总体给我的感觉是Redis上手比较容易,但是精通需要大量的实践和研究的。好在我们公司对Redis的使用并不是那么深入,目前只进行些简单的操作。总结这几天的学习结果,记录下来,希望有助于巩固和提高。

  说明:我的Redis服务是搭建在虚拟机Linux(Read Heat6.2)系统上的,Mysql数据库安装在本机,虚拟机的网络连接模式为桥接,和本机公用一个网段。网上有很多搭建的例子,这里就不进行说明了。

  导包:

<!--redis-->
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

<!--jpa-->
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<!--mysql-->
<dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
   <scope>runtime</scope>
</dependency>

  首先是SpringBoot中的配置文件(application.yml类型的配置文件,该类型文件对书写格式有严格的要求)

server:
  port: 8090
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/xxx?useUnicode=true&amp;characterEncoding=UTF-8&amp;autoReconnect=true
    username: xxx
    password: xxx
    driver-class-name: com.mysql.jdbc.Driver
    test-on-borrow: false
    test-while-idel: true
    time-between-eviction-runs-millis: 3600000
    tomcat:
      max-wait: 10000
      max-active: 50
  http:
    encoding:
      force: true
  jpa:
    hibernate:
      ddl-auto: update
      max_fetch_depth: 2
      naming:
        physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
    properties:
      hibernate:
        dialect: org.hibernate.dialect.MySQL5Dialect
        max_fetch_depth: 2
        format_sql: true
    show-sql: true
  redis:
    host: xxx
    password:
    port: 6379
    pool:
     # 连接池中的最大空闲连接
      max-idle: 8
     min-idle: 0
     # 连接池最大连接数(使用负值表示没有限制)
      max-active: 8
     # 连接池最大阻塞等待时间(使用负值表示没有限制)
      max-wait: 1
    # 连接超时时间(毫秒)
    timeout: 60000   

  

接下来是对Redis数据操作类的配置,提供了数据的序列化方式。Spring封装了RedisTimplement对象来对Redis进行操作,该模板默认采用JdkSerializationRedisSerializer的二进制序列化方式。

import com.fasterxml.jackson.annotation.JsonAutoDetect; 
import com.fasterxml.jackson.annotation.PropertyAccessor; 
import com.fasterxml.jackson.databind.ObjectMapper; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.cache.annotation.CachingConfigurerSupport; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.data.redis.connection.RedisConnectionFactory; 
import org.springframework.data.redis.core.HashOperations; 
import org.springframework.data.redis.core.ListOperations; 
import org.springframework.data.redis.core.RedisTemplate; 
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; 
import org.springframework.data.redis.serializer.StringRedisSerializer; 

@Configuration //标注一个配置类,交由spring管理 
public class Config extends CachingConfigurerSupport{ 

    @Autowired  
    private RedisConnectionFactory factory; //通过RedisConnectionFactory 引入redis在配置文件中的连接配置 
  
    /* * 此处为什么要序列化 原因:普通的连接使用没有办法把Java对象直接存入Redis, 
       * 而需要我们自己提供方案-对象序列化,然后存入redis, 
       * 取回序列化内容后,转换为java对
    * */  

    // 实例化 RedisTemplate 对象
    @Bean  
    public RedisTemplate<String,Object> redisTemplate(){ 
      RedisTemplate<String,Object> template = new RedisTemplate<>(); 
      initDomainRedisTemplate(template, factory); // 设置数据存入 redis 的序列化方式
      return template; 
    } 
   
    public void initDomainRedisTemplate(RedisTemplate template,RedisConnectionFactory factory){ 
        template.setConnectionFactory(factory); //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的 value 值 
        // 使用Jackson2JsonRedisSerialize 替换默认序列化
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
 
        ObjectMapper objectMapper = new ObjectMapper(); //ObjectMapper是jackson的主要类,作用序列化  
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); //设置任何字段可见  
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);//反序列化
 
        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);//设置序列化反序列化redis的value值
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        // 设置value的序列化规则和 key的序列化规则
        redisTemplate.setKeySerializer(stringRedisSerializer);//设置序列化反序列化key值的方式为String  
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.setHashKeySerializer(stringRedisSerializer);
        redisTemplate.setHashValueSerializer(stringRedisSerializer);
        redisTemplate.afterPropertiesSet(); //初始化操作,在设置完成后进行 
    } 

    //实例化HashOperations对象,可以使用Hash类型操作  
    @Bean  
    public HashOperations<String,String,Object> hashOperations(RedisTemplate<String,Object> redisTemplate){ 
         return redisTemplate.opsForHash(); //opsForHash()该方法用于操作Hash  
       } 

    //实例化ListOperations对象,可以使用List类型操作  
    @Bean  
    public ListOperations<String,Object> listOperations(RedisTemplate<String,Object> redisTemplate){ 
        return redisTemplate.opsForList(); //opsForList()该方法用于操作List  
       } 
}
 然后就是对Redis数据进行操作的工具类了,在此列举了三种数据类型,String、Hash、List
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Component
public class RedisUtil {
    
    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    @Autowired
    private HashOperations<String,String,Object> hashOperations;

    @Autowired
    private ListOperations<String,Object> listOperations;

    /*---------------------------------------------公共区域---------------------------------------------------*/

    //判断key是否存在
    public boolean hasKey(String key){
        return redisTemplate.hasKey(key);
    }

    //根据key删除key和value
    public void deleteByKey(String key){
        redisTemplate.delete(key);
    }

    /*
    * 设置key的有效期
    * @param key,time(有效时间),unit(hours,days,minutes)
    * */
    public void setExpire(String key,long time,TimeUnit unit){
        if (time != -1){
            redisTemplate.expire(key,time,unit);
        }
    }

    /*---------------------------------------------公共区域---------------------------------------------------*/




    /*----------------------------------------------String-------------------------------------------------*/

    //根据key获取value值
    public String getValue(String key){
       return (String) redisTemplate.opsForValue().get(key);
    }

    //插入数据
    public void setValue(String key,String value){
        redisTemplate.opsForValue().set(key,value);
    }

    /*----------------------------------------------String------------------------------------------------*/




    /*-----------------------------------------------hash--------------------------------------------------*/

    //存入hash类型的值
    public void addAllForHash(String key, Map<String,Object> map){
        hashOperations.putAll(key,map);
    }

    /*
    * 根据key查询该key对应map下的所有value
    * @param key
    * @return  List<AllValue>
    * */
    public List<Object> getAllValueForHash(String key){
       return hashOperations.values(key);
    }

    //获取Hash中的单个value
    public Object getValueForHash(String key, String hashKey){
        return hashOperations.get(key,hashKey);
    }

    //获取Hash数量
    public Long getCount(String key){
       return hashOperations.size(key);
    }

    /*
    * 根据key和hashKey删除value
    * @param key,hashKey
    * @return void
    * */
    public void deleteValueByKeyAndHashKey(String key,String hashKey){
        hashOperations.delete(key,hashKey);
    }

    /*
    * 判断当前key中hashKey是否存在
    * @param  key,hashKey
    * @return true / false
    * */
    public boolean hasHashKey(String key,String hashKey){
       return hashOperations.hasKey(key,hashKey);
    }

    /*
    * 查询key下所有Hash值
    * @param key
    * @return Map<key,value>
    * */
    public Object getAllHashByKey(String key){
       return hashOperations.entries(key);
    }

    /*-----------------------------------------------hash----------------------------------------------------*/


    /*-----------------------------------------------list----------------------------------------------------*/

    /*
    * 从list队列尾部存数据
    * @param key,List
    * @return null
    * */
    public void rightPushAll(String key, List<String> values){
        listOperations.rightPushAll(key,values);
    }

    /*
    * 从list队列尾部存数据
    * @param key,value
    * @return null
    * */
    public void rightPush(String key, String value){
        listOperations.rightPush(key,value);
    }

    /*
    *从list队列中取出全部数据(0,listSize)
    * @param key
    * @return List
    * */
    public List<Object> getListAll(String key){
       return listOperations.range(key,0,listOperations.size(key));
    }


    /*-----------------------------------------------list---------------------------------------------------*/

}

 

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值