hibernate之映射关系一对一(2种方式)
Hibernate实体关系映射
a) 一对一
i. 共享主键一对一方式:实现两个表或对象使用同一主键的值、通过主键映射方式实现一对一的关联
1. 使用范围:一般确定一对一的关系不变化,比如:用户登录(账号和密码)、用户详细信息(名称、性别、。。。)
2. 创建表:
create table t_user(
u_id varchar(255),
u_name varchar(255),
u_age Integer,
u_price double(5,2),
primary key(u_id)
);
create table t_user_class(
uc_id varchar(255),
uc_classNo Integer,
uc_funds double(5,2),
uc_back varchar(255),
primary key(uc_id));
3. java类
public class UserT implements Serializable{
private String id;
public String name;
private Integer age;
private double price;
private UserClass userclass;
public UserT(){}
....此处略去get、set方法
public class UserClass {
private String id;
private Integer classNo;
private double funds;
private String back;
private UserT user;
public UserClass(){}
....此处略去get、set方法
4. 映射文件:
UserT .hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"https://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.wolf.pojo.oneToone" auto-import="false">
<class name="UserT" table="t_user">
<!-- 一对一:共享主键 -->
<id name="id" column="u_id">
<generator class="foreign">
<param name="property">userclass</param>
</generator>
</id>
<property name="name" column="u_name"/>
<property name="age" column="u_age"/>
<property name="price" column="u_price"/>
<!-- constrained=true :标识当前表的主键上存在外键 (子表-子类)-->
<one-to-one name="userclass" class="UserClass" constrained="true"></one-to-one>
</class>
</hibernate-mapping>
UserClass .hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"https://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.wolf.pojo.oneToone">
<class name="UserClass" table="t_user_class">
<id name="id" column="uc_id"/>
<property name="classNo" column="uc_classNo"/>
<property name="funds" column="uc_funds"/>
<property name="back" column="uc_back"/>
<!-- 主表:cascade="all" 保存主表数据级联保存子表的数据 -->
<one-to-one name="user" class="UserT" cascade="all" lazy="false"></one-to-one>
</class>
</hibernate-mapping>
在此遇到一个问题,主表保存级联保存子表,但是子表不能设置子表的ID主键,否则会抛出
Exception in thread "main" org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1的异常
程序代码:
Session session= HibernateSessionFactory.getSession();
Transaction tr=session.beginTransaction();
UserT user=new UserT();
user.setId(UUID.randomUUID().toString());//此处不能设置id值
UserClass usercls=new UserClass();
usercls.setId(UUID.randomUUID().toString());
user.setUserclass(usercls);
usercls.setUser(user);
session.save(usercls);
tr.commit();
ii. 唯一外键方式
1. 创建表:
create table t_user(
u_id varchar(255),
u_name varchar(255),
u_age Integer,
u_price double(5,2),
uc_id varchar(255),
primary key(u_id)
);
create table t_user_class(
uc_id varchar(255),
uc_classNo Integer,
uc_funds double(5,2),
uc_back varchar(255),
primary key(uc_id));
2. java类
public class UserT implements Serializable{
private String id;
public String name;
private Integer age;
private double price;
private UserClass userclass;
public UserT(){}
....此处略去get、set方法
public class UserClass {
private String id;
private Integer classNo;
private double funds;
private String back;
private UserT user;
public UserClass(){}
....此处略去get、set方法
3. 映射文件:
UserT .hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"https://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.wolf.pojo.oneToone" auto-import="false">
<class name="UserT" table="t_user">
<!-- 一对一:外键 -->
<id name="id" column="u_id">
</id>
<property name="name" column="u_name"/>
<property name="age" column="u_age"/>
<property name="price" column="u_price"/>
<many-to-one name="userclass" class="UserClass" column="uc_id" unique="true" lazy="false" cascade="all"></many-to-one>
</class>
</hibernate-mapping>
UserClass .hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"https://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.wolf.pojo.oneToone">
<class name="UserClass" table="t_user_class">
<id name="id" column="uc_id"/>
<property name="classNo" column="uc_classNo"/>
<property name="funds" column="uc_funds"/>
<property name="back" column="uc_back"/>
<one-to-one name="user" class="UserT" ></one-to-one>
</class>
</hibernate-mapping>
4. 测试代码
package com.wolf.main;
import java.util.UUID;
import org.hibernate.Session;
import org.hibernate.Transaction;
import com.wolf.pojo.oneToone.UserClass;
import com.wolf.pojo.oneToone.UserT;
public class UtilMain {
public static void main(String[] args) {
Session session= HibernateSessionFactory.getSession();
Transaction tr=session.beginTransaction();
UserT user=new UserT();
user.setId(UUID.randomUUID().toString());
UserClass usercls=new UserClass();
usercls.setId(UUID.randomUUID().toString());
user.setUserclass(usercls);
usercls.setUser(user);
session.save(user);
tr.commit();
// System.out.println(((UserClass)session.get(UserClass.class, "8b69936a-cfe0-401a-a895-45f1df4422a4")).getUser().getId());
}
}
最后更新:2017-04-04 07:03:25