Hibernate5.2之一对一主键关联(四)

                                                  Hibernate5.2之一对一主键关联(四)

一.简介

  一对一关联关系分为两种:a.主键关联;b.外键关联。这两种关联关系在日常的开发中都比较的常用,本篇文章介绍主键关联,在下一篇文章中介绍外键关联。

二.主键关联

2.1 数据库的创建

create table cards (
    id varchar2(255 char) not null, 
    card_num varchar2(255 char),  
    primary key (id)
);

create table people (
    id varchar2(255 char) not null, 
    name varchar2(255 char), 
    sex varchar2(255 char), 
    primary key (id)
);

2.2 hbm文件的方式

public class People {
    private String id;
    private String name;
    private String sex;
    private IdCard idCard;
    //setter and getter
}

public class IdCard {
    private String id;
    private String cardNum;
    private People people;
    //setter and getter
}

People.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class name="com.demo.hibernate.one2one.People" table="people">
        <id name="id" type="string">
            <generator class="uuid"></generator>
        </id>
        
        <property name="name" type="string" column="name"></property>
        <property name="sex" type="string" column="sex"></property>
        <!-- fetch默认值为join的方式,采用左外连接的方式查询;当fetch=‘select’的时候,默认会发送两条SQL -->
        <!-- 一对一的延迟加载的方式是将 constrained设置为true,然后将被延迟加载的一方的class中的lazy属性设置为true(默认值为true)-->
        <one-to-one name="idCard" class="com.demo.hibernate.one2one.IdCard" cascade="all" fetch="select" constrained="true"></one-to-one>
    </class>
</hibernate-mapping>

IdCard.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class name="com.demo.hibernate.one2one.IdCard" table="cards">
        <id name="id" type="string" column="id">
            <generator class="foreign">
                <param name="property">people</param>
            </generator>
        </id>
    
        <property name="cardNum" type="string" column="card_num"></property>
        <one-to-one name="people" class="com.demo.hibernate.one2one.People"></one-to-one>
    </class>
</hibernate-mapping>

2.3 注解的方式

IdCard.java

@Entity
@Table(name="cards")
public class IdCard {
    
    @Id
    @Column(name="id")
    @GenericGenerator(name="foreignGenerator", strategy="foreign", parameters={@Parameter(value="people", name="property")})
    @GeneratedValue(generator="foreignGenerator")
    private String id;
    
    @Column(name="card_num")
    private String cardNum;
    
    /**
     * mappedBy="idCard",其中idCard为People类中的属性名
     */
    @OneToOne(mappedBy="idCard", fetch=FetchType.LAZY)
    private People people;
}

People.java

@Entity
@Table(name="people")
public class People {
    
    @Id
    @Column(name="id")
    @GenericGenerator(name="uuidGenerator", strategy="uuid")
    @GeneratedValue(generator="uuidGenerator")
    private String id;
    
    @Column(name="name")
    private String name;
    
    @Column(name="sex")
    private String sex;
    
    /**
     * cascade表示级联的意思
     * FetchMode.SELECT的方式表示,查询与之关联的数据的时候,使用select的方式,而不是左外连接,与在
     * 在@OneToOne()中间加上fetch=FetchType.LAZY所表达出来的意思是一样的。
     * @PrimaryKeyJoinColumn必须在生产主键的一方指定,不然会在被关联的一方多出一列
     */
    @OneToOne(cascade=CascadeType.ALL)
    @Fetch(value=FetchMode.SELECT)  
    @PrimaryKeyJoinColumn   
    private IdCard idCard;
}

2.4 代码测试

A.保存

@Test
public void save(){
    Transaction tx = session.beginTransaction();
    People people = new People();
    people.setName("AAA");
    people.setSex("男");
        
    IdCard idCard = new IdCard();
    idCard.setCardNum("889900");
    idCard.setPeople(people);
        
    people.setIdCard(idCard);
    session.save(people);
        
    tx.commit();
}

B.load

@Test
public void load(){
    People people = session.load(People.class, "402882e65649c101015649c1031e0000");
    System.out.println("此时没有发送任何的SQL语句");
    System.out.println(people.getName() + "::" + people.getSex());
    IdCard idCard = people.getIdCard();
    System.out.println(idCard.getCardNum());
}

C.get

@Test
public void get(){
    People people = session.get(People.class, "402882e65649c101015649c1031e0000");
    System.out.println("此时已经发送了SQL语句");
    System.out.println(people.getName() + "::" + people.getSex());
    IdCard idCard = people.getIdCard();
    System.out.println(idCard.getCardNum());
}

D.update

@Test
public void update(){
    Transaction tx = session.beginTransaction();
    People people = new People();
    people.setId("402882e65649c92e015649c92fd90000");
    people.setName("HHHNNN");
    people.setSex("女");
    session.update(people);
    tx.commit();
}

E.delete

@Test
public void delete(){
    People people = new People();
    people.setId("402882e65649c101015649c1031e0000");
        
    IdCard card = new IdCard();
    card.setId("402882e65649c101015649c1031e0000");
        
    people.setIdCard(card);
    Transaction tx = session.beginTransaction();
    session.delete(people);
    tx.commit();
}
原文地址:https://www.cnblogs.com/miller-zou/p/5727792.html