联接:
在path expressions中(relationship.attribute)声明的联接在criteria中会被OJB自
动处理。Path expressions支持1:1,1:n,m:n多种关系。
下面的例子查找属于Liquors产品组的所有文章。文章和产品组的关系是在Article类中
的productGroup关系来建立的:
<!-- Definitions for org.apache.ojb.ojb.broker.Article -->
<class-descriptor
class="org.apache.ojb.broker.Article"
proxy="dynamic"
table="Artikel"
>
...
<reference-descriptor
name="productGroup"
class-ref="org.apache.ojb.broker.ProductGroup"
>
<foreignkey field-ref="productGroupId"/>
</reference-descriptor>
</class-descriptor>
<class-descriptor
class="org.apache.ojb.broker.ProductGroup"
proxy="org.apache.ojb.broker.ProductGroupProxy"
table="Kategorien"
>
...
<field-descriptor
name="groupName"
column="KategorieName"
jdbc-type="VARCHAR"
/>
...
</class-descriptor>
path expressions包含了productGroup和groupName间1:1的关系
Criteria crit = new Criteria();
crit.addEqualTo("productGroup.groupName", "Liquors");
Query q = QueryFactory.newQuery(Article.class, crit);
Collection results = broker.getCollectionByQuery(q);
如果path expressions指向一个有限制的类,那么查询条件就变成了Ored。下面的例子
查询所有文章名以F开头的ProductGroups。Path expressions 声明了allArticlesInGr
oup来表示Articles的限制:Books和CDs:
Criteria crit = new Criteria();
crit.addLike("allArticlesInGroup.articleName", "F%");
Query q = QueryFactory.newQuery(ProductGroup.class, crit, true);
Collection results = broker.getCollectionByQuery(q);
SQL语句如下:
SELECT DISTINCT A0.KategorieName,A0.Kategorie_Nr,A0.Beschreibung
FROM Kategorien A0
INNER JOIN Artikel A1 ON A0.Kategorie_Nr=A1.Kategorie_Nr
LEFT OUTER JOIN BOOKS A1E0 ON A0.Kategorie_Nr=A1E0.Kategorie_Nr
LEFT OUTER JOIN CDS A1E1 ON A0.Kategorie_Nr=A1E1.Kategorie_Nr
WHERE A1.Artikelname LIKE 'F%' OR
A1E0.Artikelname LIKE 'F%' OR
A1E1.Artikelname LIKE 'F%'
Prefetched 关系:
能够使通过关系查询对象的查询次数最小化。在我们的测试中,我们指定ProductGroup
s和Articles有一对多的关系。当查询ProductGroups,通过一个查询获得ProductGroup
s,对于每个ProductGroup我们再通过查询获得它的Articles。
OJB试着通过prefetched关系将属于ProductGroups的所有Ariticles通过一个查询得到。
让我们来看看为什么一个查询基本上不能实现:
Criteria crit = new Criteria();
crit.addLessOrEqualThan("groupId", new Integer(5));
crit.addOrderByDescending("groupId");
crit.addPrefetchedRelationship("allArticlesInGroup");
Query q = QueryFactory.newQuery(ProductGroup.class, crit);
Collection results = broker.getCollectionByQuery(q);
第一个查询获得所有匹配的ProductGroups:
SELECT ... FROM Kategorien A0 WHERE
A0.Kategorie_Nr <= ? ORDER BY 3 DESC
第二个查询从第一个查询的结构中获得属于ProductGroups的Articles:
SELECT ... FROM Artikel A0 WHERE A0.Kategorie_Nr
IN ( ? , ? , ? , ? , ? ) ORDER BY 7 DESC
获得了所有相关的Articles后,该方法还不支持对关系使用Arrays。
查询对象:
OJB查询返回完全的对象,这就意味着所有的实例变量会被赋值,所有的自动获得关系会
被加载。到现在为止,还没有方法能够只获得部分的对象(如仅仅得到personde 的fir
stname和lastname)
Report查询:
Report查询适合获得一行数据,但是不使真正意义上的商业对象。一行数据就是一个对
象数组,通过这些查询你能够定义什么样的对象属性你希望在一行数据中存在。属性名
也可以包括path expressions如'owner.address.street'。可以使用ReportQuery#setC
olumns(String[] columns)来定义属性。注意:这里的columns不是数据库中的columns
,column的名字应该和查询中的属性名一样。
下面的ReportQuery总结了每个ProductGroup的库存文章数目和价格:
Criteria crit = new Criteria();
Collection results = new Vector();
ReportQueryByCriteria q = QueryFactory.newReportQuery(
ProductGroup.class, crit);
// define the 'columns' of the report
q.setColumns(new String[] { "groupName",
"sum(allArticlesInGroup.stock)",
"sum(allArticlesInGroup.price)" });
crit.addGroupBy("groupName");
Iterator iter = broker.getReportQueryIteratorByQuery(q);