Hibernate(九):基于主键映射的1-1关联关系

  • 背景:

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

 1 package com.dx.hibernate005.onetoonebyprimary;
 2 
 3 import java.util.Date;
 4 
 5 public class Member {
 6     private Integer id;
 7     private String username;
 8     private String password;
 9     private Date createTime;
10     private MemberDetail memberDetail;
11 
12     public Member() {
13         super();
14     }
15 
16     public Member(String username, String password, Date createTime) {
17         super();
18         this.username = username;
19         this.password = password;
20         this.createTime = createTime;
21     }
22 
23     public Integer getId() {
24         return id;
25     }
26 
27     public void setId(Integer id) {
28         this.id = id;
29     }
30 
31     public String getUsername() {
32         return username;
33     }
34 
35     public void setUsername(String username) {
36         this.username = username;
37     }
38 
39     public String getPassword() {
40         return password;
41     }
42 
43     public void setPassword(String password) {
44         this.password = password;
45     }
46 
47     public Date getCreateTime() {
48         return createTime;
49     }
50 
51     public void setCreateTime(Date createTime) {
52         this.createTime = createTime;
53     }
54 
55     public MemberDetail getMemberDetail() {
56         return memberDetail;
57     }
58 
59     public void setMemberDetail(MemberDetail memberDetail) {
60         this.memberDetail = memberDetail;
61     }
62 
63 }
View Code

Member.hbm.xml

 1 <?xml version="1.0"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 4 <!-- Generated 2017-6-5 15:39:57 by Hibernate Tools 3.5.0.Final -->
 5 <hibernate-mapping package="com.dx.hibernate005.onetoonebyprimary">
 6     <class name="Member" table="MEMBER">
 7         <id name="id" type="java.lang.Integer">
 8             <column name="ID" />
 9             <generator class="native" />
10         </id>        
11         <property name="username" type="java.lang.String">
12             <column name="USERNAME" />
13         </property>        
14         <property name="password" type="java.lang.String">
15             <column name="PASSWORD" />
16         </property>        
17         <property name="createTime" type="java.util.Date">
18             <column name="CREATETIME" />
19         </property>        
20         <one-to-one name="memberDetail" class="com.dx.hibernate005.onetoonebyprimary.MemberDetail"></one-to-one>
21     </class>
22 </hibernate-mapping>
View Code

MemberDetail.java

 1 package com.dx.hibernate005.onetoonebyprimary;
 2 
 3 import java.util.Date;
 4 
 5 public class MemberDetail {
 6     private Integer memberId;
 7     private Date birthDay;
 8     private String address;
 9     private Member member;
10 
11     public MemberDetail() {
12         super();
13     }
14 
15     public MemberDetail(Date birthDay, String address) {
16         super();
17         this.birthDay = birthDay;
18         this.address = address;
19     }
20 
21     public Integer getMemberId() {
22         return memberId;
23     }
24 
25     public void setMemberId(Integer memberId) {
26         this.memberId = memberId;
27     }
28 
29     public Date getBirthDay() {
30         return birthDay;
31     }
32 
33     public void setBirthDay(Date birthDay) {
34         this.birthDay = birthDay;
35     }
36 
37     public String getAddress() {
38         return address;
39     }
40 
41     public void setAddress(String address) {
42         this.address = address;
43     }
44 
45     public Member getMember() {
46         return member;
47     }
48 
49     public void setMember(Member member) {
50         this.member = member;
51     }
52 }
View Code

MemberDetail.hbm.xml

 1 <?xml version="1.0"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 4 <!-- Generated 2017-6-5 15:39:57 by Hibernate Tools 3.5.0.Final -->
 5 <hibernate-mapping package="com.dx.hibernate005.onetoonebyprimary">
 6     <class name="MemberDetail" table="MEMBERDETAIL">
 7         <id name="memberId" type="java.lang.Integer">
 8             <column name="MEMBERID" />
 9             <generator class="foreign">
10                 <param name="property">member</param>
11             </generator>
12         </id>
13         <property name="birthDay" type="java.util.Date">
14             <column name="BIRTHDAY" />
15         </property>
16         <property name="address" type="java.lang.String">
17             <column name="ADDRESS" />
18         </property>
19         <one-to-one name="member" class="com.dx.hibernate005.onetoonebyprimary.Member" constrained="true"></one-to-one>
20     </class>
21 </hibernate-mapping>
View Code

在src下创建hibernate.cfg.xml

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE hibernate-configuration PUBLIC
 3         "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
 4         "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
 5 <hibernate-configuration>
 6     <session-factory>
 7         <property name="hibernate.connection.username">root</property>
 8         <property name="hibernate.connection.password">123456</property>
 9         <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
