我试图了解何时应该调用Query.close(Object)或Query.closeAll();
从the docs我看到它将“关闭查询结果”并“释放与之关联的所有资源”,但“关闭”是什么意思?这是否意味着我在调用它们之后不能使用我从查询中获取的对象?
我问,因为我试图用像getUser(id)这样的函数划分我的代码,这将创建一个Query,获取User,并销毁查询。如果我必须保持查询只是为了访问用户,那么我不能真正做那种划分。
如果我不在某个物体上打电话会怎么样?它会被收集为垃圾吗?我以后能够访问该对象吗?
如果我能以某种方式进一步说明我的问题,请告诉我。
答案 0 :(得分:2)
您不能使用查询结果,因为您关闭了它们(即您从query.execute返回的List对象)。您可以访问结果中的对象 ...如果您将它们复制到您自己的列表中,或者在代码中对它们进行了引用。无法调用关闭可能会泄漏内存
答案 1 :(得分:1)
当您的查询方法返回单个对象时,很容易在返回单个对象之前简单地关闭查询。
另一方面,当您的查询方法返回一个集合时,查询方法本身无法在返回结果之前关闭查询,因为查询需要在调用者迭代结果时保持打开状态。
这就要求关闭一个在调用者上返回一个集合的查询,并且如果调用者忽略了关闭查询,则会引入泄漏 - 我认为必须有一种更安全的方式并且存在!
Guido,一位长期以来的DataNucleus用户,创建了一个“自动关闭”集合外观,它包装了JDO的Query.execute方法返回的集合。用法非常简单:将查询结果包装在自动结束集合对象的实例中:
而不是像这样返回Query结果集:
return q.execute();
只需返回一个'自动关闭'包装版本:
return new JDOQueryResultCollection(q, q.execute());
对于调用者来说,它看起来像任何其他Collection,但是包装器保留对创建集合结果的查询的引用,并在GC处理包装器时自动关闭它。
Guido慷慨地允许我们在我们的开源exPOJO库中包含他聪明的自动关闭代码。自动关闭类完全独立于exPOJO,可以单独使用。感兴趣的类在expojo_jdo * .jar文件中,可以从以下位置下载:
JDOQueryResultCollection是唯一直接使用的类,但它确实有一些支持类。
只需将jar添加到项目中,然后将com.sas.framework.expojo.jdo.JDOQueryResultCollection导入任何包含将结果作为集合返回的查询方法的Java文件中。
或者,您可以从jar中提取源文件并将其包含在项目中:它们是:
JDOQueryResultCollection.java
Disposable.java
AutoCloseQueryIterator.java
ReadonlyIterator.java