0

Java は初めてで、基本的なデータベース アクセス レイヤーを実装しようとしています。JDBC ボイラープレート コードを削減するために Apache DBUtils を使用していますが、これは非常にうまく機能しています。

問題は、私の実装では、データベース内の各テーブルの CRUD に個別のクラスを使用しているため、多くの機能を複製するのが間違っていると感じていることです。

これは受け入れられる設計ですか? そうでない場合、コードの重複を減らすために何ができますか?
なんらかの方法でジェネリックを使用するようにソリューションをリファクタリングできますか?

ORM (myBatis、Hibernate など) を解決策として使用できることはわかっていますが、できることなら DBUtils とプレーンな JDBC を使い続けたいと思っています。

明確にするために:
2つのテーブルがあるとしましょう...

---------------------  
User    |  File  
---------------------  
userId  |  fileId  
name    |  path  
age     |  size  
---------------------  

私の現在のソリューションでは、2 つのクラス (UserStore、FileStore) を作成し、各クラスは同様の基本的な CRUD メソッドを実装します。

protected boolean Create(User newUser)
{
    QueryRunner run = new QueryRunner(dataSource);
    try 
    {
        run.update("INSERT INTO User (name, age) " +
                "VALUES (?, ?)", newUser.getName(), newUser.getAge()); 
    }
    catch (SQLException ex) 
    {
        Log.logException(ex);
        return false;
    }
    return true;
}

protected User Read(int userId)
{
    try
    {
        User user = run.query("SELECT * FROM User WHERE userId = ? ", userId);
        return user;
    }
    catch (SQLException ex) 
    {
        Log.logException(ex);
        return null;
    }
}

protected update(User user)
{
    ... perform database query etc
}

protected delete(int userId)
{
    ... perform database query etc
}
4

4 に答える 4

0

mybatis を使用すると、結果タイプをハッシュマップとして返​​すことができます。

<select id="mCount" resultType="hashmap"> select managerName, count(reportees) AS count from mgr_employee group by managerName; </select>

したがって、次のようなワークフローで効果的に書き出すことができます: 1) インターフェースを開発する 2a) mybatis アノテーションを使用して必要なクエリを定義する または 2b) インターフェースを xml にリンクしてクエリを書く

これにはDAOは関与せず、他の定型文は上記のように関与することに注意してください

于 2013-06-01T14:25:43.657 に答える
0

Template メソッドでこれを行う方法を尋ねました。これを行う方法の例を次に示します。

public class AbstractDAO<T> {
private String table;
private String id_field;

public AbstractDAO(String table, String id_field){
this.table = table;
...
}

public T read(int id){
    try
{
    T user = run.query("SELECT * FROM "+ table + " WHERE "+id_field +" = ? ", id);
    return user;
}
catch (SQLException ex) 
{
    Log.logException(ex);
    return null;
}
}

これは簡単に見えますが、Create はどうですか?

public boolean Create(T user){
    QueryRunner run = new QueryRunner(dataSource);
try 
{
    run.update("INSERT INTO "+table+ getFields() +
            "VALUES " + getParameters(user)); 
}
catch (SQLException ex) 
{
    Log.logException(ex);
    return false;
}

    return true;
}

protected abstract String getFields(); 
protected abstract String getParameters(T user);

醜く、不安ですが、アイデアを伝えるのは問題ありません。

于 2013-05-13T09:41:14.993 に答える
0

DBUtils を使用すると、既に多くのボイラープレート コードを抽象化しています。残っているのは、ほとんどエンティティ間で異なる作業です: 適切な sql ステートメント、エンティティ オブジェクトの UPDATE パラメータへの変換、および SELECT を使用したその逆の変換、例外処理。

残念ながら、これらの残りのタスクに対して十分な柔軟性を備えた一般的な抽象化を作成することは容易ではありません。それが ORM マッパーのすべてです。これらのいずれかを調べることをお勧めします。JPA API に固執している場合でも、標準化された土地にいて、ORM プロバイダーをより簡単に切り替えることができます (ただし、常にいくつかの結合があります)。SpringData のリポジトリの抽象化には感銘を受けました。単純な使用例では、DAOのコードはゼロです。すでに Spring を使用していて、オブジェクト モデルを保持したいだけの場合は、必ず検討する必要があります。

または、 jooqでいくつかの良い経験をしました。また、スキーマ内のテーブルに基づいて、DTO および対応する DAO を作成することもできます。ORM マッパーとは対照的に、リレーショナル スキーマに近いため、長所にも短所にもなります。

于 2013-05-13T09:14:46.933 に答える