版本openjpa-2.4.1=2.4.1.SNAPSHOT
我在OpenJPA中有一个复杂的sql作为本机查询运行。在遍历arraylist时,某些值过滤是在应用程序端完成的。
这意味着List<MyObject>
会在将任何行写入servlet输出流之前保留在内存中。更不用说MySQL jdbc结果集已完全读取到RAM,因为mysql jdbc驱动程序是如何工作的。因此,行会在一段时间内两次保存在RAM中。
调用query.getResultList()
函数时是否可以有一个自定义的渐进行处理程序?我只能将有意义的jdbc行写入json响应,并跳过那些不感兴趣的行。
或者是否可以使用原始的jdbc结果集并将行强制转换为应用程序端的MyObject jpa对象实例?它确实需要被管理的实例,但是希望重用现有的从sql到对象的序列化。
当前代码
Query query = em.createNativeQuery(sql, MyObject.class);
query.setParameter(1, "serverX");
List<MyObject> list=query.getResultList();
JsonGenerator jsonG = MyApplication.createJsonGenerator(providers, os);
jsonG.writeStartObject();
jsonG.writeFieldName("items");
jsonG.writeStartArray();
for(MyObject obj : list) {
if (obj.getType()==1) MyObject.writeJSONv1(jsong, obj);
else if (obj.getType()==2) MyObject.writeJSONv2(jsong, obj);
else if (obj.isValid() && obj.getType()==3) MyObject.writeJSONv3(jsong, obj);
else if (obj.getName().startsWith("abc")) MyObject.writeJSONvX(jsong, obj);
else Logger.log("Skipped " + obj.getId());
}
jsonG.writeEndArray();
jsonG.writeEndObject();
jsonG.flush();
jsonG.close();
伪代码,渐进式迭代器
Query query = em.createNativeQuery(sql, MyObject.class);
query.setParameter(1, "serverX");
Iterator iter=query.getCustomProgressiveRowIterator();
JsonGenerator jsonG = MyApplication.createJsonGenerator(providers, os);
jsonG.writeStartObject();
jsonG.writeFieldName("items");
jsonG.writeStartArray();
for(iter.hasNext()) {
MyObject obj = (MyObject)iter.next();
if (obj.getType()==1) MyObject.writeJSONv1(jsong, obj);
else if (obj.getType()==2) MyObject.writeJSONv2(jsong, obj);
else if (obj.isValid() && obj.getType()==3) MyObject.writeJSONv3(jsong, obj);
else if (obj.getName().startsWith("abc")) MyObject.writeJSONvX(jsong, obj);
else Logger.log("Skipped " + obj.getId());
}
jsonG.writeEndArray();
jsonG.writeEndObject();
jsonG.flush();
jsonG.close();
伪代码,将jdbc行强制转换为对象
PreparedStatement stmt = con.prepareStatement("Select * my complex query From MyObjects");
ResultSet rs = stmt.executeQuery();
while(rs.next()) {
// check few resultset fields, if all good then get MyObject
MyObject obj = OpenJPA.castResultSetToObject(rs);
MyObject.writeJSON(jsong, obj);
}
rs.close();
stmt.close();
编辑:
@Gimby对getResultStream()进行了评论,如果有一天,OpenJPA将其链接到这里以供以后参考。也链接到OpenJPA 3.x票证。
https://www.thoughts-on-java.org/jpa-2-2s-new-stream-method-and-how-you-should-not-use-it/
https://issues.apache.org/jira/browse/OPENJPA-2711