SpringBoot整合Redis
最近学习了一下Redis,并与SpringBoot进行了整合,在此与大家分享。
一、Redis
关于Redis的解释网上有很多,我在这里不做出多余解释,大家可以自行搜索,我在这里要提到的是,Redis与SpringBoot整合有两种方式,第一种是使用Jedis,它是Redis官方推荐的面向Java的操作Redis的客户端,第二种是使用RedisTemplate,它是SpringDataRedis中对JedisApi的高度封装。我此次使用的是RedisTemplate,并整理了redis工具类方便大家使用,GitHub地址文末给出。
二、项目结构
我在此贴出项目目录结构,方便大家观察:
config中是对Redis的相关配置,controller中是测试接口,dao中是对数据库操作的相关接口,entity中数据表实体,service中是具体实现,util中含有Redis工具类。
三、项目开发
1、准备pom文件
此项目使用SpringBoot版本为2.1.3.RELEASE,下面引入依赖:
<!-- mysql依赖 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.34</version> </dependency>
<!-- mybatis依赖 --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.1.1</version> </dependency>
<!-- redis依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
<!-- 日志 --> <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency>
使用JDK1.8
<properties> <java.version>1.8</java.version> </properties>
至此,pom文件已经准备好。
2、项目相关配置
application.properties文件如下:
1 server.port=8088 2 mybatis.type-aliases-package=com.neo.entity 3 spring.datasource.driverClassName = com.mysql.jdbc.Driver 4 spring.datasource.url= jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=utf-8&useSSL=false 5 spring.datasource.username = root 6 spring.datasource.password = yingziairen 7 logging.level.root=info
application.yml文件如下,其中配置了Mybatis:
1 mybatis: 2 typeAliasesPackage: com.cone.redis.entity 3 mapperLocations: classpath:mapper/*.xml
3、配置Redis
当添加Redis依赖后,SpringBoot会自动帮我们在容器中生成一个RedisTemplate和一个StringRedisTemplate,但是,这个RedisTemplate的泛型是<Object,Object>,在代码中会不可避免的需要类型转换,这样不够安全,也过于麻烦,而且RedisTemplate没有设置序列化方式,所以,我们需要配置Redis:
1 @Bean 2 @SuppressWarnings("all") 3 public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { 4 5 RedisTemplate<String, Object> template = new RedisTemplate<String, Object>(); 6 template.setConnectionFactory(factory); 7 Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); 8 ObjectMapper om = new ObjectMapper(); 9 om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); 10 om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); 11 jackson2JsonRedisSerializer.setObjectMapper(om); 12 StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); 13 //key采用String的序列化方式 14 template.setKeySerializer(stringRedisSerializer); 15 //hash的key也采用String的序列化方式 16 template.setHashKeySerializer(stringRedisSerializer); 17 //value序列化方式采用jackson 18 template.setValueSerializer(jackson2JsonRedisSerializer); 19 //hash的value序列化方式采用jackson 20 template.setHashValueSerializer(jackson2JsonRedisSerializer); 21 template.afterPropertiesSet(); 22 return template; 23 }
4、编写Entity
这张表是我其它项目的,这里用来举例:(项目中有sql语句文件,可自己在本地测试)
1 package com.cone.redis.entity; 2 3 /** 4 * 图书信息实体 5 * @author Cone 6 */ 7 public class Product { 8 9 private Integer productId; 10 private String productCategories; 11 12 public Integer getProductId() { 13 return productId; 14 } 15 public void setProductId(Integer productId) { 16 this.productId = productId; 17 } 18 public String getProductCategories() { 19 return productCategories; 20 } 21 public void setProductCategories(String productCategories) { 22 this.productCategories = productCategories; 23 } 24 25 }
5、编写Dao
项目使用Mybatis操作数据库:
1 package com.cone.redis.dao; 2 3 import java.util.List; 4 import org.apache.ibatis.annotations.Mapper; 5 import com.cone.redis.entity.Product; 6 7 @Mapper 8 public interface ProductDao { 9 /** 10 * 查询图书列表 11 * @return 12 */ 13 public List<Product> searchProduct(); 14 }
xml文件如下:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 3 <mapper namespace="com.cone.redis.dao.ProductDao"> 4 <!-- 查询图书类别 --> 5 <select id="searchProduct" resultType="com.cone.redis.entity.Product"> 6 7 select * from product 8 9 </select> 10 11 12 </mapper>
6、编写Service
1 package com.cone.redis.service; 2 3 import java.util.List; 4 import com.cone.redis.entity.Product; 5 6 7 public interface RedisService { 8 9 public List<Product> searchProduct(); 10 11 }
实现类如下:
①首先注入相关Bean
1 @Autowired 2 private RedisUtil.redisList redisList; 3 4 @Autowired 5 private RedisUtil redisUtil; 6 7 @Autowired 8 private ProductDao productDao;
RedisUtil是我的工具类,这里大家只需要知道这个即可。
②实现
1 @Override 2 public List searchProduct() { 3 4 List list = new ArrayList<>(); 5 if (redisUtil.hasKey("productList")) { 6 log.info("从redis中获取数据."); 7 list = redisList.get("productList", 0, -1); 8 9 } 10 else { 11 list = productDao.searchProduct(); 12 log.info("从数据库中获取数据."); 13 log.info("将数据存入redis..."); 14 redisList.set("productList", list); 15 log.info("成功存入redis."); 16 } 17 return list; 18 }
首先判断redis中有没有相关数据,若有,则从redis中查询并返回数据,若没有则从数据库中查询,并将查询到的数据存入redis中。
7、编写Controller
1 @Controller 2 @RequestMapping(value="/redis") 3 4 public class RedisController { 5 6 @Autowired 7 private RedisServiceImpl redisServiceImpl; 8 9 @SuppressWarnings("unchecked") 10 @PostMapping(value = "/test") 11 @ResponseBody 12 public List<Product> testRedis() { 13 14 return redisServiceImpl.searchProduct(); 15 16 } 17 18 }
至此,项目编写完毕。
四、Redis工具类
网上确实有很多的Redis工具类,但是编写过于冗余,方法太多不方便使用,我使用成员内部类实现了一个工具类,具有相同特性的方法放在一起,归类List、Map、String、Set的操作。因为工具类代码较多,这里就不贴出来了,大家可以去GitHub上查看。
五、项目测试
使用postman进行接口测试,对地址http://localhost:8088/redis/test进行访问,因为刚开始Redis中没有相关数据,所以会从数据库中查询,控制台证实了这一点:
观察postman发现确实拿到了数据:
现在我们再次测试接口:
操作成功,使用Redis桌面管理工具可以查看数据:
六、总结
得益于SpringBoot,我们可以方便的为系统集成一些功能,我还写过一个Spring整合Jedis的项目,实现上大同小异,听说Jedis的效率更高,这点我还未证实。写这篇博客参考了很多人的博文,感谢他们,下面是部分参考链接:
https://www.cnblogs.com/zeng1994/p/03303c805731afc9aa9c60dbbd32a323.html
此项目GitHub地址如下: