Hibernate(八):基于外键映射的1-1关联关系

  • 背景:

一个部门只有一个一把手,这在程序开发中就会设计数据映射应该设置为一对一关联。

在hibernate代码开发中,实现这个业务有两种方案:

1)基于外键映射的1-1关联;

2)基于主键映射的1-1关联。

本篇文章主要是用来学习如何使用外键实现1-1关联关系。

  • 新建项目hibernate05

新建java project,引入依赖包,在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/onetoonebyforigenkey/Deparment.hbm.xml" />
32         <mapping class="com.dx.hibernate005.onetoonebyforigenkey.Deparment" />
33         <mapping resource="com/dx/hibernate005/onetoonebyforigenkey/Manager.hbm.xml" />
34         <mapping class="com.dx.hibernate005.onetoonebyforigenkey.Manager" />
35     </session-factory>
36 </hibernate-configuration>

在src下新建包com.dx.hibernate005.onetoonebyforigenkey

在com.dx.hibernate005.onetoonebyforigenkey包下创建

Deparment.java

 1 package com.dx.hibernate005.onetoonebyforigenkey;
 2
 3 public class Deparment {
 4     private Integer departId;
 5     private String departName;
 6     private Manager manager;
 7
 8     public Deparment() {
 9         super();
10     }
11
12     public Deparment(Integer departId, String departName) {
13         super();
14         this.departId = departId;
15         this.departName = departName;
16     }
17
18     public Integer getDepartId() {
19         return departId;
20     }
21
22     public void setDepartId(Integer departId) {
23         this.departId = departId;
24     }
25
26     public String getDepartName() {
27         return departName;
28     }
29
30     public void setDepartName(String departName) {
31         this.departName = departName;
32     }
33
34     public Manager getManager() {
35         return manager;
36     }
37
38     public void setManager(Manager manager) {
39         this.manager = manager;
40     }
41
42 }

Deparment.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-2 10:54:26 by Hibernate Tools 3.5.0.Final -->
 5 <hibernate-mapping>
 6     <class name="com.dx.hibernate005.onetoonebyforigenkey.Deparment" table="DEPARMENTS">
 7         <id name="departId" type="java.lang.Integer">
 8             <column name="DEPART_ID" />
 9             <generator class="native" />
10         </id>
11         <property name="departName" type="java.lang.String">
12             <column name="DEPART_NAME" />
13         </property>
14
15         <!-- 在Deparment中定义一个Many-to-one就可以实现在Deparments表中多一个外键列 -->
16         <many-to-one name="manager" class="com.dx.hibernate005.onetoonebyforigenkey.Manager" column="MANAGER_ID" unique="true"></many-to-one>
17     </class>
18 </hibernate-mapping>

Manager.java

 1 package com.dx.hibernate005.onetoonebyforigenkey;
 2
 3 public class Manager {
 4     private Integer managerId;
 5     private String managerName;
 6     private Deparment deparment;
 7
 8     public Manager() {
 9         super();
10     }
11
12     public Manager(Integer managerId, String managerName) {
13         super();
14         this.managerId = managerId;
15         this.managerName = managerName;
16     }
17
18     public Integer getManagerId() {
19         return managerId;
20     }
21
22     public void setManagerId(Integer managerId) {
23         this.managerId = managerId;
24     }
25
26     public String getManagerName() {
27         return managerName;
28     }
29
30     public void setManagerName(String managerName) {
31         this.managerName = managerName;
32     }
33
34     public Deparment getDeparment() {
35         return deparment;
36     }
37
38     public void setDeparment(Deparment deparment) {
39         this.deparment = deparment;
40     }
41
42 }

Deparment.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-2 10:54:26 by Hibernate Tools 3.5.0.Final -->
 5 <hibernate-mapping>
 6     <class name="com.dx.hibernate005.onetoonebyforigenkey.Manager" table="MANAGERS">
 7         <id name="managerId" type="java.lang.Integer">
 8             <column name="MANAGER_ID" />
 9             <generator class="native" />
10         </id>
11         <property name="managerName" type="java.lang.String">
12             <column name="MANAGER_NAME" />
13         </property>
14
15         <!-- 在对应的数据表中已经有了外键,当前持久化类使用one-to-one进行映射 -->
16         <one-to-one name="deparment" class="com.dx.hibernate005.onetoonebyforigenkey.Deparment" property-ref="manager"></one-to-one>
17     </class>
18 </hibernate-mapping>

TestMain.java测试类,并引入JUnit4所需的依赖包。

package com.dx.hibernate005.onetoonebyforigenkey;

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();
    }
}

运行空测试类,初始化sql:

 1 Hibernate:
 2
 3     create table DEPARMENTS (
 4        DEPART_ID integer not null auto_increment,
 5         DEPART_NAME varchar(255),
 6         MANAGER_ID integer,
 7         primary key (DEPART_ID)
 8     ) engine=InnoDB
 9 Hibernate:
10
11     create table MANAGERS (
12        MANAGER_ID integer not null auto_increment,
13         MANAGER_NAME varchar(255),
14         primary key (MANAGER_ID)
15     ) engine=InnoDB
16 Hibernate:
17
18     alter table DEPARMENTS
19        drop index UK_j9bdvgylyeboig73ntlfcuyf6
20 Hibernate:
21
22     alter table DEPARMENTS
23        add constraint UK_j9bdvgylyeboig73ntlfcuyf6 unique (MANAGER_ID)
24 Hibernate:
25
26     alter table DEPARMENTS
27        add constraint FKnlmf88ii3maigw7hgc182cqi4
28        foreign key (MANAGER_ID)
29        references MANAGERS (MANAGER_ID)

  • 测试:

1)测试insert:

 1     @Test
 2     public void testInsert(){
 3         Deparment deparment=new Deparment();
 4         deparment.setDepartName("Depart1");
 5
 6         Manager manager=new Manager();
 7         manager.setManagerName("manager1");
 8
 9         deparment.setManager(manager);
10         manager.setDeparment(deparment);
11
12         session.save(manager);
13         session.save(deparment);
14     }
15     

测试通过,测试打印sql

 1 Hibernate:
 2     insert
 3     into
 4         MANAGERS
 5         (MANAGER_NAME)
 6     values
 7         (?)
 8 Hibernate:
 9     insert
10     into
11         DEPARMENTS
12         (DEPART_NAME, MANAGER_ID)
13     values
14         (?, ?)

2)测试select

 1     @Test
 2     public void testSelect() {
 3         // 1.查询时,采用懒加载。
 4         Deparment deparment = (Deparment) session.get(Deparment.class, 1);
 5         System.out.println(deparment.getDepartName());
 6
 7         // // 2.会出现懒加载异常问题
 8         // session.close();
 9         // Manager manager = deparment.getManager();
10         // System.out.println(manager.getClass());
11         // System.out.println(manager.getManagerName());
12     }

3)测试Select Manager

 1     @Test
 2     public void testSelectManager() {
 3         // 1.查询时,没采用懒加载。
 4         Manager manager = session.get(Manager.class, 1);
 5         System.out.println(manager.getManagerName());
 6
 7         // 2.不会出现懒加载异常问题
 8         session.close();
 9         System.out.println(manager.getDeparment().getDepartName());
10     }

4)测试修改

 1     @Test
 2     public void testUpdate() {
 3         // // 1) session关闭时,修改执行
 4         // Manager manager = session.get(Manager.class, 1);
 5         // manager.setManagerName("Mgr11111");
 6         // // session.save(manager);
 7         //
 8         // Deparment deparment = session.get(Deparment.class, 1);
 9         // deparment.setDepartName("Depart111111");
10         // // session.save(deparment);
11
12         // // 2)通过manager 关联修改deparment
13         // Manager manager = session.get(Manager.class, 1);
14         // manager.setManagerName("Mgr222");
15         // manager.getDeparment().setDepartName("DEPT22");
16
17         // 3)通过department关联修改manager
18         Deparment deparment = session.get(Deparment.class, 1);
19         deparment.setDepartName("DPT333");
20         deparment.getManager().setManagerName("Mgr333");
21     }

