• 背景:

  在实际开发中我们会遇到新建一个用户表,但这个表字段过长,而且有写字段常用(主要),有些字段比较不常用(次要)。此时,我们会考虑到把用户信息拆分到两张表中: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. linux性能调试之vmstat

    linux性能监控调优工具vmstat: vmstat:用于监控.显示系统运行过程中的虚拟内存/CPU/磁盘状态. 简单示例(时间间隔2s,监控2次): 重要字段解释: r 表示运行队列(等待运行的进 ...

  2. Spring Framework 简介

    Spring Framework 依赖注入.事务管理.Web应用程序.数据访问.消息传递.测试和更多的核心支持. Tips: Spring 官网:https://spring.io/ spring f ...

  3. Leaflet客户端学习笔记

    Leaflet介绍 Leaflet 是一个为建设交互性好适用于移动设备地图,而开发的现代的.开源的 JavaScript 库.代码仅有 33 KB,但它具有开发在线地图的大部分功能.支持插件扩展, L ...

  4. python全栈学习--day5

    字典 特点:字典是python中唯一的映射类型,采用键值对(key-value) 的形式存数据. 存储大量的数据,是关系型数据,查询数据快. 字典初始说明: 遍历字典从列表开始,列表是从头便利到尾的. ...

  5. (译文)开始学习Webpack-应用TypeScript,配置热加载和Source Map

    项目初始化:采用TypeScript 我们的版本是: $ node --version v8.5.0 $ npm --version 5.5.1 npm版本升级了,因为npm最近带来了新特性,本地会生 ...

  6. 通过cmd命令行连接mysql数据库

    找到 mysqld.exe所在的路径 使用cd切换到msyqld.exe路径下 输入mysql连接命令,格式如下 Mysql  -P 端口号  -h  mysql主机名\ip -u root (用户) ...

  7. 第二次作业-关于Steam游戏平台的简单分析

    1.1 Steam平台的简单介绍 你选择的产品是? 如题,这次的作业我选择了Steam作为分析的对象. 为什么选择该产品作为分析? 我选择数字游戏贩售平台STEAM作为分析对象的原因有以下几点: 1. ...

  8. 利用PCA降维

    参考:<机器学习实战>- Machine Learning in Action 一. 基本思想  PCA(Principal Component Analysis),主成分分析.是目前应用 ...

  9. 项目Beta冲刺预热

    Beta准备 1. 讨论组长是否重选的议题和结论. 经过讨论,我们认为,经过一段时间的磨合,现任组长是不需要更换的. 2. 下一阶段需要改进完善的功能. 增加关于征信的功能,贴近选题主题 美化界面,尽 ...

  10. 使用Spark MLlib进行情感分析

    使用Spark MLlib进行情感分析             使用Spark MLlib进行情感分析 一.实验说明 在当今这个互联网时代,人们对于各种事情的舆论观点都散布在各种社交网络平台或新闻提要 ...