最近學習了一下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地址如下:
https://github.com/Thinker-Mars/Demo