1. 程式人生 > >Hibernate基於主鍵的單項,雙向多對多對映關係

Hibernate基於主鍵的單項,雙向多對多對映關係

今天我們來一起談論下hibernate的基於主鍵的單項,雙向多對多對映關係
首先多對多都是基於主鍵的,沒有基於外來鍵的說法
1.基於主鍵的單項多對多
這裡寫圖片描述
在這裡就是說中間stuobject是一張關係表,將兩張表的主鍵進行關聯,形成了多對多的關係
程式碼如下:

public class StuObject {
    private int stuobjectid;
    private String objectname;
    private StuObject(){}
    public StuObject(String objectname){
        this.objectname=objectname;
    }
    public int getStuobjectid() {
        return stuobjectid;
    }
    public void setStuobjectid(int stuobjectid) {
        this.stuobjectid = stuobjectid;
    }
    public String getObjectname() {
        return objectname;
    }
    public void setObjectname(String objectname) {
        this.objectname = objectname;
    }
}


public class YoungStu {
    private int stuid;
    private String youngname;
    private Set<StuObject
>
stuobject; public YoungStu(){ } public YoungStu(String youngname){ this.youngname=youngname; } public int getStuid() { return stuid; } public void setStuid(int stuid) { this.stuid = stuid; } public String getYoungname() { return youngname; } public void setYoungname(String youngname) { this.youngname = youngname; } public Set<StuObject
>
getStuobject() { return stuobject; } public void setStuobject(Set<StuObject> stuobject) { this.stuobject = stuobject; } } hibernate.cfg.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration> <!-- session:會話 當前呼叫者與資料庫之間的一個連線 factory:工廠 其他概念: struts2中的session是指當前使用者與伺服器之間的一個連線 --> <session-factory> <!-- 配置資料庫連線資訊 --> <property name="connection.driver_class">com.mysql.jdbc.Driver</property><!-- 資料庫驅動 --> <property name="connection.url">jdbc:mysql://localhost:3306/hibernate4</property><!--資料庫地址 --> <property name="connection.username">**</property><!-- 使用者名稱 --> <property name="connection.password">****</property><!-- 密碼 --> <!-- dialect資料庫方言:指明用什麼資料庫 driver_class指定的是引用的驅動 兩者不是一碼事 --> <!-- dialect:指連線什麼資料庫 connection.driver_class:連線資料庫所需要的驅動 --> <property name="dialect"> org.hibernate.dialect.MySQL5Dialect </property> <!-- 是否列印sql --> <property name="show_sql">true</property> <!-- 格式化sql語句 --> <property name="format_sql">true</property> <mapping resource="hibernatedemo1/pojo/stuobject.hbm.xml"></mapping> <mapping resource="hibernatedemo1/pojo/Youngstu.hbm.xml"></mapping> </session-factory> </hibernate-configuration> youngstu.hbm.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="hibernatedemo1.pojo.YoungStu" table="youngstu"> <!-- id標籤必須有 id:主鍵只是hibernate在操作資料庫表的時候的一個概念,並不要求此列也為資料庫規範意義上的主鍵 --> <!-- id標籤對應的是實體類的屬性,表中可以沒有主鍵--> <id name="stuid"> <!-- generator:主鍵生成策略 native:自增長(對映檔案生成策略為native,且表中相應的列設為自增) assigned:自定義(如果此列在資料庫中是主鍵的話,那麼程式在save時,必須保證此列對應的物件屬性有值) increment:由hibernate從資料庫中取出主鍵的最大值(每個session只取一次),以該值為基礎,每次增量為1,在記憶體 中生成主鍵 不依賴於底層的資料庫,因此可以跨資料庫 sequence:採用資料庫提供的sequence機制生成主鍵,需要資料庫支援sequence 所以:native和sequence都有各自的資料庫選型的侷限性 --> <generator class="increment"></generator> </id> <!--這裡的name必須和對映類裡的欄位名一致--> <property name="youngname"/> <!--這裡的name是你對映類裡的set的別名 後面是重新建立一個關係表--> <set name="stuobject" table="stuobject"> <!--**表示當前類對映到關係表stuobject中的列,這個column是table所指引的列名,不一定要和對映類裡的id名稱一樣**--> <key column="stuid"></key> <!--所對應的另一個表(與yongstu產生關係的一方) column是table所指引的列名,不一定要和對映類裡的id名稱一樣--> <many-to-many class="hibernatedemo1.pojo.StuObject" column="stuobjectid"></many-to-many> </set> </class> </hibernate-mapping> stuobject.hbm.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="hibernatedemo1.pojo.StuObject" table="object"> <!-- id標籤必須有 id:主鍵只是hibernate在操作資料庫表的時候的一個概念,並不要求此列也為資料庫規範意義上的主鍵 --> <!-- id標籤對應的是實體類的屬性,表中可以沒有主鍵--> <id name="stuobjectid"> <!-- generator:主鍵生成策略 native:自增長(對映檔案生成策略為native,且表中相應的列設為自增) assigned:自定義(如果此列在資料庫中是主鍵的話,那麼程式在save時,必須保證此列對應的物件屬性有值) increment:由hibernate從資料庫中取出主鍵的最大值(每個session只取一次),以該值為基礎,每次增量為1,在記憶體 中生成主鍵 不依賴於底層的資料庫,因此可以跨資料庫 sequence:採用資料庫提供的sequence機制生成主鍵,需要資料庫支援sequence 所以:native和sequence都有各自的資料庫選型的侷限性 --> <generator class="increment"></generator> </id> <property name="objectname"/> </class> </hibernate-mapping>

