Spring Boot 2.X (7): использование Spring Cache

Spring Boot

Введение в Spring кэш

Поддержка множественного кэша была введена в Spring 3.1 и определена в пакете spring-context.org.springframework.cache.Cacheиorg.springframework.cache.CacheManagerДва интерфейса для объединения различных технологий кэширования. Интерфейс Cache содержит общие операции для кэширования: добавление, удаление, чтение и т.д. CacheManager — это абстрактный интерфейс для различных кешей Spring. Общие CacheManagers, поддерживаемые Spring, следующие:

CacheManager описывать
SimpleCacheManager Используйте простую коллекцию для хранения кеша
ConcurrentMapCacheManager Используйте java.util.ConcurrentHashMap для реализации кэширования.
NoOpCacheManager Только для тестирования, на самом деле не будет хранить кеш
EhCacheCacheManger Используйте EhCache в качестве технологии кэширования. EhCache — это среда внутрипроцессного кэширования на чистом языке Java с быстрыми и экономичными функциями.Это CacheProvider по умолчанию в Hibernate и наиболее широко используемый кэш в области Java.
JCacheCacheManager Поддерживает реализацию стандарта JCache (JSR-107) в качестве технологии кэширования.
CaffeineCacheManager Используйте кофеин в качестве метода кэширования. Используется для замены технологии кэширования Guava.
RedisCacheManager Использование Redis в качестве технологии кэширования
HazelcastCacheManager Использование Hazelcast в качестве технологии кэширования
CompositeCacheManager Используется для объединения CacheManagers, вы можете получить соответствующие кеши, опрашивая несколько CacheManagers.

Spring Cache предоставляет аннотации, такие как @Cacheable , @CachePut , @CacheEvict и @Caching для использования в методах. Аннотируя Cache, мы можем реализовать прозрачное применение логики кэша в нашем бизнес-коде, подобно транзакциям, и только потребуется меньше кода. Основная идея: Когда мы вызываем метод, мы будем хранить параметры метода и возвращаемый результат в виде пары ключ-значение в кеше, и в следующий раз, когда мы вызовем метод с теми же параметрами, он будет выполняться не напрямую, а напрямую. из Получить результат из кеша и вернуть его.

Кэшировать аннотацию

1.@EnableCaching

Включите функцию кеша, которая обычно помещается в класс запуска.

2.@CacheConfig

Когда нам нужно кэшировать все больше и больше мест, вы можете использовать аннотацию @CacheConfig(cacheNames = {"cacheName"}) на классе, чтобы единообразно указать значение значения, затем вы можете опустить значение, если вы все еще пишете в ваш метод на значение, то значение метода по-прежнему подлежит.

3.@Cacheable

Возвращенный результат кешируется в соответствии с методом, в следующем запросе, если кеш существует, кэшированные данные считываются и возвращаются напрямую, если кеш не существует, метод выполняется, а возвращенный результат сохраняется в кеше.Обычно используется в методах запроса. Глядя на исходный код, значения свойств следующие:

имя свойства/метода объяснять
value Имя кеша, обязательное, оно указывает, в каком пространстве имен хранится ваш кеш.
cacheNames Аналогично значению, вы можете выбрать один из двух
key Необязательный атрибут, вы можете использовать тег SpEL для настройки ключа кеша
keyGenerator генератор ключей. В качестве альтернативы используйте key/keyGenerator
cacheManager Укажите диспетчер кеша
cacheResolver Укажите парсер выборки
condition Кэшировать, если выполняются условия
unless Если условия соблюдены, не кешировать
sync Использовать ли асинхронный режим, по умолчанию — false

4.@CachePut

Метод, отмеченный этой аннотацией, будет выполняться каждый раз, а результат будет сохранен в указанном кеше. Другие методы могут считывать кэшированные данные непосредственно из кэша ответов без необходимости запрашивать базу данных.Обычно используется для добавления методов. Глядя на исходный код, значения свойств следующие:

имя свойства/метода объяснять
value Имя кеша, обязательное, оно указывает, в каком пространстве имен хранится ваш кеш.
cacheNames Аналогично значению, вы можете выбрать один из двух
key Необязательный атрибут, вы можете использовать тег SpEL для настройки ключа кеша
keyGenerator генератор ключей. В качестве альтернативы используйте key/keyGenerator
cacheManager Укажите диспетчер кеша
cacheResolver Укажите парсер выборки
condition Кэшировать, если выполняются условия
unless Если условия соблюдены, не кешировать

