• 背景:

  在实际开发中我们会遇到新建一个用户表,但这个表字段过长,而且有写字段常用(主要),有些字段比较不常用(次要)。此时,我们会考虑到把用户信息拆分到两张表中: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. 20165226 学习基础和C语言基础调查

    心得体会 驱动迭代 学习是一个老师与学生互动的过程,二者关系又恰如健身教练与学员,在进行基础知识的培训后还需借助工具加强相关方面的训练.学习提升的过程离不开学生在实践中发现问题并在老师的帮助下解决问题 ...

  2. 详解小白利用eclipse+CDT+MinGW搭建C++开发环境

    安装JDK.安装Eclipse     2.打开Eclipse 找到“help”下的“Eclipse marketplace” 如图:    3.选择相应的C插件: 因为安装过所以显示installe ...

  3. redis的主从复制(读写分离)/哨兵(主从切换)配置

    准备两个redis服务,两台机器,依次命名文件夹子master,slave1 10.10.10.7 10.10.10.8 1.master修改配置文件 [root@db2 conf]# cat 637 ...

  4. 设计模式 --> (15)职责链模式

    职责链模式 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止. 示例 考虑员工要求加薪.公司的管理者一共有 ...

  5. C++ STL 容器之栈的使用

    Stack 栈是种先进后出的容器,C++中使用STL容器Stack<T> 完美封装了栈的常用功能. 下面来个demo 学习下使用栈的使用. //引入IO流头文件 #include<i ...

  6. java 中的IO

    什么是文件文件可认为是相关记录或放在一起的数据集合 通过流来读写文件流是指一连串流动的字符,是以先进先出方式发送信息的通道输入输出流是相对计算机的内存来说的 字节流是八位通用字节流,字符流是16位Un ...

  7. hibernate框架学习笔记8:一对多关系案例

    两个实体类:客户与联系人,一个客户可以有多个联系人 客户类: package domain; import java.util.HashSet; import java.util.Set; //客户实 ...

  8. servlet本质

    首先我们先要知道servlet是什么,这有两种解释.一是目前大多数人所说的,一个实现了servlet接口的类就可以叫作servlet.二,servlet只是一个接口.那么看起来这两点都和servlet ...

  9. 关于c++停止工作

    出现这样情况有两种原因 : 1未初始化 2用scanf未用符号& 3当0做分母时

  10. 2017-2018-1 20155205 实现mypwd

    2017-2018-1 20155205 实现mypwd 课堂总结 根据上课对ls -l功能的实现,我总结了实现一个linux命令需要的步骤: 使用man -k xx | grep xx查看帮助文档, ...