缓存ResultSet

时间:2012-10-21 19:13:49

标签: java sql caching resultset cachedrowset

它更像是主观问题,问题的主要目标是Cache 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接口。将是resultSet的正确替换。驱动程序JAR,DB类可以在不同的客户环境中变化。客户可以编写自定义类并期望Abstract类中的resultSet。这会导致任何问题吗?有些事情如下

    公共类CustomerXX扩展了BaseClass {

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

    }

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

  3. 创建CachedRowSet

  4. 的效果
  5. 与所有ResultSet操作(ResultSet.getString(),ResultSet.get ..())的兼容性。如果所有驱动程序都期望/生成ResultSet的不同子类(说jdbcResultSetBaseResultSet等)

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

    不确定我的问题是如此模糊,是否足够明确我的要求。

    任何想法,想法,建议都受到高度赞赏,并提前多多感谢

1 个答案:

答案 0 :(得分:3)

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

我建议不要在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。
  3. 我建议使用一些现有的缓存解决方案,而不是编写自己的解决方案。 我发现google guava稳定且易于使用。