Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/382.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 缓存结果集_Java_Sql_Caching_Resultset_Cachedrowset - Fatal编程技术网

Java 缓存结果集

Java 缓存结果集,java,sql,caching,resultset,cachedrowset,Java,Sql,Caching,Resultset,Cachedrowset,它更像是一个主观问题,问题的主要目的是缓存java.sql.ResultSet。但我知道它不是首选机制,因为它与连接紧密耦合,当连接关闭时,数据可能会被刷新。为了解决这个问题,我使用CachedRowSet。CachedRowSet的实例将使用第三方缓存工具进行缓存,这将帮助我减少db调用 下面给出了我的实现的代码片段。方法executeQuery(String)在一个抽象类中实现,所有子类都将使用该抽象类执行查询。也可能有客户子类使用此方法从我们的系统中获取数据 public final Re

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

下面给出了我的实现的代码片段。方法
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类可以在不同的客户环境中变化。客户将编写自定义类,并期望从抽象类得到结果集。这会引起什么问题吗?像下面这样的东西

    公共类CustomerXX扩展了基类{

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

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

  • 创建缓存集的性能

  • 与所有
    ResultSet
    操作的兼容性(
    ResultSet.getString()
    ,ResultSet.get..())。如果驱动程序期望/生成不同的
    ResultSet
    子类(比如
    jdbcsresultset
    BaseResultSet
    ,等等)

  • 我有很多类似的问题是我的想法,我只是写了一些我觉得有效的,并且有更高优先级的问题

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


    我们非常感谢您的任何想法、想法和建议,并在此之前向您表示衷心的感谢

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

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

    例如,如果您使用id、名称和电子邮件列的用户表,则可以使用以下值对象

    class User {
        Long id;
        String name;
        String email;
    } 
    
    接下来,您可以介绍数据访问层

    interface UserRepository {
        List<User> retrieveUsers();
    }
    
    接口用户存储库{
    列出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;
        }
    
    }
    
    类CachingUserRepository实现UserRepository{ 专用缓存; 私有用户库代理; 列出retrieveUsers(){ 列表结果=cache.get(USERS\u KEY); 如果(结果==null){ 结果=委托。检索用户(); } 返回结果; } } 实现缓存是最具挑战性的部分。你必须担心:

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

    如果客户期望
    ResultSet
    ,并且
    CachedRowSet
    扩展/实现
    ResultSet
    ,客户将乐于接受
    CachedRowSet
    “CachedRowSet”是Java API,称为断开连接的ResultSet。我已经有了稳定的缓存解决方案,我在帖子中也提到了是的,但是在公共JavaAPI中没有实现它。您正在使用的实现是com.sun.*包层次结构的一部分,它不适合最终用户使用,在将来的Java版本中可能会发生更改,并且在非Oracle Java版本中不受支持。最好避免使用它。