• 背景:

  在实际开发中我们会遇到新建一个用户表,但这个表字段过长,而且有写字段常用(主要),有些字段比较不常用(次要)。此时,我们会考虑到把用户信息拆分到两张表中:member(存储用户主要信息),memberdetail(存储用户次要信息)。

  那么,这两个表就是很明显是一对一的关系,一个用户的基本信息只需要存储一份。

  上一章节我们介绍了在hibernate中一对一的关联关系通过外键来实现,本章节我们将会介绍,在hibernate中使用主键来实现一对一的关联关系。

  • hibernate实现过程中,需要注意事项:

  1)基于主键的映射策略:指一端的主键生成器使用foreign策略,表明根据“对方”的主键来生成自己的主键,自己并不能独立生成主键。<param>子元素指定使用当前持久化类的哪个属性作为“对方”。

  2)采用foriegn主键生成器策略的一端增加one-to-one元素映射关联属性,其one-to-one属性还应该增加constranied="true"属性;另一端增加one-to-one元素映射关联属性。

  3)constrained(约束):指定为当前持久化类对应的数据库表的主键添加一个外间约束,引用被关联的对象(“对方”)所对应的数据表主键。

  • 测试:

新建工程hibernate6,在src下新建包com.dx.hibernate005.onetoonebyprimary,

在包下新建Member.java

 package com.dx.hibernate005.onetoonebyprimary;

 import java.util.Date;

 public class Member {
private Integer id;
private String username;
private String password;
private Date createTime;
private MemberDetail memberDetail; public Member() {
super();
} public Member(String username, String password, Date createTime) {
super();
this.username = username;
this.password = password;
this.createTime = createTime;
} public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getUsername() {
return username;
} public void setUsername(String username) {
this.username = username;
} public String getPassword() {
return password;
} public void setPassword(String password) {
this.password = password;
} public Date getCreateTime() {
return createTime;
} public void setCreateTime(Date createTime) {
this.createTime = createTime;
} public MemberDetail getMemberDetail() {
return memberDetail;
} public void setMemberDetail(MemberDetail memberDetail) {
this.memberDetail = memberDetail;
} }

Member.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 2017-6-5 15:39:57 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping package="com.dx.hibernate005.onetoonebyprimary">
<class name="Member" table="MEMBER">
<id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="native" />
</id>
<property name="username" type="java.lang.String">
<column name="USERNAME" />
</property>
<property name="password" type="java.lang.String">
<column name="PASSWORD" />
</property>
<property name="createTime" type="java.util.Date">
<column name="CREATETIME" />
</property>
<one-to-one name="memberDetail" class="com.dx.hibernate005.onetoonebyprimary.MemberDetail"></one-to-one>
</class>
</hibernate-mapping>

MemberDetail.java

 package com.dx.hibernate005.onetoonebyprimary;

 import java.util.Date;

 public class MemberDetail {
private Integer memberId;
private Date birthDay;
private String address;
private Member member; public MemberDetail() {
super();
} public MemberDetail(Date birthDay, String address) {
super();
this.birthDay = birthDay;
this.address = address;
} public Integer getMemberId() {
return memberId;
} public void setMemberId(Integer memberId) {
this.memberId = memberId;
} public Date getBirthDay() {
return birthDay;
} public void setBirthDay(Date birthDay) {
this.birthDay = birthDay;
} public String getAddress() {
return address;
} public void setAddress(String address) {
this.address = address;
} public Member getMember() {
return member;
} public void setMember(Member member) {
this.member = member;
}
}

MemberDetail.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 2017-6-5 15:39:57 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping package="com.dx.hibernate005.onetoonebyprimary">
<class name="MemberDetail" table="MEMBERDETAIL">
<id name="memberId" type="java.lang.Integer">
<column name="MEMBERID" />
<generator class="foreign">
<param name="property">member</param>
</generator>
</id>
<property name="birthDay" type="java.util.Date">
<column name="BIRTHDAY" />
</property>
<property name="address" type="java.lang.String">
<column name="ADDRESS" />
</property>
<one-to-one name="member" class="com.dx.hibernate005.onetoonebyprimary.Member" constrained="true"></one-to-one>
</class>
</hibernate-mapping>

在src下创建hibernate.cfg.xml

 <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">123456</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost/hibernate_01</property> <!-- <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</property> -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property> <property name="hibernate.show_sql">true</property> <property name="hibernate.format_sql">true</property> <property name="hibernate.hbm2ddl.auto">update</property> <property name="hibernate.current_session_context_class">thread</property> <property name="hibernate.c3p0.max_size">500</property>
