无连接的N-1
无连接也就是不需要第三张表,维护我们的关联关系。对于N_1关联关系,我们只需要在N的一端增加一列外键即可。让外键的值记录到该属性的实体即可。Hibernate使用@JoinColumn来修饰代表关联实体的属性,用于映射底层的外键列。这种就不使用连接表了
好啦,我们看一下例子
/**
* @version 1.0.0
* @项目名称: yusp-uaa
* @类名称: AdminSmUser
* @类描述: 系统用户表实体
* @功能描述:
* @创建人: liuhua@********
* @创建时间: 2017-12-12 09:51
* @修改备注:
* @修改记录: 修改时间 修改人员 修改原因
* -------------------------------------------------------------
* @Copyright (c) 2017*******
*/
@Entity
@Table(name = "ADMIN_SM_USER")
public class AdminSmUser implements Serializable {
private static final long serialVersionUID = -1654620673909327705L;
private String userId;
private String loginCode;
private String userName = " ";
private String certType = "1";
private String certNo;
private String userCode;
private Time deadline;
private String orgId ;
private String dptId;
private String userPassword;
private String userSex;
private Time userBirthday;
private String userEmail;
private String userMobilephone;
private String userOfficetel;
private String userEducation;
private String userCertificate;
private Time entrantsDate;
private String positionTime;
private String financialJobTime;
private String positionDegree;
private String userAvatar;
private String offenIp;
private String userSts = "1";
private String lastLoginTime;
private Time lastEditPassTime;
private String lastChgUsr = SecurityUtils.getCurrentUserLogin();
private String lastChgDt = DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss");
private AdminSmDpt adminSmDpt;
private Set<AdminSmRole> authorities = new HashSet<>();
private AdminSmOrg adminSmOrg;
/*@Transient
private AdminSmOrg adminSmOrg;
@Transient
private AdminSmDpt adminSmDpt;*/
@Id
@Column(name = "USER_ID")
/* @GeneratedValue(generator = "uuid2" )
@GenericGenerator(name = "uuid2", strategy = "org.hibernate.id.UUIDGenerator" )*/
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid", strategy = "uuid")
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
@NotNull
@Basic
@Column(name = "LOGIN_CODE")
public String getLoginCode() {
return loginCode;
}
public void setLoginCode(String loginCode) {
this.loginCode = loginCode;
}
@Basic
@Column(name = "USER_NAME")
public String getUserName() {
return userName;
}
// ************省略相似代码
// 注意这里注解
// @JsonIgnore
***@ManyToMany
@JoinTable(
name = "ADMIN_SM_USER_ROLE_REL",
joinColumns = {@JoinColumn(name = "USER_ID", referencedColumnName = "USER_ID")},
inverseJoinColumns = {@JoinColumn(name = "ROLE_ID", referencedColumnName = "ROLE_ID")})
@BatchSize(size = 20)***
public Set<AdminSmRole> getAuthorities() {
return authorities;
}
public void setAuthorities(Set<AdminSmRole> authorities) {
this.authorities = authorities;
}
/*
// @JsonIgnore
*//* @ManyToOne(cascade = {CascadeType.REFRESH})
@JoinColumn(name = "ORG_ID", referencedColumnName = "ORG_ID", insertable = false, updatable = false)*//*
public AdminSmOrg getAdminSmOrg() {
return adminSmOrg;
}
public void setAdminSmOrg(AdminSmOrg adminSmOrg) {
this.adminSmOrg = adminSmOrg;
}
// @JsonIgnore
*//*@ManyToOne(cascade = {CascadeType.REFRESH})
@JoinColumn(name = "DPT_ID", referencedColumnName = "DPT_ID", insertable = false, updatable = false)*//*
public AdminSmDpt getAdminSmDpt() {
return adminSmDpt;
}
public void setAdminSmDpt(AdminSmDpt adminSmDpt) {
this.adminSmDpt = adminSmDpt;
}*/
@ManyToOne(targetEntity=AdminSmDpt.class,cascade = {CascadeType.REFRESH})
@JoinColumn(name="DPT_ID",referencedColumnName="DPT_ID",insertable = false, updatable = false)
public AdminSmDpt getAdminSmDpt() {
return adminSmDpt;
}
public void setAdminSmDpt(AdminSmDpt adminSmDpt) {
this.adminSmDpt = adminSmDpt;
}
以上是用户实体类
接下来看里面的用得到的两个典型例子一个是role角色表实体类,和dpt部门实体类。其中角色和用户是多对多的关系就是说一个用户可以承担多个角色,一个角色可以多人承担,用户和部门就是多对一的关系了一个用户只能属于一个部门。两个注解是不一样的。参考相关大神的描述学习了一下。
当然最重要的特点步是对应关系,而是表关系,其中用户角色表有一个关联关系表,看下图。
这就引出了连接关系的区别,进而注解也不一样
下边是学习是的讲解
//这里首先是这个注解joincolumn指出的是两个表的关联属性,其中name是该实体类的对应的表中的外键名,referencecolumnname是指关联的表中与之对应的字段名称。
joinColumns = {@JoinColumn(name = "USER_ID", referencedColumnName = "USER_ID")},
首先是第三个表维护关联关系的
我们的关联关系的维护让第三张表来维护啦。对于大部分的N_1单向关系,只要基于外键的关联关系维护已经够了。
如果有需要使用连接表来维护关联关系,程序可以使用连接表显示的维护这种关系,所谓连接表就是建立第三张表格来维护我们的关系就行了。使用@JoinTable
下面的是java给的例子,除了这些属性外,我们还可以指定targetEntity。指定关联的实体是哪个!也就是生成表的是哪个表所对应的实体。`
@ManyToMany
@JoinTable(
//第三张关联表的表明name
name = "ADMIN_SM_USER_ROLE_REL",
//当前实体类对应的表与关联表的外键对应关系
joinColumns = {@JoinColumn(name = "USER_ID", referencedColumnName = "USER_ID")},
//关联表与真正要连接的实体表之间的外键对应关系。里面的参数意思就和单个joincolumn是一样的。
inverseJoinColumns = {@JoinColumn(name = "ROLE_ID", referencedColumnName = "ROLE_ID")})
@BatchSize(size = 20)
public Set<AdminSmRole> getAuthorities() {
return authorities;
}
public void setAuthorities(Set<AdminSmRole> authorities) {
this.authorities = authorities;
}
没有第三张表的情况(比较常用)
无连接也就是不需要第三张表,维护我们的关联关系。对于N_1关联关系,我们只需要在N的一端增加一列外键即可。让外键的值记录到该属性的实体即可。Hibernate使用@JoinColumn来修饰代表关联实体的属性,用于映射底层的外键列。这种就不使用连接表了
@ManyToOne(targetEntity=AdminSmDpt.class,cascade = {CascadeType.REFRESH})
@JoinColumn(name="DPT_ID",referencedColumnName="DPT_ID",insertable = false, updatable = false)
public AdminSmDpt getAdminSmDpt() {
return adminSmDpt;
}
直接使用该注解就好了。
但是使用中有个疑问点:
insertable与updatable刚开始没有添加,运行会报错,要求必须加上。
正在研究。