# 依赖
compile('org.springframework.boot:spring-boot-starter-data-redis')# application.yml配置
spring: # redis redis: database: 0 host: localhost port: 6379 password: 12345 jedis: pool: max-active: 10 min-idle: 0 max-idle: 8 timeout: 10000
# redis配置类 new RedisConfiguration
package com.futao.springmvcdemo.foundation.configurationimport org.springframework.cache.CacheManagerimport org.springframework.cache.annotation.CachingConfigurerSupportimport org.springframework.cache.annotation.EnableCachingimport org.springframework.cache.interceptor.KeyGeneratorimport org.springframework.context.annotation.Beanimport org.springframework.context.annotation.Configurationimport org.springframework.data.redis.cache.RedisCacheManagerimport org.springframework.data.redis.connection.RedisConnectionFactoryimport org.springframework.data.redis.core.RedisTemplateimport org.springframework.data.redis.serializer.StringRedisSerializerimport javax.annotation.Resource/**
* redis配置类
*
* @author futao
* Created on 2018/10/16.
*
* redisTemplate.opsForValue();//操作字符串
* redisTemplate.opsForHash();//操作hash
* redisTemplate.opsForList();//操作list
* redisTemplate.opsForSet();//操作set
* redisTemplate.opsForZSet();//操作有序set
*
*/@Configuration@EnableCachingopen class RedisConfiguration : CachingConfigurerSupport() { /**
* 自定义redis key的生成规则
*/
@Bean
override fun keyGenerator(): KeyGenerator { return KeyGenerator { target, method, params -> val builder = StringBuilder()
builder.append("${target.javaClass.simpleName}-")
.append("${method.name}-") for (param in params) {
builder.append("$param-")
}
builder.toString().toLowerCase()
}
} /**
* 自定义序列化
* 这里的FastJsonRedisSerializer引用的自己定义的
*/
@Bean
open fun redisTemplate(factory: RedisConnectionFactory): RedisTemplate<String, Any> { val redisTemplate = RedisTemplate<String, Any>() val fastJsonRedisSerializer = FastJsonRedisSerializer(Any::class.java)
val stringRedisSerializer = StringRedisSerializer() return redisTemplate.apply {
defaultSerializer = fastJsonRedisSerializer
keySerializer = stringRedisSerializer
hashKeySerializer = stringRedisSerializer
valueSerializer = fastJsonRedisSerializer
hashValueSerializer = fastJsonRedisSerializer
connectionFactory = factory
}
} @Resource
lateinit var redisConnectionFactory: RedisConnectionFactory override fun cacheManager(): CacheManager { return RedisCacheManager.create(redisConnectionFactory)
}
}# 自定义redis中数据的序列化与反序列化 new FastJsonRedisSerializer
package com.futao.springmvcdemo.foundation.configurationimport com.alibaba.fastjson.JSONimport com.alibaba.fastjson.serializer.SerializerFeatureimport com.futao.springmvcdemo.model.system.SystemConfigimport org.springframework.data.redis.serializer.RedisSerializerimport java.nio.charset.Charset/**
* 自定义redis中数据的序列化与反序列化
*
* @author futao
* Created on 2018/10/17.
*/class FastJsonRedisSerializer<T>(java: Class<T>) : RedisSerializer<T> { private val clazz: Class<T>? = null
/**
* Serialize the given object to binary data.
*
* @param t object to serialize. Can be null.
* @return the equivalent binary data. Can be null.
*/
override fun serialize(t: T?): ByteArray? { return if (t == null) { null
} else {
JSON.toJSONString(t, SerializerFeature.WriteClassName).toByteArray(Charset.forName(SystemConfig.UTF8_ENCODE))
}
} /**
* Deserialize an object from the given binary data.
*
* @param bytes object binary representation. Can be null.
* @return the equivalent object instance. Can be null.
*/
override fun deserialize(bytes: ByteArray?): T? { return if (bytes == null || bytes.isEmpty()) { null
} else { val string = String(bytes, Charset.forName(SystemConfig.UTF8_ENCODE))
JSON.parseObject(string, clazz) as T
}
}
}# 启动类
package com.futao.springmvcdemo;import com.alibaba.fastjson.parser.ParserConfig;import org.mybatis.spring.annotation.MapperScan;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.boot.web.servlet.ServletComponentScan;import org.springframework.cache.annotation.EnableCaching;/**
* @author futao
* ServletComponentScan 开启servlet和filter
*/@SpringBootApplication@ServletComponentScan@MapperScan("com.futao.springmvcdemo.dao")@EnableCaching//@EnableAspectJAutoProxypublic class SpringmvcdemoApplication { public static void main(String[] args) {
SpringApplication.run(SpringmvcdemoApplication.class, args); /**
* redis反序列化
* 开启fastjson反序列化的autoType
*/
ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
}
}# 使用
1. 基于注解的方式
@Cacheable() redis中的key会根据我们的keyGenerator方法来生成,比如对应下面这个例子,如果曾经以mobile,pageNum,pageSize,orderBy的值执行过list这个方法的话,方法返回的值会存在redis缓存中,下次如果仍然以相同的mobile,pageNum,pageSize,orderBy的值来调用这个方法的话会直接返回缓存中的值
@Servicepublic class UserServiceImpl implements UserService { @Override
@Cacheable(value = "user") public List<User> list(String mobile, int pageNum, int pageSize, String orderBy) {
PageResultUtils<User> pageResultUtils = new PageResultUtils<>(); final val sql = pageResultUtils.createCriteria(User.class.getSimpleName())
.orderBy(orderBy)
.page(pageNum, pageSize)
.getSql(); return userDao.list(sql);
}
}测试
第一次请求(可以看到执行了sql,数据是从数据库中读取的)
第一次请求
通过redis desktop manager查看redis缓存中已经存储了我们刚才list返回的值
image.png
后续请求(未执行sql,直接读取的是redis中的值)
后续请求
2. 通过java代码手动set与get
package com.futao.springmvcdemo.controllerimport com.futao.springmvcdemo.model.entity.Userimport org.springframework.data.redis.core.RedisTemplateimport org.springframework.http.MediaTypeimport org.springframework.web.bind.annotation.GetMappingimport org.springframework.web.bind.annotation.RequestMappingimport org.springframework.web.bind.annotation.RequestParamimport org.springframework.web.bind.annotation.RestControllerimport javax.annotation.Resource/**
* @author futao
* Created on 2018/10/17.
*/@RestController@RequestMapping(path = ["kotlinTest"], produces = [MediaType.APPLICATION_JSON_UTF8_VALUE])open class KotlinTestController { @Resource
private lateinit var redisTemplate: RedisTemplate<Any, Any> /**
* 存入缓存
*/
@GetMapping(path = ["setCache"])
open fun cache( @RequestParam("name") name: String, @RequestParam("age") age: Int
): User { val user = User().apply {
username = name
setAge(age.toString())
}
redisTemplate.opsForValue().set(name, user) return user
} /**
* 获取缓存
*/
@GetMapping(path = ["getCache"])
open fun getCache( @RequestParam("name") name: String
): User? { return if (redisTemplate.opsForValue().get(name) != null) {
redisTemplate.opsForValue().get(name) as User
} else null
}
}测试结果
请求(序列化)
image.png
作者:FutaoSmile丶
链接:https://www.jianshu.com/p/38b733f7f5f3