Hibernate关联关系注解配置简单理解

Hibernate关联关系注解配置

什么是关联关系?关联关系有哪几种?

关联关系指实体之间的关系,也就是表与表之间的关系。一个关系用两个属性来描述,数量性和方向性。
从数量上来看,表与表之间主要有三种关系,一对一,一对多,多对多。
加上关系的方向,还有一个多对一。

hibernate中关联关系的维护

在实际的业务开发中,对于两个有关联的数据库实体,比如学生对教室,我们通常还需要在操作一方时,维护两方彼此之间的关系。

关系的维护分为两类:
1.级联Cascade,在操作一方时,是否对另一方也执行同样的操作。

2.外键的维护inverse,在操作一方时,是否自动维护外键关系。比如如果将 多方的对象添加给以一的一方,因为外键由多方维护,hibernate为了保证添加的这个多方对象的外键是正确的,会自动给这个多方的外键设置值(也就是一的一方的主键)
外键维护,在xml配置中使用inverse属性,在注解中使用mappedBy注解来声明。

cascade与inverse

1.cascade,指把对当前对象的操作 级联到 关联对象上。
一般在one to one ,one to many设置级联。
配置了这个属性后,当对当前对象执行如save等更新数据库的操作时,当前实体所关联的实体也会执行相应的操作。

2.inverse
默认值为true, 表示让对方来维护关系。设为false,自己维护关系。
inverse主要有两个作用:
1)维护外键
主控方保存时,是否自动update被控方的外键字段。外键字段指向的就是当前保存的实体。
2)维护级联
决定当前设置的级联是否有用,自己维护关系时,对方设置的级联就不会生效,对方保存时不会让本方也保存。而对方维护关系,则与此相反。

@mappedBy注解

1)mappedBy(name="对方标准代表当前实体的属性“)
2)只存在于OneToOne,OneToMany,ManyToMany, 不能在ManyToOne中
3)与joincolumn或jointable互斥。因为joincolumn在拥有方声明了被拥有方,而mappedby定义在被拥有方,指向拥有方。
4)一般拥有方为拥有外键的那一方,在一对多中是在多方。
有什么用:
让拥有方来自动维护与当前实体的关系。与inverse对应。inverse=true
在注解中没有设置mappedBy时,默认双方都维护关系,就如inverse。

如何确定单向与双向关联

在实际开发中,是采用单向关联还是双向关联,要看具体的业务需求,如果业务只需要在获取一方的实体时获取另一方的实体,而不是两边都能获取,那就采用单向关联。反之,如果需要在两边的实体中都能获取到对方,就使用双向关联。

一对一

双向关联,每一方都能获取到对方的实体



// CREATE TABLE `person` (
//     `id` varchar(255) NOT NULL,
//     `pname` varchar(255) DEFAULT NULL,
 //       `idcard` varchar(255),(外键)
//     PRIMARY KEY (`id`)
//   ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
   
//   CREATE TABLE `idcard` (
//     `id` varchar(255) NOT NULL,
//     `cardnum` varchar(255) DEFAULT NULL,
//     PRIMARY KEY (`id`)
//   ) ENGINE=InnoDB DEFAULT CHARSET=utf8;


@Entity
@Table(name="person")
public class Person {
    
    @Id
        @GenericGenerator(name="uuidGenerator", strategy="uuid")
        @GeneratedValue(generator="uuidGenerator")
    private String id;
    
    @Column(name="pname")
    private String pname;
    
        @OneToOne(cascade=CascadeType.ALL)
        @JoinColumn(name="idcard")
    private IdCard card;
    
    
    
}

@Entity
@Table(name="idcard")
public class IdCard {
    
    @Id
        @GenericGenerator(name="uuidGenerator", strategy="uuid")
        @GeneratedValue(generator="uuidGenerator")
    private String id;
    
    @Column(name="cardNum")
    private String cardNum;
    
    @OneToOne
    @mappedBy(name="card")
    private Person person;
    
}

单向关联,一般让外键所在的表作为主控方。

@Entity
@Table(name="person")
public class Person {
    
