365bet注册开户SpringBoot集成Redis来促成缓存本领方案

剔除缓存

在delete的时候用@CacheEvict清楚那条缓存。

    @RequestMapping("/deletePrud")
    @CacheEvict("pruddeleteCache")
    public String deletePrud(@RequestParam(required=true)String id){
        return "SUCCESS";
    }

@CachePut将这么些艺术的归来值放到缓存,假诺大家放四个Pruduct对象,他会将那些指标作为key,那分明不是我们想要的。那个时候就供给自定义大家的key。

springboot缓存有些方法

template(模版)

不过我们开掘每趟增多的key和value都以byte数组类型(使用很麻烦),于是spring为我们带来了redis
template(模版)

Spring Data Redis提供了五个模板:
  RedisTemplate
  StringRedisTemplate

先是大家先成立贰个RedisTemplate模板类,类型的key是String类型,value是Object类型(假若key和value都以String类型,提出利用StringRedisTemplate)

    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory factory){
        //创建一个模板类
        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        //将刚才的redis连接工厂设置到模板类中
        template.setConnectionFactory(factory);
        return template;
    }

单元测量检验

    @Autowired    
    RedisTemplate<String, Object> template;

    @Test
    public void testRedisTemplate(){
        template.opsForValue().set("key1", "value1");
        System.out.println(template.opsForValue().get("key1"));
    }

收获结果输出value1,是否很有利了吧。

 要是是操作会集呢,也很方便的哈。

    @Test
    public void testRedisTemplateList(){

        Pruduct prud  = new Pruduct(1, "洗发水", "100ml");
        Pruduct prud2  = new Pruduct(2, "洗面奶", "200ml");
        //依次从尾部添加元素
        template.opsForList().rightPush("pruduct", prud);
        template.opsForList().rightPush("pruduct", prud);
        //查询索引0到商品总数-1索引(也就是查出所有的商品)
        List<Object> prodList = template.opsForList().range("pruduct", 0,template.opsForList().size("pruduct")-1);
        for(Object obj:prodList){
            System.out.println((Pruduct)obj);
        }
        System.out.println("产品数量:"+template.opsForList().size("pruduct"));

    }

 


第二次搜索用户:开掘服务端并未有打字与印刷任何数据库查询日志,能够领略第一遍查询是从缓存中查询获得的多寡。

自定义key

@Cacheable和@CachePut都有八个名称叫key属性,那本特性能够替换暗中同意的key,它是通过叁个表明式(Spel表明式,spring提供的,很轻便)计算获得的。

例如下边包车型客车正是将回来对象的id当作key来存款和储蓄(可是Pruduct的id是int类型,所以须求将数字转化成String类型)

    @RequestMapping("/savePrud")
    @CachePut(value="prudsaveCache",key="#result.id +''")
    public Pruduct savePrud(Pruduct prud){
        return prud;
    }

除此以外除了#result是表示函数的重回值,spring还为大家带来了别的的有个别元数据 

365bet注册开户 1

增加缓存

接下去大家在controller层的点子内充足评释,然后运转大家的品类。

    @RequestMapping("/getPrud")
    @Cacheable("prudCache")
    public Pruduct getPrud(@RequestParam(required=true)String id){
        System.out.println("如果第二次没有走到这里说明缓存被添加了");
        return pruductDao.getPrud(Integer.parseInt(id));
    }

发觉打字与印刷的这段话只被打字与印刷二遍,表达在走到这一个办法的时候接触了五个断面,而且查找重返缓存中的数据。

当然@Cacheable注脚也可以放置这几个dao层的主意里面,可是此地会报二个错,Integer相当小概转成String,因为我们dao层方法的参数类型是int,而RedisTemplate的key类型是String,这里是要小心的。

张开redis的客户端发掘redis对应的key正是我们的参数1,那一年就能出题目,举个例子说作者在任何要缓存的点子的参数也是1,就能再次。后边大家会将自定义这一个key的值。

除此而外@Cacheable加多缓存外,springboot还为大家带了了别的多少个表明

365bet注册开户 2

key和value序列化

当保存一条数据的时候,key和value都要被连串化成json数据,抽取来的时候被类别化成对象,key和value都会使用类别化器进行连串化,spring
data redis提供多少个种类化器

  • GenericToStringSerializer:使用Spring调换服务进行体系化;
  • 杰克逊JsonRedisSerializer:使用Jackson 1,将对象体系化为JSON;
  • Jackson2JsonRedis塞里alizer:使用杰克逊 2,将目的类别化为JSON;
  • JdkSerializationRedisSerializer:使用Java序列化;
  • OxmSerializer:使用Spring
    O/X映射的编排器和解排器(marshaler和unmarshaler)实
  • 现种类化,用于XML连串化;
  • StringRedisSerializer:序列化String类型的key和value。

RedisTemplate会暗中认可使用JdkSerializationRedis塞里alizer,那意味着key和value都会透过Java进行种类化。StringRedisTemplate暗许会使用StringRedis塞里alizer

