我们知道ORM是对象—关系映射的意思,是沟通对象和底层关系数据库之间的桥梁,可以简单的将对象和关系数据库中的表对应起来,在关系数据库中,不同的表之间存在不同的关系,比如一对一,一对多,多对多等,那怎样用Java语言在上层对底层关系进行实现呢,我们本文来详细讲述一下。
一对一的映射关系
一对一的映射关系应该是最简单最基础的一种映射关系了,我们现实生活中有很多一对一映射关系的例子,最典型的就是一个人对应一个身份证号码,这里我们就用这个例子作为我们的讲述基础。
注意:本文所有的实例都将采用两种实现方法:Annotation注释和Xml配置文件方式,以供自己和大家深入理解。
1.1 一对一单向外键(Annotation)
单向外键的意思就是一个实体通过外键关联到另一个实体的主键。注:一对一,则外键必须为唯一约束。也就是说,映射关系交给一方来维护。
我们这里新建两个实体类:Students和IdCard,并且Students通过外键关联到IdCard的主键。
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
@Entity
public class Students {
private int sid;
private String sname;
private IdCard cardId;
@OneToOne(cascade=CascadeType.ALL)
@JoinColumn(name="pid",unique=true)//关联到IdCard的主键pid
public IdCard getCardId() {
return cardId;
}
public void setCardId(IdCard cardId) {
this.cardId = cardId;
}
@Id
@GeneratedValue
public int getSid() {
return sid;
}
public void setSid(int sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
}
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import org.hibernate.annotations.GenericGenerator;
@Entity
public class IdCard {
private String pid;//身份证号码
private String province;//省份
@Id
@GeneratedValue(generator="pid")//generator指明主键生成器的名称
@GenericGenerator(name="pid",strategy="assigned")
//@GenericGenerator为hibernate特有的注解方式,使其可以使用主键生成策略assigned
public String getPid() {
return pid;
}
public void setPid(String pid) {
this.pid = pid;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
}
然后执行SchemaExport():
@Test
public void testSchemaExport() {
SchemaExport se = new SchemaExport(new AnnotationConfiguration().configure());
se.create(true, true);
//第一个true就是把DDL语句输出到控制台,第二个true就是根据持久化类和映射文件先执行删除再执行创建操作
}
执行结果为:
可以看到:students表中插入了pid外键,而pid是idcard表的主键,这样两者就关联起来了。
现在,我们向两个表中插入数据:
@Test
public void testSave() {
Session session = sessionFactory.getCurrentSession();
Transaction tx = session.beginTransaction();
try {
IdCard c = new IdCard();
c.setPid("8888888888888888888");
c.setProvince("guangdong");
Students s = new Students();
s.setSname("zhangsan");
s.setCardId(c);
session.save(c);
//先保存外键对象
session.save(s);
//再保存主对象
tx.commit();
} catch (Exception e) {
e.printStackTrace();
tx.rollback();
}
}
执行结果为:
1.2 一对一单向外键(XML)
前面已经使用Annotation注解的方式实现了OneToOne关联方式,现在来简单介绍以下怎样通过配置文件,也就是*.hbm.xml,来达到相同的目的。
Students.hbm.xml的配置:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2016-7-26 21:10:34 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<class name="persistence_class_fk.Students" table="students">
<id name="sid" type="int">
<column name="sid"/>
<generator class="native"/>
</id>
<property generated="never" lazy="false" name="sname" type="string">
<column name="sname"/>
</property>
<!-- 一对一单向外键 主控方配置 name表示受控方对象 column表示关联的外键-->
<many-to-one name="cardId" column="pid" unique="true"/>
</class>
</hibernate-mapping>
IdCard.hbm.xml的配置:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2016-7-26 21:10:34 by Hibernate Tools 3.5.0.Final -->
<