SpringBoot整合Redis使用Restful風格實現CRUD功能
前言
本篇文章主要介紹的是SpringBoot整合Redis,使用Restful風格實現的CRUD功能。
Redis 介紹
Redis 是完全開源免費的,遵守BSD協議,是一個高效能的key-value資料庫。 Redis 與其他 key - value快取產品有以下三個特點:
- Redis支援資料的持久化,可以將記憶體中的資料儲存在磁碟中,重啟的時候可以再次載入進行使用。
- Redis不僅僅支援簡單的key-value型別的資料,同時還提供list,set,zset,hash等資料結構的儲存。
- Redis支援資料的備份,即master-slave模式的資料備份。
更多的使用說明可以檢視官方的文件。
SpringBoot整合Redis
說明:如果想直接獲取工程那麼可以直接跳到底部,通過連結下載工程程式碼。
開發準備
環境要求
JDK:1.8
SpringBoot:1.5.15.RELEASE
Redis:3.2或以上。
Tips:Redis的偶數為穩定版本,奇數為非穩定版本,所以在使用的時候最好使用偶數的版本!
Reids的可以看我之前的寫的這篇文章: Redis安裝教程
首先還是Maven的相關依賴:
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <fastjson>1.2.41</fastjson> <springboot>1.5.15.RELEASE</springboot> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>${springboot}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> <version>${springboot}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <version>${springboot}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <version>${springboot}</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>${fastjson}</version> </dependency> </dependencies>
添加了相應的maven依賴之後,我們再來檢視配置。
Redis配置的說明在下面中已經說的很詳細了,這裡就不在過多說明了,不過需要注意的是如果Redis是叢集版的話,需要使用這個spring.redis.cluster.nodes
這個配置,該配置為Redis的Host加上Port,多個之間用,逗號隔開。
application.properties的配置如下:
# Redis伺服器地址 # 單機版配置 spring.redis.host = 127.0.0.1 spring.redis.port = 6379 # redis最大重連數 redis.cluster.max-redirects=3 # Redis伺服器連線密碼(預設為空) redis.password= # 最大空閒數 redis.maxIdle=5 # 連線池的最大資料庫連線數。 redis.maxTotal=5 # 最大建立連線等待時間。如果超過此時間將接到異常。設為-1表示無限制。 redis.maxWaitMillis=1000 # 連線的最小空閒時間 預設1800000毫秒(30分鐘) redis.minEvictableIdleTimeMillis=300000 # 每次釋放連線的最大數目,預設3 redis.numTestsPerEvictionRun=3 # 逐出掃描的時間間隔(毫秒) 如果為負數,則不執行逐出執行緒, 預設-1 redis.timeBetweenEvictionRunsMillis=30000 # 是否在從池中取出連線前進行檢驗,如果檢驗失敗,則從池中去除連線並嘗試取出另一個 redis.testOnBorrow=true # 在空閒時檢查有效性, 預設false redis.testWhileIdle=true
程式碼編寫
首先是編寫Redis的配置類,對Redis這塊進行配置。
在使用SpringBoot整合Redis的時候,SpringBoot是可以根據配置自動完成Redis的相關配置,不過為了更靈活一點,我們這邊還是手動載入一下配置,配置成自己想要的那種效果吧。
首先,配置一個Redis的連線池,使用redis.clients.jedis.JedisPoolConfig
這個類來進行實現,相關的配置在程式碼的註釋中說明得很詳細了,這裡就不在過多講述了;
然後,再來配置一個Redis的工廠,載入Redis的連線池配置,這裡我們也可以進行一下設定,如果Redis設定了密碼,我們就載入改密碼,否則就不進行載入。
繼而,我們再來設定資料存入Redis的序列化的方式並開啟事務。這裡也順便說下為什麼要設定序列化器,如果不設定,那麼在用實體類(未序列化)進行儲存的時候,會提示錯誤: Failed to serialize object using DefaultSerializer
; 當然,也可以不設定,不過儲存的實體類必須進行序列化。
最後,我們再來例項化RedisTemplate的物件,載入上述的配置。在使用的時候,只需要使用如下的方式注入就可以使用了
@Autowired
RedisTemplate<String, Object> redisTemplate;
Redis的配置類的程式碼如下:
/**
*
* @Title: RedisConfig
* @Description: redis初始化配置
* @Version:1.0.0
* @author pancm
* @date 2018年6月7日
*/
@Component
public class RedisConfig {
@Value("${redis.maxIdle}")
private Integer maxIdle;
@Value("${redis.maxTotal}")
private Integer maxTotal;
@Value("${redis.maxWaitMillis}")
private Integer maxWaitMillis;
@Value("${redis.minEvictableIdleTimeMillis}")
private Integer minEvictableIdleTimeMillis;
@Value("${redis.numTestsPerEvictionRun}")
private Integer numTestsPerEvictionRun;
@Value("${redis.timeBetweenEvictionRunsMillis}")
private long timeBetweenEvictionRunsMillis;
@Value("${redis.testOnBorrow}")
private boolean testOnBorrow;
@Value("${redis.testWhileIdle}")
private boolean testWhileIdle;
@Value("${redis.cluster.max-redirects}")
private Integer mmaxRedirectsac;
@Value("${redis.password}")
private String redispwd;
/**
* JedisPoolConfig 連線池
*
* @return
*/
@Bean
public JedisPoolConfig jedisPoolConfig() {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
// 最大空閒數
jedisPoolConfig.setMaxIdle(maxIdle);
// 連線池的最大資料庫連線數
jedisPoolConfig.setMaxTotal(maxTotal);
// 最大建立連線等待時間
jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
// 逐出連線的最小空閒時間 預設1800000毫秒(30分鐘)
jedisPoolConfig.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
// 每次逐出檢查時 逐出的最大數目 如果為負數就是 : 1/abs(n), 預設3
jedisPoolConfig.setNumTestsPerEvictionRun(numTestsPerEvictionRun);
// 逐出掃描的時間間隔(毫秒) 如果為負數,則不執行逐出執行緒, 預設-1
jedisPoolConfig.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
// 是否在從池中取出連線前進行檢驗,如果檢驗失敗,則從池中去除連線並嘗試取出另一個
jedisPoolConfig.setTestOnBorrow(testOnBorrow);
// 在空閒時檢查有效性, 預設false
jedisPoolConfig.setTestWhileIdle(testWhileIdle);
return jedisPoolConfig;
}
/**
* 配置工廠
*/
@Bean
public JedisConnectionFactory JedisConnectionFactory(JedisPoolConfig jedisPoolConfig) {
JedisConnectionFactory JedisConnectionFactory = new JedisConnectionFactory(jedisPoolConfig);
if (redispwd == null || redispwd.length() == 0) {
JedisConnectionFactory.setPassword(redispwd);
}
return JedisConnectionFactory;
}
/**
* 設定資料存入 redis 的序列化方式,並開啟事務
*
* @param redisTemplate
* @param factory
*/
private void initDomainRedisTemplate(RedisTemplate<String, Object> redisTemplate, RedisConnectionFactory factory) {
/*
* 設定 序列化器 .
* 如果不設定,那麼在用實體類(未序列化)進行儲存的時候,會提示錯誤: Failed to serialize object using DefaultSerializer;
*/
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
// 開啟事務
redisTemplate.setEnableTransactionSupport(true);
// 將連線工廠設定到模板類中
redisTemplate.setConnectionFactory(factory);
}
/**
* 例項化 RedisTemplate 物件
* @return
*/
@Bean
public RedisTemplate<String, Object> functionDomainRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
initDomainRedisTemplate(redisTemplate, redisConnectionFactory);
return redisTemplate;
}
}
當然,如果自己想使用自定義的Redis工具類進行實現,那麼只需在該配置類中註冊一個Bean注入封裝一下就可以了,然後在工具類中載入一下就可以了。
配置類中新增:
@Bean(name = "redisUtil")
public RedisUtil redisUtil(RedisTemplate<String, Object> redisTemplate) {
RedisUtil redisUtil = new RedisUtil();
redisUtil.setRedisTemplate(redisTemplate);
return redisUtil;
}'
Redis的工具類新增如下程式碼:
private RedisTemplate<String, Object> redisTemplate;
public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
this.redisTemplate = redisTemplate;
}
使用Redis工具類示例:
@Resource
private RedisUtil redisUtil;
講完Redis的配置類之後,我們再來進行編寫相應的實體類、dao層、service層和Controller層的程式碼了。
由於這塊的程式碼比較簡單,而且格式和之前的專案基本類似,因此這裡我就簡單的貼下程式碼了。
實體類
又是萬能的使用者表 (^▽^)
程式碼如下:
public class User implements Serializable{
private static final long serialVersionUID = 1L;
/** 編號 */
private int id;
/** 姓名 */
private String name;
/** 年齡 */
private int age;
public User(){
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String toString() {
return JSONObject.toJSONString(this);
}
}
Dao 資料層
這裡我是使用的自定義的Redis工具類,其實也就是對RedisTemplate
做了二次封裝。
因為使用的是set(集合)方式儲存的,所以我這邊把使用者資料的ID作為key,使用者資料作為value了。
實現類的程式碼如下:
@Repository
public class UserDaoImpl implements UserDao {
@Resource
private RedisUtil redisUtil;
@Override
public void addUser(User user) {
redisUtil.set(String.valueOf(user.getId()), user.toString());
}
@Override
public void updateUser(User user) {
redisUtil.set(String.valueOf(user.getId()), user.toString());
}
@Override
public void deleteUser(int id) {
redisUtil.del(String.valueOf(id));
}
@Override
public User findByUserId(int id) {
String data = redisUtil.get(String.valueOf(id)).toString();
User user = JSON.parseObject(data, User.class);
return user;
}
}
Service 業務層
業務層這邊處理比較簡單,成功就返回true,失敗就返回false。
實現類的程式碼如下:
@Service
public class UserServiceImpl implements UserService {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private UserDao userDao;
@Override
public boolean addUser(User user) {
boolean flag=false;
try{
userDao.addUser(user);
flag=true;
}catch(Exception e){
logger.error("新增失敗!",e);
}
return flag;
}
@Override
public boolean updateUser(User user) {
boolean flag=false;
try{
userDao.updateUser(user);
flag=true;
}catch(Exception e){
logger.error("修改失敗!",e);
}
return flag;
}
@Override
public boolean deleteUser(int id) {
boolean flag=false;
try{
userDao.deleteUser(id);
flag=true;
}catch(Exception e){
logger.error("刪除失敗!",e);
}
return flag;
}
@Override
public User findByUserId(int id) {
return userDao.findByUserId(id);
}
}
Controller 控制層
控制層這邊也比較簡單,使用Restful風格實現的CRUD功能。
程式碼如下:
@RestController
@RequestMapping(value = "/api")
public class UserRestController {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private UserService userService;
@PostMapping("/user")
public boolean addUser(@RequestBody User user) {
logger.info("開始新增...");
return userService.addUser(user);
}
@PutMapping("/user")
public boolean updateUser(@RequestBody User user) {
logger.info("開始更新...");
return userService.updateUser(user);
}
@DeleteMapping("/user")
public boolean delete(@RequestParam(value = "id", required = true) int userId) {
logger.info("開始刪除...");
return userService.deleteUser(userId);
}
@GetMapping("/user")
public User findByUserId(@RequestParam(value = "id", required = true) int userId) {
logger.info("開始查詢所有資料...");
return userService.findByUserId(userId);
}
}
App 入口
和普通的SpringBoot專案基本一樣。
程式碼如下:
@SpringBootApplication
public class App
{
public static void main( String[] args )
{
SpringApplication.run(App.class, args);
System.out.println("程式正在執行...");
}
}
功能測試
我們成功啟動該程式之後,使用Postman工具來進行介面測試。
首先新增一條資料,使用POST方式進行請求
POST http://localhost:8180/api/user
Body引數為:
{"id":1,"name":"xuwujing","age":18}
介面返回true,表示新增成功了!
然後在進行查詢,使用GET請求。
GET http://localhost:8180/api/user?id=1
返回:
{"id":1,"name":"xuwujing","age":18}
我們再來使用RedisDesktopManager工具進行查詢看下,是否真的寫入到Redis中去了。
可以看到已經成功寫入到Redis中了。
然後我們再來更新下更新該資料,使用PUT方式請求。
PUT http://localhost:8180/api/user
這裡只是更改了下age年齡,Body引數為:
{"id":1,"name":"xuwujing","age":19}
可以看到已經成功更新了。
最後我們再來查詢一遍看下是否成功更新。
GET http://localhost:8180/api/user?id=1
返回:
{"id":1,"name":"xuwujing","age":19}
可以看到已經成功更新了。
其它
其實SpringBoot整合Redis整個專案很早之前就已經寫好並且上傳到Github了,但是一直沒有抽出時間寫篇部落格講述(還有很多SpringBoot的專案也是如此),最近不是那麼的忙了,於是準備了下時間編寫本篇博文。後續個人Github上的SpringBoot專案中以後有時間的話,也會對其中的一些發表博文進行講解,不過那是以後的事了ヽ(ー_ー)ノ
關於SpringBoot整合Redis的文章就講解到這裡了,如有不妥,歡迎指正!
專案地址
SpringBoot整合Redis的專案工程地址:
https://github.com/xuwujing/springBoot-study/tree/master/springboot-Redis
SpringBoot整個集合的地址:
https://github.com/xuwujing/springBoot-study
SpringBoot整合系列的文章
springBoot配置檔案的讀取以及過濾器和攔截器的使用
- SpringBoot的Restful風格的服務
SpringBoot+Mybatis+ Druid+PageHelper實現多資料來源並分頁
SpringBoot整合ElasticSearch實現多版本的相容
SpringBoot整合Kafka和Storm
SpringBoot整合Jsp和Thymeleaf
SpringBoot整合Netty並使用Protobuf進行資料傳輸
SpringBoot簡單打包部署
音樂推薦
原創不易,如果感覺不錯,希望給個推薦!您的支援是我寫作的最大動力!
版權宣告:
作者:虛無境
部落格園出處:http://www.cnblogs.com/xuwujing
CSDN出處:http://blog.csdn.net/qazwsxpcm
個人部落格出處:http://www.panchengming.