举例说,假诺当使用RedisTemplate的时候,大家愿意将Product类型的value类别化为JSON,而key是String类型。RedisTemplate的setKeySerializer()和setValue塞里alizer()方法就须要如下所示:

    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory factory) {
        // 创建一个模板类
        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        // 将刚才的redis连接工厂设置到模板类中
        template.setConnectionFactory(factory);
        // 设置key的序列化器
        template.setKeySerializer(new StringRedisSerializer());
        // 设置value的序列化器
        //使用Jackson 2,将对象序列化为JSON
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        //json转对象类,不设置默认的会将json转成hashmap
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        template.setValueSerializer(jackson2JsonRedisSerializer);

        return template;
    }

到此处,大家肯定会对springboot使用redis有了简约的垂询。


 

private PersonRepo personRepo;

 本文代码github地址

比很多时候,大家会在springboot中布署redis,可是就那么多少个布局就配好了,不能知道怎么,…

 总结demo:

将类名方法名和pruduct的id作为key

    @RequestMapping("/getPrud3")
    @Cacheable(value ="prudCache",key="#root.targetClass.getName() + #root.methodName + #id")
    public Pruduct getPrud3(@RequestParam(required=true)String id){
        System.out.println("如果第二次没有走到这里说明缓存被添加了");
        return pruductDao.getPrud(Integer.parseInt(id));
    }

 最后注意

#result 方法再次来到值不能够用在@Cacheable上,只好用在@CachePut

 

springboot缓存某些方法

application:

springboot缓存某些方法

springboot配置进步轻巧化

道理当然是那样的上边包车型地铁配置只是为了精通原理的哈,实际上大家运用会更轻便题。大家重写了RedisConfig

365bet注册开户 3365bet注册开户 4

@Configuration
@EnableCaching//开启缓存
public class RedisConfig extends CachingConfigurerSupport {

    @Bean
    public KeyGenerator keyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object target, Method method, Object... 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();
            }
        };
    }    
    /**
     * 申明缓存管理器,会创建一个切面(aspect)并触发Spring缓存注解的切点(pointcut)
     * 根据类或者方法所使用的注解以及缓存的状态,这个切面会从缓存中获取数据,将数据添加到缓存之中或者从缓存中移除某个值

     * @return
     */
    @Bean
    public RedisCacheManager cacheManager(RedisTemplate redisTemplate) {
        return new RedisCacheManager(redisTemplate);
    }


    @Bean
    @Primary
    public RedisTemplate redisTemplate(RedisConnectionFactory factory) {
        // 创建一个模板类
        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        // 将刚才的redis连接工厂设置到模板类中
        template.setConnectionFactory(factory);
        // 设置key的序列化器
        template.setKeySerializer(new StringRedisSerializer());
        // 设置value的序列化器
        //使用Jackson 2,将对象序列化为JSON
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        //json转对象类,不设置默认的会将json转成hashmap
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        template.setValueSerializer(jackson2JsonRedisSerializer);

        return template;
    }

}

View Code

然后在resources下的application.properties下配置

365bet注册开户 5365bet注册开户 6

# REDIS (RedisProperties)
# Redis数据库索引(默认为0)
spring.redis.database=0  
# Redis服务器地址
spring.redis.host=127.0.0.1
# Redis服务器连接端口
spring.redis.port=6379  
# Redis服务器连接密码(默认为空)
spring.redis.password=
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.pool.max-active=8  
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.pool.max-wait=-1  
# 连接池中的最大空闲连接
spring.redis.pool.max-idle=8  
# 连接池中的最小空闲连接
spring.redis.pool.min-idle=0  
# 连接超时时间(毫秒)
spring.redis.timeout=0

View Code

世家开采大家并未注册RedisConnectionFactory,那是因为spring默许帮大家读取application.properties文件同一时候注册了三个factorybean

keyGenerator方法帮我们报了名了一个key的成形准绳,就不用大家写spel表达式了,依照反射的准则读取类名+方法名+参数。然而大家不常候依旧必要结合spel的。

下一场在controller上加上@Cacheable(“cachename”),之后就能够在redis察看保存了还要key的值是keyGenerator生成的名字

 

 

 条件化缓存

通过为格局增加Spring的缓存注脚,Spring就能够围绕着这么些艺术创设叁个缓存切面。可是,在多少场景下我们恐怕希望将缓存功能关闭。

@Cacheable和@CachePut提供了多少个属性用以达成条件化缓存:unless和condition,这两本特性都承受三个SpEL表明式。若是unless属性的SpEL表明式总计结
果为true,那么缓存方法重临的数据就不会放到缓存中。与之附近,假设condition属性的SpEL表明式总结结果为false,那么对于这几个艺术缓存就能够被禁止使用掉

外表上来看,unless和condition属性做的是同一的政工。可是,这里有一点点轻微的差距。

unless属性只可以阻止将指标放进缓存,但是在这些方法调用的时候,依旧会去缓存中实行搜寻,假如找到了合作的值,就能回到找到的值。

与之差异,如若condition的表明式总结结果为false,那么在那些方法调用的长河中,缓存是被剥夺的。便是说,不会去缓存实行查找,同期再次来到值也不会放进缓存中。

 

    @RequestMapping("/getPrud2")
    @CachePut(value ="prudCache",unless="#result.desc.contains('nocache')")
    public Pruduct getPrud2(@RequestParam(required=true)String id){
        System.out.println("如果走到这里说明,说明缓存没有生效!");
        Pruduct p = new Pruduct(Integer.parseInt(id), "name_nocache"+id, "nocache");
        return p;
    }

 

