4

主観的な質問に似ています。質問の主な目的は、java.sql.ResultSetをキャッシュすることです。ただし、Connectionと緊密に結合されているため、推奨されないメカニズムであり、接続が閉じられるとデータがフラッシュされる可能性があることを私は知っています。この問題に対処するために、私は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;
        }
    }

今、私は以下の点と少し混乱しています

  1. ResultSetインターフェースの代わりに、CachedResultSetのインスタンスを返します。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. ResultSetすべての操作との互換性( ResultSet.getString()、ResultSet.get ..())。ドライバーがResultSet(Say jdbcResultSetBaseResultSetなど)の異なるサブクラスを期待/生成する場合

他にも同じような質問がたくさんありますが、私は自分が有効で優先度が高いと感じているものをいくつか書いています。

私の質問がそれほど曖昧であるかどうかはわかりませんが、私の要件は十分に明確になっています。

どんなアイデア、考え、提案も高く評価されており、事前に感謝します

4

1 に答える 1

4

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が発生する可能性があります。

独自のソリューションをコーディングする代わりに、既存のキャッシュソリューションを使用することをお勧めします。私はグーグルグアバが安定していて使いやすいことを発見しました。

于 2012-10-21T20:13:16.790 に答える