2015年12月15日 星期二

一對一單向FK關聯 (Hibernate3.x 二十五)

由CAR的CAR_ATTR_CAID欄位來關聯CAR_ATTR的PK

※準備工作

DROP TABLE CAR_ATTR PURGE;
DROP TABLE CAR PURGE;
    
CREATE TABLE CAR_ATTR (
    CAID NUMBER(5,0),
    COLOR VARCHAR2(20),
    CC NUMBER(3,0),
    CONSTRAINT CAR_ATTR_PK PRIMARY KEY(CAID)
);
    
CREATE TABLE CAR (
    CID NUMBER(5,0),
    NAME VARCHAR2(20),
    CAR_ATTR_CAID NUMBER(5,0),
    CONSTRAINT CAR_PK PRIMARY KEY(CID),
    CONSTRAINT CAR_FK FOREIGN KEY(CAR_ATTR_CAID) REFERENCES CAR_ATTR(CAID) ON DELETE CASCADE
);
    
CREATE SEQUENCE CAR_SEQ;
CREATE SEQUENCE CAR_ATTR_SEQ;


※XML設定

Car.hbm.xml

<class name="vo.Car" table="CAR">
    <id name="cid" type="java.lang.Integer">
        <column name="CID" />
        <generator class="sequence">
            <param name="sequence">CAR_SEQ</param>
        </generator>
    </id>
    
    <property name="name" type="java.lang.String">
        <column name="NAME" />
    </property>
    
    <many-to-one name="carAttr" class="vo.CarAttr" unique="true"
        column="CAR_ATTR_CAID" cascade="all" lazy="false" fetch="select" />
</class>

※many-to-one且unique="true"就是一對一了,主要在這裡設定和資料庫欄位的對應

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.java

public class Car {
    private Integer cid;
    private String name;
    private CarAttr carAttr;
    // setter/getter...
}

CarAttr.java

public class CarAttr {
    private Integer caid;
    private String color;
    private Integer cc;
    // setter/getter...
}

新增測試

CarAttr ca = new CarAttr();
// ca.setCaid(3350); // 如果不是sequence就在這塞PK
ca.setColor("藍4");
ca.setCc(540);
    
Car c = new Car();
c.setName("寶石傑4");
c.setCarAttr(ca);
    
s.save(c);
tx.commit();

※只要存Car就都會存起來了

修改測試

CarAttr ca = new CarAttr();
ca.setCaid(141); // 實務上須自行去資料庫撈出來
ca.setColor("藍5");
ca.setCc(550);
    
Car c = new Car();
c.setCid(121); // 實務上須自行去資料庫撈出來
c.setName("寶石傑5");
c.setCarAttr(ca);
    
s.update(c);
tx.commit();

※修改和刪除一樣,都一定要塞CarAttr的PK

查詢測試

Car car = (Car) s.get(Car.class, 122);
s.close();
System.out.println(car.getName());
System.out.println(car.getCarAttr().getColor());

※預設fetch是select,改成join是有用的

刪除測試

Car c = new Car();
c.setCid(123);
    
CarAttr ca = new CarAttr();
ca.setCaid(143);
    
c.setCarAttr(ca);
    
s.delete(c);
tx.commit();

※修改和刪除一樣,都一定要塞CarAttr的PK



※Annotation設定

Car.java

@Entity
@Table
public class Car {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "OOO")
    @SequenceGenerator(name = "OOO", sequenceName = "CAR_SEQ")
    private Integer cid;
    
    private String name;
    
    @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "CAR_ATTR_CAID", unique = true)
    @LazyToOne(value = LazyToOneOption.FALSE)
    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...
}

※增刪改查的測試只有一個地方不同,就是查詢時,預設不是select,是join,FetchType.LAZY和FetchType.EAGER當然也是有用的

沒有留言:

張貼留言