上边包车型客车代码中,倘使回去的靶子desc中涵盖nocache字符串,则不开始展览缓存。

 

public JsonResp removePersonByName(@QueryParam(“username”) String username) {

表达缓存处理器

在一些时候,大家也有与此相类似的须求,用户登入的时候,大家会从数据库中读取用户全体的权能,部门等音讯。并且每一遍刷新页面都亟需看清该用户有没有那些权力,若是不停的从数据库中读并且总结,

是老大耗质量的,所以我们以此时候将在采纳了springboot为大家带来的缓存管理器

 

第一在大家的RedisConfig那么些类上增多@EnableCaching其一评释。

其一表明会被spring开采,而且会创制二个断面(aspect)
并触发Spring缓存申明的切点(pointcut) 。
依据所使用的讲明以及缓存的意况, 那一个切面会从缓存中获取数据,
将数据拉长到缓存之中可能从缓存中移除有个别值。  
接下来大家须要说雀巢(Beingmate)(Karicare)个缓存管理器的bean,这么些效应正是@EnableCaching这些切面在增加产量缓存只怕去除缓存的时候会调用这么些缓存管理器的不二法门

/**
     * 申明缓存管理器,会创建一个切面(aspect)并触发Spring缓存注解的切点(pointcut)
     * 根据类或者方法所使用的注解以及缓存的状态,这个切面会从缓存中获取数据,将数据添加到缓存之中或者从缓存中移除某个值

     * @return
     */
    @Bean
    public RedisCacheManager cacheManager(RedisTemplate redisTemplate) {
        return new RedisCacheManager(redisTemplate);
    }

 当然,缓存管理器除了RedisCacheManager还应该有点其余的。比方

ConcurrentMapCacheManager,那几个大致的缓存处理器使用java.util.concurrent.ConcurrentHashMap作为其缓存存款和储蓄。它特别简单,由此对于开采、测量检验或基础的采纳来说,那是多个很准确的选用.

redis连接工厂类 

率先步,要求增多springboot的redis jar包

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

然后大家写贰个配置类,创造了一个redis连接的工厂的spring
bean。(Redis连接工厂会生成到Redis数据库服务器的连日)

@Configuration
public class RedisConfig {
    @Bean
    public RedisConnectionFactory redisCF(){
        //如果什么参数都不设置,默认连接本地6379端口
        JedisConnectionFactory factory = new JedisConnectionFactory();
        factory.setPort(6379);
        factory.setHostName("localhost");
        return factory;
    }
}

单元测验,看看这些工厂方法的采用

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = Application.class)
public class RedisTest {

    @Autowired
    RedisConnectionFactory factory;

    @Test
    public void testRedis(){
        //得到一个连接
        RedisConnection conn = factory.getConnection();
        conn.set("hello".getBytes(), "world".getBytes());
        System.out.println(new String(conn.get("hello".getBytes())));
    }

}

出口结果
:world,表明已经成功获取到连年,並且往redis赢得充裕数据, 

springboot配置提高轻易化

当然上边的安插只是为了精通原理的哈,实际上咱们利用会更轻易点。我们重写了RedisConfig

365bet注册开户 7365bet注册开户 8

@Configuration
@EnableCaching//开启缓存
public class RedisConfig extends CachingConfigurerSupport {

    @Bean
    public KeyGenerator keyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object target, Method method, Object... 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();
            }
        };
    }    
    /**
     * 申明缓存管理器,会创建一个切面(aspect)并触发Spring缓存注解的切点(pointcut)
     * 根据类或者方法所使用的注解以及缓存的状态,这个切面会从缓存中获取数据,将数据添加到缓存之中或者从缓存中移除某个值

     * @return
     */
    @Bean
    public RedisCacheManager cacheManager(RedisTemplate redisTemplate) {
        return new RedisCacheManager(redisTemplate);
    }


    @Bean
    @Primary
    public RedisTemplate redisTemplate(RedisConnectionFactory factory) {
        // 创建一个模板类
        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        // 将刚才的redis连接工厂设置到模板类中
        template.setConnectionFactory(factory);
        // 设置key的序列化器
        template.setKeySerializer(new StringRedisSerializer());
        // 设置value的序列化器
        //使用Jackson 2,将对象序列化为JSON
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        //json转对象类,不设置默认的会将json转成hashmap
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        template.setValueSerializer(jackson2JsonRedisSerializer);

        return template;
    }

}

View Code

然后在resources下的application.properties下配置

365bet注册开户 9365bet注册开户 10

# REDIS (RedisProperties)
# Redis数据库索引(默认为0)
spring.redis.database=0  
# Redis服务器地址
spring.redis.host=127.0.0.1
# Redis服务器连接端口
spring.redis.port=6379  
# Redis服务器连接密码(默认为空)
spring.redis.password=
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.pool.max-active=8  
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.pool.max-wait=-1  
# 连接池中的最大空闲连接
spring.redis.pool.max-idle=8  
# 连接池中的最小空闲连接
spring.redis.pool.min-idle=0  
# 连接超时时间(毫秒)
spring.redis.timeout=0

View Code

