SpringBoot整合Mysql、Redis_路上的追梦人的博客-CSDN博客_mysql和redis springboot

spring boot + mysql +mybatis +redis(二级缓存)实例_JasonHector的博客-CSDN博客

一、项目创建

1.1 创建项目

  1. IDEA中,File--New--Project--Spring Initializer
  2. 名称为springboot-mysql-redis

[Docker] SpringBoot整合Mysql、Redis - 图1

1.2 目录结构

[Docker] SpringBoot整合Mysql、Redis - 图2

1.3 application配置文件

  1. spring:
  2. datasource:
  3. driver-class-name: com.mysql.cj.jdbc.Driver
  4. url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC
  5. username: root
  6. password: 1234
  7. redis:
  8. host: localhost
  9. port: 6379
  10. password: 1234
  11. server:
  12. port: 8080
  13. mybatis:
  14. mapper-locations: classpath:mapper/*xml
  15. type-aliases-package: com.xsbc.entity
  16. # 开启驼峰命名
  17. configuration:
  18. map-underscore-to-camel-case: true

二、初始化数据库

  1. drop database if exists blog;
  2. create database blog;
  3. user blog;
  4. drop table if exists user;
  5. create table user(
  6. id int(11) not null,
  7. name varchar(255) DEFAULT "",
  8. age int(11) DEFAULT 0,
  9. PRIMARY KEY(id)
  10. )ENGINE=INNODB DEFAULT CHARSET=utf8;
  11. insert into user values(1,'小王',20);
  12. insert into user values(2,'老李',23);

三、初始化代码

3.1 实体类entity

  1. @Data
  2. @NoArgsConstructor
  3. @AllArgsConstructor
  4. public class User {
  5. private int id;
  6. private String name;
  7. private int age;
  8. }

3.2 Mapper接口类

  1. @Mapper
  2. public interface UserMapper {
  3. List<User> getAllUsers();
  4. int updateUser(Integer id);
  5. }
  • xml 映射文件
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="com.xsbc.mapper.UserMapper">
  6. <select id="getAllUsers" resultType="com.xsbc.entity.User">
  7. select * from user
  8. </select>
  9. <!-- User类的id参数是int类型,mysql默认是Integer -->
  10. <update id="updateUserAgeById" parameterType="java.lang.Integer">
  11. update user set age=age+2 where id=#{id}
  12. </update>
  13. </mapper>

3.3 Redis 工具类

1)config 包创建类

Redis常量类RedisConstant

  1. public class RedisConstant {
  2. public static String ALL_USER_KEY="allUser";
  3. }

Redis常量类RedisConstant

  1. @Configuration
  2. public class RedisConfig {
  3. @Resource
  4. private RedisTemplate redisTemplate;
  5. @Bean
  6. public RedisTemplate redisTemplateInit(){
  7. //序列化key的实例化对象
  8. redisTemplate.setKeySerializer(new StringRedisSerializer());
  9. //序列化value的实例化对象
  10. redisTemplate.setValueSerializer(
  11. new GenericJackson2JsonRedisSerializer());
  12. return redisTemplate;
  13. }
  14. }

2)util包下创建类

  1. @Component
  2. public class RedisUtil {
  3. @Resource
  4. private RedisTemplate<String,Object> redisTemplate;
  5. public void setRedisTemplate(RedisTemplate<String,Object> redisTemplate){
  6. this.redisTemplate=redisTemplate;
  7. }
  8. // 指定缓存失效时间
  9. public boolean expire(String key,long time) {
  10. try {
  11. if (time > 0) {
  12. redisTemplate.expire(key, time, TimeUnit.SECONDS);
  13. }
  14. return true;
  15. } catch (Exception e) {
  16. e.printStackTrace();
  17. return false;
  18. }
  19. }
  20. // 根据key获取过期时间
  21. public long getExpire(String key){
  22. return redisTemplate.getExpire(key,TimeUnit.SECONDS);
  23. }
  24. // 判断key是否存在
  25. public boolean hasKey(String key){
  26. try {
  27. return redisTemplate.hasKey(key);
  28. }catch(Exception e){
  29. e.printStackTrace();
  30. return false;
  31. }
  32. }
  33. // 删除缓存
  34. @SuppressWarnings("unchecked")
  35. public void del(String... key){
  36. if (key!=null&&key.length> 0){
  37. if (key.length==1) {
  38. redisTemplate.delete(key[0]);
  39. }else{
  40. redisTemplate.delete(
  41. (Collection<String>)CollectionUtils.arrayToList(key));
  42. }
  43. }
  44. }
  45. // 普通缓存获取
  46. public Object get(String key){
  47. return key==null?null:redisTemplate.opsForValue().get(key);
  48. }
  49. // 普通缓存放入
  50. public boolean set(String key,Object value){
  51. try {
  52. redisTemplate.opsForValue().set(key,value);
  53. return true;
  54. }catch(Exception e){
  55. e.printStackTrace();
  56. return false;
  57. }
  58. }
  59. // 普通缓存放入并设置时间
  60. public boolean set(String key,Object value,long time){
  61. try{
  62. if(time>0){
  63. redisTemplate.opsForValue()
  64. .set(key,value,time,TimeUnit.SECONDS);
  65. }else{
  66. set(key,value);
  67. }
  68. return true;
  69. }catch(Exception e){
  70. e.printStackTrace();
  71. return false;
  72. }
  73. }
  74. // 递增
  75. public long incr(String key,long delta){
  76. if(delta<0){
  77. throw new RuntimeException("递增因子必须大于0");
  78. }
  79. return redisTemplate.opsForValue().increment(key,delta);
  80. }
  81. // 递减
  82. public long decr(String key, long delta){
  83. if(delta<0){
  84. throw new RuntimeException("递减因子必须大于0");
  85. }
  86. return redisTemplate.opsForValue().increment(key,-delta);
  87. }
  88. // HashGet
  89. public Object hget(String key,String item){
  90. return redisTemplate.opsForHash().get(key,item);
  91. }
  92. // 获取hashKey对应的所有键值
  93. public Map<Object, Object> hmget(String key){
  94. return redisTemplate.opsForHash().entries(key);
  95. }
  96. // HashSet
  97. public boolean hmset(String key,Map<String, Object> map){
  98. try{
  99. redisTemplate.opsForHash().putAll(key,map);
  100. return true;
  101. }catch(Exception e){
  102. e.printStackTrace();
  103. return false;
  104. }
  105. }
  106. // HashSet 并设置时间
  107. public boolean hmset(String key,Map<String, Object> map,long time){
  108. try{
  109. redisTemplate.opsForHash().putAll(key, map);
  110. if (time>0){
  111. expire(key,time);
  112. }
  113. return true;
  114. }catch(Exception e){
  115. e.printStackTrace();
  116. return false;
  117. }
  118. }
  119. // 向一张hash表中放入数据,如果不存在将创建
  120. public boolean hset(String key,String item,Object value){
  121. try{
  122. redisTemplate.opsForHash().put(key,item,value);
  123. return true;
  124. }catch(Exception e){
  125. e.printStackTrace();
  126. return false;
  127. }
  128. }
  129. // 向一张hash表中放入数据,如果不存在将创建
  130. public boolean hset(String key,String item,Object value,long time){
  131. try{
  132. redisTemplate.opsForHash().put(key,item,value);
  133. if(time>0){
  134. expire(key,time);
  135. }
  136. return true;
  137. }catch(Exception e){
  138. e.printStackTrace();
  139. return false;
  140. }
  141. }
  142. // 删除hash表中的值
  143. public void hdel(String key,Object... item) {
  144. redisTemplate.opsForHash().delete(key,item);
  145. }
  146. // 判断hash表中是否有该项的值
  147. public boolean hHasKey(String key,String item) {
  148. return redisTemplate.opsForHash().hasKey(key,item);
  149. }
  150. // hash递增 如果不存在,就会创建一个 并把新增后的值返回
  151. public double hincr(String key,String item,double by) {
  152. return redisTemplate.opsForHash().increment(key,item,by);
  153. }
  154. // hash递减
  155. public double hdecr(String key,String item,double by) {
  156. return redisTemplate.opsForHash().increment(key,item,-by);
  157. }
  158. // 根据key获取Set中的所有值
  159. public Set<Object> sGet(String key) {
  160. try{
  161. return redisTemplate.opsForSet().members(key);
  162. }catch(Exception e){
  163. e.printStackTrace();
  164. return null;
  165. }
  166. }
  167. // 根据value从一个set中查询,是否存在
  168. public boolean sHasKey(String key,Object value) {
  169. try{
  170. return redisTemplate.opsForSet().isMember(key,value);
  171. }catch(Exception e){
  172. e.printStackTrace();
  173. return false;
  174. }
  175. }
  176. // 将数据放入set缓存
  177. public long sSet(String key,Object... values) {
  178. try{
  179. return redisTemplate.opsForSet().add(key,values);
  180. }catch(Exception e){
  181. e.printStackTrace();
  182. return 0;
  183. }
  184. }
  185. // 将set数据放入缓存
  186. public long sSetAndTime(String key,long time,Object... values){
  187. try{
  188. Long count=redisTemplate.opsForSet().add(key,values);
  189. if (time> 0)expire(key, time);
  190. return count;
  191. }catch(Exception e){
  192. e.printStackTrace();
  193. return 0;
  194. }
  195. }
  196. // 获取set缓存的长度
  197. public long sGetSetSize(String key){
  198. try{
  199. return redisTemplate.opsForSet().size(key);
  200. }catch(Exception e){
  201. e.printStackTrace();
  202. return 0;
  203. }
  204. }
  205. // 移除值为value的
  206. public long setRemove(String key,Object... values){
  207. try{
  208. Long count=redisTemplate.opsForSet().remove(key,values);
  209. return count;
  210. }catch(Exception e){
  211. e.printStackTrace();
  212. return 0;
  213. }
  214. }
  215. // 获取list缓存的内容
  216. public List<Object> lGet(String key,long start,long end){
  217. try{
  218. return redisTemplate.opsForList().range(key,start,end);
  219. }catch(Exception e){
  220. e.printStackTrace();
  221. return null;
  222. }
  223. }
  224. // 获取list缓存的长度
  225. public long lGetListSize(String key){
  226. try{
  227. return redisTemplate.opsForList().size(key);
  228. }catch(Exception e){
  229. e.printStackTrace();
  230. return 0;
  231. }
  232. }
  233. // 通过索引 获取list中的值
  234. public Object lGetIndex(String key,long index){
  235. try{
  236. return redisTemplate.opsForList().index(key,index);
  237. }catch(Exception e){
  238. e.printStackTrace();
  239. return null;
  240. }
  241. }
  242. // 将list放入缓存
  243. public boolean lSet(String key, Object value){
  244. try{
  245. redisTemplate.opsForList().rightPush(key,value);
  246. return true;
  247. }catch(Exception e){
  248. e.printStackTrace();
  249. return false;
  250. }
  251. }
  252. // 将list放入缓存
  253. public boolean lSet(String key,Object value,long time){
  254. try{
  255. redisTemplate.opsForList().rightPush(key,value);
  256. if (time > 0) expire(key, time);
  257. return true;
  258. }catch(Exception e){
  259. e.printStackTrace();
  260. return false;
  261. }
  262. }
  263. // 将list放入缓存
  264. public boolean lSet(String key, List<Object> value){
  265. try{
  266. redisTemplate.opsForList().rightPushAll(key,value);
  267. return true;
  268. }catch(Exception e){
  269. e.printStackTrace();
  270. return false;
  271. }
  272. }
  273. // 将list放入缓存
  274. public boolean lSet(String key,List<Object> value,long time){
  275. try{
  276. redisTemplate.opsForList().rightPushAll(key,value);
  277. if(time>0) expire(key, time);
  278. return true;
  279. }catch(Exception e){
  280. e.printStackTrace();
  281. return false;
  282. }
  283. }
  284. // 根据索引修改list中的某条数据
  285. public boolean lUpdateIndex(String key,long index,Object value){
  286. try{
  287. redisTemplate.opsForList().set(key,index,value);
  288. return true;
  289. }catch(Exception e){
  290. e.printStackTrace();
  291. return false;
  292. }
  293. }
  294. // 移除N个值为value
  295. public long lRemove(String key,long count,Object value){
  296. try{
  297. Long remove=redisTemplate.opsForList().remove(key,count,value);
  298. return remove;
  299. }catch(Exception e){
  300. e.printStackTrace();
  301. return 0;
  302. }
  303. }
  304. }

3.4 Service层

1)UserService接口类

  1. public interface UserService {
  2. public List<User> getAllUsers();
  3. public void updateUserAge();
  4. }

2)接口实现类

  1. @Service("userService")
  2. public class UserServiceImpl implements UserService {
  3. @Resource
  4. private UserMapper userMapper;
  5. @Autowired
  6. private RedisUtil redisUtil;
  7. @Override
  8. public List<User> getAllUsers() {
  9. List<User> users=(List<User>)redisUtil
  10. .get(RedisConstant.ALL_USER_KEY);
  11. if(CollectionUtils.isEmpty(users)){
  12. users=userMapper.getAllUsers();
  13. redisUtil.set(RedisConstant.ALL_USER_KEY,users);
  14. }
  15. return users;
  16. }
  17. @Override
  18. @Transactional
  19. public void updateUserAge() {
  20. redisUtil.del(RedisConstant.ALL_USER_KEY);
  21. userMapper.updateUserAgeById(1);
  22. userMapper.updateUserAgeById(2);
  23. }
  24. }

3.5 Controller层

  1. @Controller
  2. public class UserController {
  3. @Autowired
  4. private UserService userService;
  5. @RequestMapping("/getAll")
  6. @ResponseBody
  7. public List<User> getUsers(){
  8. return userService.getAllUsers();
  9. }
  10. @RequestMapping("/update")
  11. @ResponseBody
  12. public int updateUser(){
  13. userService.updateUserAge();
  14. return 1;
  15. }
  16. }

四、单元测试

4.1 Respository和Service层单元测试

  1. @SpringBootTest
  2. class SpringbootMysqlRedisApplicationTests {
  3. @Autowired
  4. private UserMapper userMapper;
  5. @Autowired
  6. private UserService userService;
  7. @Test
  8. void testUserMapper(){
  9. userMapper.updateUserAgeById(1);
  10. List<User> users=userMapper.getAllUsers();
  11. for(User user:users){
  12. System.out.println(user);
  13. }
  14. }
  15. @Test
  16. void testUserService(){
  17. userService.updateUserAge();
  18. List<User> users=userService.getAllUsers();
  19. for(User user:users){
  20. System.out.println(user);
  21. }
  22. }
  23. }

4.2 Controller层接口测试

[Docker] SpringBoot整合Mysql、Redis - 图3