我正在尝试使用Java Play中的Ebean 2.3.3查询部分对象!框架2.2.1。例如,要获取仅包含id
表中的字段host
,publicKey
和instance_config
的记录列表,请使用以下内容:
List<InstanceConfig> tests = Ebean.find(InstanceConfig.class)
.select("host,publicKey")
.where().eq("accountId", accountId).ne("host", "")
.findList();
这会产生以下sql查询,我期望:
[debug] c.j.b.PreparedStatementHandle - select t0.id as c0, t0.host as c1,
t0.public_key as c2 from instance_config t0 where t0.account_id = xxxxxxxxxx
and t0.host <> ''
但是,相同的代码也会为要查询的表中的每条记录生成此查询:
[debug] c.j.b.PreparedStatementHandle - select t0.id as c0, t0.host as c1,
t0.public_key as c2, t0.private_key as c3, t0.created_by as c4,
t0.account_id as c5 from instance_config t0 where t0.id = xx
从服务器返回的输出包含完整对象,包含所有字段。
我猜这些查询与Ebean对部分对象所做的Lazy Loading有关吗?
我在这个SO question中发现,绕过Lazy Loading的一种方法是一起绕过Ebean并使用标准的JDBC接口来执行查询。问题是几年前,我想重新询问这个解决方案是否仍然准确?
答案 0 :(得分:1)
很难说明你的问题具体是什么,但通常你想要出于性能原因使用部分对象查询,并且通常在执行时避免延迟加载。因此,在您的情况下,您可能只需从第一个查询中删除select()子句。
延迟加载并不总是坏的,但在你的情况下,如果你想避免它,只需删除select子句,然后所有属性都将加载到原始查询中。
现在在带有摘要级别日志记录的日志中(DEBUG级别为&#34; org.avaje.ebean.SUM&#34;)例如:
... txn[2005] select t0.id c0 from be_customer t0; --bind()
... txn[2005] FindMany type[Customer] origin[5NLfz.CdTSLn.BvQ020] exeMicros[0] rows[0] name[] predicates[] bind[]
... txn[2006] select t0.id c0, t0.inactive c1, t0.name c2, t0.registered c3, t0.comments c4, t0.version c5, t0.when_created c6, t0.when_updated c7, t0.billing_address_id c8, t0.shipping_address_id c9 from be_customer t0 where t0.id = ? ; --bind(1)
... txn[2006] FindMany mode[+lazy] type[Customer] origin[5NLfz.CdTSLn.BvQ020] lazyLoadProp[name] load[path:null batch:1] exeMicros[1079] rows[1] name[] predicates[] bind[1]
在上一个日志条目中:
现在,并非所有延迟加载都不好,但在您的情况下,我们可以看到您的表格不是很宽(延迟加载查询中没有那么多列)但我们不知道类型(任何大的varchar列)在那里等)。我猜测并说你可能只需删除select()子句。
如果你有&#34; org.avaje.ebean.SUM&#34;的DEBUG日志级别。然后你可以查找+ lazy查询,检查它们相关的原始查询,并查看是否/可以做得更好。
希望这有帮助。
答案 1 :(得分:0)
只要您不访问任何其他字段,就可以继续使用Ebean。
一旦访问返回对象中已存在的任何 字段,就会执行日志中看到的第二个查询。这似乎是Ebean默认的延迟加载行为。
我遇到了同样的问题,Ebean在使用Json.toJson()
转换查询结果后加载了所有字段,这是访问我所有模型的字段以创建JSON对象。
我通过手动操作结果解决了这个问题,确保不会访问我在select
中提取的字段旁边的任何其他字段。
例如:
List<InstanceConfig> tests = Ebean.find(InstanceConfig.class)
.select("host,publicKey")
.where().eq("accountId", accountId).ne("host", "")
.findList();
// Accessing fields
String host = tests.get(0).host; // Doesn't trigger a new query
String publicKey = tests.get(0).publicKey; // Doesn't trigger a new query
String otherField = tests.get(0).otherField; // This will trigger a query
关于此主题的Ebean文档:http://ebean-orm.github.io/docs/query/features#lazy_loading