1. 程式人生 > >(11)對映繼承關係二之每個類對應一張表(@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)

(11)對映繼承關係二之每個類對應一張表(@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)

這種策略支援雙向的一對多關聯,這裡不支援IDENTITY生成器策略。因為存在多型查詢,所以id在繼承關係的表中必須是唯一的。這就意味著不能用AUTO和IDENTITY生成器。
在mysql中,只能用生成表id來使得多個表的id保持不同。因為父類中含有共同的屬性,簡單來講id同,就在父表中,所以子表不用再寫生成表了。在實體中,每個表都含有父類及子類特有的屬性欄位。
person類

@Entity
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)//繼承策略是每個類層次結構對映一張表
@TableGenerator(
name="t_gen"
,//(requested)A unique generator name that can be referenced by one or more classes to be the generator for id values. table="t_gen_table",//Name of table that stores the generated id values. pkColumnName = "t_key",//pk列名 valueColumnName = "t_value",//pk值列名 pkColumnValue="person_pk",//pk列值 initialValue=1, allocationSize=1
/* * 在這種方式多型查詢中,不能確定是哪個子類的,所以學生、教師的id不能相同。根據多型的測試結果,也能看出id不能相同,所以mysql不嫩用自動生成策略 * 用一個id生成表,來確定插入時 的id是什麼 */ ) public class Person { private int id; private String name; @Id @GeneratedValue(generator="t_gen",strategy=GenerationType.TABLE) public int getId() { return id; } public
void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }

student 類繼承person類

@Entity

public class student extends Person {


    private int score;

    public int getScore() {
        return score;
    }

    public void setScore(int score) {
        this.score = score;
    }   
}

Test
在利用多型查詢中,是將所有的表聯合起來,組合成所有的類公用一張表的形式

@Test
    public void testSave() {
        student s=new student();
        s.setName("s1");
        s.setScore(80);

        teacher t=new teacher();
        t.setName("t1");
        t.setTitle("高階");

        Session session=sf.getCurrentSession();
        session.beginTransaction();
        session.save(s);
        session.save(t);
        session.getTransaction().commit();


    }

    @Test
    public void testGet() {
        testSave();

        Session session=sf.getCurrentSession();
        session.beginTransaction();
        //student s=(student) session.get(student.class, 1);
        /*
         * 指定學生表,則會輸出學生表的資訊
         select
        student0_.id as id0_0_,
        student0_.name as name0_0_,
        student0_.score as score2_0_ 
    from
        student student0_ 
    where
        student0_.id=?
         */

        //使用多型:
        Person p=(Person) session.get(Person.class, 2);
        /*
         *  
        select
        person0_.id as id0_0_,
        person0_.name as name0_0_,
        person0_.title as title1_0_,
        person0_.score as score2_0_,
        person0_.clazz_ as clazz_0_ 
    from
        ( select  id, null as title, name,null as score,   0 as clazz_ from Person 
          union
          select id, title,  name,null as score, 1 as clazz_  from   teacher 
          union 
          select id,  null as title, name, score,   2 as clazz_   from  student   
       ) person0_ 
where
    person0_.id=?
       union用於合併兩個或者多個select語句的結果集,並消去重複行。
       union內部的select語句必須有相同數目的列,列也必須有相似的資料型別
           上面的大from語句相當於將子表資料合併成了single.type的形式。
           再根據id確定是哪個子類的。


         */
        session.getTransaction().commit();



    }