Spring为我们提供了几个注解来支持Spring Cache。其核心主要是@Cacheable和@CacheEvict。使用@Cacheable标记的方法在执行后Spring Cache将缓存其返回结果,而使用@CacheEvict标记的方法会在方法执行前或者执行后移除Spring Cache中的某些元素。下面我们将来详细介绍一下Spring基于注解对Cache的支持所提供的几个注解。
@Cacheable可以标记在一个方法上,也可以标记在一个类上。当标记在一个方法上时表示该方法是支持缓存的,当标记在一个类上时则表示该类所有的方法都是支持缓存的
@Cacheable 实例
实例项目结构
1 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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>sqljdbc4</artifactId>
<scope>4.2</scope>
<version>4.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
<version>1.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!-- ehcache 相关依赖 -->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Add Log4j2 Dependency -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.5.3.RELEASE</version>
<configuration>
<fork>true</fork>
</configuration>
<dependencies>
<!--
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
<version>1.2.8.RELEASE</version>
</dependency>-->
</dependencies>
</plugin>
</plugins>
</build>
</project>
2配至缓存ehcache.xml
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
updateCheck="false">
<diskStore path="java.io.tmpdir/Tmp_EhCache" />
<defaultCache eternal="false" maxElementsInMemory="1000" overflowToDisk="false" diskPersistent="false"
timeToIdleSeconds="0" timeToLiveSeconds="600" memoryStoreEvictionPolicy="LRU" />
<cache name="UserCache"
eternal="false"
maxEntriesLocalHeap="0"
timeToIdleSeconds="50">
</cache>
</ehcache>
3 application.properties 配至
spring.cache.type=SIMPLE #数据库连接 SQL SERVER spring.datasource.url=jdbc:sqlserver://localhost:1433;DatabaseName=Text spring.datasource.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver spring.datasource.username=sa spring.datasource.password=123 spring.datasource.type= org.springframework.jdbc.datasource.DriverManagerDataSource spring.cache.type=ehcache spring.cache.ehcache.config=classpath:ehcache.xml
3 User实体类User.cs
package com.example.demo.entity; public class User { public int ID; public int getID() { return ID; } public void setID(int ID) { this.ID = ID; } public String UserName; public String Pwd; public String Age; public String getUserName() { return UserName; } public void setUserName(String userName) { UserName = userName; } public String getPwd() { return Pwd; } public void setPwd(String pwd) { Pwd = pwd; } public String getAge() { return Age; } public void setAge(String age) { Age = age; } }
4 数据访问 接口UserDAO.cs
package com.example.demo; import com.example.demo.entity.User; import org.apache.ibatis.annotations.*; import org.springframework.cache.annotation.CacheConfig; import org.springframework.cache.annotation.Cacheable; import java.util.List; @Mapper @CacheConfig(cacheNames="UserCache") //ehcache.xml 缓存配至名称 public interface UserDAO { /** * 用户数据新增 */ @Insert("insert into Userinfo(UserName, Pwd, Age) values (#{UserName},#{Pwd},#{Age})") void addUser(User user); /** * 用户数据修改 */ @Update("update Userinfo set UserName=#{UserName},Pwd=#{Pwd} where id=#{id}") void updateUser(User user); /** * 用户数据删除 */ @Delete("delete from Userinfo where ID=#{ID}") void deleteUser(int ID); /** * 根据用户ID查询用户信息 * */ @Select("SELECT UserName, Pwd, Age FROM Userinfo where ID=#{ID}") @Cacheable User findById(@Param("ID") int ID); /** * 根据用户age查询用户信息 */ @Select("SELECT UserName, Pwd, Age FROM Userinfo") List<User> findAll(); }
5 UserService.cs
package com.example.demo;
import com.example.demo.entity.User;
import org.hibernate.validator.internal.util.logging.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.SimpleTimeZone;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@Service
public class UserService implements UserDAO {
private static final Logger logger;
static {
logger = LogManager.getLogger(UserDAO.class);
}
@Autowired
private UserDAO userDAO;
@Override
public void addUser(User user) {
}
@Override
public void updateUser(User user) {
}
@Override
public void deleteUser(int ID) {
}
@Override
@Cacheable(key = "#ID") //缓存查询数据ID
public User findById(int ID) {
logger.info("取SQL"); //验证是否取SQL
User user=this.userDAO.findById(ID);
return user;
}
@Override
public List<User> findAll() {
return this.userDAO.findAll();
}
}
6 控制器 UserController
import com.example.demo.entity.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @Controller public class UserController { @Autowired private UserService userService; @RequestMapping("/User") public String User(){ System.out.print("开始"); return "index"; } @RequestMapping("/findById") public String getUser(int id) { System.out.print("开始"); User user = userService.findById(id); System.out.print("开始"+user.Age); return "index"; } }
7 创建index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>部署</title> </head> <body> <span >测试Cacheable</span> </body> </html>
8创建springboot启动器
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
@SpringBootApplication
@EnableCaching
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
运行结果:
http://127.0.0.1:8080//findById?id=5
请求2次
开始2019-04-10 16:02:38.614 INFO 7376 --- [nio-8080-exec-7] c.e.d.UserDAO : 取SQL
开始女 开始 开始女
结果只取1次SQL