项目目录
pom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99<?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>com.sid</groupId> <artifactId>springboot</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.5.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <!-- spring-boot的web启动的jar包 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- spring-boot 测试包 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- spring boot --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.2</version> </dependency> <!-- spring-boot redis --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!--jedis--> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.7.3</version> </dependency> <!-- json --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.12</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.4</version> </dependency> <!-- mysql数据库连接包 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.38</version> </dependency> <!-- alibaba的druid数据库连接池 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.9</version> </dependency> <!-- 分页插件--> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>1.2.5</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <!-- mybatis generator 自动生成代码插件 --> <plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>1.3.2</version> <configuration> <configurationFile>${basedir}/src/main/resources/generator/generatorConfig.xml</configurationFile> <overwrite>true</overwrite> <verbose>true</verbose> </configuration> </plugin> </plugins> </build> </project>
application.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36server: port: 8088 servlet: context-path: /sid spring: datasource: url: jdbc:mysql://localhost:3306/sid username: root password: root # 使用druid数据源 type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.jdbc.Driver redis: database: 0 host: localhost password: root port: 6379 pool: max-maxTotal: 300 max-maxIdle: 200 maxWaitMillis: 3000 ## 该配置节点为独立的节点,不是在在spring的节点下 mybatis: mapper-locations: classpath:mapping/*.xml #注意:一定要对应mapper映射xml文件的所在路径 type-aliases-package: com.sid.model # 注意:对应实体类的路径 configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #控制台打印sql #pagehelper分页插件 pagehelper: helperDialect: mysql reasonable: true supportMethodsArguments: true params: count=countSql
App.java 启动类
使用@EnableCaching表明支持缓存
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19package com.sid; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCaching; /** * @program: springboot * @description: springboot启动类 * @create: 2018-10-16 08:58 **/ @EnableCaching @SpringBootApplication @MapperScan("com.sid.mapper")//将项目中对应的mapper类的路径加进来就可以了 public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } }
RedisConfig.java
使用@EnableCaching表明支持缓存
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81package com.sid.common; import org.springframework.cache.annotation.CachingConfigurerSupport; import org.springframework.cache.annotation.EnableCaching; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.cache.RedisCacheConfiguration; import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.cache.RedisCacheWriter; 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.GenericJackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.RedisSerializationContext; import org.springframework.data.redis.serializer.StringRedisSerializer; import java.time.Duration; /** * @program: springboot * @description: * @author: liyijie * @create: 2018-10-16 11:19 **/ @Configuration @EnableCaching//这个注解是的支持缓存 public class RedisConfig extends CachingConfigurerSupport { /** * 管理缓存 springboot1 * @param redisTemplate * @return @Bean public CacheManager cacheManager(RedisTemplate redisTemplate) { //初始化一个RedisCacheWriter RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate); //设置默认的过期时间(以秒为单位) cacheManager.setDefaultExpiration(60*60*24); cacheManager.setUsePrefix(true); //rcm.setExpires();设置缓存区域(按key)的过期时间(以秒为单位) Map<String,Long> expiresMap=new HashMap<>(); expiresMap.put("sid:auth:cache:department",60*60L); expiresMap.put("sid:auth:cache:role",60*60L); expiresMap.put("sid:auth:cache:menu",60*60L); cacheManager.setExpires(expiresMap); //事务 //cacheManager.setTransactionAware(true); return cacheManager; }*/ /** * 管理缓存 springboot2 * @param redisTemplate * @return */ @Bean public RedisCacheManager redisCacheManager(RedisTemplate redisTemplate) { //初始化一个RedisCacheWriter RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisTemplate.getConnectionFactory()); RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig() .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisTemplate.getValueSerializer()));//设置序列化 //设置默认超过期时间是30秒 redisCacheConfiguration.entryTtl(Duration.ofSeconds(30)); //初始化RedisCacheManager RedisCacheManager cacheManager = new RedisCacheManager(redisCacheWriter, redisCacheConfiguration); return cacheManager; } /** * 设置统一序列化 * @param factory * @return */ @Bean(name = "redisTemplate") public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) { StringRedisTemplate template = new StringRedisTemplate(factory); template.setKeySerializer(new StringRedisSerializer()); template.setHashKeySerializer(new StringRedisSerializer()); template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer()); template.afterPropertiesSet(); //这里设置redis事务一致 //template.setEnableTransactionSupport(true); return template; } }
UserController.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52package com.sid.controller; import com.github.pagehelper.PageInfo; import com.sid.model.User; import com.sid.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; /** * @program: springboot * @description: * @author: liyijie * @create: 2018-10-16 09:28 **/ @Controller @RequestMapping(value = "/user") public class UserController { @Autowired private UserService userService; @ResponseBody @RequestMapping(value = "/add") public User addUser(User user){ return userService.addUser(user); } @ResponseBody @RequestMapping(value = "/delete") public int deleteUser(String mobilePhone){ return userService.deleteUser(mobilePhone); } @ResponseBody @RequestMapping(value = "/update") public User updateUser(User user){ return userService.updateUser(user); } @ResponseBody @RequestMapping(value = "/selectAll") public PageInfo<User> selectAll(int pageNum, int pageSize){ return userService.selectAll( pageNum, pageSize); } @ResponseBody @RequestMapping(value = "/getUserByMobilePhone") public User getUserByMobilePhone(String mobilePhone){ return userService.getUserByMobilePhone(mobilePhone); } @ResponseBody @RequestMapping(value = "/set") public void set(){ userService.set(); } }
UserMapper.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15package com.sid.mapper; import com.sid.model.User; import org.springframework.stereotype.Component; import java.util.List; @Component public interface UserMapper { int deleteByPrimaryKey(String mobilePhone); int insert(User record); int insertSelective(User record); User selectByPrimaryKey(String id); int updateByPrimaryKeySelective(User record); int updateByPrimaryKey(User record); List<User> selectAll(); User getUserByMobilePhone(String mobilePhone); }
User.java
需要实现序列化接口
申明序列化ID
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33package com.sid.model; import java.io.Serializable; public class User implements Serializable { private static final long serialVersionUID = 123456789L; private Long id; private String name; private String password; private String mobilePhone; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name == null ? null : name.trim(); } public String getPassword() { return password; } public void setPassword(String password) { this.password = password == null ? null : password.trim(); } public String getMobilePhone() { return mobilePhone; } public void setMobilePhone(String mobilePhone) { this.mobilePhone = mobilePhone == null ? null : mobilePhone.trim(); } }
UserService.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16package com.sid.service; import com.github.pagehelper.PageInfo; import com.sid.model.User; public interface UserService { void set(); User addUser(User user); int deleteUser(String mobilePhone); User updateUser(User user); /* * pageNum 开始页数 * pageSize 每页显示的数据条数 * */ PageInfo<User> selectAll(int pageNum, int pageSize); User getUserByMobilePhone(String mobilePhone); }
@CacheConfig(cacheNames = "user")//类级别的缓存注解,允许共享缓存名称
@CachePut 根据方法的请求参数对其结果进行缓存
* 缓存新增的数据到缓存user中
* 每次都会请求db
* 是用方法的返回值作为value请求redis
* userMapper.insertSelective(user); 返回1
* 如果直接 return userMapper.insertSelective(user);
* 则指定key的value变成了1
*
* 新增可以不用做缓存操作 查询的时候查询到新增的内容 会回写到缓存中
*/
@CachePut(value = "user", key = "'CACHE_REDIS_KEY_USER' + #user.mobilePhone")
@CacheEvict 根据条件对缓存进行清空
触发移除缓存 从缓存user中删除key的数据
参数:
allEntries
:非必需,默认为false。当为true时,会移除所有数据。beforeInvocation:可以改变触发清除操作的时间,该属性值为true时,Spring会在调用该方法之前清除缓存中的指定元素。
@CacheEvict(value = "user", key = "'CACHE_REDIS_KEY_USER'+ #mobilePhone", beforeInvocation=true)
@Cacheable
在调用方法之前,首先应该在缓存中查找方法的返回值,如果这个值能够找到,就会返回缓存的值。否则,这个方法就会被调用,返回值会放到缓存之中。
@Cacheable(value = "user", key = "'CACHE_REDIS_KEY_USER'+ #mobilePhone")参数:
value
、cacheNames
:两个等同的参数(cacheNames
为Spring 4新增,作为value
的别名),用于指定缓存存储的集合名。由于Spring 4中新增了@CacheConfig
,因此在Spring 3中原本必须有的value
属性,也成为非必需项了
key
:缓存对象存储在Map集合中的key值,非必需,缺省按照函数的所有参数组合作为key值,若自己配置需使用SpEL表达式,比如:@Cacheable(key = "#p0")
:使用函数第一个参数作为缓存的key值,更多关于SpEL表达式的详细内容可参考官方文档
condition
:缓存对象的条件,非必需,也需使用SpEL表达式,只有满足表达式条件的内容才会被缓存,比如:@Cacheable(key = "#p0", condition = "#p0.length() < 10")
,表示只有当第一个参数的长度小于10的时候才会被缓存。
unless
:另外一个缓存条件参数,非必需,需使用SpEL表达式。它不同于condition
参数的地方在于它的判断时机,该条件是在函数被调用之后才做判断的,所以它可以通过对result进行判断。
keyGenerator
:用于指定key生成器,非必需。若需要指定一个自定义的key生成器,我们需要去实现org.springframework.cache.interceptor.KeyGenerator
接口,并使用该参数来指定。需要注意的是:该参数与key
是互斥的
@Caching 组合使用多个操作缓存的注解 evict={}中是用@CacheEvict 、 put={}中是用@CachePut 、 cacheable={}中是用@Cacheable
@Caching(
evict = {
@CacheEvict(value = "user", key = "'CACHE_REDIS_KEY_USER'+ #mobilePhone", beforeInvocation=true),
@CacheEvict(value = "user", key = "'CACHE_REDIS_KEY_USER'+ #mobilePhone")
}
)
UserServiceImpl.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128package com.sid.service.impl; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import com.sid.mapper.UserMapper; import com.sid.model.User; import com.sid.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.*; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.ValueOperations; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.List; /** * @program: springboot * @description: * @author: liyijie * @create: 2018-10-16 09:30 **/ //@CacheConfig类级别的缓存注解,允许共享缓存名称 @CacheConfig(cacheNames = "user") //用于配置该类中会用到的一些共用的缓存配置。该数据访问对象中返回的内容将存储于名为users的缓存对象中 @Service public class UserServiceImpl implements UserService { public static final String CACHE_REDIS_KEY_USER = "sid:auth:cacahe:redis:key:user:"; @Autowired RedisTemplate<String, String> redisTemplate; @Autowired private UserMapper userMapper; /** * @Description: 不使用缓存 单独用redisTemplate操作redis * @Param: [] * @return: void * @Author: liyijie * @Date: 2018/10/16 0016 */ @Override public void set(){ redisTemplate.opsForValue().set("sid:test:sigle:redisTemplate:","123"); } /** @CachePut 根据方法的请求参数对其结果进行缓存 * 缓存新增的数据到缓存user中 * 每次都会请求db * 是用方法的返回值作为value请求redis * userMapper.insertSelective(user); 返回1 * 如果直接 return userMapper.insertSelective(user); * 则指定key的value变成了1 * * 新增可以不用做缓存操作 查询的时候查询到新增的内容 会回写到缓存中 */ //@CachePut(value = "user", key = "'CACHE_REDIS_KEY_USER' + #user.mobilePhone") @Override public User addUser(User user) { userMapper.insertSelective(user); return user; } /** @CacheEvict 根据条件对缓存进行清空 * 触发移除缓存 从缓存user中删除key的数据 * 使用beforeInvocation可以改变触发清除操作的时间,该属性值为true时,Spring会在调用该方法之前清除缓存中的指定元素。 * * @Caching 组合使用多个操作缓存的注解 evict={}中是用@CacheEvict 、 put={}中是用@CachePut 、 cacheable={}中是用@Cacheable * * 双删+超时 保证redis和mysql的数据一致性 */ @Caching( evict = { @CacheEvict(value = "user", key = "'CACHE_REDIS_KEY_USER'+ #mobilePhone", beforeInvocation=true), @CacheEvict(value = "user", key = "'CACHE_REDIS_KEY_USER'+ #mobilePhone") } ) @Override public int deleteUser(String mobilePhone) { return userMapper.deleteByPrimaryKey(mobilePhone); } /** * @Description: 修改的时候不去改缓存 直接双删 查询的时候会回写 * @Param: [user] * @return: com.sid.model.User * @Author: liyijie * @Date: 2018/10/16 0016 */ //@CachePut(value = "user",key = "'CACHE_REDIS_KEY_USER'+ #user.mobilePhone") @Caching( evict = { @CacheEvict(value = "user", key = "'CACHE_REDIS_KEY_USER'+ #user.mobilePhone", beforeInvocation=true), @CacheEvict(value = "user", key = "'CACHE_REDIS_KEY_USER'+ #user.mobilePhone") } ) @Override public User updateUser(User user) { userMapper.updateByPrimaryKey(user); return user; } /**@Cacheable * 在调用方法之前,首先应该在缓存中查找方法的返回值,如果这个值能够找到,就会返回缓存的值。否则,这个方法就会被调用,返回值会放到缓存之中。 * */ @Cacheable(value = "user", key = "'CACHE_REDIS_KEY_USER'+ #mobilePhone") @Override public User getUserByMobilePhone(String mobilePhone){ User user = userMapper.getUserByMobilePhone(mobilePhone); System.out.println(user); return user; } //todo 分页 /* * pageNum 开始页数 * pageSize 每页显示的数据条数 * */ // 配置了selectAll函数的返回值将被加入缓存。同时在查询时,会先从缓存中获取,若不存在才再发起对数据库的访问。 //@Cacheable 触发缓存入口 //@Cacheable(value = "user", key = "#p0") @Override public PageInfo<User> selectAll(int pageNum, int pageSize) { PageHelper.startPage(pageNum, pageSize,"id desc"); //开始起始页 List<User> userList = userMapper.selectAll(); // 获取数据 PageInfo<User> page = new PageInfo<>(userList); // 实例化PageInfo return page; } //todo list缓存 lpush lpop //todo 缓存过期 }
UserMapper.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94<?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.sid.mapper.UserMapper" > <resultMap id="BaseResultMap" type="com.sid.model.User" > <id column="id" property="id" jdbcType="BIGINT" /> <result column="name" property="name" jdbcType="VARCHAR" /> <result column="password" property="password" jdbcType="VARCHAR" /> <result column="mobile_phone" property="mobilePhone" jdbcType="VARCHAR" /> </resultMap> <sql id="Base_Column_List" > id, name, password, mobile_phone </sql> <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Long" > select <include refid="Base_Column_List" /> from user where id = #{id,jdbcType=BIGINT} </select> <select id="selectAll" resultMap="BaseResultMap" > select <include refid="Base_Column_List" /> from user </select> <select id="getUserByMobilePhone" resultMap="BaseResultMap" parameterType="java.lang.String" > select <include refid="Base_Column_List" /> from user where mobile_phone = #{mobilePhone,jdbcType=VARCHAR} </select> <delete id="deleteByPrimaryKey" parameterType="java.lang.String" > delete from user where mobile_phone = #{mobilePhone,jdbcType=VARCHAR} </delete> <insert id="insert" parameterType="com.sid.model.User" > insert into user (id, name, password, mobile_phone) values (#{id,jdbcType=BIGINT}, #{name,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}, #{mobilePhone,jdbcType=VARCHAR}) </insert> <insert id="insertSelective" parameterType="com.sid.model.User" > insert into user <trim prefix="(" suffix=")" suffixOverrides="," > <if test="id != null" > id, </if> <if test="name != null" > name, </if> <if test="password != null" > password, </if> <if test="mobilePhone != null" > mobile_phone, </if> </trim> <trim prefix="values (" suffix=")" suffixOverrides="," > <if test="id != null" > #{id,jdbcType=BIGINT}, </if> <if test="name != null" > #{name,jdbcType=VARCHAR}, </if> <if test="password != null" > #{password,jdbcType=VARCHAR}, </if> <if test="mobilePhone != null" > #{mobilePhone,jdbcType=VARCHAR}, </if> </trim> </insert> <update id="updateByPrimaryKeySelective" parameterType="com.sid.model.User" > update user <set > <if test="name != null" > name = #{name,jdbcType=VARCHAR}, </if> <if test="password != null" > password = #{password,jdbcType=VARCHAR}, </if> <if test="mobilePhone != null" > mobile_phone = #{mobilePhone,jdbcType=VARCHAR}, </if> </set> where id = #{id,jdbcType=BIGINT} </update> <update id="updateByPrimaryKey" parameterType="com.sid.model.User" > update user set name = #{name,jdbcType=VARCHAR}, password = #{password,jdbcType=VARCHAR}, mobile_phone = #{mobilePhone,jdbcType=VARCHAR} where id = #{id,jdbcType=BIGINT} </update> </mapper>
最后
以上就是土豪白羊最近收集整理的关于【四】Spring Boot之 Spring Boot + Cache + RedisTemplate整合的全部内容,更多相关【四】Spring内容请搜索靠谱客的其他文章。
发表评论 取消回复