Redis在web中的应用

Redis在web中的应用

 

一般而言redisjava web应用中存在两个主要的场景:

缓存常用的数据

在需要高速读/写的场合使用它快速读写

Spring 中使用Redis

  (1)先用 Spring 配置一个 JedisPoolConfig 对象

 

    <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">

        <!--最大空闲数 -->

        <property name="maxIdle" value="50" />

        <!--最大连接数 -->

        <property name="maxTotal" value="100" />

        <!--最大等待时间 -->

        <property name="maxWaitMillis" value="20000" />

    </bean>

 

  (2)在使用 Spring 提供的RedisTemplate之前需要配置Spring所提供的连接工厂,在 Spring Data Redis 方案中有4种工厂模型:选择其中的一种,JedisConnectionFactory

 

    <bean id="connectionFactory"

        class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">

        <property name="hostName" value="localhost" />

        <property name="port" value="6379" />

        <property name="poolConfig" ref="poolConfig" />

    </bean>

 

  (3)普通的连接使用没有办法把 Java 对象直接存入 Redis,可以使用 Spring 内部提供的 RedisSerializer 接口和一些实现类实现序列化和反序列化。

  JdkSerializationRedisSerializer是使用 JDK 的序列化器进行转换,而StringRedisSerializer使用字符串进行序列化

    <bean id="jdkSerializationRedisSerializer"

        class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />

        

    <bean id="stringRedisSerializer"

        class="org.springframework.data.redis.serializer.StringRedisSerializer" />

  (4)由于需要配置keyvalue两个不同的序列化方式,那么可以指定各自使用的序列化器。至此,就可以得到一个Spring提供的RedisTemplate来进行操作Redis

    <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">

        <property name="connectionFactory" ref="connectionFactory" />

        <property name="keySerializer" ref="stringRedisSerializer" />

        <property name="valueSerializer" ref="jdkSerializationRedisSerializer" />

    </bean>

  (5)创建POJO类,必须实现Serializable接口

 

package com.ssm.chapter17.pojo;

import java.io.Serializable;

public class Role implements Serializable {

    

    private static final long serialVersionUID = 6977402643848374753L;

 

    private long id;

    private String roleName;

    private String note;

  /*****************************getter and setter**************************************/

}

 

  (6)使用RedisTemplate操作Redis

 

    private static void testSpring() {

        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");

        RedisTemplate redisTemplate = applicationContext.getBean(RedisTemplate.class);

        Role role = new Role();

        role.setId(1L);

        role.setRoleName("role_name_1");

        role.setNote("note_1");

        redisTemplate.opsForValue().set("role_1", role);

        Role role1 = (Role) redisTemplate.opsForValue().get("role_1");

        System.out.println(role1.getRoleName());

    }

 

  然而,这样的方式可能存在问题:执行setget方法的Redis连接对象可能来自同一个Redis连接池的不同Redis的连接。为了使得setget操作都来自同一个连接,可以使用SessionCallback

  (7)使用SessionCallback来将多个命令放入到同一个 Redis 连接中执行

  这里使用匿名类的方式,还可以使用 Lambda 的方式进行编写SessionCallback的业务逻辑。

  由于前后使用的都是同一个连接,因此对于资源损耗就比较小,在使用Redis操作多个命令或者使用事务的时候也会用到它。

 

    private static void testSessionCallback() {

        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");

        RedisTemplate redisTemplate = applicationContext.getBean(RedisTemplate.class);

        Role role = new Role();

        role.setId(1);

        role.setRoleName("role_name_1");

        role.setNote("role_note_1");

        SessionCallback callBack = new SessionCallback<Role>() {

            @Override

            public Role execute(RedisOperations ops) throws DataAccessException {

                ops.boundValueOps("role_1").set(role);

                return (Role) ops.boundValueOps("role_1").get();

            }

        };

        Role savedRole = (Role) redisTemplate.execute(callBack);

        System.out.println(savedRole.getId());

    }

 

  例如,简化成Lambda表达式为:

 

    private static void testSessionCallback() {

        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");

        RedisTemplate redisTemplate = applicationContext.getBean(RedisTemplate.class);

        Role role = new Role();

        role.setId(1);

        role.setRoleName("role_name_1");

        role.setNote("role_note_1");

        Role savedRole = (Role) redisTemplate.execute((RedisOperations ops) -> {

            ops.boundValueOps("role_4").set(role);

            return (Role) ops.boundValueOps("role_4").get();

        });

    

        System.out.println(savedRole.getId());

    }

 

}

posted @ 2019-08-20 15:31  sdok  阅读(380)  评论(0编辑  收藏  举报