測試程式碼
HibernateUtil.java

public class HibernateUtil {
    private static final Configuration cfg;
    private static final SessionFactory sessionFactory;
    static{
        cfg = new Configuration().configure();
        ServiceRegistry registry = new StandardServiceRegistryBuilder()
        .applySettings(cfg.getProperties()).build();
        sessionFactory=cfg.buildSessionFactory(registry);
    }

    public static Session openSession(){
        return sessionFactory.openSession();
    }
}
Demo.java
//基於主鍵的單項多對多對映
    @Test
    public void fkmanytomanyTest(){
        Session session=HibernateUtil.openSession();
        Transaction tx=session.beginTransaction();
        YoungStu youngstu=new YoungStu("Align");
        session.saveOrUpdate(youngstu);
        youngstu.setStuobject(new HashSet());
        for(int i=0;i<5;i++){
            StuObject stuobject=new StuObject("高數"+i);
            youngstu.getStuobject().add(stuobject);
            session.saveOrUpdate(stuobject);
        }
        tx.commit();
        session.close();
    }

2.雙向多對多對映關係
這裡寫圖片描述
Role.java

public class Role {
    private int id;
    private String name;
    private Set<Function> function;
    public Role(){}
    public Role(String name){
        this.name=name;
    }
    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;
    }
    public Set<Function> getFunction() {
        return function;
    }
    public void setFunction(Set<Function> function) {
        this.function = function;
    }
}

Function.java

public class Function {
    private int funid;
    private String code;
    private String url;
    private Set<Role> role;
    public Function(){}
    public Function(String code,String url){
        this.code=code;
        this.url=url;
    }
    public int getFunid() {
        return funid;
    }
    public void setFunid(int funid) {
        this.funid = funid;
    }
    public String getCode() {
        return code;
    }
    public void setCode(String code) {
        this.code = code;
    }
    public String getUrl() {
        return url;
    }
    public void setUrl(String url) {
        this.url = url;
    }
    public Set<Role> getRole() {
        return role;
    }
    public void setRole(Set<Role> role) {
        this.role = role;
    }

}

role.hbm.xml

<hibernate-mapping>
    <class name="hibernatedemo1.pojo.Role" table="role">
        <id name="id">
            <generator class="increment"></generator>
        </id>   
        <property name="name"/>
        <set name="function" table="rolefunction">
            <key column="roleid"></key>
            <many-to-many class="hibernatedemo1.pojo.Function" column="funid"></many-to-many>
        </set>
    </class>
</hibernate-mapping>

function.hbm.xml

<hibernate-mapping>
    <class name="hibernatedemo1.pojo.Function" table="function">    
        <id name="funid">
            <generator class="increment"></generator>
        </id>   
        <property name="code"/>
        <property name="url"></property>
        <set name="role" table="rolefunction">
            <key column="funid"></key>
            <many-to-many class="hibernatedemo1.pojo.Role" column="roleid"></many-to-many>
        </set>
    </class>
</hibernate-mapping>

這兩個hbm.xml裡面要注意

<set name="function" table="rolefunction">
            <key column="roleid"></key>
            <many-to-many class="hibernatedemo1.pojo.Function" column="funid"></many-to-many>
        </set>


<!--這兩個裡面的column一定要一一對應,不能隨便-->


<set name="role" table="rolefunction">
            <key column="funid"></key>
            <many-to-many class="hibernatedemo1.pojo.Role" column="roleid"></many-to-many>
        </set>