配置了好几天才算配置好
个人感觉spring boot版本间兼容不好
一、创建maven项目并添加 pom 依赖
<?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>1</groupId>
<artifactId>1</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- Inherit defaults from Spring Boot -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<!--项目编码格式以及JDK版本指定-->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<!-- Add typical dependencies for a web application -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--alibaba.fastjson-->
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.41</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
//spring 包 很容易与spring boot 版本冲突 注意
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.12.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
二、yml 配置文件
################################
###### #####
###### 应用通用配置 #####
###### #####
################################
spring:
# 应用名称
application:
name: MavenDemoProject
# 多环境配置
profiles:
active: dev
# http请求编码配置
http:
encoding:
charset: UTF-8
force: true
enabled: true
# mysql数据库配置
datasource:
# type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
#url,username,password动态配置
url: jdbc:mysql://localhost:3306/test?useUnicode:true&characterEncoding:utf-8
username: root
password: ****
dbcp2:
#最大空闲连接
max-idle: 100
#最小空闲连接
min-idle: 10
#最大连接数
max-total: 200
#最大等待时间
max-wait-millis: 5000
#检测周期 单位毫秒
time-between-eviction-runs-millis: 30000
#连接池足校生存时间
min-evictable-idle-time-millis: 1800000
# test-on-borrow: true
# validation-query: SELECT 1
# test-while-idle: true
# num-tests-per-eviction-run: 100
# redis缓存配置
redis:
#host,password,port,database动态配置
host: *******
password: *****
port: 6379
database: 0
timeout: 2000
pool:
# 连接池中的最大空闲连接
max-idle: 80
# 连接池中的最小空闲连接
min-idle: 1
# 连接池最大连接数(使用负值表示没有限制)
max-active: 80
# 连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: 10
# mybatis配置
mybatis:
#config-location: classpath:/mybatis-config.xml
type-aliases-package: com.frank.dao.*
mapper-locations: classpath:/mapper/*.xml
# configuration:
# #延时加载
# lazy-loading-enabled: true
# map-underscore-to-camel-case: true
# use-column-label: true
需要在mapper xml 文件中声明二级缓存 如下
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.weixin.dao.student.StudentMapper">
<!--开启二级缓存-->
<cache type="com.weixin.config.RedisConfig"/>
<select id="get" resultType="com.weixin.model.Student">
SELECT * FROM student
WHERE id = #{id}
</select>
<update id="update" parameterType="com.weixin.model.Student">
UPDATE student SET
name = #{name},
age = #{age}
WHERE id = #{id}
</update>
</mapper>
bean类型 需要实现Serializable接口
package com.weixin.model;
import java.io.Serializable;
public class Student implements Serializable {
private int id;
private String name;
private int age;
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 void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
}
三、Redis 配置类
package com.weixin.config;
import org.apache.ibatis.cache.Cache;
import org.slf4j.Logger;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class RedisConfig implements Cache {
private static final Logger logger = org.slf4j.LoggerFactory.getLogger(RedisConfig.class);
private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
private String id; // cache instance id
private RedisTemplate redisTemplate;
private static final long EXPIRE_TIME_IN_MINUTES = 30; // redis过期时间
private static final String DEFAULT_ID = "default_id";
public RedisConfig(String id) {
if (id == null) {
id = DEFAULT_ID;
}
this.id = id;
}
public void setId(String id ){
this.id = id;
}
@Override
public String getId() {
return id;
}
/**
* Put query result to redis
*
* @param key
* @param value
*/
@Override
@SuppressWarnings("unchecked")
public void putObject(Object key, Object value) {
try {
RedisTemplate redisTemplate = getRedisTemplate();
ValueOperations opsForValue = redisTemplate.opsForValue();
opsForValue.set(key, value, EXPIRE_TIME_IN_MINUTES, TimeUnit.MINUTES);
logger.debug("Put query result to redis");
} catch (Throwable t) {
logger.error("Redis put failed", t);
}
}
/**
* Get cached query result from redis
*
* @param key
* @return
*/
@Override
public Object getObject(Object key) {
try {
RedisTemplate redisTemplate = getRedisTemplate();
ValueOperations opsForValue = redisTemplate.opsForValue();
logger.debug("Get cached query result from redis");
return opsForValue.get(key);
} catch (Throwable t) {
logger.error("Redis get failed, fail over to db", t);
return null;
}
}
/**
* Remove cached query result from redis
*
* @param key
* @return
*/
@Override
@SuppressWarnings("unchecked")
public Object removeObject(Object key) {
try {
RedisTemplate redisTemplate = getRedisTemplate();
redisTemplate.delete(key);
logger.debug("Remove cached query result from redis");
} catch (Throwable t) {
logger.error("Redis remove failed", t);
}
return null;
}
/**
* Clears this cache instance
*/
@Override
public void clear() {
RedisTemplate redisTemplate = getRedisTemplate();
redisTemplate.execute((RedisCallback) connection -> {
connection.flushDb();
return null;
});
logger.debug("Clear all the cached query result from redis");
}
/**
* This method is not used
*
* @return
*/
@Override
public int getSize() {
return 0;
}
@Override
public ReadWriteLock getReadWriteLock() {
return readWriteLock;
}
private RedisTemplate getRedisTemplate() {
if (redisTemplate == null) {
redisTemplate = ApplicationContextHolder.getBean("redisTemplate");
}
//spring-data-redis的RedisTemplate<K, V>模板类在操作redis时默认使用JdkSerializationRedisSerializer来进行序列化
//一下修改为String类型序列化 解决redis库中 K V 出现 xAC\xED\x00\x05t\x00\x04 问题
RedisSerializer stringSerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(stringSerializer);
// redisTemplate.setValueSerializer(stringSerializer);
redisTemplate.setHashKeySerializer(stringSerializer);
// redisTemplate.setHashValueSerializer(stringSerializer);
return redisTemplate;
}
}
ApplicationContextHolder 类
package com.weixin.config;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class ApplicationContextHolder implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext ctx) throws BeansException {
applicationContext = ctx;
}
/**
* Get application context from everywhere
*
* @return
*/
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
/**
* Get bean by class
*
* @param clazz
* @param <T>
* @return
*/
public static <T> T getBean(Class<T> clazz) {
return applicationContext.getBean(clazz);
}
/**
* Get bean by class name
*
* @param name
* @param <T>
* @return
*/
@SuppressWarnings("unchecked")
public static <T> T getBean(String name) {
return (T) applicationContext.getBean(name);
}
}
上面需要用到spring-context jar 包,需要注意版本,版本不同可能冲突
注意:
RedisSerializer stringSerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(stringSerializer);
// redisTemplate.setValueSerializer(stringSerializer);
redisTemplate.setHashKeySerializer(stringSerializer);
// redisTemplate.setHashValueSerializer(stringSerializer);
上面表示redis中的key值设置为String类型,这样能更清楚的找到key值,但是如果开启二级缓存的话,执行sql语句时查找的对象不会进行redis存储,因为查找到对象key为Object值,控制台会报错,如图
可以改成 key.toString() 进行存储,但是出现文件分级,如图:
所以说还要按照实际情况进行设置
四、controller层进行使用
package com.weixin.controller;
import com.alibaba.fastjson.JSONObject;
import com.weixin.config.RedisConfig;
import com.weixin.model.Student;
import com.weixin.service.student.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/test")
public class SpringBootTest {
@Autowired
private StudentService studentService;
@RequestMapping("/one")
public JSONObject test() {
JSONObject jsonObject = new JSONObject();
jsonObject.put("code", "success");
//id 没有实际价值 只是为了更好确认
RedisConfig redisConfig = new RedisConfig("100");
redisConfig.putObject("1000","hello i m frank!");
return jsonObject;
}
/**
* 根据id获取对象
*
* @param id
* @return
*/
@GetMapping("/{id}")
public JSONObject get(@PathVariable("id") int id) {
Student student = studentService.get(id);
JSONObject jsonObject = new JSONObject();
jsonObject.put("id", student.getId());
jsonObject.put("age", student.getAge());
jsonObject.put("name", student.getName());
RedisConfig redisConfig = new RedisConfig("100");
redisConfig.putObject("frank",jsonObject);
return jsonObject;
}
/**
* 更新对象
*
* @return
*/
@RequestMapping("/update")
public String put() {
Student student = new Student();
student.setId(1);
student.setAge(22);
student.setName("new frank");
studentService.update(student);
return "success";
}
@RequestMapping("/getRedis")
public JSONObject get() {
RedisConfig redisConfig = new RedisConfig("100");
return (JSONObject) redisConfig.getObject("frank");
}
}
五、运行查看
查看redis
添加JSON value 值
显示情况
如果想显示String的话 可以在RedisConfig中 setValueSerializer 进行设置
获取value值
五、项目总体结构
项目下载
http://download.youkuaiyun.com/download/jasonhector/10158450