通过表删除结果集中的列
问题描述:
我正在使用JDBI来查询我们的数据库。我有两个通过外键连接的表,我的查询返回两个表的连接。要将返回的值转换为对象,我已为我的对象实现了ResultSetMapper
。查询中的ResultSet
包含两个表的列:t1.id, t1.name, t2.id, t2.name
。我如何根据表名分割?我在寻找这样的代码:通过表删除结果集中的列
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...
}
的问题是,Table1
和Table2
有一些列具有相同的名称,所以我已经考虑更改查询,为每列返回不同的名字,只是解析整个ResultSet
但是如果我有很多列,或者我只对Table2
进行更改(我将不得不记住更改映射器Table2
,但也要返回到此处并进行更改),但这不会很好地扩展。
我发现这个solution,但它看起来过于复杂。
任何想法将是非常赞赏....
答
我建议有列名的前缀作为可选的构造函数参数实现的映射器:
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中解决了这个用例很多问题(仍然在alpha中)。现在,所有反射式映射器如BeanMapper
都支持列名前缀,如上所述,开箱即用。我们还增加了JoinRowMapper
这使得这个愚蠢简单:
@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());