大家开采大家并未注册RedisConnectionFactory,那是因为spring默许帮我们读取application.properties文件同一时间注册了三个factorybean

keyGenerator方法帮大家报了名了一个key的生成法则,就毫无我们写spel表明式了,依照反射的原理读取类名+方法名+参数。不过大家不经常依然须求结合spel的。

接下来在controller上增加@Cacheable(“cachename”),之后就能够在redis见到保存了而且key的值是keyGenerator生成的名字

 

 

return JsonResp.success();

key和value序列化

当保存一条数据的时候,key和value都要被种类化成json数据,抽取来的时候被系列化成对象,key和value都会利用种类化器进行系列化,spring
data redis提供多少个体系化器

  • GenericToStringSerializer:使用Spring转变服务开始展览类别化;
  • 杰克逊JsonRedisSerializer:使用杰克逊 1,将目的系列化为JSON;
  • 杰克逊2JsonRedisSerializer:使用杰克逊 2,将对象体系化为JSON;
  • JdkSerializationRedisSerializer:使用Java序列化;
  • OxmSerializer:使用Spring
    O/X映射的编排器和解排器(marshaler和unmarshaler)实
  • 现种类化,用于XML体系化;
  • StringRedisSerializer:序列化String类型的key和value。

RedisTemplate会私下认可使用JdkSerializationRedisSerializer,那代表key和value都会经过Java进行系列化。StringRedisTemplate暗中同意会使用StringRedis塞里alizer

例如,借使当使用RedisTemplate的时候,我们期望将Product类型的value连串化为JSON,而key是String类型。RedisTemplate的setKeySerializer()和setValue塞里alizer()方法就须求如下所示:

    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory factory) {
        // 创建一个模板类
        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        // 将刚才的redis连接工厂设置到模板类中
        template.setConnectionFactory(factory);
        // 设置key的序列化器
        template.setKeySerializer(new StringRedisSerializer());
        // 设置value的序列化器
        //使用Jackson 2,将对象序列化为JSON
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        //json转对象类,不设置默认的会将json转成hashmap
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        template.setValueSerializer(jackson2JsonRedisSerializer);

        return template;
    }

到此处,我们断定会对springboot使用redis有了简要的刺探。


 

key和value序列化

当保存一条数据的时候,key和value都要被种类化成json数据,收取来的时候被系列化成对象,key和value都会利用系列化器进行类别化,spring
data redis提供多少个系列化器

  • GenericToString塞里alizer:使用Spring调换服务拓展连串化;
  • 杰克逊JsonRedisSerializer:使用杰克逊 1,将对象体系化为JSON;
  • 杰克逊2JsonRedisSerializer:使用Jackson 2,将目的种类化为JSON;
  • JdkSerializationRedisSerializer:使用Java序列化;
  • Oxm塞里alizer:使用Spring
    O/X映射的编排器和平解决排器(marshaler和unmarshaler)实
  • 现系列化,用于XML系列化;
  • StringRedisSerializer:序列化String类型的key和value。

RedisTemplate会默许使用JdkSerializationRedisSerializer,那代表key和value都会因而Java举办种类化。StringRedisTemplate暗许会使用StringRedisSerializer

比如说,若是当使用RedisTemplate的时候,大家盼望将Product类型的value体系化为JSON,而key是String类型。RedisTemplate的setKeySerializer()和setValueSerializer()方法就供给如下所示:

    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory factory) {
        // 创建一个模板类
        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        // 将刚才的redis连接工厂设置到模板类中
        template.setConnectionFactory(factory);
        // 设置key的序列化器
        template.setKeySerializer(new StringRedisSerializer());
        // 设置value的序列化器
        //使用Jackson 2,将对象序列化为JSON
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        //json转对象类,不设置默认的会将json转成hashmap
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        template.setValueSerializer(jackson2JsonRedisSerializer);

        return template;
    }

到那边,我们自然会对springboot使用redis有了简易的询问。


 

注明缓存管理器

在少数时候,大家也有这么的要求,用户登入的时候,大家会从数据库中读取用户具备的权位,部门等消息。并且每一次刷新页面都需求剖断该用户有未有其一权力,假诺不停的从数据库中读并且总结,

是可怜耗品质的,所以我们那一年将在动用了springboot为大家带来的缓存管理器

 

率先在我们的RedisConfig这么些类上加上@EnableCaching那一个表明。

那几个注脚会被spring发掘,何况会创设叁个断面(aspect)
并触发Spring缓存注解的切点(pointcut) 。
依据所采取的笺注以及缓存的场合, 这一个切面会从缓存中获取数据,
将数据增加到缓存之中也许从缓存中移除有个别值。

 

接下去我们需求说美素佳儿个缓存管理器的bean,那一个功效正是@EnableCaching那个切面在疯长缓存可能去除缓存的时候会调用那几个缓存管理器的措施

/**
     * 申明缓存管理器,会创建一个切面(aspect)并触发Spring缓存注解的切点(pointcut)
     * 根据类或者方法所使用的注解以及缓存的状态,这个切面会从缓存中获取数据,将数据添加到缓存之中或者从缓存中移除某个值

     * @return
     */
    @Bean
    public RedisCacheManager cacheManager(RedisTemplate redisTemplate) {
        return new RedisCacheManager(redisTemplate);
    }

 当然,缓存管理器除了RedisCacheManager还会有点其余的。举个例子

  1. SimpleCacheManager
  2. NoOpCacheManager
  3. ConcurrentMapCacheManager
  4. CompositeCacheManager
  5. EhCacheCacheManager

