Spring Boot整合JPA+MySQL+Redis
2018-01-29 21:57
691 查看
Spring Boot整合JPA+MySQL+Redis
在开始之前,我们在pom.xml添入关键依赖:JPA依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>
MySQL依赖:
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency>
Redis依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
下面开始整合过程:
①首先,我们在application.yml添入以下配置:
spring: ##配置数据源 datasource: driver-class-name: com.mysql.jdbc.Driver url: ##数据库连接地址 username: ##数据库用户名 password: ##数据库密码 ##开启JPA jpa: hibernate: ##自动建表 ddl-auto: update ##打印sql语句 show-sql: true ##配置redis redis: ##默认redis客户端连接为0 可修改 database: 0 host: ##连接地址 如:00.000.000.000 ##连接端口号 默认是6379 可修改 port: 6379 password: ##redis客户端密码 pool: ##连接池最大空闲连接 max-idle: 8 ##连接池最小空闲连接 min-idle: 0 ##连接池最大连接数 max-active: 8 ##连接池最大等待时间 max-wait: 1 ##连接超时时间 timeout: 5000
②配置Redis,注意加上@EnableCaching注解开启缓存:
package com.java.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.CacheManager; 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.RedisCacheManager; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.HashOperations; import org.springframework.data.redis.core.ListOperations; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.SetOperations; import org.springframework.data.redis.core.ValueOperations; import org.springframework.data.redis.core.ZSetOperations; import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; /** * Redis配置 * @author zxy * */ @Configuration @EnableCaching//启用缓存 public class RedisConfig extends CachingConfigurerSupport{ /** * 注入 RedisConnectionFactory */ @Autowired RedisConnectionFactory redisConnectionFactory; /** * 实例化 RedisTemplate 对象 * * @return */ @Bean public RedisTemplate<String, Object> functionDomainRedisTemplate() { RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); initDomainRedisTemplate(redisTemplate, redisConnectionFactory); return redisTemplate; } /** * 设置数据存入 redis 的序列化方式 * * @param redisTemplate * @param factory */ private void initDomainRedisTemplate(RedisTemplate<String, Object> redisTemplate, RedisConnectionFactory factory) { //定义key生成策略 redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setHashKeySerializer(new StringRedisSerializer()); redisTemplate.setHashValueSerializer(new JdkSerializationRedisSerializer()); redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer()); redisTemplate.setConnectionFactory(factory); } /** * 缓存管理器 * @param redisTemplate * @return */ @Bean public CacheManager cacheManager(RedisTemplate<?,?> redisTemplate) { CacheManager cach 4000 eManager = new RedisCacheManager(redisTemplate); return cacheManager; } /** * 实例化 HashOperations 对象,可以使用 Hash 类型操作 * * @param redisTemplate * @return */ @Bean public HashOperations<String, String, Object> hashOperations(RedisTemplate<String, Object> redisTemplate) { return redisTemplate.opsForHash(); } /** * 实例化 ValueOperations 对象,可以使用 String 操作 * * @param redisTemplate * @return */ @Bean public ValueOperations<String, Object> valueOperations(RedisTemplate<String, Object> redisTemplate) { return redisTemplate.opsForValue(); } /** * 实例化 ListOperations 对象,可以使用 List 操作 * * @param redisTemplate * @return */ @Bean public ListOperations<String, Object> listOperations(RedisTemplate<String, Object> redisTemplate) { return redisTemplate.opsForList(); } /** * 实例化 SetOperations 对象,可以使用 Set 操作 * * @param redisTemplate * @return */ @Bean public SetOperations<String, Object> setOperations(RedisTemplate<String, Object> redisTemplate) { return redisTemplate.opsForSet(); } /** * 实例化 ZSetOperations 对象,可以使用 ZSet 操作 * * @param redisTemplate * @return */ @Bean public ZSetOperations<String, Object> zSetOperations(RedisTemplate<String, Object> redisTemplate) { return redisTemplate.opsForZSet(); } }
③创建User实体类,一定要实现Serializable序列化:
package com.java.entity; import java.io.Serializable; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name="t_user") public class User implements Serializable{ /** * */ private static final long serialVersionUID = 1L; private String redisKey;//redis中的key @Id @GeneratedValue private Integer id; private String name; private String sex; private String address; public String getRedisKey() { return redisKey; } public void setRedisKey(String keyStr) { this.redisKey = "user_"+keyStr; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "User [redisKey=" + redisKey + ", id=" + id + ", name=" + name + ", sex=" + sex + ", address=" + address + "]"; } }
④定义User用户JPA接口:
package com.java.repository; import org.springframework.data.jpa.repository.JpaRepository; import com.java.entity.User; /** * 用户 Repository层接口 * @author zxy * */ public interface UserRepository extends JpaRepository<User, Integer>{ }
⑤定义抽象类RedisService实现redis对泛型对象的操作,多态调用
getRedisKey()方法获取子类的自定义redis key生成相应的Hash表结构:
package com.java.redis.service; import java.util.List; import java.util.Set; import java.util.concurrent.TimeUnit; import javax.annotation.Resource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.HashOperations; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; @Service public abstract class RedisService<T> { /** * 实例化 RedisTemplate对象 */ @Autowired protected RedisTemplate<String, Object> redisTemplate; /** * 定义Hash结构 操作存储实体对象 */ @Resource protected HashOperations<String, String, T> hashOperations; /** * 定义Hash表的redis key名称 * * @return */ protected abstract String getRedisKey(); /** * 在相应Hash表中添加键值对 key:Object(doamin) * * @param key key * @param doamin 对象 * @param expire 过期时间(单位:秒),传入 -1 时表示不设置过期时间 */ public void put(String key, T doamin, long expire) { hashOperations.put(getRedisKey(), key, doamin); if (expire != -1) { redisTemplate.expire(getRedisKey(), expire, TimeUnit.SECONDS); } } /** * 在相应Hash表中删除key名称的元素 * * @param key 传入key的名称 */ public void remove(String key) { hashOperations.delete(getRedisKey(), key); } /** * 在相应Hash表中查询key名称的元素 * * @param key 查询的key * @return */ public T get(String key) { return hashOperations.get(getRedisKey(), key); } /** * 获取在相应Hash表下的所有实体对象 * * @return */ public List<T> getAll() { return hashOperations.values(getRedisKey()); } /** * 查询在相应Hash表下的所有key名称 * * @return */ public Set<String> getKeys() { return hashOperations.keys(getRedisKey()); } /** * 判断在相应Hash表下key是否存在 * * @param key 传入key的名称 * @return */ public boolean isKeyExists(String key) { return hashOperations.hasKey(getRedisKey(), key); } /** * 查询相应Hash表的缓存数量 * * @return */ public long count() { return hashOperations.size(getRedisKey()); } /** * 清空相应Hash表的所有缓存 */ public void empty() { Set<String> set = hashOperations.keys(getRedisKey()); set.stream().forEach(key -> hashOperations.delete(getRedisKey(), key)); } }
⑥继承RedisService类自定义实现UserRedisServiceImpl,泛型注入User实体,自定义redis key的名称为USER_KEY,User实体的所有缓存均存入名为USER_KEY的Hash表中:
package com.java.redis.service.impl; import org.springframework.stereotype.Service; import com.java.entity.User; import com.java.redis.service.RedisService; /** * 用户redis service继承类 * @author zxy * */ @Service("userRedisService") public class UserRedisServiceImpl extends RedisService<User>{ //自定义redis key作为Hash表的key名称 private static final String REDIS_KEY = "USER_KEY"; @Override protected String getRedisKey() { // TODO Auto-generated method stub return REDIS_KEY; } }
⑦定义User用户Service接口UserService:
package com.java.service; import java.util.List; import com.java.entity.User; /** * 用户Service层接口 * @author zxy * */ public interface UserService { /** * 根据Id查询用户信息 * @param id * @return */ public User findById(Integer id); /** * 查询所有用户信息 * @return */ public List<User> findAll(); /** * 添加或修改用户信息 * @param user */ public void save(User user); /** * 根据Id删除用户信息 * @param id */ public void delete(Integer id); }
⑧定义User用户Service接口实现类UserServiceImpl,@CacheEvict注解中的
allEntries=true属性很重要,确保数据修改后缓存能够得到刷新:
package com.java.service.impl; import java.util.List; import javax.annotation.Resource; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import com.java.entity.User; import com.java.redis.service.impl.UserRedisServiceImpl; import com.java.repository.UserRepository; import com.java.service.UserService; /** * 用户Service层接口实现类 * @author zxy * */ @Service("userService") public class UserServiceImpl implements UserService{ @Resource private UserRepository userRepository; @Resource private UserRedisServiceImpl userRedisService; @Cacheable(value="userCache") //缓存,这里没有指定key. @Override public User findById(Integer id) { // TODO Auto-generated method stub return userRepository.findOne(id); } @Cacheable(value="userCache") @Override public List<User> findAll() { // TODO Auto-generated method stub return userRepository.findAll(); } //allEntries 清空缓存所有属性 确保更新后缓存刷新 @CacheEvict(value="userCache", allEntries=true) @Override public void save(User user) { // TODO Auto-generated method stub userRepository.save(user); if(user.getRedisKey()==null||"".equals(user.getRedisKey().trim())){ user.setRedisKey(user.getId().toString()); userRepository.save(user); } userRedisService.put(user.getRedisKey(), user, -1); } //allEntries 清空缓存所有属性 确保更新后缓存刷新 @CacheEvict(value="userCache", allEntries=true) @Override public void delete(Integer id) { // TODO Auto-generated method stub User user=userRepository.findOne(id); userRedisService.remove(user.getRedisKey()); userRepository.delete(id); } }
自此,所有准备工作全部完成,下面定义一个Controller层测试类TestController:
package com.java.controller; import java.util.List; import javax.annotation.Resource; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.java.entity.User; import com.java.service.UserService; /** * 测试Controller层 * @author zxy * */ @RestController @RequestMapping("/test") public class TestController { private static Integer userNum=0; @Resource private UserService userService; /** * 根据Id查询用户信息 * @param id * @return */ @RequestMapping("/findById/{id}") public User findById(@PathVariable("id")Integer id){ return userService.findById(id); } /** * 查询所有用户信息 * @return */ @RequestMapping("/findAll") public List<User> findAll(){ return userService.findAll(); } /** * 添加用户信息 * @return */ @RequestMapping("/add") public String add(){ User user=new User(); ++userNum; user.setName("张三"+userNum); user.setSex("男"+userNum); user.setAddress("广州"+userNum); userService.save(user); return "success"; } /** * 修改用户信息 * @return */ @RequestMapping("/update/{id}") public String update(@PathVariable("id")Integer id){ User user=userService.findById(id); user.setName(user.getName()+"asd"); user.setSex(user.getSex()+"asd"); user.setAddress(user.getAddress()+"asd"); userService.save(user); return "success"; } /** * 根据Id删除用户信息 * @return */ @RequestMapping("/delete/{id}") public String delete(@PathVariable("id")Integer id){ userService.delete(id); return "success"; } }
* 测试过程:
项目启动,redis客户端数据库均为空,数据表建表t_user结构:
地址栏两次访问http://localhost/test/add后:
MySQL数据库:
redis客户端:
地址栏两次访问http://localhost/test/findById/1后,可以看到只执行了一次sql语句:
页面数据显示:
地址栏访问http://localhost/test/update/1后,分别使用http://localhost/test/findById/1和http://localhost/test/findAll查询数据,可以看到数据均发生了修改(数据库和redis客户端的数据均对应发生变化,在此笔者就不贴图了):
地址栏访问http://localhost/test/delete/1后,使用http://localhost/test/findAll查询数据,可以看到数据的变化(数据库和redis客户端的数据均对应发生变化,在此笔者就不贴图了):
总结:以上为Spring Boot整合JPA+MySQL+Redis的所有过程,实现了作为中间层的redis缓存以及MySQL数据库和redis客户端的数据同步,完成了对实体对象的CRUD操作。笔者不才,如有遗漏、错误读者可提出建议。
相关文章推荐
- SpringBoot+spring-date-jpa+Hibernate 整合mysql 与sqlserver 配置文件信息
- Spring Boot+JPA+Mysql完成数据库整合操作
- spring boot 整合redis,jpa
- 基于springboot+bootstrap+mysql+redis搭建一套完整的权限架构【二】【整合springSecurity】
- 使用 SpringBoot 之 JPA 整合 Redis 实现缓存
- spring-boot整合redis作为mysql二级缓存
- SpringBoot+spring-date-jpa+Hibernate 整合mysql 与sqlserver 配置文件信息
- 整合SpringBoot+Mysql+Redis实现缓存机制的一个Demo
- 使用spring boot 整合spring jpa做基于restful风格的增删改查(maven ,mysql)
- SpringBoot整合Spring Data JPA、MySQL、Druid并使用Mockito实现单元测试
- Spring Boot+Shiro+Redis(redisson)整合时,采用内嵌tomcat启动错误原因分析
- Spring boot + mysql +mybatis 配置整合实例
- springboot整合缓存redis-cache
- Spring Boot入门教程(7)---整合jpa,Shiro进行权限管理(附源码)
- spring boot中spring cache 整合redis
- Spring Boot 整合 mysql
- 基于springboot+redis+bootstrap+mysql开发一套属于自己的分布式springcloud云权限架构(一)【云架构前言】
- Spring Boot+JPA+Mysql+ThymeLeaf快速构建CURD系统(一)Spring Boot介绍
- Spring Boot+JPA+Mysql+ThymeLeaf快速构建CURD系统(二)搭建SpringBoot工程
- SpringBoot入门系列:第五篇 JPA mysql