<property name="hibernate.c3p0.min_size">20</property>
<property name="hibernate.c3p0.max_statements">10</property>
<property name="hibernate.c3p0.timeout">2000</property>
<property name="hibernate.c3p0.idle_test_period">2000</property>
<property name="hibernate.c3p0.acquire_increment">10</property> <mapping resource="com/dx/hibernate005/onetoonebyprimary/Member.hbm.xml" />
<mapping resource="com/dx/hibernate005/onetoonebyprimary/MemberDetail.hbm.xml" /> <!--
<mapping class="com.dx.hibernate005.onetoonebyprimary.Member" />
<mapping class="com.dx.hibernate005.onetoonebyprimary.MemberDetail" />
-->
</session-factory>
</hibernate-configuration>

添加测试类TestMain.java

 package com.dx.hibernate005.onetoonebyprimary;

 import java.util.Date;

 import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.model.naming.ImplicitNamingStrategyComponentPathImpl;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test; public class TestMain {
private SessionFactory sessionFactory = null;
private Session session = null;
private Transaction transaction = null; @Before
public void init() {
StandardServiceRegistry standardRegistry = new StandardServiceRegistryBuilder().configure().build();
Metadata metadata = new MetadataSources(standardRegistry).getMetadataBuilder().applyImplicitNamingStrategy(ImplicitNamingStrategyComponentPathImpl.INSTANCE).build(); sessionFactory = metadata.getSessionFactoryBuilder().build();
session = sessionFactory.getCurrentSession();
transaction = session.beginTransaction();
} @After
public void destory() {
transaction.commit();
session.close();
sessionFactory.close();
}
}

添加测试函数,执行测试1:

     @Test
public void testInsert() {
Member member = new Member("user1","123456",new Date());
MemberDetail memberDetail = new MemberDetail(new Date(),"address1"); member.setMemberDetail(memberDetail);
memberDetail.setMember(member); session.save(memberDetail);
session.save(member);
}

输出sql:

 Hibernate: 

     create table MEMBER (
ID integer not null auto_increment,
USERNAME varchar(255),
PASSWORD varchar(255),
CREATETIME datetime,
primary key (ID)
) engine=InnoDB
Hibernate: create table MEMBERDETAIL (
MEMBERID integer not null,
BIRTHDAY datetime,
ADDRESS varchar(255),
primary key (MEMBERID)
) engine=InnoDB
Hibernate: alter table MEMBERDETAIL
add constraint FKsfbbuql27qw1ym706tof0nwcf
foreign key (MEMBERID)
references MEMBER (ID)
Hibernate:
insert
into
MEMBER
(USERNAME, PASSWORD, CREATETIME)
values
(?, ?, ?)
Hibernate:
insert
into
MEMBERDETAIL
(BIRTHDAY, ADDRESS, MEMBERID)
values
(?, ?, ?)

添加测试函数,执行测试2:

     @Test
public void testSelect() {
// 1.查询时,没采用懒加载。
Member member = (Member) session.get(Member.class, 1);
System.out.println(member.getUsername()); // 2.不会出现懒加载异常问题
session.close();
MemberDetail memberDetail = member.getMemberDetail();
System.out.println(memberDetail.getClass());
System.out.println(memberDetail.getAddress());
}

添加测试函数,执行测试3:

     @Test
public void testSelectMemberDetail() {
// 1.查询时,采用懒加载。
MemberDetail memberDetail = session.get(MemberDetail.class, 1);
System.out.println(memberDetail.getAddress()); // 2.会出现懒加载异常问题
session.close();
System.out.println(memberDetail.getMember().getUsername());
}

添加测试函数,执行测试4:

     @Test
public void testUpdate() {
// // 1) session关闭时,修改执行
// Member member = session.get(Member.class, 1);
// member.setUsername("Mgr11112");
// // 或 session.update(member);
// // 或 session.save(member);
// // 或 不需要任何操作,关闭session自动保存
//
// MemberDetail memberDetail = session.get(MemberDetail.class, 1);
// memberDetail.setAddress("address111112");
// // 或 session.update(memberDetail);
// // 或 session.save(memberDetail);
// // 或 不需要任何操作,关闭session自动保存 // // 2)通过Member 关联修改MemberDetai
// Member member = session.get(Member.class, 1);
// member.setUsername("Mgr");
// member.getMemberDetail().setAddress("Address"); // 3)通过MemberDetai 关联修改Member
MemberDetail memberDetail = session.get(MemberDetail.class, 1);
memberDetail.setAddress("Address333");
memberDetail.getMember().setUsername("Mgr333");
}

添加测试函数,执行测试5:

     @Test
public void testDelete() {
// // 1)Member表中有记录与之关联时,删除失败
// Member member = session.get(Member.class, 1);
// session.delete(member); // 2)删除成功,只删除了MemberDetail表中的记录,Member表中的记录并没有删除,之后再删除Member就不会出现错误。
MemberDetail memberDetail = session.get(MemberDetail.class, 1);
session.delete(memberDetail);
}