10         <property name="hibernate.connection.url">jdbc:mysql://localhost/hibernate_01</property>
11 
12         <!-- <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> 
13             <property name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</property> -->
14         <property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
15 
16         <property name="hibernate.show_sql">true</property>
17 
18         <property name="hibernate.format_sql">true</property>
19 
20         <property name="hibernate.hbm2ddl.auto">update</property>
21 
22         <property name="hibernate.current_session_context_class">thread</property>
23 
24         <property name="hibernate.c3p0.max_size">500</property>
25         <property name="hibernate.c3p0.min_size">20</property>
26         <property name="hibernate.c3p0.max_statements">10</property>
27         <property name="hibernate.c3p0.timeout">2000</property>
28         <property name="hibernate.c3p0.idle_test_period">2000</property>
29         <property name="hibernate.c3p0.acquire_increment">10</property>
30 
31         <mapping resource="com/dx/hibernate005/onetoonebyprimary/Member.hbm.xml" />        
32         <mapping resource="com/dx/hibernate005/onetoonebyprimary/MemberDetail.hbm.xml" />
33         
34         <!--
35         <mapping class="com.dx.hibernate005.onetoonebyprimary.Member" />
36         <mapping class="com.dx.hibernate005.onetoonebyprimary.MemberDetail" />
37         -->
38     </session-factory>
39 </hibernate-configuration>
View Code

添加测试类TestMain.java

 1 package com.dx.hibernate005.onetoonebyprimary;
 2 
 3 import java.util.Date;
 4 
 5 import org.hibernate.Session;
 6 import org.hibernate.SessionFactory;
 7 import org.hibernate.Transaction;
 8 import org.hibernate.boot.Metadata;
 9 import org.hibernate.boot.MetadataSources;
10 import org.hibernate.boot.model.naming.ImplicitNamingStrategyComponentPathImpl;
11 import org.hibernate.boot.registry.StandardServiceRegistry;
12 import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
13 import org.junit.After;
14 import org.junit.Before;
15 import org.junit.Test;
16 
17 public class TestMain {
18     private SessionFactory sessionFactory = null;
19     private Session session = null;
20     private Transaction transaction = null;
21 
22     @Before
23     public void init() {
24         StandardServiceRegistry standardRegistry = new StandardServiceRegistryBuilder().configure().build();
25         Metadata metadata = new MetadataSources(standardRegistry).getMetadataBuilder().applyImplicitNamingStrategy(ImplicitNamingStrategyComponentPathImpl.INSTANCE).build();
26 
27         sessionFactory = metadata.getSessionFactoryBuilder().build();
28         session = sessionFactory.getCurrentSession();
29         transaction = session.beginTransaction();
30     }
31 
32     @After
33     public void destory() {
34         transaction.commit();
35         session.close();
36         sessionFactory.close();
37     }
38 }
View Code

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

 1     @Test
 2     public void testInsert() {
 3          Member member = new Member("user1","123456",new Date());        
 4          MemberDetail memberDetail = new MemberDetail(new Date(),"address1");
 5         
 6          member.setMemberDetail(memberDetail);
 7          memberDetail.setMember(member);
 8 
 9          session.save(memberDetail);
10          session.save(member);
11     }

输出sql:

 1 Hibernate: 
 2     
 3     create table MEMBER (
 4        ID integer not null auto_increment,
 5         USERNAME varchar(255),
 6         PASSWORD varchar(255),
 7         CREATETIME datetime,
 8         primary key (ID)
 9     ) engine=InnoDB
10 Hibernate: 
11     
12     create table MEMBERDETAIL (
13        MEMBERID integer not null,
14         BIRTHDAY datetime,
15         ADDRESS varchar(255),
16         primary key (MEMBERID)
17     ) engine=InnoDB
18 Hibernate: 
19     
20     alter table MEMBERDETAIL 
21        add constraint FKsfbbuql27qw1ym706tof0nwcf 
22        foreign key (MEMBERID) 
23        references MEMBER (ID)
24 Hibernate: 
25     insert 
26     into
27         MEMBER
28         (USERNAME, PASSWORD, CREATETIME) 
29     values
30         (?, ?, ?)
31 Hibernate: 
32     insert 
33     into
34         MEMBERDETAIL
35         (BIRTHDAY, ADDRESS, MEMBERID) 
36     values
37         (?, ?, ?)
View Code

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

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

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

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

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

 1     @Test
 2     public void testUpdate() {
 3         // // 1) session关闭时,修改执行
 4         // Member member = session.get(Member.class, 1);
 5         // member.setUsername("Mgr11112");
 6         // // 或 session.update(member);
 7         // // 或 session.save(member);
 8         // // 或 不需要任何操作,关闭session自动保存
 9         //
10         // MemberDetail memberDetail = session.get(MemberDetail.class, 1);
11         // memberDetail.setAddress("address111112");
12         // // 或 session.update(memberDetail);
13         // // 或 session.save(memberDetail);
14         // // 或 不需要任何操作,关闭session自动保存
15 
16         // // 2)通过Member     关联修改MemberDetai
17         // Member member = session.get(Member.class, 1);
18         // member.setUsername("Mgr");
19         // member.getMemberDetail().setAddress("Address");
20 
21         // 3)通过MemberDetai    关联修改Member
22         MemberDetail memberDetail = session.get(MemberDetail.class, 1);
23         memberDetail.setAddress("Address333");
24         memberDetail.getMember().setUsername("Mgr333");
25     }

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

 1     @Test
 2     public void testDelete() {
 3         // // 1)Member表中有记录与之关联时,删除失败
 4         // Member member = session.get(Member.class, 1);
 5         // session.delete(member);
 6 
 7         // 2)删除成功,只删除了MemberDetail表中的记录,Member表中的记录并没有删除,之后再删除Member就不会出现错误。
 8         MemberDetail memberDetail = session.get(MemberDetail.class, 1);
 9         session.delete(memberDetail);
10     }
原文地址:https://www.cnblogs.com/yy3b2007com/p/6945699.html