many-to-many

多对多关系映射,老师举得例子是用户和角色。

一个用户可以有多种角色

一个角色可以分配给多个用户

单从一边看,都是一对多的关系,但是放在一起就是多对多了.看代码吧。

单向关系:user一方持有Role一方的引用

Role.java

package com.ahuzl.hibernate;
public class Role {
    private int id;
    private String name;
。。。省略 get set方法
}

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 package="com.ahuzl.hibernate">
    <class name="Role" table="t_role">
        <id name="id" column="role_id">
            <generator class="native"/>
        </id>
        <property name="name" column="role_name"/>
    </class> 
</hibernate-mapping>

User.java

package com.ahuzl.hibernate;
import java.util.Set;
public class User {
    private int id;
    private String name;
    private Set role;
。。。省略 get set方法
}

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>
    <class name="com.ahuzl.hibernate.User" table="t_user" >
        <id name="id" column="user_id">
            <generator class="native"/>
        </id>
        <property name="name" column="user_name"/>
        <set name="role" table="t_user_role">
            <key column="user_id"/>
            <many-to-many class="com.ahuzl.hibernate.Role" column="role_id"/>
        </set>
    </class> 
</hibernate-mapping>

特别的地方就在这里了,table="t_user_role"会生成一个中间表,表中的字段为<set></set>

标签中配置的字段。

<keycolumn="user_id"/>:来自自己对象内部的属性

<many-to-manyclass="com.ahuzl.hibernate.Role"column="role_id"/>:来自其他对象的属性,所以要写清楚对象的类名

保存

public class Many2ManyTest extends TestCase {
    public void testSave(){
        Session session = null;
        try{
            session = HibernateUtils.getSession();
            session.beginTransaction();
            //保存三个角色,技术者,reader,manager
            Role role1 = new Role();
            role1.setName("技術者");
            session.save(role1);

            Role role2 = new Role();
            role2.setName("リーダー");
            session.save(role2);

            Role role3 = new Role();
            role3.setName("マネージャ");
            session.save(role3);
            
            User user1 = new User();
            user1.setName("陣野");
            Set roleOfUser1 = new HashSet();
            roleOfUser1.add(role1);
            user1.setRole(roleOfUser1);
            session.save(user1);
            //保存用户,并给其分配相应的权限
            User user2 = new User();
            user2.setName("幸島");
            Set roleOfUser2 = new HashSet();
            roleOfUser2.add(role1);
            roleOfUser2.add(role2);
            user2.setRole(roleOfUser2);
            session.save(user2);

            User user3 = new User();
            user3.setName("桑田");
            Set roleOfUser3 = new HashSet();
            roleOfUser3.add(role3);
            user3.setRole(roleOfUser3);
            session.save(user3);

            session.getTransaction().commit();
        }catch(Exception e){
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally{
             if (session != null){
                if (session.isOpen()){
                    session.close();
                }
            }
        }
    }
}

查询

public void testLoad(){
    Session session = null;
    try{
        session = HibernateUtils.getSession();
        session.beginTransaction();
        User user = (User)session.get(User.class, 2);
        System.out.println("userId : " + user.getId());
        System.out.println("userName : " + user.getName());
        //迭代输出id为2的用户的角色
        Set roleOfUser = user.getRole();
        Iterator it = roleOfUser.iterator();
        while(it.hasNext()){
            Role role = (Role)it.next();
            System.out.println("user's Role : " + role.getName());
        }
    }catch(Exception e){
        e.printStackTrace();
        session.getTransaction().rollback();
    }finally{
        if (session != null){
            if (session.isOpen()){
                session.close();
            }
        }
    }
}

双向即为:各自持有对方的引用

改变的地方不大,只在Role.java中加入了User的引用,还有在Role.hbm.xml中加入了User属性如下:

Role.java

package com.ahuzl.hibernate;
import java.util.Set;
public class Role {
    private int id;
    private String name;
    private Set user;
...省略 get set 方法
}

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 package="com.ahuzl.hibernate">
    <class name="Role" table="t_role">
        <id name="id" column="role_id">
            <generator class="native"/>
        </id>
        <property name="name" column="role_name"/>
        <set name="user" table="t_user_role">
            <key column="role_id"></key>
            <many-to-many class="User" column="user_id"/>
        </set>
    </class> 
</hibernate-mapping>

这里<set标签的写法和单向时一样,table="t_user_role"注意要一致,还有key和many-to-many的column,别写错就行了。

还有一点关于结果的排序,如果配置了,那么hibernate会为我们排序,升序默认或esc,降序desc

<set name="user" table="t_user_role" order-by="user_id desc">
    <key column="role_id"/>
    <many-to-many class="User" column="user_id"/>
</set>

如上面的配置,hibernate会在SQL中加入orderbyXXXdesc

保存不会有任何改变,只是先保存谁都无所谓了,

查询

public class Many2ManyTest extends TestCase {
    public void testLoad2(){
        Session session = null;
        try{
            session = HibernateUtils.getSession();
            session.beginTransaction();
            Role role = (Role)session.load(Role.class, 1);
            System.out.println("roleId : " + role.getId());
            System.out.println("roleName : " + role.getName());
            //迭代输出id为1的角色的用户
            Set roleOfUser = role.getUser();
            Iterator it = roleOfUser.iterator();
            while(it.hasNext()){
                User user = (User)it.next();
                System.out.println("userID : " + user.getId());
                System.out.println("userName: " + user.getName());
            }
        }catch(Exception e){
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally{
             if (session != null){
                if (session.isOpen()){
                    session.close();
                }
            }
        }
    }
}

相关推荐