8.映射(4)(多對多)(hibernate筆記)

一般的設(shè)計中,多對多關(guān)聯(lián)映射需要一個中間表,hibernate會自動生成中間表,使用many-to-many標簽來表示多對多的關(guān)聯(lián)。在實體中,跟一對多一樣,也是用集合來表示。

一、單向多對多(工程hibernate_many2many_1

這里我們使用用戶和角色的例子,相關(guān)映射:

實體類映射.png
數(shù)據(jù)庫表映射.JPG

Role.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="cn.itcast.hibernate.Role" table="_role">
        <id name="id">
            <generator class="native"/>
        </id>
        <property name="name"/>
    </class>
</hibernate-mapping>

User.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.itcast.hibernate">
    <class name="User" table="_user">
        <id name="id">
            <generator class="native"/>
        </id>
        <property name="name"/>
        <set name="roles" table="_user_role">
            <key column="userid"></key>
            <many-to-many class="Role" column="roleid"></many-to-many>
        </set>
    </class>
</hibernate-mapping>

說明:可以看到多對多的情況時我們是在數(shù)據(jù)庫中生成一張表專門維護映射關(guān)系。

測試:
Many2ManyTest.java

package cn.itcast.hibernate;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.hibernate.Session;
import org.junit.Test;

public class Many2ManyTest {

    @Test
    public void testSave1(){
        Session session = null;
        try{
            session = HibernateUtils.getSession();
            session.beginTransaction();
            Role r1 = new Role();
            r1.setName("數(shù)據(jù)錄入人員");
            session.save(r1);
            
            Role r2 = new Role();
            r2.setName("商務(wù)主管");
            session.save(r2);
            
            Role r3 = new Role();
            r3.setName("大區(qū)經(jīng)理");
            session.save(r3);
            
            User u1 = new User();
            u1.setName("張三");
            Set u1Roles = new HashSet();
            u1Roles.add(r1);
            u1Roles.add(r2);
            u1.setRoles(u1Roles);
            
            User u2 = new User();
            u2.setName("李四");
            Set u2Roles = new HashSet();
            u2Roles.add(r1);
            u2Roles.add(r2);
            u2.setRoles(u2Roles);
            
            User u3 = new User();
            u3.setName("王五");
            Set u3Roles = new HashSet();
            u3Roles.add(r3);
            u3Roles.add(r3);
            u3.setRoles(u3Roles);
            
            session.save(u1);
            session.save(u2);
            session.save(u3);

            session.getTransaction().commit();
            
        }catch(Exception e){
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally{
            HibernateUtils.closeSession(session);
        }
    }
    
    @Test
    public void testLoad1(){
        Session session = null;
        try{
            session = HibernateUtils.getSession();
            session.beginTransaction();
            User user = (User) session.load(User.class, 1);
            System.out.println(user.getName());
            for(Iterator iter = user.getRoles().iterator(); iter.hasNext();){
                Role role = (Role) iter.next();
                System.out.println(role.getName());
            }
            
            session.getTransaction().commit();
            
        }catch(Exception e){
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally{
            HibernateUtils.closeSession(session);
        }
    }
}

說明:雖然我們生成了一個關(guān)系表,但是維護關(guān)系只是在User這邊進行維護,當(dāng)然我們也可以選擇在Role這邊維護。此時我們在存儲時應(yīng)該先將不維護關(guān)系的一方(這里是Role)存儲進去,然后再存儲User。同樣在查詢的時候也一樣,也是先查詢出User,然后再查出Role。

二、雙向多對多(工程hibernate_many2many_2

雙向關(guān)系只需要在單向情況中的Role對象中維護一個保持用戶的set集合即可。存儲不變。

實體類映射.png
數(shù)據(jù)庫表映射.JPG

Role.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="cn.itcast.hibernate.Role" table="_role">
        <id name="id">
            <generator class="native"/>
        </id>
        <property name="name"/>
        <set name="users">
            <key column="roleid" />
            <many-to-many class="cn.itcast.hibernate.User" column="userid"/>
        </set>
    </class>
</hibernate-mapping>

注意:中間表的字段名一定要相同。

測試:這里就不再細說了,和單向相比,這里我們就可以雙向存儲和查詢。同時我們也可以使用inverse屬性進行關(guān)系反轉(zhuǎn),只在一方維護關(guān)系,還有可以在set標簽中使用order-by屬性來進行排序:
<set name="users" table="_user_role" order-by="userid">。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容