a.創(chuàng)建數(shù)據(jù)庫(kù) springbootdb:
CREATE DATABASE springbootdb;
b.創(chuàng)建表 city :(因?yàn)槲蚁矚g徒步)
DROP TABLE IF EXISTS `city`;
CREATE TABLE `city` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT'城市編號(hào)',
`province_id` int(10) unsigned NOT NULL COMMENT'省份編號(hào)',
`city_name` varchar(25) DEFAULT NULL COMMENT'城市名稱',
`description` varchar(25) DEFAULT NULL COMMENT'描述',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
c.插入數(shù)據(jù)
INSERT city VALUES (1 ,1,'溫嶺市','BYSocket 的家在溫嶺。');
2. springboot-mybatis-redis 工程項(xiàng)目結(jié)構(gòu)介紹
springboot-mybatis-redis 工程項(xiàng)目結(jié)構(gòu)如下圖所示:
org.spring.springboot.controller - Controller 層
org.spring.springboot.dao - 數(shù)據(jù)操作層 DAO
org.spring.springboot.domain - 實(shí)體類
org.spring.springboot.service - 業(yè)務(wù)邏輯層
Application - 應(yīng)用啟動(dòng)類
application.properties - 應(yīng)用配置文件,應(yīng)用啟動(dòng)會(huì)自動(dòng)讀取配置
在項(xiàng)目根目錄 springboot-learning-example,運(yùn)行 maven 指令:
mvn cleaninstall
再請(qǐng)求一次,獲取城市信息會(huì)發(fā)現(xiàn)數(shù)據(jù)獲取的耗時(shí)快了很多。服務(wù)端 Console 輸出的日志:
2017-04-13 18:29:00.273 INFO 13038 --- [nio-8080-exec-1] o.s.s.service.impl.CityServiceImpl : CityServiceImpl.findCityById() : 城市插入緩存 >> City{id=12, provinceId=3, cityName='三亞', description='水好,天藍(lán)'}
2017-04-13 18:29:03.145 INFO 13038 --- [nio-8080-exec-2] o.s.s.service.impl.CityServiceImpl : CityServiceImpl.findCityById() : 從緩存中獲取了城市 >> City{id=12, provinceId=3, cityName='三亞', description='水好,天藍(lán)'}
這兩種操作中,如果緩存有對(duì)應(yīng)的數(shù)據(jù),則刪除緩存。服務(wù)端 Console 輸出的日志:
2017-04-13 18:29:52.248 INFO 13038 --- [nio-8080-exec-9] o.s.s.service.impl.CityServiceImpl : CityServiceImpl.deleteCity() : 從緩存中刪除城市 ID >> 12
pom.xml 依賴配置:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>springboot</groupId>
<artifactId>springboot-mybatis-redis</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot-mybatis-redis :: 整合 Mybatis 并使用 Redis 作為緩存</name>
<!-- Spring Boot 啟動(dòng)父依賴 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.1.RELEASE</version>
</parent>
<properties>
<mybatis-spring-boot>1.2.0</mybatis-spring-boot>
<mysql-connector>5.1.39</mysql-connector>
<spring-boot-starter-redis-version>1.3.2.RELEASE</spring-boot-starter-redis-version>
</properties>
<dependencies>
<!-- Spring Boot Reids 依賴 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId>
<version>${spring-boot-starter-redis-version}</version>
</dependency>
<!-- Spring Boot Web 依賴 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Boot Test 依賴 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Spring Boot Mybatis 依賴 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis-spring-boot}</version>
</dependency>
<!-- MySQL 連接驅(qū)動(dòng)依賴 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql-connector}</version>
</dependency>
<!-- Junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
</project>
在 application.properties 應(yīng)用配置文件,增加 Redis 相關(guān)配置
## 數(shù)據(jù)源配置
spring.datasource.url=jdbc:mysql://localhost:3306/springbootdb?useUnicode=true&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
## Mybatis 配置
mybatis.typeAliasesPackage=org.spring.springboot.domain
mybatis.mapperLocations=classpath:mapper/*.xml
## Redis 配置
## Redis數(shù)據(jù)庫(kù)索引(默認(rèn)為0)
spring.redis.database=0
## Redis服務(wù)器地址
spring.redis.host=127.0.0.1
## Redis服務(wù)器連接端口
spring.redis.port=6379
## Redis服務(wù)器連接密碼(默認(rèn)為空)
spring.redis.password=
## 連接池最大連接數(shù)(使用負(fù)值表示沒(méi)有限制)
spring.redis.pool.max-active=8
## 連接池最大阻塞等待時(shí)間(使用負(fù)值表示沒(méi)有限制)
spring.redis.pool.max-wait=-1
## 連接池中的最大空閑連接
spring.redis.pool.max-idle=8
## 連接池中的最小空閑連接
spring.redis.pool.min-idle=0
## 連接超時(shí)時(shí)間(毫秒)
spring.redis.timeout=0
CityRestController 控制層依舊是 Restful 風(fēng)格的,詳情可以參考《Springboot 實(shí)現(xiàn) Restful 服務(wù),基于 HTTP / JSON 傳輸》。 http://www.bysocket.com/?p=1627 domain 對(duì)象 City 必須實(shí)現(xiàn)序列化,因?yàn)樾枰獙?duì)象序列化后存儲(chǔ)到 Redis。如果沒(méi)實(shí)現(xiàn) Serializable ,控制臺(tái)會(huì)爆出以下異常:
Serializable
java.lang.IllegalArgumentException: DefaultSerializer requires a Serializable payload but received an object oftype
City.java 城市對(duì)象:
package org.spring.springboot.domain;
import java.io.Serializable;
/**
* 城市實(shí)體類
*
* Created by bysocket on 07/02/2017.
*/
public class City implements Serializable {
private static final long serialVersionUID = -1L;
/**
* 城市編號(hào)
*/
private Longid;
/**
* 省份編號(hào)
*/
private Long provinceId;
/**
* 城市名稱
*/
private String cityName;
/**
* 描述
*/
private String description;
public Long getId() {
return id;
}
public void setId(Longid) {
this.id =id;
}
public Long getProvinceId() {
return provinceId;
}
public void setProvinceId(Long provinceId) {
this.provinceId = provinceId;
}
public String getCityName() {
return cityName;
}
public void setCityName(String cityName) {
this.cityName = cityName;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@Override
public String toString() {
return "City{" +
"id=" +id +
", provinceId=" + provinceId +
", cityName='" + cityName + '\'' +
", description='" + description + '\'' +
'}';
}
}
主要還是城市業(yè)務(wù)邏輯實(shí)現(xiàn)類 CityServiceImpl.java:
package org.spring.springboot.service.impl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.spring.springboot.dao.CityDao;
import org.spring.springboot.domain.City;
import org.spring.springboot.service.CityService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* 城市業(yè)務(wù)邏輯實(shí)現(xiàn)類
* <p>
* Created by bysocket on 07/02/2017.
*/
@Service
public class CityServiceImpl implements CityService {
private static final Logger LOGGER = LoggerFactory.getLogger(CityServiceImpl.class);
@Autowired
private CityDao cityDao;
@Autowired
private RedisTemplate redisTemplate;
/**
* 獲取城市邏輯:
* 如果緩存存在,從緩存中獲取城市信息
* 如果緩存不存在,從 DB 中獲取城市信息,然后插入緩存
*/
public City findCityById(Longid) {
// 從緩存中獲取城市信息
String key ="city_" +id;
ValueOperations<String, City> operations = redisTemplate.opsForValue();
// 緩存存在
boolean hasKey = redisTemplate.hasKey(key);
if (hasKey) {
City city = operations.get(key);
LOGGER.info("CityServiceImpl.findCityById() : 從緩存中獲取了城市 >> " + city.toString());
return city;
}
// 從 DB 中獲取城市信息
City city = cityDao.findById(id);
// 插入緩存
operations.set(key, city, 10, TimeUnit.SECONDS);
LOGGER.info("CityServiceImpl.findCityById() : 城市插入緩存 >> " + city.toString());
return city;
}
@Override
public Long saveCity(City city) {
return cityDao.saveCity(city);
}
/**
* 更新城市邏輯:
* 如果緩存存在,刪除
* 如果緩存不存在,不操作
*/
@Override
public Long updateCity(City city) {
Long ret = cityDao.updateCity(city);
// 緩存存在,刪除緩存
String key ="city_" + city.getId();
boolean hasKey = redisTemplate.hasKey(key);
if (hasKey) {
redisTemplate.delete(key);
LOGGER.info("CityServiceImpl.updateCity() : 從緩存中刪除城市 >> " + city.toString());
}
return ret;
}
@Override
public Long deleteCity(Longid) {
Long ret = cityDao.deleteCity(id);
// 緩存存在,刪除緩存
String key ="city_" +id;
boolean hasKey = redisTemplate.hasKey(key);
if (hasKey) {
redisTemplate.delete(key);
LOGGER.info("CityServiceImpl.deleteCity() : 從緩存中刪除城市 ID >> " +id);
}
return ret;
}
}
更多建議: