12.Hibernate多对多关系

JavaBean的编写

Person

private long pid ;
private String name ;

private Set<Role> roles = new HashSet<Role>();
//省略get/set/无参构造

Role

private long rid ;
private String name ;

private Set<Person> persons = new HashSet<Person>();
//省略get/set/无参构造

配置文件编写

person.hbm.xml(放弃外键维护,多对多必须有一方放弃外键维护)

    <!-- table 表在数据库的名字 -->
    <class name="com.hibernateday3.domain.Person" table="sys_person">
        
        <id name="pid" column="pid">
            <generator class="native"/>        
        </id>
        
        <property name="name" column="name"/>
        
        <!-- 
            name:当前对象的集合
            table:中间表的名字
            column:当前对象在中间表的字段
            class:集合对象的路径
            column:集合对象在中间表的字段
         -->
        <set name="roles" table="sys_person_role">
            <key column="pid"/>
            <many-to-many class="com.hibernateday3.domain.Role" column="rid"/>
        </set>
        
    </class>

role.hbm.xml

    <!-- table 表在数据库的名字 -->
    <class name="com.hibernateday3.domain.Role" table="sys_role">
        
        <id name="rid" column="rid">
            <generator class="native"/>        
        </id>
        
        <property name="name" column="name"/>
        
        <!-- 
            name:当前对象的集合
            table:中间表的名字
            column:当前对象在中间表的字段
            class:集合对象的路径
            column:集合对象在中间表的字段
         -->
        <set name="persons" table="sys_person_role" inverse="true">
            <key column="rid"/>
            <many-to-many class="com.hibernateday3.domain.Person" column="pid"/>
        </set>
        
    </class

核心文件中配置映射

        <mapping resource="com/hibernateday3/domain/Person.hbm.xml"/>                
        <mapping resource="com/hibernateday3/domain/Role.hbm.xml"/>    

测试:

1.双向保存

/**
     * 测试多对多:双向保存
     * 必须要有一份放弃维护外键
     */
    @Test
    public void m01(){
        
        Session session = HibernateUtils.openSession();
        Transaction tr = session.beginTransaction();

        //创建对象
        Person p1 = new Person();
        p1.setName("人物一");
        Person p2 = new Person();
        p2.setName("人物二");
        Role r1 = new Role();
        r1.setName("角色1");
        Role r2 = new Role();
        r2.setName("角色1");
        //-----------------保存数据
        
        //人物一:角色1+角色2
        p1.getRoles().add(r1);
        p1.getRoles().add(r2);
        r1.getPersons().add(p1);
        r2.getPersons().add(p1);
        
        //人物二:角色1
        p2.getRoles().add(r1);
        r1.getPersons().add(p1);
        
        //保存
        session.save(p1);
        session.save(p2);
        session.save(r1);
        session.save(r2);
        
        //-----------------释放资源
        tr.commit();
        session.close();
    }

2.级联保存(在没有放弃外键的一方添加cascsde)

Person.hbm.xml

<set name="roles" table="sys_person_role" cascade="save-update">
    /**
     * 测试多对多:级联保存保存
     * 在没有放弃外键的一方添加cascsde
     */
    @Test
    public void m02(){
        
        Session session = HibernateUtils.openSession();
        Transaction tr = session.beginTransaction();

        //创建对象
        Person p1 = new Person();
        p1.setName("人物一");
        Person p2 = new Person();
        p2.setName("人物二");
        Role r1 = new Role();
        r1.setName("角色1");
        Role r2 = new Role();
        r2.setName("角色1");
        //-----------------保存数据
        
        //人物一:角色1+角色2
        p1.getRoles().add(r1);
        p1.getRoles().add(r2);
        
        //人物二:角色1
        p2.getRoles().add(r1);
        
        //保存
        session.save(p1);
        session.save(p2);
        
        //-----------------释放资源
        tr.commit();
        session.close();
    }

3.让人物一失去角色1

    /**
     * 测试多对多:让人物一没有角色1
     * 
     */
    @Test
    public void m03(){
        
        Session session = HibernateUtils.openSession();
        Transaction tr = session.beginTransaction();

        //-----------------获取数据
        Person p1 = session.get(Person.class, 1l);
        Role r1 = session.get(Role.class, 1l);
        
        //保存
        p1.getRoles().remove(r1);
        
        //-----------------释放资源
        tr.commit();
        session.close();
    }

在多对多中一般不使用级联删除

原文地址:https://www.cnblogs.com/NEWHOM/p/6773810.html