zoukankan      html  css  js  c++  java
  • 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());

        }

     

    }

  • 相关阅读:
    CTF-pwn-tips-zh_CN
    Linux 内核中 offset_of 和 container_of 宏的实现
    glibc2.26 -- tcache (2)
    glibc2.26 -- tcache (1)
    漏洞复现 -- 条件竞争 -- TOCTOU
    Linux 内核源码分析 -- read
    ospf lsa 4是不可替代的
    MPLS_Lab_3_AToM
    配置多链路捆绑PPP
    OSPF在转换LSA 5时的转发地址抑制 cyrus
  • 原文地址:https://www.cnblogs.com/LuoPengSdok/p/11383204.html
Copyright © 2011-2022 走看看