缓存ResultSet - java

它更像是主观问题,该问题的主要目的是缓存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;
        }
    }

现在,我对以下几点感到困惑

  • 我将返回CachedResultSet的实例,而不是ResultSet接口。将是resultSet的正确替换。驱动程序JAR,DB类可以在不同的客户环境中变化。客户将编写自定义类,并期望Abstract类有一个resultSet。这会引起任何问题吗?像下面这样

    公共类CustomerXX扩展BaseClass {

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

  • 涉及此类操作的风险(缓存CachedRowSet,数据正确性)
  • 创建CachedRowSet的性能
  • 与所有ResultSet操作(ResultSet.getString(),ResultSet.get ..())兼容。如果驾驶员完全希望/产生ResultSet的不同子类(请说jdbcResultSetBaseResultSet等)
  • 我有很多其他类似的问题,我只是在写一些我认为有效且具有较高优先级的问题。

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

    任何想法,想法,建议都将受到高度赞赏,并在此先感谢

    参考方案

    实现自定义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;
        }
    
    }
    

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

  • 并发-多个线程将访问缓存
  • 内存-缓存可能变得太大,并且可能发生OutOfMemoryException。
  • 我建议使用一些现有的缓存解决方案,而不是编写自己的解决方案。
    我发现google guava稳定且易于使用。

    ResultSet getFetchSize()似乎不起作用? - java

    我在使用getFetchSize()函数时遇到麻烦。我只需要知道SQL查询是否返回零行。我已经尝试过以下简单的语句:if (rs.getFetchSize()==0) System.out.println("HEADLINE"); 其中rs是ResultSet类型。上面的代码似乎无效。无论rs是否为空,它总是打印消息。我检查了SQL查询本…

    Java:正则表达式模式匹配器是否有大小限制? - java

    我的模式类似于OR:“word1 | word2 | word3”我大约有800个字。可能有问题吗? 参考方案 您仅受记忆和理智的限制。 :)

    Java:线程池如何将线程映射到可运行对象 - java

    试图绕过Java并发问题,并且很难理解线程池,线程以及它们正在执行的可运行“任务”之间的关系。如果我创建一个有10个线程的线程池,那么我是否必须将相同的任务传递给池中的每个线程,或者池化的线程实际上只是与任务无关的“工人无人机”可用于执行任何任务?无论哪种方式,Executor / ExecutorService如何将正确的任务分配给正确的线程? 参考方案 …

    JAVA:字节码和二进制有什么区别? - java

    java字节代码(已编译的语言,也称为目标代码)与机器代码(当前计算机的本机代码)之间有什么区别?我读过一些书,他们将字节码称为二进制指令,但我不知道为什么。 参考方案 字节码是独立于平台的,在Windows中运行的编译器编译的字节码仍将在linux / unix / mac中运行。机器代码是特定于平台的,如果在Windows x86中编译,则它将仅在Win…

    java:继承 - java

    有哪些替代继承的方法? java大神给出的解决方案 有效的Java:偏重于继承而不是继承。 (这实际上也来自“四人帮”)。他提出的理由是,如果扩展类未明确设计为继承,则继承会引起很多不正常的副作用。例如,对super.someMethod()的任何调用都可以引导您通过未知代码的意外路径。取而代之的是,持有对本来应该扩展的类的引用,然后委托给它。这是与Eric…