我正在尝试将一些新功能放入使用iBatis的现有应用程序中,但我对其中一项设计决策感到困惑。
有一个现有的类(称之为A类),我想添加一些新字段。这些字段的类型为B.
查询将通过外部联接加入B.
所以它会像
public class A {
//... existing fields
private List<B> bList; // may use a Map rather than a list?
// etc.
}
public class B {
private int id; // primary key
private int type;
private String description;
// etc.
}
我在网络应用中使用它。在第一页上,我想返回一个“A”的列表,然后在B旁边放置链接。
例如:
LinktoRecordA1 - LinktoB1 LinktoB2 LinktoB3
LinktoRecordA2 - LinktoB1 LinktoB3
LinktoRecordA3 - LinktoB1 LinktoB2 LinktoB3
LinktoRecordA4
等
(注意:记录A4没有任何B的链接 - 因此上面提到的外部连接)
在“A”的初始提取中,我只想知道B记录存在,它的主要关键是将链接呈现给B详细记录。所以我的问题是,如何在不在“A”对象上创建完整填充的“B”列表的情况下执行此操作?
答案 0 :(得分:0)
关于你的评论:
How else should I do it? I think what I'm having trouble understading is
this- should I return a list of "A" objects with only minimal data
populated, or would should I create some kind of new object?
在您描述的情况下(当返回列表并且用户可以从中选择某些内容时),我注意到用户通常会选择一个或两个记录来查看更多详细信息。在这种情况下,您最终会返回一个完全填充的对象列表。
在这种情况下,我所做的只是选择对象标识符而不是完整对象。
所以你可以创建一个只包含这些数据的新类:
public class C {
private Integer idForA;
private List<Integer> listOfIdsForB = new ArrayList<Integer>();
//...
}
然后使用外部联接编写查询以返回A和B的标识符,并返回与此类似的结果:
IDtoRecordA1 | IDtoB1
IDtoRecordA1 | IDtoB2
IDtoRecordA1 | IDtoB3
IDtoRecordA2 | IDtoB1
IDtoRecordA2 | IDtoB3
IDtoRecordA3 | IDtoB1
IDtoRecordA3 | IDtoB2
IDtoRecordA3 | IDtoB3
IDtoRecordA4 | null
在此阶段,groupBy
标记的resultMap
属性可以方便地将结果转换为包含此内容的C
对象列表:
C1: IDtoRecordA1, [IDtoB1, IDtoB2, IDtoB3]
C2: IDtoRecordA2, [IDtoB1, IDtoB3]
C3: IDtoRecordA3, [IDtoB1, IDtoB2, IDtoB3]
C4: IDtoRecordA4, []
这在避免N + 1查询方面也非常有用。当您返回带有B列表的A对象时,您可能已经这样做了,但是如果您使用单独的查询来检索列表(即select
标签上的result
属性),那么我建议您使用查看iBatis Data Mapper开发人员指南中的“避免N + 1选择”部分,以最大限度地减少返回数据所需的查询次数。
底线是......
...如果您处理大量数据,然后返回完整加载的对象只是为了显示少量信息,可能有点过分。
..另一方面,如果你处理少量数据,引入另一个处理ID的类可能会使事情变得复杂,所以你也可以返回A的完整对象。和B(但当然要避免N + 1个查询)。