java 从数据库和样板代码缓存数据

b1zrtrql  于 2023-01-04  发布在  Java
关注(0)|答案(2)|浏览(141)

假设我有一个Util类:

public class Resources {

    public static List<Product> PRODUCTS;

    public static List<Customer> CUSTOMERS;

    public static Product getProductById(int id) {
        for (Product product : PRODUCTS) {
            if (product.getIdProduct() == id) {
                return product;
            }
        }
        return null;
    }

    public static Customer getCustomerById(int id) {
        for (Customer customer : CUSTOMERS) {
            if (customer.getId() == id) {
                return customer;
            }
        }
        return null;
    }

}

  • 这作为实体ProductCustomer的缓存机制,它们是从数据库中检索的。所以每当我需要首先处理客户(或产品)时,我都会查看Resources.CUSTOMERS (PRODUCTS),如果它在那里的话,我保存了时间,也不必调用服务器。不确定Spring是否可以自己处理它,所以我这样做了。
  • 我的问题是大量的样板代码在这里。如果我将有10,20,...实体,我将不得不写10,20,... getter方法,所有这些将做几乎相同的事情。* 什么是最好的可接受的解决方案尊重一些最佳实践?*
yyyllmsg

yyyllmsg1#

您可以使用泛型方法通过实体的ID来检索实体。只需在方法中引入一个类型参数,该参数表示要检索的实体的类型。
然后,您可以对getCustomerById(int id)getProductById(int id)方法使用单个方法:

public class Resources {
public static <T> T getEntityById(List<T> entities, int id, Function<T, Integer> idExtractor) {
        for (T entity : entities) {
            if (idExtractor.apply(entity) == id) {
                return entity;
            }
        }
        return null;
    }

}

然后,您可以调用此方法来检索Product或Customer实体,如下所示:

Product product = Resources.getEntityById(PRODUCTS, productId, Product::getId);
Customer customer = Resources.getEntityById(CUSTOMERS, customerId, Customer::getId);

这将使将来添加对其他实体类型的支持变得容易得多。

9njqaruj

9njqaruj2#

不确定Spring是否可以自行处理
例如,如果您使用JPA访问数据库,JPA缓存就可以做到这一点。
配置它是一项工作,因为您需要指定回收策略(即内存耗尽时会发生什么)。这些实现还考虑线程安全性,许多实现提供磁盘上的存储或在集群中复制存储。
当然,你可以重新发明轮子,如果你需要的轮子简单得多的话,它甚至可能是有意义的,例如,因为一旦构造了缓存,你就永远不会更新它(所以线程安全性是微不足道的),而且整个表都适合内存(所以你不需要驱逐)。
要做到这一点,我首先要选择一个更合适的数据结构,它能提供高效的按键查找,例如Map,然后我会将所有这些冗余方法合并为一个:

class Resources {
    static Map<Class<?>, Map<Integer, ?>> CACHE = new HashMap<>(); 
    // ... or something thread safe, if you intend to update the cache later

    public getEntity<E>(Class<E> entityClass, int id) {
        return entityClass.cast(CACHE.get(entityClass).get(id));
    }
}

用途

Product p = Resources.getEntity(Product.class, 42);
    Customer c = Resources.getEntity(Customer.class, 36);

相关问题