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

  • 相关阅读:
    【Codechef】Chef and Bike(二维多项式插值)
    USACO 完结的一些感想
    USACO 6.5 Checker Challenge
    USACO 6.5 The Clocks
    USACO 6.5 Betsy's Tour (插头dp)
    USACO 6.5 Closed Fences
    USACO 6.4 Electric Fences
    USACO 6.5 All Latin Squares
    USACO 6.4 The Primes
    USACO 6.4 Wisconsin Squares
  • 原文地址:https://www.cnblogs.com/skychenjiajun/p/8608310.html
Copyright © 2011-2022 走看看