5.@CacheEvict

Метод, отмеченный этой аннотацией, очистит указанный кеш.Обычно используется для методов обновления или удаленияГлядя на исходный код, значения свойств следующие:

имя свойства/метода объяснять
value Имя кеша, обязательное, оно указывает, в каком пространстве имен хранится ваш кеш.
cacheNames Аналогично значению, вы можете выбрать один из двух
key Необязательный атрибут, вы можете использовать тег SpEL для настройки ключа кеша
keyGenerator генератор ключей. В качестве альтернативы используйте key/keyGenerator
cacheManager Укажите диспетчер кеша
cacheResolver Укажите парсер выборки
condition Кэшировать, если выполняются условия
allEntries Очистить ли все кеши, по умолчанию — false. Если указано значение true, все кеши будут очищены сразу после вызова метода.
beforeInvocation Нужно ли очищать перед выполнением метода, по умолчанию — false. Если указано значение true, кеш будет очищен перед выполнением метода.

6.@Caching

Эта аннотация позволяет одновременно использовать несколько аннотаций для одного и того же метода. Это видно из его исходного кода:

public @interface Caching {

	Cacheable[] cacheable() default {};

	CachePut[] put() default {};

	CacheEvict[] evict() default {};

}

Использование Spring-кэша

1. Соберите проект и добавьте зависимости

<?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 https://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.9.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>cn.zwqh</groupId>
	<artifactId>spring-boot-cache</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>spring-boot-cache</name>
	<description>spring-boot-cache</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-test</artifactId>
			<scope>test</scope>
		</dependency>
		<!-- Spring Cache -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-cache</artifactId>
		</dependency>
		<!-- jdbc -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-jdbc</artifactId>
		</dependency>

		<!-- 热部署模块 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<optional>true</optional> <!-- 这个需要为 true 热部署才有效 -->
		</dependency>


		<!-- mysql 数据库驱动. -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>

		<!-- mybaits -->
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>2.1.0</version>
		</dependency>
		
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

2.файл конфигурации application.properties

