※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)都有用了,這點居然不同步,很奇怪
沒有留言:
張貼留言