ConcurrentMapCacheManager,那些轻巧的缓存管理器使用java.util.concurrent.ConcurrentHashMap作为其缓存存款和储蓄。它特别简单,因而对于开垦、测验或基础的利用来说,这是三个很不利的选拔.

}

template(模版)

唯独大家发现每一趟增添的key和value都以byte数组类型(使用很劳累),于是spring为我们带来了redis
template(模版)

Spring Data Redis提供了四个模板:
  RedisTemplate
  StringRedisTemplate

先是大家先创制多个RedisTemplate模板类,类型的key是String类型,value是Object类型(即便key和value都以String类型,提出利用StringRedisTemplate)

    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory factory){
        //创建一个模板类
        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        //将刚才的redis连接工厂设置到模板类中
        template.setConnectionFactory(factory);
        return template;
    }

单元测量试验

    @Autowired    
    RedisTemplate<String, Object> template;

    @Test
    public void testRedisTemplate(){
        template.opsForValue().set("key1", "value1");
        System.out.println(template.opsForValue().get("key1"));
    }

得到结果输出value1,是还是不是很便利了吧。

 即使是操作会集呢,也很有益于的哈。

    @Test
    public void testRedisTemplateList(){

        Pruduct prud  = new Pruduct(1, "洗发水", "100ml");
        Pruduct prud2  = new Pruduct(2, "洗面奶", "200ml");
        //依次从尾部添加元素
        template.opsForList().rightPush("pruduct", prud);
        template.opsForList().rightPush("pruduct", prud);
        //查询索引0到商品总数-1索引(也就是查出所有的商品)
        List<Object> prodList = template.opsForList().range("pruduct", 0,template.opsForList().size("pruduct")-1);
        for(Object obj:prodList){
            System.out.println((Pruduct)obj);
        }
        System.out.println("产品数量:"+template.opsForList().size("pruduct"));

    }

 


表明缓存管理器

在某个时候,我们或者有这么的必要,用户登入的时候,大家会从数据库中读取用户全体的权柄,部门等消息。何况每一趟刷新页面都急需看清该用户有没有其一权力,假如不停的从数据库中读並且总结,

是可怜耗品质的,所以我们这一年就要采用了springboot为大家带来的缓存管理器

 

先是在大家的RedisConfig那一个类上丰盛@EnableCaching以此评释。

其一申明会被spring开采,而且会创制三个断面(aspect)
并触发Spring缓存注明的切点(pointcut) 。
依据所采纳的注释以及缓存的场地, 这些切面会从缓存中获取数据,
将数据增加到缓存之中或然从缓存中移除某些值。

 

接下去大家要求说美素佳儿(Friso)个缓存管理器的bean,这些功效正是@EnableCaching其一切面在新扩张缓存也许去除缓存的时候会调用那一个缓存管理器的方法

/**
     * 申明缓存管理器,会创建一个切面(aspect)并触发Spring缓存注解的切点(pointcut)
     * 根据类或者方法所使用的注解以及缓存的状态,这个切面会从缓存中获取数据,将数据添加到缓存之中或者从缓存中移除某个值

     * @return
     */
    @Bean
    public RedisCacheManager cacheManager(RedisTemplate redisTemplate) {
        return new RedisCacheManager(redisTemplate);
    }

 当然,缓存管理器除了RedisCacheManager还恐怕有一点点别样的。比方

  1. SimpleCacheManager
  2. NoOpCacheManager
  3. ConcurrentMapCacheManager
  4. CompositeCacheManager
  5. EhCacheCacheManager

ConcurrentMapCacheManager,那一个轻巧的缓存管理器使用java.util.concurrent.ConcurrentHashMap作为其缓存存款和储蓄。它特别简单,因而对此开荒、测验或基础的使用来说,那是多少个很不错的选取.

丰盛缓存

接下去大家在controller层的主意内增加评释,然后运维我们的品类。

    @RequestMapping("/getPrud")
    @Cacheable("prudCache")
    public Pruduct getPrud(@RequestParam(required=true)String id){
        System.out.println("如果第二次没有走到这里说明缓存被添加了");
        return pruductDao.getPrud(Integer.parseInt(id));
    }

发掘打字与印刷的这段话只被打字与印刷二遍,表明在走到那几个主意的时候接触了二个断面,况兼查找重临缓存中的数据。

自然@Cacheable注脚也可以放置那些dao层的秘技里面,不过此地会报贰个错,Integer无法转成String,因为我们dao层方法的参数类型是int,而RedisTemplate的key类型是String,这里是要留神的。

展开redis的客户端开掘redis对应的key就是大家的参数1,那一年就能够出问题,譬喻说笔者在其余要缓存的主意的参数也是1,就能重复。前面大家会将自定义那几个key的值。

除外@Cacheable加多缓存外,springboot还为大家带了了其余多少个注脚

365bet注册开户 11

