在实际开发中,对于要反复读写的数据,最好的处理方式是将之在内存中缓存一份,频繁的数据库访问会造成程序效率低下,同时内存的读写速度本身就要强于硬盘。Spring在这一方面给我们提供了诸多的处理手段,而Spring Boot又将这些处理方式进一步简化,接下来我们就来看看如何在Spring Boot中解决数据缓存问题。
标题
使用MySQL,在pom.xml中添加数据库驱动。
pom.xml
<?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.wangh</groupId>
<artifactId>springboot_cache</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>springboot_cache</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.4.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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.40</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
配置application.properties
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/girl?useUnicode=true&characterEncoding=utf-8
spring.datasource.username=system
spring.datasource.password=mysql
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jackson.serialization.indent_output=true
创建实体类
@Entity
public class Person {
@Id
@GeneratedValue
private Long id;
private String name;
private String address;
private Integer age;
public Person() {
}
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;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Person(Long id, String name, String address, Integer age) {
this.id = id;
this.name = name;
this.address = address;
this.age = age;
}
}
创建实体类的Repository
public interface PersonRepository extends JpaRepository<Person,Long> {
}
创建业务类
业务接口
public interface PersonService {
Person save(Person person);
void remove(Long id);
Person findOne(Person person);
}
实现类
@Service
public class PersonServiceImpl implements PersonService {
@Resource
private PersonRepository personRepository;
//@CachePut: 新增或更新数据到缓存,缓存名称为people,数据的key是person.id
@CachePut(value = "people", key = "#person.id")
@Override
public Person save(Person person) {
Person p = personRepository.save(person);
System.out.println("为id、key为" + p.getId() + "数据做了缓存");
return p;
}
//@CacheEvict:从缓存people中删除key为id的数据,如果没有指定key,方法参数作为key保存在缓存中
@CacheEvict(value = "people")
@Override
public void remove(Long id) {
System.out.println("删除了key为" + id + "数据缓存");
personRepository.delete(id);
}
//key为person的id数据缓存到people中
@Cacheable(value = "people", key = "#person.id")
@Override
public Person findOne(Person person) {
Person p = personRepository.findOne(person.getId());
System.out.println("为id、key为" + p.getId() + "数据做了缓存");
return p;
}
}
关于这个实现类注意如下几点:
1.@CachePut表示缓存新添加的数据或者更新的数据到缓存中,两个参数value表示缓存的名称为people,key表示缓存的key为person的id
2.@CacheEvict表示从缓存people中删除key为id的数据
3.@Cacheable表示添加数据到缓存中,缓存名称为people,缓存key为person的id属性。
创建Controller
@RestController
public class CacheController {
@Resource
private PersonService personService;
@RequestMapping("/put")
public Person put(Person person){
return personService.save(person);
}
@RequestMapping("/cache")
public Person cache(Person person){
return personService.findOne(person);
}
@RequestMapping("/evict")
public String evict(Long id){
personService.remove(id);
return "ok";
}
}
大功告成了!