单个类缓存
实现缓存以减少数据库查询的一个方法是使用简单的内存缓存,如Java中的HashMap
,或者更高级的缓存解决方案,如Redis。下面是使用内存缓存的基本示例:
首先,你需要创建一个缓存。在这个例子中,我们使用ConcurrentHashMap
作为缓存的实现,因为它支持并发操作。
import java.util.concurrent.ConcurrentHashMap;
public class InsulationQualityCache {
private static final ConcurrentHashMap<String, InsulationQuality> cache = new ConcurrentHashMap<>();
public static InsulationQuality getFromCache(String barcode) {
return CACHE.get(barcode);
}
public static void addToCache(InsulationQuality insulationQuality) {
if (insulationQuality != null && insulationQuality.getBarcode() != null) {
CACHE.put(insulationQuality.getBarcode(), insulationQuality);
}
}
public static void updateCache(InsulationQuality updatedInsulationQuality) {
if (updatedInsulationQuality != null && updatedInsulationQuality.getBarcode() != null) {
CACHE.put(updatedInsulationQuality.getBarcode(), updatedInsulationQuality);
}
}
public static void removeFromCache(String barcode) {
CACHE.remove(barcode);
}
}
然后,在你的业务逻辑中,你可以先尝试从缓存中获取InsulationQuality
实例,如果缓存中没有,再从数据库中查询,并将结果放入缓存以供将来使用。
InsulationQuality insulationQuality = InsulationQualityCache.getFromCache(ironCoreBarCode);
if (insulationQuality == null) {
insulationQuality = insulationQualityService.getOne(Wrappers.<InsulationQuality>lambdaQuery()
.eq(InsulationQuality::getBarcode, ironCoreBarCode).eq(InsulationQuality::getDeleted, BaseConstant.ZERO));
if (insulationQuality == null) {
insulationQuality = new InsulationQuality();
insulationQuality.setPkId(String.valueOf(idWorker.nextId()))
.setBarcode(ironCoreBarCode)
.setDeleted(BaseConstant.ZERO)
.setMakeTime(LocalDateTime.now())
.setModifyTime(LocalDateTime.now());
insulationQualityService.save(insulationQuality);
} else {
// 如果从数据库中找到了实例,将其加入缓存
InsulationQualityCache.addToCache(insulationQuality);
}
}
return insulationQuality;
这种方式减少了对数据库的直接查询次数,因为在许多情况下,数据可以直接从缓存中检索,特别是对于频繁读取但不经常更改的数据。需要注意的是,使用缓存时,你还需要考虑数据一致性和缓存失效策略,以确保缓存的数据是最新的。对于更复杂的场景,可能需要使用专门的缓存解决方案,如Redis,它提供了更丰富的功能和更好的性能
通用缓存管理类
我们定义一个GenericCacheManager
类,这个类可以管理任意类型的数据缓存,实现了添加、获取和清理等基本操作。
public class GenericCacheManager<T> {
private ConcurrentHashMap<String, CacheEntry<T>> cache = new ConcurrentHashMap<>();
// 添加或更新缓存数据
public void put(String key, T value, long durationInMillis) {
long expiryTime = System.currentTimeMillis() + durationInMillis;
cache.put(key, new CacheEntry<>(value, expiryTime));
}
// 获取数据前检查是否过期
public T get(String key) {
CacheEntry<T> entry = cache.get(key);
if (entry != null && !entry.isExpired()) {
return entry.getValue();
} else {
cache.remove(key); // 移除过期数据
return null;
}
}
// 定期执行的方法,用于清理过期的缓存条目
public void cleanup() {
for (String key : cache.keySet()) {
CacheEntry<T> entry = cache.get(key);
if (entry != null && entry.isExpired()) {
cache.remove(key);
}
}
}
}
其中CacheEntry<T>
是一个泛型类,与之前例子中的CacheEntry
类似,但它可以持有任意类型的数据:
public class CacheEntry<T> {
private T value;
private long expiryTime;
public CacheEntry(T value, long expiryTime) {
this.value = value;
this.expiryTime = expiryTime;
}
public T getValue() {
return value;
}
public long getExpiryTime() {
return expiryTime;
}
public boolean isExpired() {
return System.currentTimeMillis() > expiryTime;
}
}
使用示例
// 实例化缓存管理器,管理InsulationQuality对象
GenericCacheManager<InsulationQuality> insulationQualityCache = new GenericCacheManager<>();
// 添加数据到缓存
insulationQualityCache.put("someKey", new InsulationQuality(/* parameters */), 60000); // 60秒后过期
// 从缓存获取数据
InsulationQuality result = insulationQualityCache.get("someKey");
// 定期清理过期数据,可能在某个定时任务中调用
insulationQualityCache.cleanup();
通过这种方式,我们定义了一个灵活的缓存管理器,它可以被复用于不同类型的缓存管理场景,大大减少了代码的重复,并且提高了代码的维护性。
System.currentTimeMillis()
是Java中的一个方法,它返回当前时间与1970年1月1日00:00:00 UTC(协调世界时间)之间的差值,这个差值以毫秒为单位。这通常被用于测量时间间隔或者处理与时间相关的逻辑。例如,在缓存过期策略中,
System.currentTimeMillis()
用来获取当前时间的毫秒值,然后与缓存条目的过期时间进行比较,以决定一个条目是否已经过期。如果缓存条目的过期时间小于当前时间(即System.currentTimeMillis()
返回的值),那么这个条目就被认为是过期的。