hibernate里面的数据映射关系:
个人理解:1)双向与单向,数据库表里面都是一样的结构,可是在pojo里面就不一样,2个对应表都要互相保存对方的引用(双向),都要写注解注明是什么对什么。(我感觉一般都用单向)
2)而一对多,多对一等,只是站的角度不一样,站在谁的角度上看问题,谁就是主导。
1对1关联 :onetoone (如果是双向,则在另外一方也写上onetoone,并且要写mappedby,否则会有冗余)
单向举例 :一个丈夫有一个妻子,在丈夫里面保存一个妻子的引用,在丈夫这写上onetoone,并且写上@JoinColumn(name="wife_id"),用来设置丈夫这里一个字段关联妻子的id(默认是关联妻子的主键id,如果你想关联妻子里面另外个非主键字段otherid,你得这样写@JoinColumn(name="wife_id",referencedColumnName="otherid"),但是那个wife里面的otherid必须设置成unique属性,即唯一约束。), 妻子那别写什么了(双向妻子那就得写)。
双向举例 :丈夫有了妻子的引用,在妻子那也保存一个丈夫的引用,写上onetoone,并且写上mappedby(写上在hasband中做映射的那个属性wife)意思是通过丈夫设置一个外键(wife_id)关联妻子的id,妻子这就不设置外键(husband_id)去关联丈夫的id了。或者理解为:告诉hibernate说,这里别做映射了,在hasband里面的wife属性,已经做了映射
单向表结构为:
create table Hasband (
id integer not null auto_increment,
hasbandName varchar(255),
wife_id integer,
primary key (id)
)
create table Wife (
id integer not null auto_increment,
wifeName varchar(255),
primary key (id)
)
alter table Hasband
add index FK8CC953AFD7B39F38 (wife_id),
add constraint FK8CC953AFD7B39F38
foreign key (wife_id)
references Wife (id)
双向表结构也是
create table Hasband (
id integer not null auto_increment,
hasbandName varchar(255),
wife_id integer,
primary key (id)
)
create table Wife (
id integer not null auto_increment,
wifeName varchar(255),
primary key (id)
)
alter table Hasband
add index FK8CC953AFD7B39F38 (wife_id),
add constraint FK8CC953AFD7B39F38
foreign key (wife_id)
references Wife (id)
在数据库中单向和双向中,数据库里面表的表现没有区别,但是区别在于java程序中,单向可以通过某一方找到另一方,而不能通过另一方找到某一方。而双向可以。
注:双向关联,必设mappedby
1对1主键关联 :(很少用)主键的生成方式要改成foreign,不能native由hibernate生成,并指定根据哪个表生成。
@joinClum换成 @primaryKeyJoinClunm
单向和双向的设置方式就是直接在另外一个表中加上另一个表的引用,在加上 @primaryKeyJoinClunm就行了,2边设置基本一样
单向表结构和双表结构在数据库中都是一样的:
create table Hasband (
id integer not null auto_increment,
hasbandName varchar(255),
primary key (id)
)
create table Wife (
id integer not null auto_increment,
wifeName varchar(255),
primary key (id)
)
alter table Hasband
add index FK8CC953AF87B48F4A (id),
add constraint FK8CC953AF87B48F4A
foreign key (id)
references Wife (id)
在项目中,一般1对1 很少用,因为1对1可以设计成1张表,没必要设计成2张表.即把wife的所有信息放在丈夫这张表上面。
/********************************华丽分隔************************************************/
联合主键:
我就不写了,没时间,要写个联合组件类(必须要实现Serializable接口),关键注解地方: @Idclass (XX.class),记得要在联合组件那个表上写2个@Id或者多个
@joinclunms(
{
@joinclunm(name="xx", referencedColumnName="xx"),
@joinclunm(name="xx", referencedColumnName="xx")
}
)
那个联合组件类不是实体,只要把联合主键的字段写进去然后get和set就行了。
/**********************************再一次华丽分隔***********************************************/
组件映射:
妻子和丈夫的关系,在数据库中设计成一张表,在java中用2个类表示。 @Embedded
///wife是组件类,不用注解
public class Wife {
private String wifeName;
private Integer wifeid;
public String getWifeName() {
return wifeName;
}
public void setWifeName(String wifeName) {
this.wifeName = wifeName;
}
public Integer getWifeid() {
return wifeid;
}
public void setWifeid(Integer wifeid) {
this.wifeid = wifeid;
}
}
///hasband类
@Entity
public class Hasband {
private Integer id;
private String hasbandName;
private Wife wife;
@Id
@GeneratedValue
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getHasbandName() {
return hasbandName;
}
public void setHasbandName(String hasbandName) {
this.hasbandName = hasbandName;
}
@Embedded // 嵌入,用于组件
public Wife getWife() {
return wife;
}
public void setWife(Wife wife) {
this.wife = wife;
}
}
表结构如下:
create table Hasband (
id integer not null auto_increment,
hasbandName varchar(255), //husband中的字段
wifeName varchar(255), //wife组件中的字段
wifeid integer, //wife组件中的字段
primary key (id)
)
/**********************************第三次华丽分隔***********************************************/
多对1:manyTOone
单向的多对一 :一个人在一个组中,一个组有多个人。User是多的一方,Group是1的那方,在User那方保持一个Group的引用,
然后设置manytoone
多对一,就是站在多的那一方来考虑
多的一方
@Entity
@Table(name="t_user")
public class User {
private Integer id;
private String userName;
private Group group;
@Id
@GeneratedValue
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
@ManyToOne
@JoinColumn(name="group_id")
public Group getGroup() {
return group;
}
public void setGroup(Group group) {
this.group = group;
}
}
/1的那方
@Entity
@Table(name="t_gruop")
public class Group {
private Integer id;
private String groutName;
@Id
@GeneratedValue
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getGroutName() {
return groutName;
}
public void setGroutName(String groutName) {
this.groutName = groutName;
}
}
生成数据库表结构:
create table t_gruop (
id integer not null auto_increment,
groutName varchar(255),
primary key (id)
)
create table t_user (
id integer not null auto_increment,
userName varchar(255),
group_id integer,
primary key (id)
)
alter table t_user
add index FKCB63CCB68C2CFDFC (group_id),
add constraint FKCB63CCB68C2CFDFC
foreign key (group_id)
references t_gruop (id)
1对多:onetomany
单向1对多: 一个人在一个小组,一个小组多个人,User是多,Gruop是1,站在1这一角度看,Group里面写个集合,保存多个User,然后写onetomany
一定要写 @JoinColumn(name="group_id") ,不然hibernate会生成三张表,一张是中间表,认为是多对多。
无论在1对多,还是多对1,joincolumn的字段永远是在多的那一方。
生成数据表结构: ///貌似和多对1生成的表结构一样,只是站在不同的角度上看问题而已。能从1放推出多方,而多对1能在多方推出1放。
create table t_gruop (
id integer not null auto_increment,
groutName varchar(255),
primary key (id)
)
create table t_user (
id integer not null auto_increment,
userName varchar(255),
group_id integer,
primary key (id)
)
alter table t_user
add index FKCB63CCB68C2CFDFC (group_id),
add constraint FKCB63CCB68C2CFDFC
foreign key (group_id)
references t_gruop (id)
1对多,多对1双向关联:
在1这方写上onetomany,在多方写上manytoone,外键写在多方,关联1方的id。
@Entity
@Table(name="t_user")
public class User {
private Integer id;
private String userName;
private Group group;
@Id
@GeneratedValue
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
@ManyToOne
@JoinColumn(name="ttttttt")
public Group getGroup() {
return group;
}
public void setGroup(Group group) {
this.group = group;
}
}
@Entity
@Table(name="t_gruop")
public class Group {
private Integer id;
private String groutName;
private Set<User> user = new HashSet<User>(); //记得要初始化,我也不知道为什么,我看视频上是这样做的。
@Id
@GeneratedValue
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getGroutName() {
return groutName;
}
public void setGroutName(String groutName) {
this.groutName = groutName;
}
@OneToMany(mappedBy="group") ///对hibernate说,“在多方的group上设置关联,我这你就别管了,我只是打酱油”
public Set<User> getUser() {
return user;
}
public void setUser(Set<User> user) {
this.user = user;
}
}
生成数据库表结构:
create table t_gruop (
id integer not null auto_increment,
groutName varchar(255),
primary key (id)
)
create table t_user (
id integer not null auto_increment,
userName varchar(255),
ttttttt integer,
primary key (id)
)
alter table t_user
add index FKCB63CCB632DCAC15 (ttttttt),
add constraint FKCB63CCB632DCAC15
foreign key (ttttttt)
references t_gruop (id)
/**********************最后一次分隔***********************************************/
多对多:manytomany
///单向的
@Entity
public class Student {
private Integer id ;
private String studentName;
private Set<Teacher> teachers = new HashSet<Teacher>();
@Id
@GeneratedValue
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getStudentName() {
return studentName;
}
public void setStudentName(String studentName) {
this.studentName = studentName;
}
@ManyToMany
@JoinTable(name="t_s",
joinColumns={@JoinColumn(name="student_id")},
inverseJoinColumns={@JoinColumn(name="teacher_id")}
)
public Set<Teacher> getTeachers() {
return teachers;
}
public void setTeachers(Set<Teacher> teachers) {
this.teachers = teachers;
}
}
@Entity
public class Teacher {
private Integer id;
private String name;
/*private Set<Student> students = new HashSet<Student>();*/
@Id
@GeneratedValue
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
/双向的话,在Teacher写个set保存Student