SpringBoot整合Redis使用Restful風(fēng)格實(shí)現(xiàn)CRUD功能
真香!24W字的Java面試手冊(cè)(點(diǎn)擊查看)
前言
本篇文章主要介紹的是SpringBoot整合Redis,使用Restful風(fēng)格實(shí)現(xiàn)的CRUD功能。
Redis 介紹
Redis支持?jǐn)?shù)據(jù)的持久化,可以將內(nèi)存中的數(shù)據(jù)保存在磁盤(pán)中,重啟的時(shí)候可以再次加載進(jìn)行使用。 Redis不僅僅支持簡(jiǎn)單的key-value類(lèi)型的數(shù)據(jù),同時(shí)還提供list,set,zset,hash等數(shù)據(jù)結(jié)構(gòu)的存儲(chǔ)。 Redis支持?jǐn)?shù)據(jù)的備份,即master-slave模式的數(shù)據(jù)備份。
更多的使用說(shuō)明可以查看官方的文檔。官方文檔: https://redis.io
SpringBoot整合Redis
說(shuō)明:如果想直接獲取工程那么可以直接跳到底部,通過(guò)鏈接下載工程代碼。
環(huán)境要求 JDK:1.8 SpringBoot:1.5.15.RELEASE Redis:3.2或以上。
Tips:Redis的偶數(shù)為穩(wěn)定版本,奇數(shù)為非穩(wěn)定版本,所以在使用的時(shí)候最好使用偶數(shù)的版本!
首先還是Maven的相關(guān)依賴(lài):
<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>
添加了相應(yīng)的maven依賴(lài)之后,我們?cè)賮?lái)查看配置。 Redis配置的說(shuō)明在下面中已經(jīng)說(shuō)的很詳細(xì)了,這里就不在過(guò)多說(shuō)明了,不過(guò)需要注意的是如果Redis是集群版的話(huà),需要使用這個(gè)spring.redis.cluster.nodes這個(gè)配置,該配置為Redis的Host加上Port,多個(gè)之間用,逗號(hào)隔開(kāi)。 application.properties的配置如下:
# Redis服務(wù)器地址
# 單機(jī)版配置
spring.redis.host = 127.0.0.1
spring.redis.port = 6379
# redis最大重連數(shù)
redis.cluster.max-redirects=3
# Redis服務(wù)器連接密碼(默認(rèn)為空)
redis.password=
# 最大空閑數(shù)
redis.maxIdle=5
# 連接池的最大數(shù)據(jù)庫(kù)連接數(shù)。
redis.maxTotal=5
# 最大建立連接等待時(shí)間。如果超過(guò)此時(shí)間將接到異常。設(shè)為-1表示無(wú)限制。
redis.maxWaitMillis=1000
# 連接的最小空閑時(shí)間 默認(rèn)1800000毫秒(30分鐘)
redis.minEvictableIdleTimeMillis=300000
# 每次釋放連接的最大數(shù)目,默認(rèn)3
redis.numTestsPerEvictionRun=3
# 逐出掃描的時(shí)間間隔(毫秒) 如果為負(fù)數(shù),則不運(yùn)行逐出線(xiàn)程, 默認(rèn)-1
redis.timeBetweenEvictionRunsMillis=30000
# 是否在從池中取出連接前進(jìn)行檢驗(yàn),如果檢驗(yàn)失敗,則從池中去除連接并嘗試取出另一個(gè)
redis.testOnBorrow=true
# 在空閑時(shí)檢查有效性, 默認(rèn)false
redis.testWhileIdle=true
代碼編寫(xiě)
首先是編寫(xiě)Redis的配置類(lèi),對(duì)Redis這塊進(jìn)行配置。在使用SpringBoot整合Redis的時(shí)候,SpringBoot是可以根據(jù)配置自動(dòng)完成Redis的相關(guān)配置,不過(guò)為了更靈活一點(diǎn),我們這邊還是手動(dòng)加載一下配置,配置成自己想要的那種效果吧。首先,配置一個(gè)Redis的連接池,使用redis.clients.jedis.JedisPoolConfig這個(gè)類(lèi)來(lái)進(jìn)行實(shí)現(xiàn),相關(guān)的配置在代碼的注釋中說(shuō)明得很詳細(xì)了,這里就不在過(guò)多講述了;然后,再來(lái)配置一個(gè)Redis的工廠(chǎng),加載Redis的連接池配置,這里我們也可以進(jìn)行一下設(shè)置,如果Redis設(shè)置了密碼,我們就加載改密碼,否則就不進(jìn)行加載。繼而,我們?cè)賮?lái)設(shè)置數(shù)據(jù)存入Redis的序列化的方式并開(kāi)啟事務(wù)。這里也順便說(shuō)下為什么要設(shè)置序列化器,如果不設(shè)置,那么在用實(shí)體類(lèi)(未序列化)進(jìn)行存儲(chǔ)的時(shí)候,會(huì)提示錯(cuò)誤: Failed to serialize object using DefaultSerializer; 當(dāng)然,也可以不設(shè)置,不過(guò)存儲(chǔ)的實(shí)體類(lèi)必須進(jìn)行序列化。最后,我們?cè)賮?lái)實(shí)例化RedisTemplate的對(duì)象,加載上述的配置。在使用的時(shí)候,只需要使用如下的方式注入就可以使用了
@Autowired
RedisTemplate<String, Object> redisTemplate;
Redis的配置類(lèi)的代碼如下:
/**
*
* @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();
// 最大空閑數(shù)
jedisPoolConfig.setMaxIdle(maxIdle);
// 連接池的最大數(shù)據(jù)庫(kù)連接數(shù)
jedisPoolConfig.setMaxTotal(maxTotal);
// 最大建立連接等待時(shí)間
jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
// 逐出連接的最小空閑時(shí)間 默認(rèn)1800000毫秒(30分鐘)
jedisPoolConfig.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
// 每次逐出檢查時(shí) 逐出的最大數(shù)目 如果為負(fù)數(shù)就是 : 1/abs(n), 默認(rèn)3
jedisPoolConfig.setNumTestsPerEvictionRun(numTestsPerEvictionRun);
// 逐出掃描的時(shí)間間隔(毫秒) 如果為負(fù)數(shù),則不運(yùn)行逐出線(xiàn)程, 默認(rèn)-1
jedisPoolConfig.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
// 是否在從池中取出連接前進(jìn)行檢驗(yàn),如果檢驗(yàn)失敗,則從池中去除連接并嘗試取出另一個(gè)
jedisPoolConfig.setTestOnBorrow(testOnBorrow);
// 在空閑時(shí)檢查有效性, 默認(rèn)false
jedisPoolConfig.setTestWhileIdle(testWhileIdle);
return jedisPoolConfig;
}
/**
* 配置工廠(chǎng)
*/
@Bean
public JedisConnectionFactory JedisConnectionFactory(JedisPoolConfig jedisPoolConfig) {
JedisConnectionFactory JedisConnectionFactory = new JedisConnectionFactory(jedisPoolConfig);
if (redispwd == null || redispwd.length() == 0) {
JedisConnectionFactory.setPassword
當(dāng)然,如果自己想使用自定義的Redis工具類(lèi)進(jìn)行實(shí)現(xiàn),那么只需在該配置類(lèi)中注冊(cè)一個(gè)Bean注入封裝一下就可以了,然后在工具類(lèi)中加載一下就可以了。配置類(lèi)中添加:
@Bean(name = "redisUtil")
public RedisUtil redisUtil(RedisTemplate<String, Object> redisTemplate) {
RedisUtil redisUtil = new RedisUtil();
redisUtil.setRedisTemplate(redisTemplate);
return redisUtil;
}'
Redis的工具類(lèi)添加如下代碼:
private RedisTemplate<String, Object> redisTemplate;
public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
this.redisTemplate = redisTemplate;
}
使用Redis工具類(lèi)示例:
@Resource
private RedisUtil redisUtil;
實(shí)體類(lèi)
又是萬(wàn)能的用戶(hù)表 (^▽^)
代碼如下:
public class User implements Serializable{
private static final long serialVersionUID = 1L;
/** 編號(hào) */
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 數(shù)據(jù)層
這里我是使用的自定義的Redis工具類(lèi),其實(shí)也就是對(duì)RedisTemplate做了二次封裝。因?yàn)槭褂玫氖莝et(集合)方式存儲(chǔ)的,所以我這邊把用戶(hù)數(shù)據(jù)的ID作為key,用戶(hù)數(shù)據(jù)作為value了。
實(shí)現(xiàn)類(lèi)的代碼如下:
<pre style="overflow: auto; font-family: consolas, Menlo, "PingFang SC", "Microsoft YaHei", monospace; font-size: 13px; margin: 0px; padding: 10px; color: rgb(77, 77, 76); background: rgb(247, 247, 247); line-height: 1.6; border: none; width: 571px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;">@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;
}
}
</pre>
業(yè)務(wù)層這邊處理比較簡(jiǎn)單,成功就返回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 控制層
控制層這邊也比較簡(jiǎn)單,使用Restful風(fēng)格實(shí)現(xiàn)的CRUD功能。
代碼如下:
<pre style="overflow: auto; font-family: consolas, Menlo, "PingFang SC", "Microsoft YaHei", monospace; font-size: 13px; margin: 0px; padding: 10px; color: rgb(77, 77, 76); background: rgb(247, 247, 247); line-height: 1.6; border: none; width: 642px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;">@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("開(kāi)始新增...");
return userService.addUser(user);
}
@PutMapping("/user")
public boolean updateUser(@RequestBody User user) {
logger.info("開(kāi)始更新...");
return userService.updateUser(user);
}
@DeleteMapping("/user")
public boolean delete(@RequestParam(value = "id", required = true) int userId) {
logger.info("開(kāi)始刪除...");
return userService.deleteUser(userId);
}
@GetMapping("/user")
public User findByUserId(@RequestParam(value = "id", required = true) int userId) {
logger.info("開(kāi)始查詢(xún)所有數(shù)據(jù)...");
return userService.findByUserId(userId);
}
}
</pre>
App 入口
和普通的SpringBoot項(xiàng)目基本一樣。
代碼如下:
<pre style="overflow: auto; font-family: consolas, Menlo, "PingFang SC", "Microsoft YaHei", monospace; font-size: 13px; margin: 0px; padding: 10px; color: rgb(77, 77, 76); background: rgb(247, 247, 247); line-height: 1.6; border: none; width: 414px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;">@SpringBootApplication
public class App
{
public static void main( String[] args )
{
SpringApplication.run(App.class, args);
System.out.println("程序正在運(yùn)行...");
}
}
</pre>
功能測(cè)試
我們成功啟動(dòng)該程序之后,使用Postman工具來(lái)進(jìn)行接口測(cè)試。
首先添加一條數(shù)據(jù),使用POST方式進(jìn)行請(qǐng)求
POST http://localhost:8180/api/user
Body參數(shù)為:
{“id”:1,”name”:”xuwujing”,”age”:18}

