我很快就会进入休眠状态,你很快就会看到。如果这个问题有一个简单的答案我很抱歉,但我对所有的术语都不太熟悉,很容易找到它。
假设我有一个基类“A”和一个子类“B”,我用Hibernate映射,也许使用每个子类策略的表。基类不是抽象的。所有的B都是As,但不是所有的B都是。这反映在数据库中,表B引用表A。
好的,现在假设我有一个显示A对象列表的某种程序。用户可以选择任何A对象并进入屏幕进行修改......但是,如果A对象也是B,则屏幕将允许用户修改B而不是A。
我如何处理这个问题?
注意:我不是在询问如何确定对象是什么类。我问的是如何让hibernate返回一个正确类的对象列表。
答案 0 :(得分:6)
我再次为这个问题道歉。我对hibernate的工作原理感到非常惊讶,这真的很酷。我不认为它会自动完成所有这些,我甚至不确定我想要问的是什么。当我回复评论时,我开始在脑海中改进这个问题,然后能够找到我想要的答案。感谢所有帮助过的人。
答案是:hibernate会自动执行此操作。
假设您的数据库表A中有一个主键“id”,另一个表B有一个名为“a_id”的主键,它引用了表A.
所以你创建了以下类(缩写):
public class A {
private String aProperty;
// ... getter and setter, etc
{
public class B extends A {
private String bProperty;
// ... getter and setter, etc
}
然后像这样映射它们:
<hibernate-mapping>
<class name="A" table="a" catalog="testokdelete">
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="identity" />
</id>
<property name="aProperty" column="a_property"/>
<joined-subclass name="B" table="b">
<key column="a_id"/>
<property name="bProperty" column="b_property"/>
</joined-subclass>
</class>
</hibernate-mapping>
您可以使用简单的“from A”查询返回A和B对象,如下面的代码所示:
Query query = session.createQuery("from A");
List<Object> objects = query.list();
for (Object object: objects) {
System.out.print("A property: ");
System.out.print(((A)object).getAProperty());
System.out.print(", B property: ");
System.out.println( (object.getClass() == B.class) ? ((B)object).getBProperty() : "not a B");
}
所有这一切都是使用“来自A”的查询返回一个对象列表,然后遍历它们从A类中打印出aProperty,如果类是B类,则从我们的B类中打印出bProperty。 / p>
在这种情况下,hibernate查询是自动多态的,并在适当的时候给你一个B对象。
答案 1 :(得分:2)
您可以使用带有instanceof的RTTI,但这不是面向对象的。
相反,为基类A
提供一个方法,该方法与B
的额外内容有关,例如A
是Customer
还是B
是PreferredCustomer
,方法可能是isPreferredCustomer()
。
在A
中,方法返回false,在B
中返回true。
重要的是要注意,我们不是在询问一个物体是否属于某一类;我们问一个商业问题,问对象是否可以做某事。这是一个微妙但重要的区别。
特别是,这意味着只要每个子类真实地回答了问题Customer
,就可以在何时以及如果添加更多isPreferredCustomer()
子类时更改下面的代码。
在您的代码中:
if( a.isPreferredCustomer() ) {
showPreferredCustomerPage( a) ;
else {
show CustomerPage(a);
}
您可能认为给Customer
showPage()
方法提供更好的方法,但这会使您的模型与您的观点紧密联系。
相反,您将上面的代码放在某个ViewDispatcher
类中,该类可以与Customer及其子类正交。
例如,您可能有几个ViewDispatcher
子类,其中一些关注PreferredCustomer
s,另一些关注{{1}}。
答案 2 :(得分:1)
好吧我会假设您已正确映射您的类。如果你这样做了,你应该能够做到以下几点,我想:
public List<A> getAllClassA(){
Session session = HibernateUtil.getSession();
Criteria criteria = session.createCriteria(A.class);
List<A> ret = criteria.list();
return ret;
}
如果你不熟悉Criteria,它很容易上手。这段代码将从数据库中检索出A类的所有对象。如果你已正确映射它,我认为Hibernate也将维护你A对象的B属性,如果它们实际上是B对象(对不起,如果那令人困惑)。
如果您正在寻找或者您是否需要HibernateUtil的代码,请告诉我。