1. 程式人生 > >Hibernate物件關聯對映

Hibernate物件關聯對映

物件關係對映(Object Relational Mapping,簡稱ORM)是一種為了解決面向物件與關係資料庫存在的互不匹配的現象的技術。

多對一單向關係對映:student-classes

public class Classes implements Serializable{
    private Integer cid;
    private String cname;
    private String ccode;
get/set方法省略

public class Student implements Serializable{
    private Integer sid;
    private
String sname; private Integer age; private String gender; private Date birthday; private Boolean ismarried; private Double wight; //班級物件的引用 private Classes cls; get/set方法省略

配置Classes.hbm.xml

<hibernate-mapping package="cn.gzsxt.test.many2one">
    <class name="Classes"
table="tb_classes"> <id name="cid"> <generator class="native" /> </id> <property name="cname" /> <property name="ccode" /> </class> </hibernate-mapping>

配置Student.hbm.xml

<hibernate-mapping package="cn.gzsxt.test.many2one"
> <class name="Student" table="tb_student"> <id name="sid"> <generator class="native" /> </id> <property name="sname" /> <property name="age" /> <property name="gender" /> <property name="birthday" /> <property name="ismarried" /> <property name="wight" /> <!-- 配置many-to-one name:班級物件的引用名 class:班級物件的類名 column:外來鍵名(引用班級物件對應的表) foreign-key:外來鍵的約束名 --> <many-to-one name="cls" class="Classes" column="cid" not-null="true" foreign-key="FK_STU_CLS"/> </class> </hibernate-mapping>

執行java檔案程式碼,生成表結構和資料

public class TestMany2One {
    Session session;
    Transaction transaction;
    @Before
    public void setUp() throws Exception {
        session = SessionFactoryUtils.getCurrentSession();
        transaction = session.getTransaction();
        transaction.begin();
    }
    @After
    public void tearDown() throws Exception {
        transaction.commit();
    }
    @Test
    public void createTable(){
        Configuration cfg = new Configuration().configure("/hibernate.cfg.xml");
        SchemaExport export = new SchemaExport(cfg);
        export.create(true,true);
    }
    @Test
    public void save() {
        Student bx = new Student(null, "benxi", 26, "女", new Date(System.currentTimeMillis()), false, 47.5);
        Student zf = new Student(null, "zhangfeng", 22, "男", new Date(System.currentTimeMillis()), false, 77.5);
        Student dhy = new Student(null, "杜紅豔", 25, "女", new Date(System.currentTimeMillis()), false, 42.5);

        Classes java = new Classes(null,"java","java0706");
        Classes php = new Classes(null,"php","java0710");

        //分班(學生選擇班級)-建立物件關係。學生選擇班級
        bx.setCls(java);
        zf.setCls(java);
        dhy.setCls(php);

        /*儲存到資料庫
         * 先儲存多的一方,再儲存一的一方
         * 先儲存一的一方再儲存多的一方會發出多餘的update或者執行不通過
         */
        session.save(java);
        session.save(php);
        session.save(bx);
        session.save(zf);
        session.save(dhy);

    }

