第六章 一对一关系

什么时候采用一对一关系映射呢?
比如我们有时在网上注册的时候,用户名,密码,邮箱必填,然后提供了一个复选框,可以选填用户的详细资料.那么如果在数据库中, 我们通常会建两张表,如下:
[img]http://dl.iteye.com/upload/attachment/241733/74c13966-936a-3ada-a449-a710e74939f1.bmp[/img]
但是在Hibernate中会怎么实现这个呢,大家过细观察一下,会不会觉得这个外键有点多余,如果我们让从表的ID和主表的ID一样,即让从表的ID即是主键又是外键,会不会更好呢,Hibernate中就是这样实现一对一的关系的.
[img]http://dl.iteye.com/upload/attachment/241735/fe7bc3e4-5d52-3a98-a30e-f84b4d2389e1.bmp[/img]
那么下面请看具体代码:
我们将利用自动创建SQL的特点来建表,我们就不需要建表了,只需要建立类,关联类之间的关系就可以了.

UserBase:
public class UserBase {
private String id;
private String userAccount;
private String userPwd;
private String userEmail;
private UserData userData;

public UserBase() {
super();
}

public UserBase(String userAccount, String userPwd, String userEmail) {
super();
this.userAccount = userAccount;
this.userPwd = userPwd;
this.userEmail = userEmail;
}

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public String getUserAccount() {
return userAccount;
}

public void setUserAccount(String userAccount) {
this.userAccount = userAccount;
}

public String getUserPwd() {
return userPwd;
}

public void setUserPwd(String userPwd) {
this.userPwd = userPwd;
}

public String getUserEmail() {
return userEmail;
}

public void setUserEmail(String userEmail) {
this.userEmail = userEmail;
}

public UserData getUserData() {
return userData;
}

public void setUserData(UserData userData) {
this.userData = userData;
}
}

UserData:
import java.util.Date;

public class UserData {
private String id;
private String userName;
private Date birthday;
private String mobile;
private UserBase userBase;

public UserData() {
super();
}

public UserData(String userName, Date birthday, String mobile) {
super();
this.userName = userName;
this.birthday = birthday;
this.mobile = mobile;
}

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public String getUserName() {
return userName;
}

public void setUserName(String userName) {
this.userName = userName;
}

public Date getBirthday() {
return birthday;
}

public void setBirthday(Date birthday) {
this.birthday = birthday;
}

public String getMobile() {
return mobile;
}

public void setMobile(String mobile) {
this.mobile = mobile;
}

public UserBase getUserBase() {
return userBase;
}

public void setUserBase(UserBase userBase) {
this.userBase = userBase;
}
}

UserBase.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="chapter3.model.UserBase" table="user_base">
<id name="id" type="java.lang.String" column="id" length="32">
<generator class="uuid.hex" />
</id>
<property name="userAccount" type="java.lang.String" column="userAccount"
length="20" />
<property name="userPwd" type="java.lang.String" column="userPwd"
length="20" />
<property name="userEmail" type="java.lang.String" column="userEmail"
length="50" />
<one-to-one name="userData" class="chapter3.model.UserData" />
</class>
</hibernate-mapping>

UserData.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="chapter3.model.UserData" table="user_data">
<id name="id" type="java.lang.String" column="id" length="32">
<generator class="foreign">
<param name="property">userBase</param>
</generator>
</id>
<property name="userName" type="java.lang.String" column="userName"
length="50" />
<property name="birthday" type="java.util.Date" column="birthday"
length="10" />
<property name="mobile" type="java.lang.String" column="mobile"
length="11" />
<one-to-one name="userBase" class="chapter3.model.UserBase" />
</class>
</hibernate-mapping>

UserBaseDao:
public class UserBaseDao {
public void create(UserBase userBase) throws Exception {
Session session = null;
try {
session = HibernateUtil.getSession();
session.beginTransaction();
session.save(userBase);
session.getTransaction().commit();
} catch (Exception e) {
session.getTransaction().rollback();
throw e;
}
}

public UserBase findById(Serializable id) throws Exception {
Session session = null;
UserBase userBase = null;
try {
session = HibernateUtil.getSession();
session.beginTransaction();
userBase = (UserBase) session.get(UserBase.class, id);
session.getTransaction().commit();
} catch (Exception e) {
session.getTransaction().rollback();
throw e;
}
return userBase;
}
}

UserDataDao:
public class UserDataDao {
public void create(UserData userData) throws Exception {
Session session = null;
try {
session = HibernateUtil.getSession();
session.beginTransaction();
session.save(userData);
session.getTransaction().commit();
} catch (Exception e) {
session.getTransaction().rollback();
throw e;
}
}

public UserData findById(Serializable id) throws Exception {
Session session = null;
UserData userData = null;
try {
session = HibernateUtil.getSession();
session.beginTransaction();
userData = (UserData) session.get(UserData.class, id);
session.getTransaction().commit();
} catch (Exception e) {
session.getTransaction().rollback();
throw e;
}
return userData;
}
}

Test:
public class Test {
public static void main(String[] args) throws Exception {
UserBaseDao userBaseDao = new UserBaseDao();
UserDataDao userDataDao = new UserDataDao();

UserBase userBase = new UserBase("zhanghaidang", "791126",
"wdpc@163.com");
userBaseDao.create(userBase);

UserData userData = new UserData("张海当", new Date(), "13986007262");
userData.setUserBase(userBase);
userDataDao.create(userData);
}
}

总结:
主键关联一对一映射不需要额外的字段,对象之间必须共享相同的主键;
一对一映射默认采用级联操作,存储一个对象的时候,另一个对象也同时被储存;
配置子表的主键时,注意主键的生成策略:
<id name="id" type="java.lang.String" column="id" length="32">
<generator class="foreign">
<param name="property">userBase</param>
</generator>
</id>
采用的是foreign外键策略,意指该表的主键来自另一张表, 并且需要告诉策略对应的类,可以查看源码包下的ForeignGenerator类的源代码,重点看下面的代码,该类会获取一个参数 params.getProperty("property"); 那么这时我们需要将property参数的值传给它, 传参的代码为上面的形式.
public void configure(Type type, Properties params, Dialect d)
throws MappingException {
propertyName = params.getProperty("property");
entityName = params.getProperty(ENTITY_NAME);
if (propertyName==null) throw new MappingException(
"param named \"property\" is required for foreign id generation strategy"
);
}

运用的时候需要注意,一定要先创建主表的对应类,因为只有创建了主表的对应类,子表才能够取得ID主键,从而为自己设置主键的值.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值