※XML設定
※一對一單向PK關聯
準備工作
DROP TABLE CAR PURGE; DROP TABLE CAR_ATTR PURGE; CREATE TABLE CAR ( CID NUMBER(5,0), NAME VARCHAR2(20), CONSTRAINT CAR_PK PRIMARY KEY (CID) ); CREATE TABLE CAR_ATTR ( CAID NUMBER(5,0), COLOR VARCHAR2(20), CC NUMBER(3,0), CONSTRAINT CAR_ATTR_PK PRIMARY KEY (CAID) ); CREATE SEQUENCE CAR_ATTR_SEQ;
※和一對一雙向PK關聯一樣,只是多個自動產生PK的sequence
hibernate.cfg.xml
要增加xml連到hbm.xml的設定<mapping resource="vo/Car.hbm.xml" /> <mapping resource="vo/CarAttr.hbm.xml" />
Car.hbm.xml
<class name="vo.Car" table="CAR"> <id name="cid" type="java.lang.Integer"> <column name="CID" /> <generator class="foreign"> <param name="property">carAttr</param> </generator> </id> <property name="name" type="java.lang.String"> <column name="NAME" /> </property> <one-to-one name="carAttr" class="vo.CarAttr" constrained="true" /> </class>
※PK交給CarAttr設定
CarAttr.hbm.xml
<class name="vo.CarAttr" table="CAR_ATTR"> <id name="caid" type="java.lang.Integer"> <column name="CAID" /> <generator class="sequence"> <param name="sequence">CAR_ATTR_SEQ</param> </generator> </id> <property name="color" type="java.lang.String"> <column name="COLOR" /> </property> <property name="cc" type="java.lang.Integer"> <column name="CC" /> </property> </class>
※因為是單向,所以不用關聯到Car
Car.java
public class Car { private Integer cid; private String name; private CarAttr carAttr; //setter/getter... }
※要關聯到CarAttr,所以要寫
CarAttr.java
public class CarAttr { private Integer caid; private String color; private Integer cc; //setter/getter... }
※不用關聯到Car,所以不用寫
新增測試
Session s = HibernateUtil2.getSession(); Transaction tx = s.beginTransaction(); try { CarAttr ca = new CarAttr(); // ca.setCaid(3350);// 如果不是sequence就在這塞PK ca.setColor("藍2"); ca.setCc(530); Car c = new Car(); c.setName("寶石傑2"); c.setCarAttr(ca); s.save(c); tx.commit(); } catch (Exception e) { tx.rollback(); System.err.println("例外錯誤!"); e.printStackTrace(); } finally { if (s.isOpen()) { s.close(); } }
※只要save(c)就可以了,我試過沒有cascade="all"也可以
修改測試
CarAttr ca = new CarAttr(); ca.setCaid(103); // 實務上須自行去資料庫撈出來 ca.setColor("藍5"); ca.setCc(530); Car c = new Car(); c.setName("寶石傑5"); c.setCarAttr(ca); c.setCid(ca.getCaid()); s.update(c); // s.update(ca);// 如果在Car.hbm.xml加cascade="all" 可不用這行 tx.commit();
※要注意cascade的差異
查詢測試
Car car = (Car) s.get(Car.class, 103); s.close(); System.out.println(car.getName()); System.out.println(car.getCarAttr().getColor());
※需在Car.hbm.xml加lazy="false",否則會出Session is close的錯
※資料庫撈不到也會出Session is close的錯
※fetch="join"無效,一直都是select
※因為是單向,查Car肯定只會查到自己的,所以不用測
刪除測試
Car c = new Car(); c.setCid(105); CarAttr ca = new CarAttr(); ca.setCaid(c.getCid()); c.setCarAttr(ca); s.delete(c); // 需在Car.hbm.xml加cascade="all",不然只會刪除Car tx.commit();
※要注意cascade的差異
※Annotation設定
hibernate.cfg.xml
<mapping class="vo.Car" /> <mapping class="vo.CarAttr" />
Car.java
@Entity @Table public class Car { @Id @GenericGenerator(name = "xxx", strategy = "foreign", parameters = { @Parameter(name = "property", value = "carAttr") }) @GeneratedValue(generator = "xxx") private Integer cid; private String name; @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER) @PrimaryKeyJoinColumn private CarAttr carAttr; //setter/getter... }
CarAttr.java
@Entity @Table(name = "CAR_ATTR") public class CarAttr { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "XXX") @SequenceGenerator(name = "XXX", sequenceName = "CAR_ATTR_SEQ") private Integer caid; private String color; private Integer cc; //setter/getter... }
※增刪改查的測試只有一個地方不同,那就是查詢Car時,FetchType.LAZY和FetchType.EAGER(也就是select和join)都有用了,這點居然不同步,很奇怪
沒有留言:
張貼留言