Hibernate一对多双向关联

分别学习了hibernate多对一、一对多单向关联,今天来看看双向关联。
还是延续上面的学生和班级的例子。

1.基于xml的映射配置

先看实体类:

public class Student {
    private int id; 
    private String name;    
    private Classes classes;
    //省略了getter和setter
}

public class Classes {  
    private int id; 
    private String name;    
    private Set students;
    //省略了getter和setter
}

再来看xml映射文件:

<!--Student的映射文件-->
<hibernate-mapping>
    <class name="com.jackie.hibernate.Student" table="t_student">
        <id name="id">
            <generator class="native"/>
        </id>
        <property name="name"/>
        <many-to-one name="classes" column="classes_id"/>
    </class>
</hibernate-mapping>

<!--Classes类的映射文件-->
<hibernate-mapping>
    <class name="com.jackie.hibernate.Classes" table="t_classes">
        <id name="id">
            <generator class="native"/>
        </id>
        <property name="name"/>

        <set name="students" inverse="true">
            <key column="classes_id"/>
            <one-to-many class="com.jackie.hibernate.Student"/>
        </set>
    </class>
</hibernate-mapping>

由于一对多关联的缺陷,通常将一对多关系设成双向的,让多的一方来维护关系。 inverse=”true”,用了设置将维护关系的一方交给另一端,本段不再维护关系。
我们来写测试用例看一下输出:

/**
 * 测试由多的一方(Student)来保存数据
 */
@Test
public void testSave3() {
        Session session = null;
        try {
            session = HibernateUtils.getSession();
            session.beginTransaction();

            Classes classes = new Classes();
            classes.setName("中一班");
            session.save(classes);

            Student student1 = new Student();
            student1.setName("张三");
            student1.setClasses(classes);
            session.save(student1);

            Student student2 = new Student();
            student2.setName("李四");
            student2.setClasses(classes);

            //可以正常的保存数据,原因是关系交由多的一方来维护,
            //也就是Student来维护
            session.save(student2);

            session.getTransaction().commit();
        }catch(Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally {
            HibernateUtils.closeSession(session);
        }
    }

hibernate的输出:
Hibernate: insert into t_classes (name) values (?)
Hibernate: insert into t_student (name, classesid) values (?, ?)
Hibernate: insert into t_student (name, classesid) values (?, ?)
可以正常保存数据!再来看看一的一方保存数据的情况:

/**
 * 测试由一的一方(Classes)来保存数据
 */
@Test
public void testSave2() {
        Session session = null;
        try {
            session = HibernateUtils.getSession();
            session.beginTransaction();
            Student student1 = new Student();
            student1.setName("张三");
            session.save(student1);

            Student student2 = new Student();
            student2.setName("李四");
            session.save(student2);

            Classes classes = new Classes();
            classes.setName("中一班");

            Set students = new HashSet();
            students.add(student1);
            students.add(student2);
            classes.setStudents(students);

            //同样由于inverse=true, 一的一方已经不能完全保存数据,
            //只能保存自己的数据,不能保存关联关系
            session.save(classes);
            session.getTransaction().commit();
        }catch(Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally {
            HibernateUtils.closeSession(session);
        }
    }

Hibernate日志输出:
Hibernate: insert into t_student (name, classesid) values (?, ?)
Hibernate: insert into t_student (name, classesid) values (?, ?)
Hibernate: insert into t_classes (name) values (?)

在看一下数据:
t_classes表:
这里写图片描述

t_student表:
这里写图片描述
可以看到,t_student表中的classesid是空的,也就是说,关系没有写入到数据库中去。这就是inverse=true的效果,强制让关系用多的一端来维护。
源代码地址

2.基于Annotation的关联配置

先看Student类的代码:

@Entity
@Table(name="t_student")
public class Student {

    private int id; 
    private String name;    
    private Classes classes;

    @Id 
    @GeneratedValue
    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;
    }

    @ManyToOne
    @JoinColumn(name="classesid")
    public Classes getClasses() {
        return classes;
    }

    public void setClasses(Classes classes) {
        this.classes = classes;
    }
}

Classes实体的代码:

@Entity
@Table(name="t_classes")
public class Classes {  
    private int id; 
    private String name;    
    private Set students;

    @Id 
    @GeneratedValue
    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;
    }

    //mappedBy在哪一端,哪一端就不维护关系,它成为了关系的被管理端
    //向当于hibernate中的inverse=true
    //如果采用了泛型,可以不用采用targetEntity属性
    @OneToMany(mappedBy="classes",targetEntity=Student.class)
    @JoinColumn(name="classesid")
    public Set getStudents() {
        return students;
    }

    public void setStudents(Set students) {
        this.students = students;
    }

}

ok,这种配置就是这样简单。测试代码同上。
源代码地址

猜你喜欢

转载自blog.csdn.net/maodou95838/article/details/52983958
今日推荐