public JsonResp getPersonByName(@QueryParam(“username”) String username) {

redis连接工厂类 

率先步,需求丰富springboot的redis jar包

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

下一场大家写二个配置类,创立了三个redis连接的工厂的spring
bean。(Redis连接工厂会生成到Redis数据库服务器的连接)

@Configuration
public class RedisConfig {
    @Bean
    public RedisConnectionFactory redisCF(){
        //如果什么参数都不设置,默认连接本地6379端口
        JedisConnectionFactory factory = new JedisConnectionFactory();
        factory.setPort(6379);
        factory.setHostName("localhost");
        return factory;
    }
}

单元测量检验,看看那个工厂方法的行使

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = Application.class)
public class RedisTest {

    @Autowired
    RedisConnectionFactory factory;

    @Test
    public void testRedis(){
        //得到一个连接
        RedisConnection conn = factory.getConnection();
        conn.set("hello".getBytes(), "world".getBytes());
        System.out.println(new String(conn.get("hello".getBytes())));
    }

}

出口结果 :world,表达已经成功赢获得三番五次,何况往redis赢得丰裕数据, 

多多时候,大家会在springboot中配置redis,可是就那么几个布局就配好了,不可能知道为啥,这里就详细的任课一下

此地即使已经成功开创了二个springboot项目。

 本文代码github地址

mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);

充裕缓存

接下去大家在controller层的情势内增多注解,然后运行大家的种类。

    @RequestMapping("/getPrud")
    @Cacheable("prudCache")
    public Pruduct getPrud(@RequestParam(required=true)String id){
        System.out.println("如果第二次没有走到这里说明缓存被添加了");
        return pruductDao.getPrud(Integer.parseInt(id));
    }

意识打字与印刷的这段话只被打字与印刷一回,表明在走到那几个法子的时候接触了叁个断面,而且查找再次回到缓存中的数据。

本来@Cacheable评释也得以停放这几个dao层的方法里面,然而此间会报贰个错,Integer不能够转成String,因为大家dao层方法的参数类型是int,而RedisTemplate的key类型是String,这里是要专注的。

开采redis的客户端开掘redis对应的key正是大家的参数1,那年就能够出标题,例如说作者在其余要缓存的格局的参数也是1,就可以再也。前面大家会将自定义这几个key的值。

除此之外@Cacheable增加缓存外,springboot还为大家带了了其余多少个注明

365bet注册开户 12

 条件化缓存

通过为艺术增加Spring的缓存注脚,Spring就能够围绕着这些艺术创建二个缓存切面。可是,在多少场景下我们或然希望将缓存功用关闭。

@Cacheable和@CachePut提供了多少个天性用以实现条件化缓存:unless和condition,那三个属性都承受多少个SpEL表明式。借使unless属性的SpEL表明式总括结
果为true,那么缓存方法再次回到的数码就不会放到缓存中。与之类似,固然condition属性的SpEL表明式总结结果为false,那么对于这些措施缓存就能够被禁止使用掉

外表上来看,unless和condition属性做的是一致的业务。不过,这里有几许微小的差异。

unless属性只可以阻止将对象放进缓存,不过在这一个格局调用的时候,依旧会去缓存中实行找寻,假若找到了相当的值,就能回来找到的值。

与之不一样,如若condition的表达式计算结果为false,那么在那几个格局调用的经过中,缓存是被剥夺的。正是说,不会去缓存举办搜寻,同期重临值也不会放进缓存中。

 

    @RequestMapping("/getPrud2")
    @CachePut(value ="prudCache",unless="#result.desc.contains('nocache')")
    public Pruduct getPrud2(@RequestParam(required=true)String id){
        System.out.println("如果走到这里说明,说明缓存没有生效!");
        Pruduct p = new Pruduct(Integer.parseInt(id), "name_nocache"+id, "nocache");
        return p;
    }

 

地点的代码中,尽管回到的目的desc中包罗nocache字符串,则不实行缓存。

 

自定义key

@Cacheable和@CachePut都有贰个名字为key属性,这么些天性能够替换暗许的key,它是因而二个表明式(Spel表明式,spring提供的,比极粗略)总结拿到的。

举例下边包车型的士正是将回来对象的id当作key来囤积(但是Pruduct的id是int类型,所以要求将数字转化成String类型)

    @RequestMapping("/savePrud")
    @CachePut(value="prudsaveCache",key="#result.id +''")
    public Pruduct savePrud(Pruduct prud){
        return prud;
    }

别的除了#result是表示函数的重返值,spring还为大家带来了其他的部分元数据 

365bet注册开户 13

文章来源http://www.roncoo.com/article/detail/129345

 总结demo:

将类名方法名和pruduct的id作为key

    @RequestMapping("/getPrud3")
    @Cacheable(value ="prudCache",key="#root.targetClass.getName() + #root.methodName + #id")
    public Pruduct getPrud3(@RequestParam(required=true)String id){
        System.out.println("如果第二次没有走到这里说明缓存被添加了");
        return pruductDao.getPrud(Integer.parseInt(id));
    }

 最后注意

#result 方法重返值无法用在@Cacheable上,只好用在@CachePut

 

 本文代码github地址

数不完时候,大家会在springboot中配置redis,但是就那么多少个布局就配好了,不可能知道干什么,这里就详细的讲课一下

