我有一个案例,我通过一系列查询构造一个对象。为了优化,对象的构造是一起批处理的,查询使用IN
子句来允许处理一批对象。
在下面的示例中,给定 的列表MyObject
,我想MyObject.c
根据 和 的值MyObject.a
进行填充MyObject.b
。使用skife.jdbi 库,我的实现如下所示。
有什么改进建议吗?
如果我解析原始结果集可能会更有效(尽管我找不到如何让我的界面来映射结果集)?
或者,如果有某种方法可以直接将查询参数映射到结果(但我还没有找到方法),它会更整洁吗?
class MyObject {
String a;
String b;
String c;
// ....
String z;
}
void populateC(Set<MyObject> objects) {
// parse the list, populating Lists which will be used for the query and a
// Map which will be used to map query results back to the MyObjects in the Set param
Map<PopulateCQuerydata, MyObject> queryDataToParamMap = new HashMap<>;
List<String> aList = new ArrayList<>;
List<String> bList = new ArrayList<>;
for (MyObject object : objects) {
queryDataToParamMap.put(new CResult(object), object);
aList.add(object.a);
bList.add(object.b);
}
Set<CResult> results = dao.getC(aList, bList);
for (CResult result : results) {
queryDataToParamMap.get(result).c = result.c;
}
}
@RegisterMapper(CResultMapper.class)
@UseStringTemplate3StatementLocator("/sql/PopulateCDao.sql.stg")
interface PopulateCDao {
@SqlQuery
List<CResults> getC(@BindIn("aList") List<String> a, @BindIn("bList") List<String> b);
}
class CResults {
String a;
String b;
String c;
CResults(MyObject object) {
a = object.a;
b = object.b;
}
// implement these so this type can be used in the HashMap
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
} else if (!(other instanceof CResults )) {
return false;
} else {
CResults otherQueryData = (CResults)other;
return a.equals(otherQueryData.a) && b.equals(otherQueryData.b);
}
}
@Override
public int hashCode() {
int hash = 1;
hash = hash * 31 + a.hashCode() + b.hashCode();
return hash;
}
}
public class CResultMapper implements ResultSetMapper<CResult> {
@Override
public CResult map(int index, ResultSet resultSet, StatementContext statementContext) throws SQLException {
CResult result = new CResult();
result.a = resultSet.getInt("a");
result.b = resultSet.getInt("b");
result.c = resultSet.getInt("c");
return result;
}
}
//sql/PopulateCDao.sql.stg
group PopulateCDao;
getC(aList, bList) ::= <<
SELECT a, b, c FROM tblJoinC WITH (NOLOCK) WHERE a IN (<aList>) AND b IN (<bList>)
>>