本文基于Springboot2.0,使用mysql数据库,通过jpa实现orm,再用redis实现数据库的缓存。
目录
1、项目结构
2、环境配置
3、代码
4、测试
5、参考文章
1、项目结构
项目结构2、环境配置
1)pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- 引入Redis缓存 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
</dependencies>
2)application.yml
注意:
- 创建mysql数据库名称为 jpa_redis
- redis 端口、
- mysql 数据库账号密码
server:
port: 8081
# context-path: /
spring:
redis:
host: localhost
port: 6379
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/jpa_redis
username: root
password: abc
jpa:
hibernate:
ddl-auto: update
show-sql: true
3、代码
1)SpringBootRedisApplication
注意添加 @EnableCaching
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
@SpringBootApplication
@EnableCaching
public class SpringBootRedisApplication
{
public static void main(String[] args)
{
SpringApplication.run(SpringBootRedisApplication.class, args);
}
}
2)RedisConfig
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.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.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import java.lang.reflect.Method;
import java.time.Duration;
/**
* Redis 缓存配置类
*/
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport
{
/**
* 缓存对象集合中,缓存是以 key-value 形式保存的。
* 当不指定缓存的 key 时,SpringBoot 会使用 SimpleKeyGenerator 生成 key。
*/
// @Bean
public KeyGenerator wiselyKeyGenerator()
{
// key前缀,用于区分不同项目的缓存,建议每个项目单独设置
final String PRE_KEY = "test";
final char sp = ':';
return new KeyGenerator()
{
@Override
public Object generate(Object target, Method method, Object... params)
{
StringBuilder sb = new StringBuilder();
sb.append(PRE_KEY);
sb.append(sp);
sb.append(target.getClass().getSimpleName());
sb.append(sp);
sb.append(method.getName());
for (Object obj : params)
{
sb.append(sp);
sb.append(obj.toString());
}
return sb.toString();
}
};
}
@Bean
public CacheManager cacheManager(RedisConnectionFactory factory)
{
// 更改值的序列化方式,否则在Redis可视化软件中会显示乱码。默认为JdkSerializationRedisSerializer
RedisSerializationContext.SerializationPair<Object> pair = RedisSerializationContext.SerializationPair
.fromSerializer(new GenericJackson2JsonRedisSerializer());
RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration
.defaultCacheConfig()
.serializeValuesWith(pair) // 设置序列化方式
.entryTtl(Duration.ofHours(1)); // 设置过期时间
return RedisCacheManager
.builder(RedisCacheWriter.nonLockingRedisCacheWriter(factory))
.cacheDefaults(defaultCacheConfig).build();
}
}
3)实体类User
注意实现 Serializable 接口
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* 用户实体
*/
@Entity
@Table(name = "user")
public class User implements Serializable {
private static final long serialVersionUID = 1l;
@Id
@GeneratedValue
private Integer id;
@Column(length = 20)
private String userName;
@Column(length = 20)
private String password;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
4)UserDao
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import com.cun.entity.User;
/**
* 用户 dao 接口
*/
public interface UserDao extends JpaRepository<User, Integer>, JpaSpecificationExecutor<User>
{
}
5)UserService
import java.util.List;
import com.cun.entity.User;
public interface UserService
{
List<User> getAllUsers();
User findById(Integer pId);
void clearAllUserCache();
void clear(Integer pId);
}
6)UserServiceImpl
cacheNames
与 value
作用一样
import java.util.List;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import com.cun.dao.UserDao;
import com.cun.entity.User;
import com.cun.service.UserService;
@Service
@CacheConfig(cacheNames = "userService")
public class UserServiceImpl implements UserService
{
@Autowired
private UserDao userDao;
/**
* cacheNames 与 value 定义一样,设置了 value 的值,则类的 cacheNames 配置无效。<br>
* 使用 keyGenerator ,注意是否在config文件中定义好。
* @see com.cun.service.UserService#getAllUsers()
*/
@Override
@Cacheable(value = "getAllUsers")
// @Cacheable(value = "getAllUsers", keyGenerator = "wiselyKeyGenerator")
public List<User> getAllUsers()
{
return userDao.findAll();
}
/**
* 执行该函数时,将清除以 userService 的缓存,【cacheNames = "userService"】<br>
* 也可指定清除的key 【@CacheEvict(value="abc")】
*/
@CacheEvict(value = "getAllUsers")
public void clearAllUserCache()
{
}
/**
* key ="#p0" 表示以第1个参数作为 key
*/
@Override
@Cacheable(value="user", key ="#p0")
public User findById(Integer pId)
{
Optional<User> _User = userDao.findById(pId);
return Optional.ofNullable(_User).get().orElse(null);
}
@CacheEvict(value="user", key ="#p0")
public void clear(Integer pId)
{
}
}
7)UserController
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.cun.entity.User;
import com.cun.service.UserService;
/**
* 参考 https://blog.csdn.net/larger5/article/details/79696562
*/
@RestController
public class UserController
{
@Autowired
private UserService userService;
// http://localhost:8081/all
@GetMapping("/all")
public List<User> getAllUsers()
{
System.out.println("只有第一次才会打印sql语句");
return userService.getAllUsers();
}
// http://localhost:8081/findById?id=1
@GetMapping("/findById")
public User findById(@RequestParam(name = "id")Integer pId)
{
return userService.findById(pId);
}
// http://localhost:8081/clear
@GetMapping("/clear")
public void clear()
{
userService.clearAllUserCache();
}
// http://localhost:8081/clearOne?id=1
@GetMapping("/clearOne")
public void clear(@RequestParam(name = "id")Integer pId)
{
userService.clear(pId);
}
}
4、测试
启动服务后,可以看到 jpa 框架自动生成 user 表
user表
1)添加测试数据
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.*;
import com.cun.SpringBootRedisApplication;
import com.cun.dao.UserDao;
import com.cun.entity.User;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes=SpringBootRedisApplication.class)
public class AddTester {
@Autowired
private UserDao userDao;
@Test
public void test()
{
User _User = new User();
_User.setPassword("123");
_User.setUserName("老王");
userDao.save(_User);
User _User2 = new User();
_User2.setPassword("456");
_User2.setUserName("小李");
userDao.save(_User2);
}
}
2)缓存测试
访问 http://localhost:8081/all ,可看到缓存数据
访问 http://localhost:8081/findById?id=1,可看到缓存数据
则调用 http://localhost:8081/clear 后,getAllUsers 的缓存将被清除;
则调用 http://localhost:8081/clearOne?id=1 后,user::1 的缓存将被清除。
网友评论