Hibernate对应关系(了解)

布置的任务要用就写一下总结一下

hibernate有以下几种关系

一对一

一对多

多对一

多对多

 

首先这些对应关系是分单向和双向的 单向和双向有什么区别呢?

这个双向单向是面向对象的说法 意思就是你更新一个表另外一个表里面关联的数据跟着改变
双向就是这两个表无论哪一个更新另外一个表都更新 单向就是只有一个主表更新从表才更新 从表更新主表不管

单向:就是父亲管理孩子,父亲知道自己的孩子是谁,孩子并不知道自己的父亲是谁,比如我们user表单向一对多 book表 我们在user表里面设置book 的外键关联,当我们查询数据库的时候只能查找 用户的书籍有哪些,不能查看某一本书是哪个用户的

双向:查询的时候都可以从一方获取另一方的数据

 

注解的含义:

@Table(name = " ",catalog=" ", schema=" ")
//name表名,虽然可选,建议写上。catalog在MySql不支持,不必写。schema在MySql中指数据库名。
 
@Table(uniqueConstraints = {@UniqueConstraint(columnNames="name")})
或
@Column(name = "name",unique = true)
//指定建表时需要建唯一约束的列(使除主键外的列保持唯一约束)
 
@Embeddable  
//表示一个非Entity类嵌入到一个Entity类作为属性而存在。
//使用方法,新建一个类注上该注解即可。在此类同样可使用注解对字段进行约束。
 
@embedded
//该注解是用来注释属性的,表示该类为嵌入类,同时,该类也得注释@Embeddable注解
 
@GeneratedValue(strategy=GenerationType)
GenerationType.AUTO //默认,根据底层数据库自动选择
GenerationType.INDENTITY //根据数据库的Identity字段生成
GenerationType.SEQUENCE //根据sequenqe来决定主键的取值
GenerationType.TABLE //使用指定表来决定主键取值,结合TableGenerator使用
 
@Id //自定义主键生成策略
@GeneratedValue(generator="sid")    //名字
@GenericGenerator(name="sid",strategy="assigned")   //策略
 
@EmbeddedId
//使用嵌入式主键类实现复合主键
//主键类必须实现Serializable接口,必须有默认的public无参构造方法,
//必须覆盖equals和hashCode()方法,必须注解@Embeddable 
//使用时,把主键类对象当做参数传入Table类,对Table类进行保存即可。
 
 
@Transient
//表示该属性并非是到数据库表的字段的映射,否则默认注解@Basic
 
@Column(columnDefinition="TEXT", nullable=true)
//表示该字段为数据库中的TEXT类型,存储长文本
关系映射注解
@OneToOne(cascade = {CascadeType.ALL}) CascadeType.PERSIST:级联新增(又称级联保存):对order对象保存时也对items里的对象也会保存。对应EntityManager的presist方法。 CascadeType.MERGE:级联合并(级联更新):若items属性修改了那么order对象保存时同时修改items里的对象。对应EntityManager的merge方法 。 CascadeType.REMOVE:级联删除:对order对象删除也对items里的对象也会删除。对应EntityManager的remove方法。 CascadeType.REFRESH:级联刷新:获取order对象里也同时也重新获取最新的items时的对象。对应EntityManager的refresh(object)方法有效。即会重新查询数据库里的最新数据。 CascadeType.ALL:以上四种都是。

hibernate的FetchType注解属性

FetchType.LAZY:懒加载,加载一个实体时,定义懒加载的属性不会马上从数据库中加载,即从数据库读到内存。
FetchType.EAGER:急加载,加载一个实体时,定义急加载的属性会立即从数据库中加载。也可以说成表示关联关系的从类在主类加载时同时加载

 

orphanRemoval=true

在一对多的关系当中,我们通常喜欢使用  CascadeType.ALL 假设现在有 user ,book 表 一个用户对应多本书,当我们删除用户的时候通常会删除他所关联的书籍, 当我们删除书本时如果不设置orphanRemoval=true 用户也会被删除,设置之后 user 就不会被删除

一对一:

单向:

@Entity
@Table(name="User")
public class User {
    @Id
    @GeneratedValue
    @Column(name="sid")
    private int sid;
 
    @Column(name="name")
    private String name;
 