此地假若已经打响创制了贰个springboot项目。

@Autowired

springboot配置进步轻巧化

本来上边的配备只是为着明白原理的哈,实际上大家使用会更不难点。大家重写了RedisConfig

365bet注册开户 14@Configuration
@EnableCaching//开启缓存 public class RedisConfig extends
CachingConfigurerSupport { @Bean public KeyGenerator keyGenerator() {
return new KeyGenerator() { @Override public Object generate(Object
target, Method method, Object… 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(); } }; } /** *
表明缓存管理器,会创立一个断面(aspect)并触发Spring缓存注脚的切点(pointcut)
*
依照类可能措施所采纳的注释以及缓存的景色,这么些切面会从缓存中获取数据,将数据拉长到缓存之中可能从缓存中移除有些值
* @return */ @Bean public RedisCacheManager cacheManager(RedisTemplate
redisTemplate) { return new RedisCacheManager(redisTemplate); } @Bean
@Primary public RedisTemplate redisTemplate(RedisConnectionFactory
factory) { // 创造三个模板类 RedisTemplate<String, Object>
template = new RedisTemplate<String, Object>(); //
将刚刚的redis连接工厂设置到模板类中
template.setConnectionFactory(factory); // 设置key的种类化器
template.setKeySerializer(new StringRedisSerializer()); //
设置value的类别化器 //使用杰克逊 2,将指标类别化为JSON
杰克逊2JsonRedisSerializer jackson2JsonRedisSerializer = new
杰克逊2JsonRedisSerializer(Object.class);
//json转对象类,不安装私下认可的会将json转成hashmap ObjectMapper om = new
ObjectMapper(); om.setVisibility(PropertyAccessor.ALL,
JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
template.setValueSerializer(jackson2JsonRedisSerializer); return
template; } } View Code

然后在resources下的application.properties下配置

365bet注册开户 15# REDIS
(RedisProperties) # Redis数据库索引(默感到0) spring.redis.database=0
# Redis服务器地址 spring.redis.host=127.0.0.1 # Redis服务器连接端口
spring.redis.port=6379 # Redis服务器连接密码(默以为空)
spring.redis.password= # 连接池最地拉那接数(使用负值表示不曾限定)
spring.redis.pool.max-active=8 #
连接池最大阻塞等待时间(使用负值表示尚无限定)
spring.redis.pool.max-wait=-1 # 连接池中的最大空闲连接
spring.redis.pool.max-idle=8 # 连接池中的最小空闲连接
spring.redis.pool.min-idle=0 # 连接超时时间(纳秒)
spring.redis.timeout=0 View
Code

我们开采我们并从未注册RedisConnectionFactory,那是因为spring暗中同意帮大家读取application.properties文件同一时间注册了一个factorybean

keyGenerator方法帮大家报了名了三个key的变化准绳,就不要我们写spel表明式了,依照反射的规律读取类名+方法名+参数。可是我们不常照旧要求整合spel的。

然后在controller上助长@Cacheable(“cachename”),之后就可以在redis观望保存了况且key的值是keyGenerator生成的名字

 

 

自定义key

@Cacheable和@CachePut都有一个名叫key属性,那几个天性能够替换暗中同意的key,它是通过三个表明式(Spel表明式,spring提供的,异常的粗略)计算得到的。

举例上边包车型客车便是将回来对象的id当作key来囤积(但是Pruduct的id是int类型,所以要求将数字转化成String类型)

    @RequestMapping("/savePrud")
    @CachePut(value="prudsaveCache",key="#result.id +''")
    public Pruduct savePrud(Pruduct prud){
        return prud;
    }

其它除了#result是意味着函数的重回值,spring还为大家带来了其他的有个别元数据 

365bet注册开户 16

 总结demo:

将类名方法名和pruduct的id作为key

    @RequestMapping("/getPrud3")
    @Cacheable(value ="prudCache",key="#root.targetClass.getName() + #root.methodName + #id")
    public Pruduct getPrud3(@RequestParam(required=true)String id){
        System.out.println("如果第二次没有走到这里说明缓存被添加了");
        return pruductDao.getPrud(Integer.parseInt(id));
    }

 最终注意

#result 方法重返值不可能用在@Cacheable上,只好用在@CachePut

 

@Bean

行远自迩学习springboot中运用redis,springbootredis

很多时候,我们会在springboot中配置redis,但是就那么几个配置就配好了,没办法知道为什么,这里就详细的讲解一下
这里假设已经成功创建了一个springboot项目。

template(模版)

可是大家发掘每一回增多的key和value都以byte数组类型(使用很困苦),于是spring为我们带来了redis
template(模版)

Spring Data Redis提供了三个模板:
  RedisTemplate
  StringRedisTemplate

先是我们先创建二个RedisTemplate模板类,类型的key是String类型,value是Object类型(假诺key和value都是String类型,提议利用StringRedisTemplate)

    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory factory){
        //创建一个模板类
        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        //将刚才的redis连接工厂设置到模板类中
        template.setConnectionFactory(factory);
        return template;
    }

单元测量试验

    @Autowired    
    RedisTemplate<String, Object> template;

    @Test
    public void testRedisTemplate(){
        template.opsForValue().set("key1", "value1");
        System.out.println(template.opsForValue().get("key1"));
    }

