2016-09-29 8 views
1

私はJDBIを使用してDBにクエリしています。私は外部キーを介して接続されている2つのテーブルがあり、私のクエリは両方のテーブルの結合を返します。返された値をオブジェクトに変換するには、私のオブジェクトにResultSetMapperを実装しました。クエリのResultSetには、両方のテーブルの列が含まれています。t1.id, t1.name, t2.id, t2.name。テーブル名に応じて分割するにはどうすればよいですか?私はこのコードを探しています:テーブルによってResultSetからカラムを削除します。

public class T1Object { 
    private long id; 
    private String name; 
    private T2Object t2Object; 
} 

public class T2Object { 
    private long id; 
    private String name; 
} 

public void map(ResultSet r) { 
    String t1Name = "Table1 name"; 
    String t2Name = "Table2 name"; 

    t1ResultSet = getResultSetByTableName(r, t1Name); // looking for this function's implementation 
    t2ResultSet = getResultSetByTableName(r, t2Name); 

    // convert each result set to an object using it's mapper... 
} 

問題がTable1Table2は、同じ名前を持ついくつかの列を持っているということですので、私は、各列に異なる名前を返すようにクエリを変更すると考えられてきましたし、ちょうど全体ResultSetを解析しますしかし、私は多くの列を持っているか、またはTable2に変更を加えるだけでこれはうまくスケールされません(Table2のマッパーを変更するだけでなく、ここに戻って変更を加えることを覚えておく必要があります)。

私はこれを見つけましたsolutionしかし、それはあまりにも複雑に見えます。

任意の考えは非常に高く評価されるだろう....私はオプションのコンストラクタの引数として列名の接頭辞を使用してマッパーを実装示唆

答えて

0

:あなたは参加が必要な状況がある場合、このように

class T1Mapper implements ResultSetMapper<T1Object> { 
    public T1Mapper() { this(""); } 
    public T1Mapper(String prefix) { 
    this.prefix = prefix; 
    } 

    private final String prefix; 

    T1Object map(int i, ResultSet rs, StatementContext ctx) throws SQLException { 
    return new T1Object(rs.getInt(prefix + "id"), 
         rs.getString(prefix + "name")); 
    } 
} 

// ditto for t2 mapper 

共通の列名を持つ複数のテーブル、それらを明確にするために、クエリの各列にラベルを付ける:

List<T1Object> handle.createQuery("select t1.id t1_id, t1.name t1_name, " + 
        "t2.id t2_id, t2.name t2_name " + 
        "from table1 t1 left join table2 t2 " + 
        "on t1.id = t2.t1_id") 
     .map(new ResultSetMapper<T1Object>() { 
     T1Mapper t1Mapper = new T1Mapper("t1_"); 
     T2Mapper t2Mapper = new T2Mapper("t2_"); 

     public T1Object map(int i, ResultSet rs, StatementContext ctx) { 
      T1Object t1 = t1Mapper.map(i, rs, ctx); 
      T2Object t2 = t2Mapper.map(i, rs, ctx); 
      t1.setT2Object(t2); 
      return t1; 
     } 
     }) 
     .list(); 

一部の派手なトリックがありますない限り、私は聞いたことがありませんが、実際にカスタムの行マッパを手作業で作成しない限り、そのようなカラム名にプレフィックスを付ける必要はありません。

私はこの使用例をv3(アルファ版でも)の方がはるかに優れていると思います。 BeanMapperのようなすべての反射マッパーは、上記のように、すぐに列名の接頭辞をサポートします。したがって

@SqlQuery("select t1.id t1_id, t1.name t1_name, " + 
      "t2.id t2_id, t2.name t2_name " + 
      "from table1 t1 left join table2 t2 " + 
      "on t1.id = t2.t1_id") 
@RegisterBeanMapper(value = {T1Object.class, T2Object.class}, 
        prefix = {"t1_", "t2_"}) 
@RegisterJoinRowMapper({T1Object.class, T2Object.class}) 
List<JoinRow> listJoins(); 

myDao.listJoins() 
    .stream() 
    .map(joinRow -> { 
     T1Object t1 = joinRow.get(T1Object.class); 
     T2Object t2 = joinRow.get(T2Object.class); 

     // merge the individual entities in your join rows however you like 
     t1.setT2(t2); 
     return t1; 
    }) 
    .collect(toList()); 
我々はまた、この愚か簡単になり JoinRowMapperを追加しました
関連する問題