Java 在SpringHibernate项目中,初始化实体集合(POJO)的正确方法是什么?
我有一个POJO类,比如Foo,它有一组其他实体实例,比如bar。 此外,对于这样的项目还有标准的杂项类:Foo和Bar的service和dao 我希望BarService获得与某些Foo关联的Bar实例集。现在我有了下面的代码,我认为它在概念上是不好的Java 在SpringHibernate项目中,初始化实体集合(POJO)的正确方法是什么?,java,hibernate,spring,architecture,collections,Java,Hibernate,Spring,Architecture,Collections,我有一个POJO类,比如Foo,它有一组其他实体实例,比如bar。 此外,对于这样的项目还有标准的杂项类:Foo和Bar的service和dao 我希望BarService获得与某些Foo关联的Bar实例集。现在我有了下面的代码,我认为它在概念上是不好的 public class Foo { Set<Bar> bars; public Set<Bar> getBars() { if (bars == null) retur
public class Foo {
Set<Bar> bars;
public Set<Bar> getBars() {
if (bars == null)
return ( bars = new HashSet() );
return bars;
}
}
公开课Foo{
设置横杆;
公共设置getbar(){
如果(条==null)
返回(bar=newhashset());
返回杆;
}
}
公共类BarServiceImpl{
公共列表getListOfBars(Foo-Foo){
返回新的ArrayList(foo.getBars());
}
}
3个问题:
在哪里初始化Foo的集合更好?
哪些特定的集合和列表更适合此类目的?
我当前的实现存在哪些概念性问题,以及如何做得更好
提前感谢。我倾向于在服务层初始化集合,在那里我也保留事务处理。因此,我可以在我的BaseDAO中使用一个方法,通过将集合名称传递到要立即获取(初始化)的方法中,使我可以使用反射初始化项目中任何实体的任何集合: 一个更详细的例子:
您的实体可以是一组带有getter和setter的简单字段。您需要注意的是如何关联对象和填充对象的方法。
ORMAPI提供了使用对象而不是SQL的自由。您应该小心选择何时初始化对象的字段。例如,如果您有一个对象person,其中包括姓名、年龄、联系人集合和访问过的城市。在您感兴趣的人的姓名和年龄而不是联系人和城市的情况下,您应该只加载姓名和年龄。这意味着联系人和城市应该延迟加载。
如果对联系人感兴趣,则只加载联系人,而不加载整个person对象或通过person对象。您可能希望仅使用Dao/服务和显式定义方法加载联系人集,以加载对象的特定方面(使用反向关联)。
有关hibernate的一些最佳实践,请访问。 更新: 1) 实体不会自行填充。一种流行的方法是使用DAO来完成这项工作。你的实体可能很简单
public class Foo {
private Set<Bar> bar=new HashSet<Bar>();
public Set<Bar> getBar {
return bar;
}
public void setBar(Bar bar) {
this.bar = bar;
}
}
公共类Foo{
private Set bar=new HashSet();
公共设置栏{
返回杆;
}
公共空间立根杆(杆){
这个.bar=bar;
}
}
2) 您可以在另一层(也称为服务层)中管理事务
在哪里初始化Foo的集合更好
大多数时候,我在声明集合时初始化集合,这是Hibernate建议的。引用文件:
Hibernate需要持久的
不能声明集合值字段
作为接口类型。例如:
public class Product {
private String serialNumber;
private Set parts = new HashSet();
public Set getParts() { return parts; }
void setParts(Set parts) { this.parts = parts; }
public String getSerialNumber() { return serialNumber; }
void setSerialNumber(String sn) { serialNumber = sn; }
}
实际接口可能是
java.util.Set
,
java.util.Collection
,
java.util.List
,java.util.Map
,
java.util.SortedSet
,
java.util.SortedMap
或任何您需要的
喜欢(“任何你喜欢的”意思就是你
必须编写一个实现
属于
org.hibernate.usertype.UserCollectionType
)
注意实例变量是如何定义的
已使用的实例初始化
HashSet
。这是最好的方法
初始化集合值
新实例化的
(非持久性)实例。当你
通过以下方式使实例持久化
例如,调用persist()
,
Hibernate实际上将取代
HashSet
的实例
Hibernate自己的
设置
如果将其保留为空是您业务的一部分,我的建议是使用(通用)链接管理方法初始化它:
public class Foo {
...
private Set<Bar> bars;
...
public void addBar(Bar bar) {
if (this.bars == null) {
this.bars = new HashSet<Bar>();
}
this.bars.add(bar);
}
}
公共类Foo{
...
私人酒吧;
...
公共无效添加栏(栏){
如果(this.bar==null){
this.bar=新的HashSet();
}
此.bar.add(bar);
}
}
哪些特定的集合和列表更适合此类目的
这完全取决于您需要的语义。集合
不允许重复,而列表
允许重复并引入位置索引
我当前的实现存在哪些概念性问题,以及如何做得更好
- 如果此时集合假定为
,则将其设为null
李>null
- 为什么不直接调用
foo.getbar()
- 为什么要转换集合
有用的代码片段,我肯定会在我未来的项目中使用这种方法。但现在我正在做一个非常小的自学项目,春季冬眠之王hello world,所以就目前而言,这对我来说非常复杂。不管怎样,谢谢你,谢谢。所以,如果我理解正确的话,我必须在DAO中定义方法,它将以用户ID作为参数,并执行hibernate查询来加载所需的方面?对吧?没错。当您进一步了解它时,请阅读有关如何加载特定字段集、延迟加载、反向关联、条件和HQL的内容。我发现HQL非常有效地控制对象中加载的内容。根据具体情况,您可以选择加载哪些字段,从而避免不必要的SQL联接或n+1问题。实现jsf视图层需要转换集合,但如果我想将datatable与set一起使用,我必须实现自定义datamodel。至于“为什么不调用foo.getBars()?”这不坏吗,我的视图层将与实体直接通信,而不是与它的服务通信?至于在申报时的初始化:不是吗
public class Foo {
private Set<Bar> bar=new HashSet<Bar>();
public Set<Bar> getBar {
return bar;
}
public void setBar(Bar bar) {
this.bar = bar;
}
}
public class Product {
private String serialNumber;
private Set parts = new HashSet();
public Set getParts() { return parts; }
void setParts(Set parts) { this.parts = parts; }
public String getSerialNumber() { return serialNumber; }
void setSerialNumber(String sn) { serialNumber = sn; }
}
public class Foo {
...
private Set<Bar> bars;
...
public void addBar(Bar bar) {
if (this.bars == null) {
this.bars = new HashSet<Bar>();
}
this.bars.add(bar);
}
}