Hibernate入门(七)Hibernate关联映射

前言

      本章讲解Hibernate的关联关系及其配置方式

方法

1.一对一关联关系

我们之前学过MyBatis,也了解了其关联关系的配置方式。那么Hibernate该如何配置呢?首先我以一对一关联进行讲解!

范例:人和身份证的关系

人和身份证是一对一的关系,也就是说一个人只能拥有一个身份证,一个身份证只属于一个人!

那么,我们首先先建立两个实体类,Person和IDCard,示例代码如下:

package cn.edu.ccut.bo;

import org.hibernate.annotations.GenericGenerator;

import javax.persistence.*;
import java.io.Serializable;

@Entity
public class Person implements Serializable {
    @Id
    @GenericGenerator(name = "uuid",strategy = "uuid")
    @GeneratedValue(generator = "uuid")
    private String id;
    private String name;

    public Person() {
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
package cn.edu.ccut.bo;

import org.hibernate.annotations.GenericGenerator;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import java.io.Serializable;

@Entity
public class IDCard implements Serializable {

    @Id
    @GenericGenerator(name = "uuid",strategy = "uuid")
    @GeneratedValue(generator = "uuid")
    private String id;
    private String code;

    public IDCard() {
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    @Override
    public String toString() {
        return "IDCard{" +
                "id='" + id + '\'' +
                ", code='" + code + '\'' +
                '}';
    }
}

1)单向一对一关联

我们在Person类中加入关联属性idCard如下:

这个时候,我们需要添加一对一关联关系所使用的注解,那就是@OneToOne

@OneToOne注解解释:

  • cascade:关联属性,这个属性定义了当前类对象操作了之后,级联对象的操作。其中CascadeType.ALL,当前类增删改查改变之后,关联类跟着增删改查。
  • fetch属性:FetchType类型的属性。可选择项包括:FetchType.EAGER 和FetchType.LAZY。  FetchType.EAGER表示关系类在主类加载的时候同时加载,FetchType.LAZY表示关系类在被访问时才加载。默认值是FetchType.LAZY。
  • mappedBy:拥有关联关系的域,如果关系是单向的就不需要,双向关系表,那么拥有关系的这一方有建立、解除和更新与另一方关系的能力,而另一方没有,只能被动管理,这个属性被定义在关系的被拥有方。

这个时候我们通过@OneToOne注解配置Person如下:

package cn.edu.ccut.bo;

import org.hibernate.annotations.GenericGenerator;

import javax.persistence.*;
import java.io.Serializable;

@Entity
public class Person implements Serializable {
    @Id
    @GenericGenerator(name = "uuid",strategy = "uuid")
    @GeneratedValue(generator = "uuid")
    private String id;
    private String name;
    @OneToOne(cascade = CascadeType.ALL,fetch = FetchType.EAGER)
    private IDCard iDCard;

    public IDCard getIDCard() {
        return iDCard;
    }

    public void setIDCard(IDCard iDCard) {
        this.iDCard = iDCard;
    }

    public Person() {
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Person{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                ", iDCard=" + iDCard +
                '}';
    }
}

我们在hibernate.cfg.xml配置如下:

<!-- 自动创建|更新|验证数据库表结构 create表示每次删除表新建表,update表示没表新建表,有表直接更新 -->
<property name="hbm2ddl.auto">create</property>

<!-- 配置映射文件路径 -->
<mapping class="cn.edu.ccut.bo.Person"/>
<mapping class="cn.edu.ccut.bo.IDCard"/>

编写测试类如下:

import cn.edu.ccut.bo.IDCard;
import cn.edu.ccut.bo.Person;
import cn.edu.ccut.util.DBUtil;
import org.hibernate.Session;
import org.junit.Test;

public class HibernateTest {

    @Test
    public void testHibernateConfig() throws Exception{
        //创建Session对象
        Session session = DBUtil.getSession();
        //开启事务
        session.beginTransaction();
        IDCard idCard = new IDCard();
        idCard.setCode("123143");
        Person person = new Person();
        person.setName("张三");
        person.setIDCard(idCard);
        session.save(idCard);
        session.save(person);
        session.getTransaction().commit();
       /* Person person = (Person) session.get(Person.class, "297ebee0688a626701688a6269090000");
        System.out.println(person);*/
        DBUtil.close();
    }
}

执行结果如下:

我们通过上面的结果可以发现,默认创建的关联列名称为  关联表名称_关联表主键

但是,一般情况下,我们的关联字段的设置是自定义的,那么可以使用@JoinColumn注解

@JoinColumn注解解释:

  • name:定义关联字段的名称
  • referencedColumnName:定义参照表的字段(参照表主键)

使用该注解示例如下:

执行结果如下:

  

2)双向一对一关联

有些时候,我们需要通过人查到其身份证信息,通过身份证信息查到其人员信息,那么就需要双向的一对一关联,IDCard.java编写如下:

mappedBy属性表示关联关系由拥有iDCard属性的Person类进行管理,双向关联务必在被管理方配置该选项!

此时,我们分别对人和身份证分别执行查询,看是否可以查到关联数据!

查询Person类测试代码:

import cn.edu.ccut.bo.IDCard;
import cn.edu.ccut.bo.Person;
import cn.edu.ccut.util.DBUtil;
import org.hibernate.Session;
import org.junit.Test;

public class HibernateTest {

    @Test
    public void testHibernateConfig() throws Exception{
        //创建Session对象
        Session session = DBUtil.getSession();
        Person person = (Person) session.get(Person.class, "40288d81688c96ce01688c96ed880001");
        System.out.println(person);
        DBUtil.close();
    }
}

 执行结果如下:

查询IDCard类代码如下:

import cn.edu.ccut.bo.IDCard;
import cn.edu.ccut.util.DBUtil;
import org.hibernate.Session;
import org.junit.Test;

public class HibernateTest {

    @Test
    public void testHibernateConfig() throws Exception{
        //创建Session对象
        Session session = DBUtil.getSession();
        IDCard iDCard = (IDCard) session.get(IDCard.class, "40288d81688c96ce01688c96ed7e0000");
        System.out.println(iDCard.getPerson());
        DBUtil.close();
    }
}

 特别的:被动管理类不允许重写toString()方法,如本例中IDCard类配置toString()会发生递归调用造成死循环

2.一对多关联关系

一对多的关联关系其实和一对一配置方式一致,只需要注意多的要用集合表示即可!
如人和手机的关系,人可以有多个手机,但是一个手机只能属于一个人,那么我们设置Person类和Phone类如下:

Person设置为上面例子中最初始的例子即可,我们编写下Phone类如下:

package cn.edu.ccut.bo;


public class Phone {
    private String id;
    private String phoneName;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getPhoneName() {
        return phoneName;
    }

    public void setPhoneName(String phoneName) {
        this.phoneName = phoneName;
    }
}

我这里直接讲双向的一对多关联关系!

在Phone类中进行如下配置:

package cn.edu.ccut.bo;

import org.hibernate.annotations.GenericGenerator;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;

@Entity
public class Phone {
    @Id
    @GenericGenerator(name = "uuid",strategy = "uuid")
    @GeneratedValue(generator = "uuid")
    private String id;
    private String phoneName;
    @ManyToOne
    private Person person;

    public Person getPerson() {
        return person;
    }

    public void setPerson(Person person) {
        this.person = person;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getPhoneName() {
        return phoneName;
    }

    public void setPhoneName(String phoneName) {
        this.phoneName = phoneName;
    }
}

Person类进行如下配置:

package cn.edu.ccut.bo;

import org.hibernate.annotations.GenericGenerator;

import javax.persistence.*;
import java.io.Serializable;
import java.util.List;

@Entity
public class Person implements Serializable {
    @Id
    @GenericGenerator(name = "uuid",strategy = "uuid")
    @GeneratedValue(generator = "uuid")
    private String id;
    private String name;
    @OneToMany(mappedBy = "person")
    private List<Phone> phones;

    public List<Phone> getPhones() {
        return phones;
    }

    public void setPhones(List<Phone> phones) {
        this.phones = phones;
    }

    public Person() {
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Person{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                ", phones=" + phones +
                '}';
    }
}

编写测试类测试:

import cn.edu.ccut.bo.Person;
import cn.edu.ccut.bo.Phone;
import cn.edu.ccut.util.DBUtil;
import org.hibernate.Session;
import org.junit.Test;

public class HibernateTest {

    @Test
    public void testHibernateConfig() throws Exception{
        //创建Session对象
        Session session = DBUtil.getSession();
        //开启事务
        session.beginTransaction();
        Phone p1 = new Phone();
        p1.setPhoneName("华为");
        Phone p2 = new Phone();
        p2.setPhoneName("苹果");
        Person person = new Person();
        person.setName("张三");
        session.save(person);
        p1.setPerson(person);
        p2.setPerson(person);
        session.save(person);
        session.save(p1);
        session.save(p2);
        session.getTransaction().commit();
        /*Person person = (Person) session.get(Person.class, "40288d81688c96ce01688c96ed880001");
        System.out.println(person);*/
        DBUtil.close();
    }
}

测试结果如下:

 

我们进行一下查询操作,查询Person类和它所拥有的手机:

测试类编写如下:

import cn.edu.ccut.bo.Person;
import cn.edu.ccut.bo.Phone;
import cn.edu.ccut.util.DBUtil;
import org.hibernate.Session;
import org.junit.Test;

public class HibernateTest {

    @Test
    public void testHibernateConfig() throws Exception{
        //创建Session对象
        Session session = DBUtil.getSession();
        Person person = (Person) session.get(Person.class, "40288d81688cb42701688cb428810000");
        System.out.println(person);
        DBUtil.close();
    }
}

 测试类执行效果如下:

可见我们成功了!

多对多的配置请私下自主进行学习,使用注解@ManyToMany 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值