Hibernate(九):基于主键映射的1-1关联关系的更多相关文章

  1. hibernate中基于主键映射1-1关联关系和基于外键映射1-1关联关系的不同

    基于主键映射1-1关联关系和基于外键映射1-1关联关系的不同,主要区别是在配置映射文件上会有区别 两个持久化类为Manager和Department 1:基于主键映射1-1关联关系 1)使用其他持久化 ...

  2. Hibernate之基于主键映射的一对一关联关系

    1. 基于主键的映射策略:指一端的主键生成器使用foreign策略,表明根据"对方"的主键来生成自己的主键,自己并不能独立生成主键.并用<param> 子元素指定使用当 ...

  3. Hibernate之基于外键映射的一对一(1-1)关联关系

    1.对于基于外键的1-1关联,其外键可以存放在任意一边,在需要存放外键一端,增加many-to-one元素.为many-to-one元素增加unique="true"属性来表示为1 ...

  4. hibernate笔记--基于主键的单(双)向的一对一映射关系

    上一节介绍的基于外键的一对一映射关系中,在Person表中有一个外键列idCard_id,对应的idCard表的主键id,至于基于主键的一对一映射关系,就是指Person表中抛弃了idcard_id这 ...

  5. java之hibernate之基于主键的双向一对一关联映射

    这篇 基于主键的双向一对一关联映射 1.依然考察人和身份证的一对一关系,如果采用主键关联,那么其表结构为: 2.类结构 Person.java public class Person implemen ...

  6. java之hibernate之基于主键的单向一对一关联映射

    这篇讲 基于主键的单向一对一关联映射 1.依然考察人和身份证的一对一关系,如果采用主键关联,那么其表结构应该为: 2.类结构 Person.java public class Person imple ...

  7. 一对一关联关系基于主键映射的异常 IdentifierGenerationException

    具体异常:org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one pro ...

  8. Hibernate 中 联合主键映射 组合关系映射 大对象映射(或者说文本大对象,二进制数据大对象)

    Clob:文本大对象,最长4G Blob:二进制数据大对象,最长4G util: public class HibUtil { private static SessionFactory sessio ...

  9. hibernate 注解 联合主键映射

    联合主键用Hibernate注解映射方式主要有三种: 第一.将联合主键的字段单独放在一个类中,该类需要实现java.io.Serializable接口并重写equals和hascode,再将 该类注解 ...

随机推荐

  1. DB2开发系列之一——基本语法

    最近看了些db2开发方面的资料,现做摘要,以供自己和大家参考: 1.变量声明 DECLARE v_salary DEC(9,2) DEFAULT 0.0; DECLARE v_status char( ...

  2. javascript - 个人笔记汇总

    1. onSubmit = "return function ()"; 2.  <input type="text" name="fname&q ...

  3. python基础学习二 数据结构之list及相关基本操作

    list是py内置的一种数据类型,list就是列表的意思,list就是一种有序的数据集合,可以随时增加和删除list的元素. 生活中,比如我们要列出全班同学的名字,就可以用list来表示 >&g ...

  4. Markdown 语法手册 (完整整理版)

    http://blog.csdn.net/witnessai1/article/details/52551362

  5. ArrayList 源码分析

    ArrayList 源码分析 1. 结构   首先我们需要对 ArrayList 有一个大致的了解就从结构来看看吧. 1. 继承   该类继承自 AbstractList 这个比较好说 2. 实现 这 ...

  6. 大数据 --> MapReduce原理与设计思想

    MapReduce原理与设计思想 简单解释 MapReduce 算法 一个有趣的例子:你想数出一摞牌中有多少张黑桃.直观方式是一张一张检查并且数出有多少张是黑桃? MapReduce方法则是: 给在座 ...

  7. postman简单教程-环境变量,全局变量的设置及作用

    讲postman环境变量设置之前,先讲一个小插曲,环境变量.全局变量的区别在于Globals,只能用一组,而Environmen可以设置多组,所以我更喜欢设置环境变量 1.环境变量-Environme ...

  8. shell随机生成身份证,姓名,电话,日期,分数,等级和insert语句

    #!/bin/bash#生成随机身份证号,性别,年龄,电话,姓名,日期,分数和对应等级,并生成insert语句#作者AiYS,2018-02-06,转载请注明http://www.cnblogs.co ...

  9. C#数组随机生成四个随机数

    int[] face = new int[4]; Random ra = new Random(); for (int i = 0; i < face.Length; i++) { int co ...

  10. 《构建之法》教学笔记——Python中的效能分析与几个问题

    <构建之法:现代软件工程>中第2章对效能分析进行了介绍,基于的工具是VSTS.由于我教授的学生中只有部分同学选修了C#,若采用书中例子讲解,学生可能理解起来比较困难.不过所有这些学生都学习 ...