5)测试删除

 1     @Test
 2     public void testDelete() {
 3         // 1)在department表中有记录与之关联时,删除失败
 4         // Manager manager = session.get(Manager.class, 1);
 5         // session.delete(manager);
 6
 7         // 2)删除成功,只删除了deparment表中的记录,manger表中的记录并没有删除,之后再删除manager就不会出现错误。
 8         Deparment deparment = session.get(Deparment.class, 1);
 9         session.delete(deparment);
10     }
时间: 2024-08-07 17:04:26

Hibernate(八):基于外键映射的1-1关联关系的相关文章

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

基于主键映射1-1关联关系和基于外键映射1-1关联关系的不同,主要区别是在配置映射文件上会有区别 两个持久化类为Manager和Department 1:基于主键映射1-1关联关系 1)使用其他持久化类的主键生成主键的实体的映射文件 首先需要指定主键生成方式为foreigner 格式为: <id name="departmentId" type="java.lang.Integer"> <column name="department_i

java之hibernate之基于外键的双向一对一关联映射

这篇讲解 基于外键的双向一对一关联映射 1.考察如下信息,人和身份证之间是一个一对一的关系.表的设计 2.类结构 Person.java public class Person implements Serializable{ private int id; private String name; private IdCard idCard; public Person() { } public Person(String name) { super(); this.name = name;

Hibernate关系映射(二) 基于外键的双向一对一

基于外键的双向一对一关联映射 需要在一端添加<one-to-one>标签,用property-ref来指定反向属性引用. 还是通过刚才用户和地址来演示双向一对一关联. 代码演示 一.实体类 Account.cs,需要添加被控端的引用 package com.lxit.entity; import java.io.Serializable; public class Account implements Serializable{ public Account(){ } private int

hibernate 之 关联映射的基于外键的双向一对一关联

1. 人和身份证是一个一对一的关系,他们的表结构为: 2. 类结构:Person.java public class Person { private int id; private String name; private int age; private IdCard idCard; public Person() { } public Person(String name, int age) { super(); this.name = name; this.age = age; } pu

hibernate 之 关联映射的基于外键的单向一对一映射

1. 人和身份证是一个一对一的关系,他们的表结构为: 2. 类结构:IdCard.java : public class IdCard { private String id; private String address; public IdCard() { } public IdCard(String id, String address) { super(); this.id = id; this.address = address; } public String getId() { r

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

上一节介绍的基于外键的一对一映射关系中,在Person表中有一个外键列idCard_id,对应的idCard表的主键id,至于基于主键的一对一映射关系,就是指Person表中抛弃了idcard_id这个外键列,而与idCard表共用一个主键,或者说是其外键为主键的表结构,这种基于主键的双向一对一映射关系应该这样配置: 新建一个IdCard实体类: public class IdCard { private int id; private String code; private Person p

hibernate映射-基于主键映射的1-1关联关系

(学习记录,错误不足之处,请您耐心指正^_^) hibernate映射-基于主键映射的1-1关联关系 基于主键的映射策略:指一端的主键生成器使用foreign策略,表明根据对方的主键来生成自己的主键,自己并不独立生成主键. 一.代码示例: {类文件↓} Manager.class 1 package com.zit.hibernate.one2one.primary; 2 3 public class Manager { 4 5 private Integer mgrId; 6 private

注解:【基于外键的】Hibernate单向1-&gt;1关联

Person与Address关联:单向1->1,[基于外键的] Person.java package org.crazyit.app.domain; import javax.persistence.CascadeType;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Generati

Hibernate之关联关系映射(一对一主键映射和一对一外键映射)

1:Hibernate的关联关系映射的一对一外键映射: 1.1:第一首先引包,省略 1.2:第二创建实体类: 这里使用用户信息和身份证信息的关系,用户的主键编号既可以做身份证信息的主键又可以做身份证信息的外键,这里先做外键. 创建User.java: 用户和身份证一对一的关联关系映射       private IdCart idCart; IdCart.java: 身份证和用户,一对一的关系       private User user; 1 package com.bie.bean; 2