java - 缓存结果集

标签 java sql caching resultset cachedrowset

它更像是一个主观问题,问题的主要目的是缓存java.sql.ResultSet。但我知道这不是首选机制,因为它与 Connection 紧密耦合,并且当连接关闭时数据可能会被刷新。为了解决这个问题,我使用了 CachedRowSet。 CachedRowSet 的实例将使用第三方缓存工具进行缓存,这将帮助我减少数据库调用。

我的实现代码片段如下。 executeQuery(String) 方法在一个抽象类中实现,所有子类都将使用它来执行查询。也可能有客户子类使用此方法从我们的系统中获取数据。

public final ResultSet executeQuery(String query){
        try {
        // return data if it is available in cache, else execute and store in cache
            CachedRowSet cachedRowSet=getDataFromCache(query);
            if(cachedRowSet!=null) {
                return cachedRowSet;   
            }
            PreparedStatement statement=getStatment();
            ResultSet rs= statement.executeQuery(query);
            CachedRowSet cachedRowSet=new CachedRowSetImpl();
            cachedRowSet.populate(rs);
                    cachedData(cachedRowSet);
            return cachedRowSet;
        } catch (Exception e) {
            return null;
        }
    }

现在,我对以下几点有点困惑

  1. 我将返回 CachedResultSet 的实例,而不是 ResultSet 接口(interface)。将是 resultSet 的正确替代品。驱动程序 JAR、DB 类可能因客户环境而异。客户会编写自定义类并期望来自抽象类的结果集。那会引起任何问题吗?像下面这样的东西

    公共(public)类 CustomerXX 扩展 BaseClass {

    public void process(String query){
    
        ResultSet rs = executeQuery(query);
    
        //process rs to fetch data
    
    }
    

  2. 这种操作涉及的风险(缓存CachedRowSet,数据正确性)

  3. 创建CachedRowSet

    的性能
  4. 兼容所有 ResultSet 操作(ResultSet.getString()、ResultSet.get..())。如果 Driver 期望/生成 ResultSet 的不同子类(比如 jdbcResultSetBaseResultSet 等)

我有类似的许多其他问题是我的想法,我只是写了其中一些我认为有效且具有更高优先级的问题。

不确定我的问题是否含糊,是否足够清楚我的要求。

任何想法、想法、建议都非常感谢,非常感谢

最佳答案

实现自定义 CachedRowSet 可能会很痛苦,因为您已经实现了 ResultSet 接口(interface)公开的所有方法。

我建议不要在 jdbc 级别缓存,而是在数据访问层缓存一些值对象。

例如,如果你的用户表有 id、name 和 email 列,你可以有以下值对象

class User {
    Long id;
    String name;
    String email;
} 

接下来可以介绍数据访问层

interface UserRepository {
    List<User> retrieveUsers();
}

使用默认的 JdbcUserRepository 从数据库加载数据。

可以使用代理模式实现缓存:

class CachingUserRepository implements UserRepository {
    private Cache cache;
    private UserRepository delegate;

    List<User> retrieveUsers() {
        List<User> result = cache.get(USERS_KEY);
        if (result == null) {
            result = delegate.retrieveUsers();
        }

        return result;
    }

}

实现缓存是最具挑战性的部分。您必须担心:

  1. 并发性 - 多个线程将访问缓存
  2. 内存 - 缓存可能变得太大,并且可能会发生 OutOfMemoryException。

我建议使用一些现有的缓存解决方案,而不是编写您自己的解决方案。 我找到了 google guava稳定且易于使用。

关于java - 缓存结果集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13001216/

相关文章:

java - 为 Java 应用程序筛选格式不佳的 XHTML 页面的最佳方法是什么

Spring Redis 性能

spring - 如何更新/删除项目集合中已缓存的项目

java - ANTLR Ubuntu Java Makefile

java - 模型- View -控制和 Swing GUI

java - JDSL,图形库——它在哪里?

sql - 如何在 select 中使用函数以及 Sequelize 中的所有记录?

sql - Postgres - 如果两个子查询产生结果,则只返回查询结果

mysql - SQL查询获取最小、最大行数

django - @cache_page() 装饰器在 django-redis-cache 中的工作