前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Hibernate多表关系配置

Hibernate多表关系配置

作者头像
木瓜煲鸡脚
修改2019-09-18 10:02:59
7280
修改2019-09-18 10:02:59
举报
文章被收录于专栏:Jasper小笔记

Hibernate多表关系配置

1.表的关系

2.一对多配置

3.级联操作

4.多对多配置

5.多对多操作

1

表的关系

表之间的关系

一对多(一个部门有多个员工,一个员工只能属于某一个部门)

多对多(一个老师教多个学生,一个学生可以被多个老师教)

一对一(一个公司只能对应一个注册地址)

表之间关系建表原则

一对多在多的一方创建一个外键,指向一的一方的主键)

多对多(创建一个中间表,中间表至少有两个字段,分别作为外键指向多对多双方的主键)

一对一(唯一外键对应或主键对应)

2

一对多配置

1.建表(班级、学生)

class_id

class_name

numbers

stu_id

stu_name

stu_age

class_id

2.建立ORM

domain类

代码语言:javascript
复制
@Getter@Setter
public class Classes {
    private Integer class_id;
    private String class_name;
    private Integer class_student;
    //一个班级包含多个学生
    private Set<Student> students = new HashSet<>();
}
代码语言:javascript
复制
@Setter@Getter
public class Student {
    private Integer stu_id;
    private String stu_name;
    private Integer stu_age;
    //一个学生属于一个班级
    private Classes stu_class;
}

映射文件

映射文件中普通字段段的配置不用写上外键,在一的一方配置文件写上set标签name属性为关联属性名,里面还有key标签有column属性关系中的外键即另一个表的外键字段名,还有一个标签one-to-many写上另一表的domain类全路径。在多的一方只有一个many-to-one标签里面name属性也是关联属性名,class属性关系表它的domain地址,还有一个column外键

代码语言:javascript
复制
<hibernate-mapping>
    <class name="com.hao.domain.Classes" table="classes">

        <id name="class_id" >
            <generator class="identity"/>
        </id>
        <property name="class_name"/>
        <set name="students">
            <key column="class_id"></key>
            <one-to-many class="com.hao.domain.Student"></one-to-many>
        </set>
    </class>
</hibernate-mapping>
代码语言:javascript
复制
<hibernate-mapping>
<class name="com.hao.domain.Student" table="student">

    <id name="stu_id">
        <generator class="identity"/>
    </id>
    <property name="stu_name" />
    <property name="stu_age" />
    <many-to-one name="stu_class" class="com.hao.domain.Classes" column="class_id" lazy="false"></many-to-one>
</class>
</hibernate-mapping>

3.添加核心配置文件

代码语言:javascript
复制
<mapping resource="com/hao/domain/Student.hbm.xml"/>
<mapping resource="com/hao/domain/Classes.hbm.xml"/>

4.编写测试类

代码语言:javascript
复制
    public void saveTest() {
        Session session = HibernateUtil.openSession();
        Transaction tra = session.beginTransaction();
        //创建三个班级
        Classes c1 = new Classes();
        Classes c2 = new Classes();
        Classes c3 = new Classes();
        c1.setClass_name("c1");
        c2.setClass_name("c2");
        c3.setClass_name("c3");
        //创建三个学生
        Student s1 = new Student();
        Student s2 = new Student();
        Student s3 = new Student();
        s1.setStu_name("张三");
        s2.setStu_name("李四");
        s3.setStu_name("王五");
        //班级1添加两个学生,班级2添加一个学生
        c1.getStudents().add(s1);
        c1.getStudents().add(s2);
        c2.getStudents().add(s3);
        //保存全部
        session.save(s1);
        session.save(s2);
        session.save(s3);
        session.save(c1);
        session.save(c2);
        session.save(c3);

        tra.commit();
    }

结果

class_id

class-name

numbers

1

c1

null

2

c2

null

3

c3

null

stu_id

stu_name

stu_age

class_id

1

s1

null

1

2

s2

null

1

3

s3

null

2

默认是先保存各自的内容,再建立连接(添上外键),删除也是先去掉外键再删除。接下来通过级联操作实现关联关系表同步更新

3

级联操作

按照上面的操作保存3个班级3个学生,共六条保存

理论上只保存一边是可行的。

比如只保存班级c1、c2、c3,它们添加了s1、s2、s3。

所以添加班级也会在学生表中添加对应的记录。

但是实际上会报错——瞬时对象异常

这是因为保存的对象关联了处于瞬时态的对象

我们可以在配置文件中去开启级联操作

在哪个配置文件去开启,就在它对应的domain保存时才有级联

在Classes的映射文件去添加cascade,保存classes时就会级联保存不用再单独去保存student,关联信息本来在classes就有

代码语言:javascript
复制
 <set name="students" cascade="save-update">
   <key column="class_id" ></key>
   <one-to-many class="com.hao.domain.Student" ></one-to-many>
 </set>

还可以写在Student的映射文件,这样保存student就会同时保存关联的classes信息

代码语言:javascript
复制
<many-to-one  cascade="save-update" name="stu_class" class="com.hao.domain.Classes" column="class_id" lazy="false" ></many-to-one>

在更新时也会有级联操作,当classes移除一个学生,那么student表会变

还有删除,当删除一个班级,那么student表中属于这个班的student也会全删掉

代码语言:javascript
复制
cascade="delete"

4

多对多配置

配置和一对多一样,只是set标签中多一个table属性值为中间关系表的表名

建表

course_id

course_name

stu_id

stu_name

stu_age

class_id

stu_id

course_id

建立ORM

domain类

代码语言:javascript
复制
@Setter@Getter
public class Student {
    private Integer stu_id;
    private String stu_name;
    private Integer stu_age;
    //一个学生有多门课程
    private set<Course> courses;
}
代码语言:javascript
复制
@Setter@Getter
public class Course {
    private Integer Course_id;
    private String Course_name;
    //一个课程有众多学生学习
    private set<Student> students;
}

映射文件

代码语言:javascript
复制
<set name="courses" table="c-s" cascade="save-update,delete">
  <key column="stu_id"></key>
  <many-to-many class="com.hao.domain.Course" column="course_id"></many-to-many>
</set>
代码语言:javascript
复制
<set name="students" table="c-s">
  <key column="course_id"></key>
  <many-to-many class="com.hao.domain.Student" column="stu_id"></many-to-many>
</set>

最后再在核心配置文件加载上映射文件

代码语言:javascript
复制
<mapping resource="com/hao/domain/Course.hbm.xml"/>

编写测试

代码语言:javascript
复制
@Test
public void manytomany(){
  Course c1 = new Course();
  Course c2 = new Course();
  Course c3 = new Course();
  c1.setCourse_name("语文");
  c2.setCourse_name("数学");
  c3.setCourse_name("英语");
 
  Student s1 = new Student();
  Student s2= new Student();
  Student s3 = new Student();
  s1.setStu_name("张三");
  s2.setStu_name("李四");
  s3.setStu_name("王五");

  c1.getStudents().add(s1);
  c1.getStudents().add(s2);
  c1.getStudents().add(s3);
  c2.getStudents().add(s1);
  c3.getStudents().add(s2);
  c3.getStudents().add(s3);

  Session session = HibernateUtil.openSession();
  Transaction tra = session.beginTransaction();
  session.save(c1);
  session.save(c2);
  session.save(c3);
  tra.commit();
}

5

多对多操作

对多对的操作双方的关系都在中间表上,都在各自得关联集合中。所以它们得操作就是操作集合

给上面王五添加数学课

代码语言:javascript
复制
@Test
public void manytomany(){
  Session session = HibernateUtil.openSession();
  Transaction tra = session.beginTransaction();
  //获取王五
  Student stu = session.get(Student.class,1);
  //获取数学课
  Course course = session.get(Course.class,2)
  //修改集合
  stu.getCourses().add(course);
  tra.commit();
}

其他也是一样

给王五删除数学课

代码语言:javascript
复制
@Test
public void manytomany(){
  Session session = HibernateUtil.openSession();
  Transaction tra = session.beginTransaction();
  //获取王五
  Student stu = session.get(Student.class,1);
  //获取数学课
  Course course = session.get(Course.class,2)
  //修改集合
  stu.getCourses().remove(course);
  tra.commit();
}

给王五把英语课改为数学课(其实就是前面的删除和添加)

代码语言:javascript
复制
@Test
public void manytomany(){
  Session session = HibernateUtil.openSession();
  Transaction tra = session.beginTransaction();
  //获取王五
  Student stu = session.get(Student.class,1);
  //获取英语课
  Course course1 = session.get(Course.class,3);
  //获取数学课
  Course course2 = session.get(Course.class,2);
  //修改集合
  stu.getCourses().remove(course1);
  stu.getCourses().add(course2);
  tra.commit();
}

特别注意:事务提交、建表引擎(坑)

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-09-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 IT那个小笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档