    @OneToOne(cascade = {CascadeType.ALL})
    @JoinColumn(name = "pid",unique=true)
    //name=定义外键在本表的字段名,若只配置本类,则为单向关联
    //unique=true是指这个字段的值在这张表里不能重复,所有记录值都要唯一,就像主键那样
    private Room room;
    ...
}

双向:

@Entity
@Table(name="Room")
public class Room {
    @Id
    @Column(name="cid")
    private int cid;
 
    @Column(name="addr")
    private String addr;
 
    @OneToOne(mappedBy="room")//被控方
    //mappedBy同样指定由对方来进行维护关联关系
// 关于mappedBy的解释 参考博客:https://www.cnblogs.com/chiangchou/p/mappedBy.html
private User user; ... }

一对多:

单向:

//正常建表
@Entity
@Table(name="User")
public class User {
    @Id
    @GeneratedValue
    @Column(name="sid")
    private int sid;
    @Column(name="name")
    private String name;
     ...
 
}
@Entity
@Table(name="Room")
public class Room {
    @Id
    @GeneratedValue
    @Column(name="cid")
    private int cid;
 
    @Column(name="addr")
    private String addr;
 
    @OneToMany(cascade={CascadeType.ALL}, fetch=FetchType.LAZY) //一对多为Lazy,多对一为Eager
    @JoinColumn(name="cid") //name=定义外键在本表的字段名
    private Set<User> users;
    ...
 
}

多对一:

//正常建表
@Entity
@Table(name="Room")
public class Room {
    @Id
    @Column(name="cid")
    private int cid;
    @Column(name="addr")
    private String addr;
    ...
}
@Entity
@Table(name="User")
public class User {
    @Id
    @GeneratedValue
    @Column(name="sid")
    private int sid;
 
    @Column(name="name")
    private String name;
 
    @ManyToOne(cascade={CascadeType.ALL}, fetch=FetchType.EAGER)    //一对多为Lazy,多对一为Eager
    @JoinColumn(name="cid", referencedColumnName="cid") //name=定义外键在本表的字段名 rCN=关联外键对象的哪个字段
    private Room room;
    ...
}

双向(一对多,多对一):

@Entity
@Table(name="User")
public class User {
    @Id
    @GeneratedValue
    @Column(name="sid")
    private int sid;
 
    @Column(name="name")
    private String name;
 
    @ManyToOne(cascade={CascadeType.ALL}, fetch=FetchType.EAGER)    //一对多为Lazy,多对一为Eager
    @JoinColumn(name="cid") //name=定义外键在本表的字段名
    private Room room;
    ...
}
@Entity
@Table(name="Room")
public class Room {
    @Id
    @GeneratedValue
    @Column(name="cid")
    private int cid;
 
    @Column(name="addr")
    private String addr;
 
    @OneToMany(cascade={CascadeType.ALL}, fetch=FetchType.LAZY) //一对多为Lazy,多对一为Eager
    @JoinColumn(name="cid") //name=定义外键在本表的字段名
    private Set<User> users;
    ...
 
}

多对多

多对多需要创建一张中间表

单向

@Entity
@Table(name="t_course")
public class Course
{
    @Id
    @GeneratedValue
    private int id;
 
    private String name;
 
    @ManyToMany   ---> ManyToMany指定多对多的关联关系
    @JoinTable(name="t_teacher_course", 
    joinColumns={@JoinColumn(name="cid")}, 
    inverseJoinColumns={ @JoinColumn(name = "tid") }) 
    /*因为多对多之间会通过一张中间表来维护两表直接的关系,所以通过 JoinTable        
    这个注解来声明,我方是Course,所以在对方外键的名称就是 rid,
    inverseJoinColumns也是一个 @JoinColumn类型的数组,
    表示的是对方在我这放中的外键名称,对方是Teacher,所以在我方外键的名称就是 tid*/
    private Set<Teacher> teachers;
 
     ...
 
}

 

双向

 

@Entity
@Table(name="t_teacher")
public class Teacher
{   
    @Id
    @GeneratedValue
 
    private String name;
 
    @ManyToMany(mappedBy="teachers")//表示由Course那一方来进行维护
    private Set<Course> courses;
    ...
 
}

 

posted @ 2019-03-25 16:27  dingyl  阅读(258)  评论(0编辑  收藏  举报