    @Id
        @GenericGenerator(name="uuidGenerator", strategy="uuid")
        @GeneratedValue(generator="uuidGenerator")
    private String id;
    
    @Column(name="pname")
    private String pname;
    
        @OneToOne(cascade=CascadeType.ALL)
        @JoinColumn(name="idcard")
    private IdCard card;
    
    
    
}

@Entity
@Table(name="idcard")
public class IdCard {
    
    @Id
        @GenericGenerator(name="uuidGenerator", strategy="uuid")
        @GeneratedValue(generator="uuidGenerator")
    private String id;
    
    @Column(name="cardNum")
    private String cardNum;
    
// 单向关联,这边不用保存对方的引用
    
}

一对多

 
  // 表,多个student对应一个class


  CREATE TABLE `student` (
    `id` varchar(255) NOT NULL,
    `name` varchar(255) DEFAULT NULL,
       `classId` varchar(255),(外键)
    PRIMARY KEY (`id`)
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
   
  CREATE TABLE `class` (
    `id` varchar(255) NOT NULL,
    `nane` varchar(255) DEFAULT NULL,
    PRIMARY KEY (`id`)
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
@Entity
@Table(name="person")
public class Person {

CREATE TABLE `teacher` (
    `id` varchar(255) NOT NULL,
    `name` varchar(255) DEFAULT NULL,
 
    PRIMARY KEY (`id`)
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
   
  CREATE TABLE `teacher_to_student` (
    `id` varchar(255) NOT NULL,
    `tid` varchar(255) NOT NULL,
      `sid` varchar(255)NOT NULL
    PRIMARY KEY (`id`)
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
   
  

一对多,多对一双向关联,单向关联只需要去掉一的那方对多方的引用。


@Entity
@Table(name="student")
public class Student {
    
    @Id
    @GenericGenerator(name="uuidGenerator", strategy="uuid")
    @GeneratedValue(generator="uuidGenerator")
    private String id;
    
    @Column(name="name")
    private String name;
    
     @ManyToOne(cascade=CascadeType.ALL)
     @JoinColumn(name="classId")
    private StudentClass class;
    
    
    
}

@Entity
@Table(name="class")
public class StudentClass {
    
    @Id
    @GenericGenerator(name="uuidGenerator", strategy="uuid")
    @GeneratedValue(generator="uuidGenerator")
    private String id;
    
    @Column(name="name")
    private String name;
    
    @OneToMany
    //mappedBy和Joincolumn互斥
    // mappedBy在一的一方
    @mappedBy(name="classId")
    private List students;
    
}

多对多关联。分为两种情况:

1.建立一个中间表,并为中间表建立持久化类。这样就拆分成了两个多对一关联,配置如上。
2.不为中间表建立持久化类,而是交给hibernate去维护。
主控方:
@ManyToMany
@joinTable表示中间表
joinColumns 表示 当前实体在中间表的外键
inverseJoincolumns 关联的另一方在中间表的外键
被控方:
ManyToMany(@MappedBy=主控方对象持有的被控方的属性名)

@Entity
@Table(name="student")
public class Student {
    
    @Id
    @GenericGenerator(name="uuidGenerator", strategy="uuid")
    @GeneratedValue(generator="uuidGenerator")
    private String id;
    
    @Column(name="name")
    private String name;
    
     @ManyToOne(cascade=CascadeType.ALL)
     @JoinTable(name = "teacher_to_student",
     joinColumns = @JoinColumn(name = "sid"),
     inverseJoinColumns = @JoinColumn(name = "tid"))
    private Set teachers;
    
}

@Entity
@Table(name="teacher")
public class Teacher {
    
    @Id
    @GenericGenerator(name="uuidGenerator", strategy="uuid")
    @GeneratedValue(generator="uuidGenerator")
    private String id;
    
    @Column(name="name")
    private String name;
    
     @ManyToMany(mappedBy="teachers",cascade=CascadeType.ALL)
    private Set student;
    
}

转载于:https://www.cnblogs.com/yuesheng-blog/p/10142858.html

你可能感兴趣的:(java,数据库)