界面返回true,表示新增成功了!
然后在進(jìn)行查詢(xún),使用GET請(qǐng)求。
GET http://localhost:8180/api/user?id=1
返回:
{“id”:1,”name”:”xuwujing”,”age”:18}

我們?cè)賮?lái)使用RedisDesktopManager工具進(jìn)行查詢(xún)看下,是否真的寫(xiě)入到Redis中去了。
可以看到已經(jīng)成功寫(xiě)入到Redis中了。
然后我們?cè)賮?lái)更新下更新該數(shù)據(jù),使用PUT方式請(qǐng)求。
PUT http://localhost:8180/api/user
這里只是更改了下age年齡,Body參數(shù)為:
{“id”:1,”name”:”xuwujing”,”age”:19}
可以看到已經(jīng)成功更新了。
最后我們?cè)賮?lái)查詢(xún)一遍看下是否成功更新。
GET http://localhost:8180/api/user?id=1
返回:
{“id”:1,”name”:”xuwujing”,”age”:19}
可以看到已經(jīng)成功更新了。
其它
其實(shí)SpringBoot整合Redis整個(gè)項(xiàng)目很早之前就已經(jīng)寫(xiě)好并且上傳到Github了,但是一直沒(méi)有抽出時(shí)間寫(xiě)篇博客講述(還有很多SpringBoot的項(xiàng)目也是如此)
關(guān)于SpringBoot整合Redis的文章就講解到這里了,如有不妥,歡迎指正!
項(xiàng)目地址
SpringBoot整合Redis的項(xiàng)目工程地址: https://github.com/xuwujing/springBoot-study/tree/master/springboot-Redis
如有文章對(duì)你有幫助,
“在看”和轉(zhuǎn)發(fā)是對(duì)我最大的支持!
點(diǎn)擊文末“閱讀原文”可直達(dá)

