关系映射是指对象之间的关系,并不是指数据库的关系,关系映射是解决当对象处于以下关系之一时,数据库表该如何映射的问题
(一)一对一单向外键关联
1、注解方式配置
创建一个Husband类和Wife类
Husband类:(getWife方法上加注解OneToOne)
package cn.orlion.hibernate.model; import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne; @Entity
public class Husband { private int id; private String name; private Wife wife; @Id
@GeneratedValue
public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
@OneToOne
@JoinColumn(name="wifeId")//默认生成的外键id是wife_id在这里使用JoinColumn注解name属性指定为wifeId
public Wife getWife() {
return wife;
} public void setWife(Wife wife) {
this.wife = wife;
}
}
Wife类
package cn.orlion.hibernate.model; import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id; @Entity
public class Wife { private int id; private String name; @Id
@GeneratedValue
public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
}
然后创建一个测试类HibernateMappingTest
package cn.orlion.hibernate.model; import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.tool.hbm2ddl.SchemaExport; import org.junit.Test; public class HibernateORMappingTest { @Test
public void testSchemaExport(){ new SchemaExport(new AnnotationConfiguration().configure()).create(true , true);
} }
运行testSchemaExport可以在控制台看到建表语句:
2、xml方式配置
首先创建一个Student类和StuIdCard(学生证)
Student类:
package cn.orlion.hibernate.model; public class Student { private int id; private String name; private String sex; public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getSex() {
return sex;
} public void setSex(String sex) {
this.sex = sex;
}
}
StuIdCard:
package cn.orlion.hibernate.model; public class StuIdCard { private int id; private int num; private Student student; public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public int getNum() {
return num;
} public void setNum(int num) {
this.num = num;
} public Student getStudent() {
return student;
} public void setStudent(Student student) {
this.student = student;
}
}
然后创建两个配置文件Student.hbm.xml:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="cn.orlion.hibernate.model">
<class name="cn.orlion.hibernate.model.Student">
<id name="id">
<generator class="native"></generator>
</id> <property name="name"></property> <property name="sex"></property>
</class>
</hibernate-mapping>
StuIdCard.hbm.xml:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="cn.orlion.hibernate.model">
<class name="cn.orlion.hibernate.model.StuIdCard">
<id name="id">
<generator class="native"></generator>
</id> <property name="num" /> <many-to-one name="student" column="studentId" unique="true"></many-to-one>
<!-- many-to-one是当前类即StuIdCard类相对于Student类是多对一关系 (多个学生证对应一个学生) ,unique=true限定为了一对一 -->
</class>
</hibernate-mapping>
然后运行测试类HibernateORMappingTest类的testSchemaExport方法可以在控制台看到建表语句:
(二)一对一双向外键关联
1、注解方式设置
双向外键关联注解方式设置是在wife类中添加husband属性,在getHusband()方法上添加注解@OneToOne(mappedBy="wife")//mappedBy="wife"表示Husband中wife属性已经做映射了,不用管当前类的设置(不再从wife表中生成指向husband的外键)注:如果不写mappedBy="wife"会在wife表中生成一个husband_id外键,这是多余的。
Wife类:
package cn.orlion.hibernate.model; import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne; @Entity
public class Wife { private int id; private String name; private Husband husband; @Id
@GeneratedValue
public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
@OneToOne(mappedBy="wife")//mappedBy="wife"表示Husband中wife属性已经做映射了,不用管当前类的设置(不再从wife表中生成指向husband的外键)
public Husband getHusband() {
return husband;
} public void setHusband(Husband husband) {
this.husband = husband;
} }
2、xml方式配置
在Student.hbm.xml配置文件中添加<one-to-one name="stuIdCard" property-ref="student"></one-to-one>,在Student类中添加stuIdCard属性:
Student类:
package cn.orlion.hibernate.model; public class Student { private int id; private String name; private String sex; private StuIdCard stuIdCard; public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getSex() {
return sex;
} public void setSex(String sex) {
this.sex = sex;
} public StuIdCard getStuIdCard() {
return stuIdCard;
} public void setStuIdCard(StuIdCard stuIdCard) {
this.stuIdCard = stuIdCard;
} }
Student.hbm.xml:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="cn.orlion.hibernate.model">
<class name="cn.orlion.hibernate.model.Student">
<id name="id">
<generator class="native"></generator>
</id> <property name="name"></property> <property name="sex"></property> <one-to-one name="stuIdCard" property-ref="student"></one-to-one>
<!-- one-to-one只会在一边生成主键,如果这里设置为many-to-one会在student表中生成多余的stuidcard_id外键 -->
<!-- property-ref="student" 类似于mappedby="student"是指在StuIdCard中student属性已经设置好了关联关系 -->
</class>
</hibernate-mapping>
注:一对一单向和双向在数据库中表现没有区别
主键关联是指的一个表的主键和另外一个表的主键关联
外键关联是指的一个表的主键和另外一个表的非主键关联
(三)一对一单向主键关联
xml方式配置:
创建Student类
package cn.orlion.hibernate.model; public class Student { private int id; private String name; private String sex; public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getSex() {
return sex;
} public void setSex(String sex) {
this.sex = sex;
}
}
StuIdCard类:
package cn.orlion.hibernate.model; public class StuIdCard { private int id; private int num; private Student student; public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public int getNum() {
return num;
} public void setNum(int num) {
this.num = num;
} public Student getStudent() {
return student;
} public void setStudent(Student student) {
this.student = student;
}
}
Student.hbm.xml:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="cn.orlion.hibernate.model">
<class name="cn.orlion.hibernate.model.Student">
<id name="id">
<generator class="native"></generator>
</id> <property name="name"></property> <property name="sex"></property>
</class>
</hibernate-mapping>
StuIdCard.hbm.xml:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="cn.orlion.hibernate.model">
<class name="cn.orlion.hibernate.model.StuIdCard">
<id name="id">
<generator class="foreign"><!-- StuIdCard的主键应该靠外键来生成,StuIdCard -->
<param name="property">student</param><!-- 依靠student属性的关联关系 -->
</generator>
</id> <property name="num" /> <one-to-one name="student" constrained="true"></one-to-one>
<!-- constrained="true"用来生成外键约束,不加这个属性就不会加外键 -->
</class>
</hibernate-mapping>
运行:
(四)一对一双向主键关联
注解方式配置:
Husband类:
package cn.orlion.hibernate.model; import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn; @Entity
public class Husband { private int id; private String name; private Wife wife; @Id
@GeneratedValue
public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
@OneToOne
@PrimaryKeyJoinColumn
public Wife getWife() {
return wife;
} public void setWife(Wife wife) {
this.wife = wife;
}
}
Wife类:
package cn.orlion.hibernate.model; import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne; @Entity
public class Wife { private int id; private String name; private Husband husband; @Id
@GeneratedValue
public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
@OneToOne
@PrimaryKeyJoinColumn
public Husband getHusband() {
return husband;
} public void setHusband(Husband husband) {
this.husband = husband;
} }
(五)联合主键映射
Wife类:
package cn.orlion.hibernate.model; import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.IdClass; @Entity
@IdClass(WifePK.class)
public class Wife { private int id; private String name; private String age; @Id
public int getId() {
return id;
} public void setId(int id) {
this.id = id;
}
@Id
public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getAge() {
return age;
} public void setAge(String age) {
this.age = age;
} }
WifePK:
package cn.orlion.hibernate.model; public class WifePK implements java.io.Serializable{ private int id; private String name; public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
}
Husband类:
package cn.orlion.hibernate.model; import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinColumns;
import javax.persistence.OneToOne; @Entity
public class Husband { private int id; private String name; private Wife wife; @Id
@GeneratedValue
public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
@OneToOne
@JoinColumns(
{
@JoinColumn(name="wifeId" , referencedColumnName="id"),
@JoinColumn(name="wifeName" , referencedColumnName="name")
}
)
public Wife getWife() {
return wife;
} public void setWife(Wife wife) {
this.wife = wife;
}
}
运行结果: