【jpa】映射关系:单向一对多,多对一,双向多对一,双向一对一,双向多对多(和hibernate一样)

映射关系(外键在哪,就是谁维护关联关系)
 
基本步骤思路:
  1. 实体类创建
  2. 大配置文件设置(实体类关联)
  3. 小配置设定,在配置文件中加入或者在实体类中注解开发(这里介绍注解开发的)
 
总结:
  • 谁管理,谁设外键,对应字段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=“”)})
  1. name指向中间表名
  2. joinColumns 映射当前类所在的表在中间表中的外键
    1. name 指定中间表的中,关联当前表的外建名字
    2. referenceColumnName  中间表关联的此表的那一列,此表关联外键的列名
  3. 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"))
 
 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值