Hibernate一对一数据关联
(1)一对一关联
例如:一个人有一份个人资料。应该有两张表,一张是个人表,另外一张是信息表
create table personInfo
(
uid int identity(1,1) primary key,
name varchar(20) not null,
age int not null
)
create table info
(
id int,
address varchar(100) not null,
tel varchar(100) not null,
email varchar(100) not null
foreign key(id) references personInfo(uid) on delete cascade
)
此时被关联的表存在多个字段,所以此时建立POJO类的时候肯定要建立两个POJO类
PersonInfo 中应该包含Info属性,而Info类中要包含PersonInfo属性
PersonInfo.java
public class PersonInfo {
private int uid;
private String name;
private int age;
private Info info;
public Info getInfo() {
return info;
}
public void setInfo(Info info) {
this.info = info;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getUid() {
return uid;
}
public void setUid(int uid) {
this.uid = uid;
}
}
Info.java:
public class Info {
private int id;
private String address;
private String tel;
private String email;
private PersonInfo personInfo;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public PersonInfo getPersonInfo() {
return personInfo;
}
public void setPersonInfo(PersonInfo personInfo) {
this.personInfo = personInfo;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
}
但是两个类的关系如果想要正确,还必须配置映射文件。
PersonInfo.hbm.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="collection.PersonInfo" table="personInfo" catalog="myshop" schema="dbo">
<id name="uid" type="java.lang.Integer">
<column name="uid"></column>
<generator type="java.lang.String">
<column name="name" length="20" not-null="true"></column>
</property>
<property name="age" type="java.lang.Integer">
<column name="age" not-null="true"/>
</property>
<one-to-one name="info" cascade="all"></one-to-one>
</class>
</hibernate-mapping>
Info.hbm.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="collection.Info" table="info" catalog="myshop" schema="dbo">
<id name="id" type="java.lang.Integer">
<column name="id"></column>
<generator type="java.lang.String">
<column name="address" length="100" not-null="true"/>
</property>
<property name="tel" type="java.lang.String">
<column name="tel" length="100" not-null="true"/>
</property>
<property name="email" type="java.lang.String">
<column name="email" length="100" not-null="true"></column>
</property>
<one-to-one name="personInfo" cascade="all"></one-to-one>
观察结果:
public void find1()
{
String hql="FROM PersonInfo p where p.uid=6";
PersonInfo p=(PersonInfo)session.createQuery(hql).uniqueResult();
System.out.println(p.getName());
System.out.println(p.getInfo().getAddress());
}
执行两条查询语句
public void find2()
{
PersonInfo p=(PersonInfo)session.get(PersonInfo.class, new Integer(6));
System.out.println(p.getName());
System.out.println(p.getInfo().getAddress());
}
执行一条查询语句
更新操作:
public void doUpdate1()
{
PersonInfo p=new PersonInfo();
p.setUid(6);
p.setName("小八");
p.setAge(20);
Info info=new Info();
info.setAddress("河南");
info.setTel("13260100334");
info.setEmail("[B: adfk@dfkl.com[/B]]adfk@dfkl.com");
p.setInfo(info);
info.setPersonInfo(p);
session.update(p);
session.beginTransaction().commit();
session.close();
}
以上是一个新的实体,进行更新操作。
执行SQL语句:
Hibernate: insert into myshop.dbo.info (address, tel, email, id) values (?, ?, ?, ?)
Hibernate: update myshop.dbo.personInfo set name=?, age=? where uid=?
出现两个记录,导致垃圾数据
更新的时候如果配置好了级联关系,则可能会执行插入新记录的操作。
public void doUpdate2()
{
PersonInfo p=(PersonInfo)session.get(PersonInfo.class, new Integer(7));
p.setName("小八");
p.setAge(20);
p.getInfo().setAddress("地球");
p.getInfo().setTel("23423423");
p.getInfo().setEmail("[B: adfa@aldf.com[/B]]adfa@aldf.com");
session.update(p);
session.beginTransaction().commit();
session.close();
}
执行的SQL语句:
Hibernate: update myshop.dbo.info set address=?, tel=?, email=? where id=?
Hibernate: update myshop.dbo.personInfo set name=?, age=? where uid=?
因为是先查询出来的实体,所以保存了对象的状态,更新的时候就不会进行插入的了
以上都是使用update方法来完成的,本身不建议这样使用,最好使用HQL中update方法。