Hibernate實現雙向一對一關係,很黃很暴力的方法

3張表
A表 AID(主鍵) bID cID其他屬性略。。。
B表 BID(主鍵) aID cID其他屬性略。。。
C表 CID(主鍵) aID bID其他屬性略。。。 有點類似關聯的表,但又不是

數據庫裏未設外鍵
暫且不討論這張表設計的好壞(數據庫表已經設計好了,改動表結構按目前項目來說有點複雜)
hibernate是工具,是拿來用的,所以在項目中是它適應項目,不是項目去適應他。
如果一個項目被工具所累,那是非常糟糕的事情。

主鍵是通過hibernate自動生成UUID
在A表中,如果它和B表沒有關係,則bID設置爲-1
因此要求:
能通過任意一張表對其他表一起來查詢
但不能相互修改

通常PO中是這樣的

public class A {
private String aID;
private B b;
private C c;
...
public void setAID(String aID); {
this.aID = aID;
}
public void setB(B b); {
this.b = b;
}
public void setC(C c); {
this.c = c;
}
public String getAID(); {
return aID;
}
public B getB(); {
return b;
}
public C getC(); {
return c;
}
...
}



public class B {
private String bID;
private A a;
private C c;
...
public void setBID(String bID); {
this.bID = bID;
}
public void setA(A a); {
this.a = a;
}
public void setC(C c); {
this.c = c;
}
public String getBID(); {
return aID;
}
public A getA(); {
return b;
}
public C getC(); {
return c;
}
...
}


配置文件裏如下

<hibernate-mapping>
<class name="com.pojo.A" table="A">
<id name="aID" type="java.lang.String">
<column name="AID" length="32" />
<generator class="assigned" />
</id>
...
<one-to-one name="b" class="com.pojo.B"
property-ref="a" />
</class>
</hibernate-mapping>



<hibernate-mapping>
<class name="com.pojo.B" table="B">
<id name="bID" type="java.lang.String">
<column name="BID" length="32" />
<generator class="assigned" />
</id>
...
<many-to-one name="a" class="com.A" fetch="select"
column="aID" cascade="none" unique="true" />
</class>
</hibernate-mapping>

但是這樣設計的話,如果要對錶A解除和表B的關聯,同時把表A中的bID設置爲-1,必定要通過B對象的實體進行操作,但問題是實體B中的BID由UUID自動生成了,這樣會產生類型錯誤

所以我對B.hbm.xml進行了修改

<hibernate-mapping>
<class name="com.pojo.B" table="B">
<id name="bID" type="java.lang.String">
<column name="BID" length="32" />
<generator class="assigned" />
</id>
...
<many-to-one name="a" class="com.A" fetch="select"
column="aID" cascade="none" unique="true" update="false" insert="false" />
</class>
</hibernate-mapping>



update,insert:指定對應的字段是否在用於UPDATE 和/或 INSERT的SQL語句中包含。如果二者都是false,則這是一個純粹的“外源性(derived)”關聯,它的值是通過映射到同一個(或多個)字段的某些其他屬性得到的,或者通過trigger(除法器),或者是其他程序(可選 - 默認爲 true)

這裏加入update="false" insert="false"。打個比方,對錶A進行修改和插入,不會對A表中的bID字段進行影響,具體你可以查看HQL語句。
但是這裏我們要對A表的bID進行修改,而這樣設置的話,bID是無法修改的

===============================
想了N種解決方案,也嘗試了N種,都不是很滿意,最後的方法可能會讓您很吃驚,這也是我說很黃很暴力的原因 :oops:
PO修改如下

public class A {
private String aID;
private B b;
private C c;
private String bID;
private String cID;
...
public void setAID(String aID); {
this.aID = aID;
}
public void setB(B b); {
this.b = b;
}
public void setC(C c); {
this.c = c;
}
public String getAID(); {
return aID;
}
public B getB(); {
return b;
}
public C getC(); {
return c;
}

public void setBID(String bID); {
this.bID = bID;
}
public String getBID(); {
return bID;
}
public void setCID(String cID); {
this.cID = cID;
}
public String getCID(); {
return cID;
}
...
}

B.java省略

配置文件修改如下

<hibernate-mapping>
<class name="com.pojo.A" table="A">
<id name="aID" type="java.lang.String">
<column name="AID" length="32" />
<generator class="assigned" />
</id>
...
<property name="bID" type="java.lang.String">
<column name="bID" length="32" />
</property>
<property name="cID" type="java.lang.String">
<column name="cID" length="32" />
</property>
<one-to-one name="b" class="com.pojo.B"
property-ref="a" />
</class>
</hibernate-mapping>

這樣的話,要對A表中的bID進行操作的話,就不用通過B實體對象進行操作了。
而且也符合預先的所有要求,查可以通過可自對象互相關聯,各自刪改,不會對其他表產生影響
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章