    //查詢學生資訊和班級資訊
    @Test
    public void qeury(){
        Student stu = (Student) session.get(Student.class, 1);
        System.out.println(stu);
        System.out.println(stu.getCls().getCname());
    }

}

一對多單向關係對映:classes-Student

classes檔案

public class Classes implements Serializable{
    private Integer cid;
    private String cname;
    private String ccode;
    //班級中有多個學生
    private Set<Student> stuset = new HashSet<>();

Student檔案

public class Student implements Serializable{
    private Integer sid;
    private String sname;
    private Integer age;
    private String gender;
    private Date birthday;
    private Boolean ismarried;
    private Double wight;

classes.hbm.xml檔案中,改變如下:

<class name="Classes" table="tb_classes">
    <id name="cid"> <generator class="native" /> </id>
    <property name="cname" />
    <property name="ccode" />
    <!-- 配置one to many -->
    <set name="stuset">
        <!-- 在學生表(多的一方)加上外來鍵 -->
        <key column="c_id"/>
        <one-to-many class="Student"/>
    </set>
</class>
student.hbm.xml檔案,改變如下:
<class name="Student" table="tb_student">
        <id name="sid"> <generator class="native" /> </id>
        <property name="sname" />
        <property name="age" />
        <property name="gender" />
        <property name="birthday" />
        <property name="ismarried" />
        <property name="wight" />
        相對於前面,把多對一配置刪除
    </class>

操作的java檔案;

//分班(學生選擇班級)-建立物件關係。班級選擇學生
java.getStuset().add(bx);
java.getStuset().add(zf);
php.getStuset().add(dhy);

多對一雙向關係對映:Student-Classes

在student和classes檔案中,都加入物件引用。
在*.hbm.xml檔案中也配置對應的內容
然後在java檔案中就可以實現雙向選擇

/*分班(學生選擇班級)-建立物件關係
* 預設情況下,一的一方處於主動(主動權)
* 在學生選擇班級,班級也選擇學生多的情況下,
* 班級選擇生效
*/
bx.setCls(java);
zf.setCls(java);
dhy.setCls(php);
java.getStuset().add(dhy);
php.getStuset().add(bx);

設定Student為主動權:

<!-- 如果需要讓多的一方主動,一的一方被動
    需要配置inverse屬性-控制反轉,只能配置在集合中
    true - 放棄
    false - 不放棄 -->
<set name="stuset" inverse="true">
    <key column="cid"/>
    <one-to-many class="Student"/>
</set>

其他物件關聯對映方式:

一對多(單向):
只寫xml檔案配置

<class name="Classes" table="tb_classes">
    <id name="cid"> <generator class="native" /> </id>
省略。。。
    <!-- 配置one to many -->
    <set name="stuset">
        <!-- 在學生表(多的一方)加上外來鍵 -->
        <key column="c_id"/>
        <one-to-many class="Student"/>
    </set>  
</class>
<class name="Student" table="tb_student">
    <id name="sid"> <generator class="native" /> </id>
    <property name="sname" />
省略。。。
</class>

多對一(單向):

<class name="Student" table="tb_student">
    <id name="sid"> <generator class="native" /> </id>
    省略...
    <!-- 配置many-to-one
        name:班級物件的引用名
        class:班級物件的類名
        column:外來鍵名(引用班級物件對應的表)
        foreign-key:外來鍵的約束名,可以隨便起
     -->
    <many-to-one name="cls" class="Classes" column="cid" not-null="true" foreign-key="FK_STU_CLS"/>
</class>
<class name="Classes" table="tb_classes">
    <id name="cid"> <generator class="native" /> </id>
    <property name="cname" />
    <property name="ccode" />
</class>

多對一(雙向):

<class name="Student" table="tb_student">
    <id name="sid"> <generator class="native" /> </id>
    省略...   
    <!-- 配置many-to-one
    name:班級物件的引用名
    class:班級物件的類名
    column:外來鍵名(引用班級物件對應的表)
    foreign-key:外來鍵的約束名
    級聯操作cascade:當操作一個物件時,此物件引用了其他物件,則其他物件會先同樣的操作
     save-upade 級聯儲存更新
     delete  級聯刪除
     none   不操作
-->
    <many-to-one cascade="save-update" name="cls" class="Classes" column="cid" not-null="true" foreign-key="FK_STU_CLS"/>
</class>
<class name="Classes" table="tb_classes">
    <id name="cid"> <generator class="native" /> </id>
    <property name="cname" />
    <property name="ccode" />
    <!-- 如果需要讓多的一方主動,一的一方被動
          需要配置inverse屬性-控制反轉,只能配置在集合中
         true - 放棄
          false - 不放棄
        由多的一方管理一的一方比較有效-->
    <set name="stuset" inverse="true">
        <key column="cid"/>
        <one-to-many class="Student"/>
    </set>
</class>

一對一(唯一外來鍵):

<class name="Student" table="tb_student">
    <id name="sid"> <generator class="native" /> </id>
    省略。。。
    <!-- 配置many to one
        保持外來鍵唯一性:unique="true"
     -->
    <many-to-one name="stup" cascade="save-update" class="StudentPager" column="p_id" unique="true"/>
</class>
<class name="StudentPager" table="tb_StudentPager">
    <id name="pid" column="p_id"> <generator class="native" /> </id>
    <property name="pname" />
    <one-to-one name="stu" class="Student"/>
</class>

一對一(主鍵關聯):

<class name="Student" table="tb_student">
    <id name="sid"> <generator class="native" /> </id>
    省略。。。
    <one-to-one name="sp" class="StudentPager" constrained="true"/>

</class>
<class name="StudentPager" table="tb_StudentPager">
    <id name="pid" column="p_id"> 
        <generator class="Student">
            <param name="stu">sp</param>
    </generator>
     </id>
    <property name="pname" />
    </class>

多對多(第一種方式):
兩個物件,三張表。建立中間表,儲存對應關係

<class name="Student" table="tb_student">
    <id name="sid" type="integer"> <generator class="native" /> </id>
    省略。。。
    <!-- 配置many to many
        table:中間表
        key:存放Student的id,
        many-to-many:存放course物件和表中欄位名
     -->
     <set name="courseset" table="tb_stu_sc">
         <key column="sid"/>
         <many-to-many class="Course" column="cid"/>
     </set>
</class>
<class name="Course" table="tb_course">
    <id name="cid" type="integer"> <generator class="native" /> </id>
    <property name="cname" />
     <set name="stuset" table="tb_stu_sc" inverse="true">
         <key column="cid"/>
         <many-to-many class="Student" column="sid"/>
     </set>
</class>

多對多(第二種方式):
三個物件,三張表。中間物件和表儲存對應關係

<class name="Course" table="tb_course">
    <id name="cid" type="integer"> <generator class="native" /> </id>
    <property name="cname" />
    <set name="stucour" inverse="true">
         <key column="c_id"/>
         <one-to-many class="StudentCourse"/>
     </set>
</class>
<class name="Student" table="tb_student">
    <id name="sid" type="integer"> <generator class="native" /> </id>
    省略。。。
    <!-- 配置many to many
        table:中間表
        key:存放Student的id,
        many-to-many:存放course物件和表中欄位名
     -->
     <set name="stucour" inverse="true">
         <key column="s_id"/>
         <one-to-many class="StudentCourse"/>
     </set>
</class>
<class name="StudentCourse" table="tb_studentcourse">
    <id name="scid" type="integer"> <generator class="native" /> </id>
    省略。。。
    <!-- 配置兩個多對一 -->
    <many-to-one name="stu" class="Student" column="s_id"></many-to-one>
    <many-to-one name="course" class="Course" column="c_id"></many-to-one>
</class>