映射关系(外键在哪,就是谁维护关联关系)
基本步骤思路:
-
实体类创建
-
大配置文件设置(实体类关联)
-
小配置设定,在配置文件中加入或者在实体类中注解开发(这里介绍注解开发的)
总结:
-
谁管理,谁设外键,对应字段JoinColumn
-
管理者在前(多对一:多是关联外键;一对多:一是关联外键)
-
一对多,一带set容器
-
@joinColumn注解放在get方法上,放在字段上会报错找不到列
1.单项多对一(在多的一方注解,多表外键关联)
@ManyToOne(fetch=
) 多对一
@JoinColumn(name=‘’) 映射外键,name为列名
保存
先保存一,再保存多,建议使用这个,不会多出来update
先保存多,再保存一,多和一都会insert,再update多,每个再填入一的属性
remove()
删除多,可以
删除一,不能删除,因为有外键
查
ManyToOne(
fetch=
FetchType
.
LAZY
)
-fetch.type.LAZY 懒加载
改
直接根据对象set修改就行
#员工-部门多对一,员工为多,外键:员工表的dept字段,JoinColumn放在get方法上,放在字段上会报错找不到列
@Entity
17 @Table(name = "EMP")
18 public class Emp {
19 @Id
20 @Column(name = "EMPNO")
21 @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "emp_num")
22 @SequenceGenerator(name = "emp_num", sequenceName = "emp_num_id", allocationSize = 1, initialValue = 1)
23 private Integer empNo;
24
25 @Column(name = "EMPNAME")
26 private String empName;
private Dept dept;
27
28 @ManyToOne()
29 @JoinColumn(name = "DEPTNO",fetch=FetchType.LAZY)
30 public Dept getDept dept{
32
33 @Entity
21 @Table(name = "DEPT")
22 public class Dept {
23 @Id
24 @Column(name = "DEPTNO")
25 @GeneratedValue(strategy=GenerationType.SEQUENCE,generator="dept_num")
26 @SequenceGenerator(name="dept_num",sequenceName="dept_num_no",allocationSize=1,initialValue=1)
27 private Integer deptNo;
28
29 @Column(name = "DEPTNAME")
30 private String deptName;
31
2.单项一对多(在一的类注解,注解可以方法get多方法上)
@OneToMany 一对多
@JoinColumn(name=“”)外键关联
保存 persist
一定会多出update语句,因为多插入时,不会插入外键列一,就必须再update。
find
默认对多的一方,
实现懒加载策略,可以修改fetch,不让懒加载
remove()
默认:删除一的一端,会把关联的多的一端外键值置null,然后删除一
级联删除:@OneToMany (cascade={CascadeType.REMOVE})删除一的时候,对应的多的一方也删除了
改
用一的一方,set方法就行
#部门-员工,一对多,部门为一,外键:Set<Emp>
@Entity
20 @Table(name="Dept")
21 public class Dept {
22 @Id
23 @GeneratedValue(strategy=GenerationType.SEQUENCE,generator="dept_num")
24 @SequenceGenerator(name="dept_num",sequenceName="dept_num_no",allocationSize=1,initialValue=1)
25 private Integer deptNo;
26 @Column
27 private String deptName;
28 private Set<Emp> = new HashSet<Emp>()
29
30 @OneToMany(cascade={CascadeType.ALL})
31 @JoinColumn(name="deptno")
32 private Set<Emp> getemps{
@Entity
21 @Table(name = "EMP")
22 public class Emp {
25
26 @Id
27 @GeneratedValue(strategy=GenerationType.SEQUENCE,generator="emp_num")
28 @SequenceGenerator(name="emp_num",sequenceName="emp_num_no",allocationSize=1,initialValue=9)
29 private Integer empNo;
30
31 @Column
32 private String empName;
33
3.双向一对多
#部门-员工,一对多,部门mapperBy,不负责维护外键关系,员工维护
多的一方维护关联关系
@Entity
20 @Table(name="Dept")
21 public class Dept {
22 @Id
23 @GeneratedValue(strategy=GenerationType.SEQUENCE,generator="dept_num")
24 @SequenceGenerator(name="dept_num",sequenceName="dept_num_no",allocationSize=1,initialValue=1)
25 private Integer deptNo;
26 @Column
27 private String deptName;
28
29
30 @OneToMany(mappedBy="dept",cascade={CascadeType.ALL})//dept是对应EMP表中关联字段dept,代表多方表EMP的dept维护外键关系
public Set<Emp> getEmps() {
35 return emps;
36 }
37
@Entity
@Table(name = "EMP")
public class Emp {
25
26 @Id
27 @GeneratedValue(strategy=GenerationType.SEQUENCE,generator="emp_num")
28 @SequenceGenerator(name="emp_num",sequenceName="emp_num_no",allocationSize=1,initialValue=9)
29 private Integer empNo;
30
31 @Column
32 private String empName;
33
34
35 @ManyToOne(fetch=FetchType.LAZY)
36 @JoinColumn(name="deptno")
40 public Dept getDept() {
41 return dept;
42 }
双向多对一(多对一和一对多双向的一样)
两边get彼此属性方法上注解
@JoinColumn(name="") name的value一定要一致
@ManyToOne(fetch=)
保存(由多的一方维护关联关系)
先保存n,再保存一:默认多出n+1条update语句
先保存一,再保存n:默认多出1条update语句
双向关联1-n时候,建议使用n的一方维护关联关系,
若在1的一方加上(这样将关系维护交给n)@ManyToOne(mappedBy=“”)且去除@JoinColumn注解,不能定义两次
4.双向一对一
@JoinColumn(name=,unique=true)一对一,需要添加unique
@OnetoOne
不维护一方(没有外键的一方)设置:
@OneToOne(mappedBy=“维护关系一方的字段名”),比如表A.B是维护表的外键,这里表C的mapperdeBy填写B
保存:
先保存不维护不维护关联关系的一方,没有多出的update
find:
1.find会通过左外连接find,维护关联一方,通过@OneToOne的fetch属性修改成懒加载,可以一条普通查询即可。不维护一方的改了也要多查询一次。
解释:关联一方,一次查询,外键部分没有就置空,有就弄代理。未关联一方,没有外键,不知道有没有,所以必须左外连接或者多一次sql查询。
//DataSetDef.java
@JoinColumn(name="sync_destination_id",referencedColumnName="id")
@OneToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE }, orphanRemoval = true)
private SyncDestination syncDestination;
//数据库表data_set_def
//添加外键外键data_set_def_ibfk_1 该表外键关联字段sync_destination_id 关联表sync_destination 关联表主键id
JoinColumn的name属性:本表关联外键字段
JoinColumn的referencedColumnName属性:关联表的主键
注解变量名为关联表,此处为SyncDestination
OneToOne的orphanRemoval属性:如果删除,是否会删除关联的实体。true删除,false,会将删除关系,被关联对象将引用设置为null
#idcard-student 简单案例
@Entity
12 @Table
13 public class IdCard {
14
15 @Id
16 @Column(length=18)
17 private String cid;
18 @Column
19 private String cname;
20
21 @OneToOne
22 @JoinColumn(name="stu_id")
23 public Student getStu() {
42 return stu;
43 }
@Entity
13 @Table
14 public class Student {
15
16 @Id
17 @GeneratedValue
18 private Integer sid;
19 @Column
20 private String sname;
21
22 @OneToOne(cascade={CascadeType.ALL})
23 @JoinColumn(name="card_id")
public IdCard getCard() {
43 return card;
44 }
24
5.双向多对多
多对多由中间表,必须由一方放弃管理关联关系
@ManyToMany 映射多对多关系
@JoinTable(name=“”,joinColums={@joinColums(name=“”,referencedColumnName=“”)},inverseJoinColums={@JoinColumn(name=“”,referencedColumnName=“”)})
-
name指向中间表名
-
joinColumns 映射当前类所在的表在中间表中的外键
-
name 指定中间表的中,关联当前表的外建名字
-
referenceColumnName 中间表关联的此表的那一列,此表关联外键的列名
-
-
inverseJoinColums映射关联的类所在的中间表的外键
放弃管理啊关联关系的一方mapperby即可
persist保存
n*n次update
find方法
对于关联集合对象,默认使用懒加载策略
获取维护关系or不维护关系的一方,sql相同
案例:
//创建一个中间表AUTHORITY_DIRECTORY,外键字段就是DIRECTORY_ID,DIRECTORY_AUTHORITY_ID,分别关联DIRECTOR.id列、DIRECTORY_AUTHORITY.id列
//在DIRECTORY.java
@ManyToMany(cascade = { CascadeType.MERGE, CascadeType.PERSIST })
@JoinTable(name = "AUTHORITY_DIRECTORY", joinColumns = @JoinColumn(name = "DIRECTORY_ID", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "DIRECTORY_AUTHORITY_ID", referencedColumnName = "id"))
//在DIRECTORY_AUTHORITY.java
@ManyToMany(cascade = { CascadeType.MERGE, CascadeType.PERSIST })
@JoinTable(name = "AUTHORITY_DIRECTORY", joinColumns = @JoinColumn(name = "DIRECTORY_AUTHORITY_ID", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "DIRECTORY_ID", referencedColumnName = "id"))