1)添加依赖 pom.xml 添加的依赖包含Redis,Mysql,MyBatis,fastjson,junit
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.47</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.0.0</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency>2)配置application.properties
application.properties 配置mysql,redis服务器
spring.datasource.url=jdbc:mysql://127.0.0.1/book?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=true spring.datasource.username=root spring.datasource.password=root spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.jpa.properties.hibernate.hbm2ddl.auto=update spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect spring.jpa.show-sql= true spring.datasource.initialization-mode=always spring.datasource.schema=classpath:db/schema.sql # Redis数据库索引(默认为0) spring.redis.database=1 # Redis服务器地址 spring.redis.host=127.0.0.1 # Redis服务器连接端口 spring.redis.port=6379 # Redis服务器连接密码(默认为空) spring.redis.password= # 连接池最大连接数(使用负值表示没有限制) spring.redis.jedis.pool.max-active=8 # 连接池最大阻塞等待时间(使用负值表示没有限制) spring.redis.jedis.pool.max-wait=-1 # 连接池中的最大空闲连接 spring.redis.jedis.pool.max-idle=8 # 连接池中的最小空闲连接 spring.redis.jedis.pool.min-idle=0 # 连接超时时间(毫秒) spring.redis.timeout=50003)在入口类加上@EnableCaching注解,开启缓存支持
RedisDemoApplication.java
package com.example.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCaching; @SpringBootApplication @EnableCaching public class RedisDemoApplication { public static void main(String[] args) { SpringApplication.run(RedisDemoApplication.class, args); } }4)建立下面的项目结构
要想启动Spring缓存支持,需要创建一个CacheManager的Bean。
RedisConfig.java
package com.example.demo.config; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator; import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.CachingConfigurerSupport; import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.interceptor.KeyGenerator; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; import java.lang.reflect.Method; @Configuration public class RedisConfig extends CachingConfigurerSupport{ @Bean public KeyGenerator keyGenerator() { return new KeyGenerator() { @Override public Object generate(Object target, Method method, Object... params) { StringBuilder sb = new StringBuilder(); sb.append(target.getClass().getName()); sb.append(method.getName()); for (Object obj : params) { sb.append(obj.toString()); } return sb.toString(); } }; } @SuppressWarnings("rawtypes") @Bean //缓存管理器 public CacheManager cacheManager(RedisConnectionFactory connectionFactory) { RedisCacheManager cacheManager = RedisCacheManager.create(connectionFactory); //设置缓存过期时间 return cacheManager; } @Bean public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) { //配置连接工厂 StringRedisTemplate template = new StringRedisTemplate(factory); //使用Jackson2JsonRedisSerializer来序列化和反序列化redis 的value值 Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); ObjectMapper om = new ObjectMapper(); //指定要序列化的域,field,get和set,以及修饰符范围 om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); //om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); //指定序列化输入的类型,类必须是非final类 om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance , ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY); jackson2JsonRedisSerializer.setObjectMapper(om); //序列化配置为String格式 template.setValueSerializer(new StringRedisSerializer()); // template.setKeySerializer(new StringRedisSerializer()); template.afterPropertiesSet(); return template; } }关于数据的“序列化/反序列化”,提供了多种可选择策略(RedisSerializer)
序列化/发序列化解释JdkSerializationRedisSerializerPOJO对象的存取场景,使用JDK本身序列化机制,将pojo类通过ObjectInputStream/ObjectOutputStream进行序列化操作,最终redis-server中将存储字节序列。StringRedisSerializer适用于Key或者value为字符串的场景,根据指定的charset对数据的字节序列编码成stringJacksonJsonRedisSerializer提供了javabean与json之间的转换能力,可以将pojo实例序列化成json格式存储在redis中,也可以将json格式的数据转换成pojo实例。OxmSerializer提供了将javabean与xml之间的转换能力,目前可用的三方支持包括jaxb,apache-xmlbeans;redis存储的数据将是xml工具。上面4种策略中:
JdkSerializationRedisSerializer和StringRedisSerializer是最基础的策略,在设计时仍然不推荐直接使用后面两种,即JacksonJsonRedisSerializer和OxmSerializer,因为无论是json还是xml,他们本身仍然是String。
如果数据需要被第三方工具解析,那么数据应该使用StringRedisSerializer而不是JdkSerializationRedisSerializer。
如果数据格式必须为json或者xml,那么在编程级别,在redisTemplate配置中仍然使用StringRedisSerializer,在存储之前或者读取之后,使用“SerializationUtils”工具转换转换成json或者xml
User.java
package com.example.demo.model; import lombok.Data; import java.io.Serializable; @Data public class User implements Serializable { private String id; private String name; private int age; }这里需要注意的是spring boot在启动时会自动创建user表 在项目的resources目录下新建db目录,并添加schema.sql文件,写入创建user表的sql语句 当然还需要配置数据库连接,并加上数据表初始化的配置(配置工作前面的文件中已经包含) 这里是schema.sql
DROP TABLE IF EXISTS user; --IF object_id('user','U') is not NULL drop table 'user'; CREATE TABLE user( id int(11) NOT NULL AUTO_INCREMENT, name varchar(255) DEFAULT NULL, age int(11) DEFAULT NULL, PRIMARY KEY (id) )ENGINE=InnoDB DEFAULT CHARSET=utf8;UserMapper.java
package com.example.demo.mapper; import com.example.demo.model.User; import org.apache.ibatis.annotations.Delete; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; import org.apache.ibatis.annotations.Update; import org.springframework.stereotype.Repository; @Repository @Mapper public interface UserMapper { @Insert("insert into user(name,age) values(#{name},#{age})") int addUser(@Param("name")String name,@Param("age")String age); @Select("select * from user where id=#{id}") User findById(@Param("id")String id); @Update("update user set name=#{name},age=#{age} where id=#{id}") int updateById(User user); @Delete("delete from user where id=#{id}") void deleteById(@Param("id")String id); }创建Redis缓存服务器,即缓存在服务器层面 UserService.java
代码解释 @Cacheable:将查询结果缓存到Redis中 key="#p0":指定传入的第一个参数作为Redis的key @CachePut:指定key,将更新的结果同步到Redis中 @CacheEvict:指定key,删除缓存数据 allEntries:方法调用后将立即清除缓存
package com.example.demo.service; import com.example.demo.model.User; import com.example.demo.mapper.UserMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CacheConfig; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.CachePut; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; //Redis缓存服务层 @Service @CacheConfig(cacheNames = "users") public class UserService { @Autowired UserMapper userMapper; @Cacheable(key="#p0") public User selectUser(String id){ System.out.println("select"); return userMapper.findById(id); } @CachePut(key="#p0") public void updateById(User user){ System.out.println("uddate"); userMapper.updateById(user); } //如果allEntries指定为true,则调用CacheEvict方法后将立即清空所有缓存 @CacheEvict(key="#p0",allEntries = true) public void deleteById(String id){ System.out.println("delete"); userMapper.deleteById(id); } }RedisController.java
package com.example.demo.controller; import com.example.demo.service.UserService; import com.example.demo.model.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/user") public class RedisController { @Autowired UserService userService; @RequestMapping("/{id}") public User ForTest(@PathVariable String id){ return userService.selectUser(id); } @RequestMapping( "/update/") public String update(User user){ userService.updateById(user); return "success"; } @RequestMapping( "/delete/{id}") public String delete (@PathVariable String id){ userService.deleteById(id); return "delete success"; } }1)启动Redis服务 由于没有设置环境变量,需要手动进入到Redis安装目录cd /d D:\Redis-x64-3.2.100,然后启动服务
redis-server.exe redis.windows.conf在cmd窗口打开的情况下,运行项目 2)多次访问
http://localhost:8080/user/2第一次时控制台会出现select信息,代表对数据库进行了查询操作。后面再访问则不会出现提示,表示没有对数据库执行操作,而是使用Redis中的缓存数据。