#datasource
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/db_test?useUnicode=true&characterEncoding=UTF-8&useSSL=true
spring.datasource.username=root
spring.datasource.password=123456
#mybatis
mybatis.mapper-locations=classpath:/mapper/*Mapper.xml

3. Класс сущности

public class UserEntity implements Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = 5237730257103305078L;
	private Long id;
	private String userName;
	private String userSex;
	public Long getId() {
		return id;
	}
	public void setId(Long id) {
		this.id = id;
	}
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	public String getUserSex() {
		return userSex;
	}
	public void setUserSex(String userSex) {
		this.userSex = userSex;
	}
	
}

4. Dao слоя данных и mapper.xml

public interface UserDao {
	//mapper.xml方式 
	/**
	 * 获取所有用户
	 * @return
	 */
	List<UserEntity> getAll();
	/**
	 * 根据id获取用户
	 * @return
	 */
	UserEntity getOne(Long id);
	/**
	 * 新增用户
	 * @param user
	 */
	void insertUser(UserEntity user);
	/**
	 * 修改用户
	 * @param user
	 */
	void updateUser(UserEntity user);
	/**
	 * 删除用户
	 * @param id
	 */
	void deleteUser(Long id);
		

}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.4//EN" 
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.zwqh.springboot.dao.UserDao">
	<resultMap type="cn.zwqh.springboot.model.UserEntity" id="user">
		<id property="id" column="id"/>
		<result property="userName" column="user_name"/>
		<result property="userSex" column="user_sex"/>
	</resultMap>
	<!-- 获取所有用户 -->
	<select id="getAll" resultMap="user">
		select * from t_user
	</select>
	<!-- 根据用户ID获取用户 -->
	<select id="getOne" resultMap="user">
		select * from t_user where id=#{id}
	</select>
	<!-- 新增用户 -->
	<insert id="insertUser" parameterType="cn.zwqh.springboot.model.UserEntity">
		insert into t_user (user_name,user_sex) values(#{userName},#{userSex})
	</insert>
	<!-- 修改用户 -->
	<update id="updateUser" parameterType="cn.zwqh.springboot.model.UserEntity">
		update t_user set user_name=#{userName},user_sex=#{userSex} where id=#{id}
	</update>
	<!-- 删除用户 -->
	<delete id="deleteUser" parameterType="Long">
		delete from t_user where id=#{id}
	</delete>
</mapper>


5. Интерфейс уровня бизнес-кода Сервис и класс реализации ServiceImpl

public interface UserService {

	/**
	 * 查找所有
	 * @return
	 */
	List<UserEntity> getAll();
	/**
	 * 根据id获取用户
	 * @param id
	 * @return
	 */
	UserEntity getOne(Long id);
	/**
	 * 新增用户
	 * @param user
	 */
	void insertUser(UserEntity user);
	/**
	 * 修改用户
	 * @param user
	 */
	void updateUser(UserEntity user);
	
	void deleteAll1();
	
	void deleteAll12();
}

@Service
@CacheConfig(cacheNames = {"userCache"})
public class UserServiceImpl implements UserService {

	@Autowired
	private UserDao userDao;

	@Override
	@Cacheable("userList") // 标志读取缓存操作,如果缓存不存在,则调用目标方法,并将结果放入缓存
	public List<UserEntity> getAll() {
		System.out.println("缓存不存在,执行方法");
		return userDao.getAll();
	}

	@Override
	@Cacheable(cacheNames = { "user" }, key = "#id")//如果缓存存在,直接读取缓存值;如果缓存不存在,则调用目标方法,并将结果放入缓存
	public UserEntity getOne(Long id) {
		System.out.println("缓存不存在,执行方法");
		return userDao.getOne(id);
	}

	@Override
	@CachePut(cacheNames = { "user" }, key = "#user.id")//写入缓存,key为user.id,一般该注解标注在新增方法上
	public void insertUser(UserEntity user) {
		System.out.println("写入缓存");
		userDao.insertUser(user);
	}

	@Override
	@CacheEvict(cacheNames = { "user" }, key = "#user.id")//根据key清除缓存,一般该注解标注在修改和删除方法上
	public void updateUser(UserEntity user) {
		System.out.println("清除缓存");
		userDao.updateUser(user);
	}
	
	@Override
    @CacheEvict(value="userCache",allEntries=true)//方法调用后清空所有缓存
    public void deleteAll1() {
	
	}
	
	@Override
    @CacheEvict(value="userCache",beforeInvocation=true)//方法调用前清空所有缓存
    public void deleteAll2() {

    }

}

6. Протестируйте контроллер

@RestController
@RequestMapping("/user")
public class UserController {

	@Autowired
	private UserService userService;

	/**
	 *  查找所有
	 * @return
	 */
	@RequestMapping("/getAll")
	public List<UserEntity> getAll(){
		return userService.getAll(); 
	}
	/**
	 * 根据id获取用户
	 * @return
	 */
	@RequestMapping("/getOne")
	public UserEntity getOne(Long id){
		return userService.getOne(id); 
	}
	/**
	 * 新增用户
	 * @param user
	 * @return
	 */
	@RequestMapping("/insertUser")
	public String insertUser(UserEntity user) {
		userService.insertUser(user);
		return "insert success";
	}	
	/**
	 * 修改用户
	 * @param user
	 * @return
	 */
	@RequestMapping("/updateUser")
	public String updateUser(UserEntity user) {
		userService.updateUser(user);
		return "update success";
	}
}

7. Запустите функцию кэширования

@SpringBootApplication
@MapperScan("cn.zwqh.springboot.dao")
@EnableCaching //启动 Cache 功能
public class SpringBootCacheApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringBootCacheApplication.class, args);
	}

}

8. База данных и тестовые данные

База данных и тестовые данные по-прежнему используются, как и раньше.

9. Тест

напишите модульные тесты или посетивhttp://127.0.0.1:8080/user/Добавьте соответствующий путь и параметры.

Документация

org.springframework.cache

образец кода

github

Облако кода

Если не указано иное, авторские права на эту статью принадлежатутренний туманВсе, пожалуйста, указывайте источник при перепечатке.

Оригинальное название: Spring Boot 2.X (7): Использование Spring Cache

Оригинальный адрес: https://www.zwqh.top/article/info/13

Если статья была вам полезна, отсканируйте код и подпишитесь на мой официальный аккаунт, статья постоянно обновляется...