一、demo
1、pom
<?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>org.example</groupId>
<artifactId>localcache-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.4</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--尽量不要同时导入mybatis 和 mybatis_plus,避免版本差异-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>3.5.5</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.13</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--spring cache-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<!-- 添加Caffeine Cache依赖 -->
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
</dependencies>
</project>
2、util
package com.pluscache.demo.localcache;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.TimeUnit;
@Slf4j
public class LocalCache<K, V> {
private final Cache<K, V> cache;
private final String name;
public LocalCache(String name, long duration, TimeUnit unit, int maxSize) {
cache = Caffeine.newBuilder()
.maximumSize(maxSize)
.expireAfterWrite(duration, unit)
.build();
this.name = name;
log.info("create one LocalCache: {}", name);
}
public V get(K key, CacheLoader<K, V> loader) {
return cache.get(key, loader::load);
}
public V getIfPresent(K key) {
if (key == null) {
return null;
}
return cache.getIfPresent(key);
}
public void put(K key, V value) {
if (key == null) {
return;
}
cache.put(key, value);
}
public void delete(K key) {
if (key == null) {
return;
}
cache.invalidate(key);
}
public void deleteAll() {
cache.invalidateAll();
}
public interface CacheLoader<K, V> {
V load(K key);
}
}
3、使用
package com.pluscache.demo.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pluscache.demo.constructor.UserKeyConstructor;
import com.pluscache.demo.dto.UserDTO;
import com.pluscache.demo.localcache.LocalCache;
import com.pluscache.demo.repository.UserRepository;
import com.pluscache.demo.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.concurrent.TimeUnit;
@Service("userService")
@Slf4j
public class UserServiceImpl implements UserService {
@Autowired
public UserRepository userRepository;
//local cache
public static final LocalCache<String, List<UserDTO>> USER_SERVICE_LOCAL_CACHE =
new LocalCache<>("userService", 1, TimeUnit.DAYS, 10000);
@Override
public List<UserDTO> listUsers() {
List<UserDTO> listUsers = USER_SERVICE_LOCAL_CACHE.getIfPresent(UserKeyConstructor.listAll());
if(CollectionUtils.isEmpty(listUsers)){
listUsers = userRepository.listUsers();
USER_SERVICE_LOCAL_CACHE.put(UserKeyConstructor.listAll(), listUsers);
return listUsers;
}
log.info("命中local cache缓存");
return listUsers;
}
@Override
public List<UserDTO> listUsersByAccount(String userAccount) {
List<UserDTO> listUsers = USER_SERVICE_LOCAL_CACHE.getIfPresent(UserKeyConstructor.listByAccount(userAccount));
if(CollectionUtils.isEmpty(listUsers)){
listUsers = userRepository.listUsersByAccount(userAccount);
USER_SERVICE_LOCAL_CACHE.put(UserKeyConstructor.listByAccount(userAccount), listUsers);
return listUsers;
}
log.info("命中local cache缓存");
return listUsers;
}
@Override
public UserDTO getById(Integer id) {
return userRepository.getById(id);
}
@Override
public UserDTO getByIdAndAccount(Integer id, String userAccount) {
return userRepository.getByIdAndAccount(id,userAccount);
}
@Override
public void saveOrUpdate(UserDTO userDTO) {
userRepository.saveOrUpdate(userDTO);
}
@Override
public void updateBatch(List<UserDTO> userDTOs) {
userRepository.updateBatch(userDTOs);
}
@Override
public void deleteById(Integer id) {
UserDTO userDTO = userRepository.getById(id);
if (userDTO != null){
userRepository.deleteById(userDTO,id);
}
}
@Override
public void deleteByIds(List<Integer> ids) {
List<UserDTO> userDTOs = userRepository.listByIds(ids);
if(CollectionUtils.isEmpty(userDTOs)){
return;
}
userRepository.deleteByIds(userDTOs,ids);
}
}
4、测试
4.1、
(1)第一次访问localhost:7777/cacheDemo/user/listUsers从数据库查询
(2)再次访问,先命中local cache缓存
2024-07-17T17:10:01.817+08:00 INFO 65088 --- [nio-7777-exec-3] c.p.demo.service.impl.UserServiceImpl : 命中local cache缓存
4.2、
(1)第一次访问localhost:7777/cacheDemo/user/listByAccount?userAccount=zs从数据库查询
JDBC Connection [HikariProxyConnection@1475868044 wrapping com.mysql.cj.jdbc.ConnectionImpl@33d4cbb8] will not be managed by Spring
==> Preparing: SELECT id,user_name,user_account,age FROM t_user WHERE (user_account = ?)
==> Parameters: zs(String)
<== Columns: id, user_name, user_account, age
<== Row: 1, testzs, zs, 18
<== Total: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@62bdbace]
(2)再次访问,命中local cache缓存
2024-07-17T18:05:35.383+08:00 INFO 65088 --- [nio-7777-exec-8] c.p.demo.service.impl.UserServiceImpl : 命中local cache缓存