zoukankan      html  css  js  c++  java
  • springboot集成redis(mybatis、分布式session)

    安装Redis请参考:《CentOS快速安装Redis》

    一、springboot集成redis并实现DB与缓存同步

    1.添加redis及数据库相关依赖(pom.xml)

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-redis</artifactId>
            <version>1.4.7.RELEASE</version>
        </dependency>
        
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.1</version>
        </dependency>
        
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    2.添加数据库、mybatis、redis相关配置(application.properties)

    #数据库相关配置
    spring.datasource.driverClassName=com.mysql.jdbc.Driver
    spring.datasource.url=jdbc:mysql://192.168.15.129:3306/springboot?useUnicode=true&characterEncoding=utf-8&useSSL=false
    spring.datasource.username=root
    spring.datasource.password=123456
    
    #Mybatis相关配置
    mybatis.type-aliases-package=com.lianjinsoft.pojo
    mybatis.config-locations=classpath:mybatis/mybatis-config.xml
    mybatis.mapper-locations=classpath:mybatis/mapper/*.xml
    
    #Redis相关配置
    #数据库索引(默认为0)
    spring.redis.database=0
    #服务器地址
    spring.redis.host=192.168.15.129
    #服务器连接端
    spring.redis.port=6379
    #服务器连接密码(默认为空)
    spring.redis.password=123456
    #连接池最大连接数(使用负值表示没有限制)
    spring.redis.pool.max-active=100
    #连接池最大阻塞等待时间(使用负值表示没有限制)
    spring.redis.pool.max-wait=10000
    #连接池中的最大空闲连接
    spring.redis.pool.max-idle=8
    #连接池中的最小空闲连接
    spring.redis.pool.min-idle=2
    #连接超时时间(毫秒)
    spring.redis.timeout=5000

    3.springboot启动类,增加Mybatis扫描注解

    @MapperScan("com.lianjinsoft.mapper")
    @SpringBootApplication
    public class RedisApplication {
    
    	public static void main(String[] args) {
    		SpringApplication.run(RedisApplication.class, args);
    	}
    }
    

    4.增加pojo数据表映射类

    public class Order {
    	private Integer id;
    	private String orderNo;
    	private String orderName;
    	private BigDecimal amount;
    	private Date addTime;
    	//省略get、set
    }
    

      

     5.增加Mapper数据持久层操作方法

    public interface OrderMapper {
    	void addOrder(Order order);
    	
    	void delOrder(String orderNo);
    	
    	void updOrder(Order order);
    	
    	Order queryOrderByNo(String orderNo);
    }
    

      

    6.增加Mybatis主配置文件

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
        <typeAliases>
            <typeAlias alias="Integer" type="java.lang.Integer" />
            <typeAlias alias="Long" type="java.lang.Long" />
            <typeAlias alias="HashMap" type="java.util.HashMap" />
            <typeAlias alias="LinkedHashMap" type="java.util.LinkedHashMap" />
            <typeAlias alias="ArrayList" type="java.util.ArrayList" />
            <typeAlias alias="LinkedList" type="java.util.LinkedList" />
        </typeAliases>
    </configuration>

      

    7.增加Mapper对应的配置文件及sql

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
    <mapper namespace="com.lianjinsoft.mapper.OrderMapper" >
        <resultMap id="BaseResultMap" type="com.lianjinsoft.pojo.Order" >
            <id column="id" property="id" jdbcType="INTEGER" />
            <result column="order_no" property="orderNo" jdbcType="VARCHAR" />
            <result column="order_name" property="orderName" jdbcType="VARCHAR" />
            <result column="amount" property="amount" jdbcType="DECIMAL"/>
            <result column="add_time" property="addTime" jdbcType="TIMESTAMP" />
        </resultMap>
        
        <sql id="Base_Column_List" >
            id, order_no, order_name, amount, add_time
        </sql>
    
        <select id="queryOrderByNo" parameterType="java.lang.String" resultMap="BaseResultMap" >
            SELECT 
           <include refid="Base_Column_List" />
           FROM orders
           WHERE order_no = #{orderNo}
        </select>
    
        <insert id="addOrder" parameterType="com.lianjinsoft.pojo.Order" >
           INSERT INTO orders
                   (order_no,order_name,amount,add_time)
               VALUES
                   (#{orderNo}, #{orderName}, #{amount}, #{addTime})
        </insert>
        
        <delete id="delOrder" parameterType="java.lang.String" >
           DELETE FROM
                    orders 
           WHERE 
                    order_no =#{orderNo}
        </delete>
        
        <update id="updOrder" parameterType="com.lianjinsoft.pojo.Order" >
           UPDATE orders 
                   SET order_name=#{orderName}
           WHERE 
                   id=#{id}
        </update>
    </mapper>

     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 sf = new StringBuilder();
                    sf.append(target.getClass().getName());
                    sf.append("_");
                    sf.append(method.getName());
                    for (Object obj : params) {
                    	sf.append("_");
                    	sf.append(obj.toString());
                    }
                    return sf.toString();
                }
            };
        }
    
        @Bean
        public CacheManager cacheManager(RedisTemplate redisTemplate) {
            return new RedisCacheManager(redisTemplate);
        }
        
        @Bean
        public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
            StringRedisTemplate template = new StringRedisTemplate(factory);
            Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
            ObjectMapper om = new ObjectMapper();
            om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
            om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
            jackson2JsonRedisSerializer.setObjectMapper(om);
            template.setValueSerializer(jackson2JsonRedisSerializer);
            template.afterPropertiesSet();
            return template;
        }
    }
    

      

    9.增加OrderService接口及实现类

    public interface OrderService {
    	void addOrder(Order order);
    	
    	void delOrder(String orderNo);
    	
    	void updOrder(Order order);
    	
    	Order queryOrderByNo(String orderNo);
    }
    @Service
    public class OrderServiceImpl implements OrderService{
    	private final String prefix = "order:";
    	
    	@Autowired
    	private OrderMapper orderMapper;
    	
    	@Autowired
    	private RedisTemplate redisTemplate;
    
    	@Override
    	public void addOrder(Order order) {
    		orderMapper.addOrder(order);
    		redisTemplate.opsForValue().set(prefix+order.getOrderNo(), order);
    		LogUtil.info("新增订单,添加缓存:"+order);
    	}
    
    	@Override
    	public void delOrder(String orderNo) {
    		if(redisTemplate.hasKey(prefix+orderNo)){
    			redisTemplate.delete(prefix+orderNo);
    			LogUtil.info("删除缓存数据:"+orderNo);
    		}
    		orderMapper.delOrder(orderNo);
    	}
    
    	@Override
    	public void updOrder(Order order) {
    		orderMapper.updOrder(order);
    		if(redisTemplate.hasKey(prefix+order.getOrderNo())){
    			redisTemplate.opsForValue().set(prefix+order.getOrderNo(), order);
    			LogUtil.info("更新缓存订单信息:"+order);
    		}
    	}
    	
    	@Override
    	public Order queryOrderByNo(String orderNo) {
    		Order order = (Order)redisTemplate.opsForValue().get(prefix+orderNo);
    		if(order != null){
    			LogUtil.info("从缓存获取到数据:"+order);
    			return order;
    		}
    		
    		order = orderMapper.queryOrderByNo(orderNo);
    		if(order != null){
    			redisTemplate.opsForValue().set(prefix+orderNo, order);
    		}
    		return order;
    	}
    }
    

      

    10.增加OrderServiceTests测试类(Junit)

    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class OrderServiceTests {
    	@Autowired
    	private OrderService orderService;
    
    	@Test
    	public void test1_add() {
    		//添加订单
    		orderService.addOrder(new Order("100001", "XX手机", new BigDecimal("4999")));
    	}
    	
    	@Test
    	public void test2_query() {
    		//查询订单
    		orderService.queryOrderByNo("100001");
    	}
    	
    	@Test
    	public void test3_update() {
    		//先查询订单信息
    		Order order = orderService.queryOrderByNo("100001");
    		order.setOrderName("国民手机");
    		
    		//更新DB及缓存
    		orderService.updOrder(order);
    		
    		//再次查询
    		orderService.queryOrderByNo("100001");
    	}
    	
    	@Test
    	public void test4_del() {
    		//删除DB及缓存
    		orderService.delOrder("100001");
    		
    		//再次查询
    		orderService.queryOrderByNo("100001");
    	}
    }
    

    10.1)执行test1_add()方法

    10:57:45.873 [main] INFO  c.l.service.OrderServiceTests - Starting OrderServiceTests on LAPTOP-1DF7S904 with PID 8316 (started by lianjinsoft in E:workspacespringbootspring-boot-redis)
    10:57:45.875 [main] INFO  c.l.service.OrderServiceTests - No active profile set, falling back to default profiles: default
    10:57:45.908 [main] INFO  o.s.c.a.AnnotationConfigApplicationContext - Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@306cf3ea: startup date [Mon Apr 23 10:57:45 CST 2018]; root of context hierarchy
    10:57:46.233 [main] INFO  o.s.d.r.c.RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode!
    10:57:47.370 [main] WARN  o.s.b.s.r.RedisStarterDeprecationWarningAutoConfiguration - spring-boot-starter-redis is deprecated as of Spring Boot 1.4, please migrate to spring-boot-starter-data-redis
    10:57:47.399 [main] INFO  c.l.service.OrderServiceTests - Started OrderServiceTests in 1.752 seconds (JVM running for 2.512)
    10:57:47.931 [main] INFO  com.lianjinsoft.util.LogUtil - 新增订单,添加缓存:Order [id=null, orderNo=100001, orderName=XX手机, amount=4999, addTime=Mon Apr 23 10:57:47 CST 2018]
    10:57:47.939 [Thread-2] INFO  o.s.c.a.AnnotationConfigApplicationContext - Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@306cf3ea: startup date [Mon Apr 23 10:57:45 CST 2018]; root of context hierarchy
    

    从日志的第7行可以看出,订单信息已经添加成功。并添加到缓存中。

    10.2)执行test2_query()方法

    10:58:04.273 [main] INFO  c.l.service.OrderServiceTests - Starting OrderServiceTests on LAPTOP-1DF7S904 with PID 20492 (started by lianjinsoft in E:workspacespringbootspring-boot-redis)
    10:58:04.277 [main] INFO  c.l.service.OrderServiceTests - No active profile set, falling back to default profiles: default
    10:58:04.301 [main] INFO  o.s.c.a.AnnotationConfigApplicationContext - Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@306cf3ea: startup date [Mon Apr 23 10:58:04 CST 2018]; root of context hierarchy
    10:58:04.618 [main] INFO  o.s.d.r.c.RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode!
    10:58:05.920 [main] WARN  o.s.b.s.r.RedisStarterDeprecationWarningAutoConfiguration - spring-boot-starter-redis is deprecated as of Spring Boot 1.4, please migrate to spring-boot-starter-data-redis
    10:58:05.953 [main] INFO  c.l.service.OrderServiceTests - Started OrderServiceTests in 1.903 seconds (JVM running for 2.659)
    10:58:06.101 [main] INFO  com.lianjinsoft.util.LogUtil - 从缓存获取数据:Order [id=null, orderNo=100001, orderName=XX手机, amount=4999, addTime=Mon Apr 23 10:57:47 CST 2018]
    10:58:06.109 [Thread-2] INFO  o.s.c.a.AnnotationConfigApplicationContext - Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@306cf3ea: startup date [Mon Apr 23 10:58:04 CST 2018]; root of context hierarchy
    

    从日志的第7行可以看出,查询信息从缓存中获取(没有查询数据库)。

    10.3)执行test3_update()方法

    10:58:17.172 [main] INFO  c.l.service.OrderServiceTests - Starting OrderServiceTests on LAPTOP-1DF7S904 with PID 12316 (started by lianjinsoft in E:workspacespringbootspring-boot-redis)
    10:58:17.172 [main] INFO  c.l.service.OrderServiceTests - No active profile set, falling back to default profiles: default
    10:58:17.207 [main] INFO  o.s.c.a.AnnotationConfigApplicationContext - Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@306cf3ea: startup date [Mon Apr 23 10:58:17 CST 2018]; root of context hierarchy
    10:58:17.530 [main] INFO  o.s.d.r.c.RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode!
    10:58:18.679 [main] WARN  o.s.b.s.r.RedisStarterDeprecationWarningAutoConfiguration - spring-boot-starter-redis is deprecated as of Spring Boot 1.4, please migrate to spring-boot-starter-data-redis
    10:58:18.750 [main] INFO  c.l.service.OrderServiceTests - Started OrderServiceTests in 1.809 seconds (JVM running for 2.553)
    10:58:19.032 [main] INFO  com.lianjinsoft.util.LogUtil - 从缓存获取数据:Order [id=null, orderNo=100001, orderName=XX手机, amount=4999, addTime=Mon Apr 23 10:57:47 CST 2018]
    10:58:19.450 [main] INFO  com.lianjinsoft.util.LogUtil - 更新缓存订单信息:Order [id=null, orderNo=100001, orderName=国民手机, amount=4999, addTime=Mon Apr 23 10:57:47 CST 2018]
    10:58:19.454 [main] INFO  com.lianjinsoft.util.LogUtil - 从缓存获取数据:Order [id=null, orderNo=100001, orderName=国民手机, amount=4999, addTime=Mon Apr 23 10:57:47 CST 2018]
    10:58:19.458 [Thread-2] INFO  o.s.c.a.AnnotationConfigApplicationContext - Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@306cf3ea: startup date [Mon Apr 23 10:58:17 CST 2018]; root of context hierarchy
    

    从日志的第7~9行可以看出,订单先从缓存中获取,然后执行了更新DB、更新缓存,最后再从缓存中获取到了订单信息。

    10.4)执行test4_del()方法

    10:58:34.652 [main] INFO  c.l.service.OrderServiceTests - Starting OrderServiceTests on LAPTOP-1DF7S904 with PID 7428 (started by lianjinsoft in E:workspacespringbootspring-boot-redis)
    10:58:34.652 [main] INFO  c.l.service.OrderServiceTests - No active profile set, falling back to default profiles: default
    10:58:34.676 [main] INFO  o.s.c.a.AnnotationConfigApplicationContext - Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@306cf3ea: startup date [Mon Apr 23 10:58:34 CST 2018]; root of context hierarchy
    10:58:34.997 [main] INFO  o.s.d.r.c.RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode!
    10:58:36.107 [main] WARN  o.s.b.s.r.RedisStarterDeprecationWarningAutoConfiguration - spring-boot-starter-redis is deprecated as of Spring Boot 1.4, please migrate to spring-boot-starter-data-redis
    10:58:36.140 [main] INFO  c.l.service.OrderServiceTests - Started OrderServiceTests in 1.856 seconds (JVM running for 2.61)
    10:58:36.281 [main] INFO  com.lianjinsoft.util.LogUtil - 删除缓存数据:100001
    10:58:36.689 [main] INFO  com.lianjinsoft.util.LogUtil - 从数据库获取数据:null
    10:58:36.693 [Thread-2] INFO  o.s.c.a.AnnotationConfigApplicationContext - Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@306cf3ea: startup date [Mon Apr 23 10:58:34 CST 2018]; root of context hierarchy
    

    从日志的第7、8行可以看出,订单信息已经从DB、缓存中删除了。

    注意:

    本案例只是简单的介绍如何将DB与缓存数据同步操作,并不一定适合您当前的业务需求。并且以上操作不能保证缓存与DB数据完全一致。

    二、springboot集成redis并实现分布式session缓存

    分布式session共享有很多方案,其中缓存托管就是主流一种实现。

    1.添加session缓存相关依赖(pom.xml)

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

    2.添加session配置(启用session缓存)

    maxInactiveIntervalInSeconds: 设置session失效时间。

    @Configuration
    @EnableRedisHttpSession(maxInactiveIntervalInSeconds = 60*30)
    public class SessionConfig {
    }
    

      

    3.测试

    3.1)修改本地服务端口并启动,模拟分布式应用部署(application.properties)

    #服务端口(8001、8002、8003)
    server.port=8001

    3.2)分别调用各应用接口,查看sessionId

     

    3.3)查看redis缓存信息 

    如图:缓存中的sessionId与接口返回信息一致。

     

    源代码:https://gitee.com/skychenjiajun/spring-boot

  • 相关阅读:
    paip.数据库全文检索 attilax总结
    软件网站安全性的设计与检测与解决方案
    防止SQL注入解决方案
    paip.账务系统的安全性
    快速开发字段很多的MIS表
    paip.php调试不能显示局部变量内容w/ xdebug
    程序安全性之配置文件安全
    paip.VS2010未能加载类型
    paip.盘古汉字转拼音组件库使用总结
    paip.跟踪DISCUZ积分日志功能总结
  • 原文地址:https://www.cnblogs.com/skychenjiajun/p/8608310.html
Copyright © 2011-2022 走看看