赢得结果输出value1,是还是不是很便宜了吧。

 假若是操作集结呢,也很有益的哈。

    @Test
    public void testRedisTemplateList(){

        Pruduct prud  = new Pruduct(1, "洗发水", "100ml");
        Pruduct prud2  = new Pruduct(2, "洗面奶", "200ml");
        //依次从尾部添加元素
        template.opsForList().rightPush("pruduct", prud);
        template.opsForList().rightPush("pruduct", prud);
        //查询索引0到商品总数-1索引(也就是查出所有的商品)
        List<Object> prodList = template.opsForList().range("pruduct", 0,template.opsForList().size("pruduct")-1);
        for(Object obj:prodList){
            System.out.println((Pruduct)obj);
        }
        System.out.println("产品数量:"+template.opsForList().size("pruduct"));

    }

 


redis连接工厂类 

率先步,须求充足springboot的redis jar包

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

然后大家写一个配置类,创造了贰个redis连接的工厂的spring
bean。(Redis连接工厂会生成到Redis数据库服务器的连天)

@Configuration
public class RedisConfig {
    @Bean
    public RedisConnectionFactory redisCF(){
        //如果什么参数都不设置,默认连接本地6379端口
        JedisConnectionFactory factory = new JedisConnectionFactory();
        factory.setPort(6379);
        factory.setHostName("localhost");
        return factory;
    }
}

单元测量试验,看看这么些工厂方法的使用

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = Application.class)
public class RedisTest {

    @Autowired
    RedisConnectionFactory factory;

    @Test
    public void testRedis(){
        //得到一个连接
        RedisConnection conn = factory.getConnection();
        conn.set("hello".getBytes(), "world".getBytes());
        System.out.println(new String(conn.get("hello".getBytes())));
    }

}

输出结果
:world,表达已经打响博获得连年,并且往redis获取丰盛数据, 

}

 条件化缓存

经过为格局增加Spring的缓存表明,Spring就能围绕着那么些办法创制二个缓存切面。不过,在多少场景下大家大概希望将缓存作用关闭。

@Cacheable和@CachePut提供了五个天性用以完成条件化缓存:unless和condition,那八个脾性都领受一个SpEL表明式。假设unless属性的SpEL说明式计算结
果为true,那么缓存方法重回的数码就不会安置缓存中。与之接近,要是condition属性的SpEL表达式总括结果为false,那么对于那个法子缓存就能够被禁止使用掉

外表上来看,unless和condition属性做的是一模一样的事务。不过,这里有几许微小的差距。

unless属性只好阻止将指标放进缓存,可是在这些主意调用的时候,照旧会去缓存中张开搜寻,假设找到了协作的值,就能够回去找到的值。

与之不一样,假若condition的说明式总括结果为false,那么在这几个主意调用的经过中,缓存是被剥夺的。便是说,不会去缓存进行查找,同期重临值也不会放进缓存中。

 

    @RequestMapping("/getPrud2")
    @CachePut(value ="prudCache",unless="#result.desc.contains('nocache')")
    public Pruduct getPrud2(@RequestParam(required=true)String id){
        System.out.println("如果走到这里说明,说明缓存没有生效!");
        Pruduct p = new Pruduct(Integer.parseInt(id), "name_nocache"+id, "nocache");
        return p;
    }

 

上边的代码中,如若回去的对象desc中蕴藏nocache字符串,则不开始展览缓存。

 

剔除缓存

在delete的时候用@CacheEvict清楚那条缓存。

    @RequestMapping("/deletePrud")
    @CacheEvict("pruddeleteCache")
    public String deletePrud(@RequestParam(required=true)String id){
        return "SUCCESS";
    }

@CachePut将以此点子的归来值放到缓存,假使大家放三个Pruduct对象,他会将以此指标作为key,那鲜明不是大家想要的。那一年就要求自定义我们的key。

除去缓存

在delete的时候用@CacheEvict清楚这条缓存。

    @RequestMapping("/deletePrud")
    @CacheEvict("pruddeleteCache")
    public String deletePrud(@RequestParam(required=true)String id){
        return "SUCCESS";
    }

@CachePut将以此格局的回来值放到缓存,假诺我们放叁个Pruduct对象,他会将以此目的作为key,那显然不是大家想要的。这一年就供给自定义大家的key。

Redis
是二个开源(BSD许可)的,内部存款和储蓄器中的数据结构存款和储蓄系统,它能够用作数据库、缓存和音讯中间件,Redis
的优势包蕴它的进程、协理加多的数据类型、操作原子性,以及它的通用性。

}

/**

ObjectMapper mapper = new ObjectMapper();

serializer.setObjectMapper(mapper);

}

return JsonResp.fail(“用户名已存在!”);

public boolean isExistPersonName(Person person) {

Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);

* @param person

@Produces(MediaType.APPLICATION_JSON)

return JsonResp.success();

host: 192.168.145.132

public class PersonService {

max-idle: 8

${boot.version}

return JsonResp.success(person);

public class PersonMgrResource {

redis:

public Person getPersonByName(String username) {

@Path(“removePersonByName”)

发表评论

电子邮件地址不会被公开。 必填项已用*标注