首页 > 其他分享 >hibernate的OneToOne映射

hibernate的OneToOne映射

时间:2022-10-22 11:46:08浏览次数:56  
标签:hibernate name 映射 teacher _. relation student id OneToOne

hibernate的OneToOne映射

1、前言

@OneToOne注解可以建立实体bean之间的一对一的关联。 一对一关联有四种情况:

一是关联的实体都共享同样的主键;

二是其中一个实体通过外键关联到另一个实体的主键 (注意要模拟一对一关联必须在外键列上添加唯一约束);

三是通过关联表来保存两个实体之间的连接关系 (注意要模拟一对一关联必须在每一个外键上添加唯一约束);

以上三种情况在源码中可见说明,但其实在实际开发过程中,总会有第四种情况:两个实体类只是通过两个普通字段关联(外键关联的特殊案例)。

2、共享主键

通过共享主键来进行一对一关联映射。

单向关联

entity:Body
@Entity
@Data
@Table(name = "jei_body")
public class Body implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    @ApiModelProperty(value = "id")
    private Long id;

    @Column(name = "name")
    @ApiModelProperty(value = "姓名")
    private String name;

    @Column(name = "gender")
    @ApiModelProperty(value = "性别")
    private Integer gender;

    @OneToOne(fetch = FetchType.LAZY)
    @PrimaryKeyJoinColumn
    private Heart heart;

}

注意:

@OneToOne(fetch = FetchType.LAZY)
@PrimaryKeyJoinColumn

使用注解@PrimaryKeyJoinColumn定义了一对一关联。

双向关联

entity:Heart
@Entity
@Data
@Table(name = "jei_heart")
public class Heart implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    @ApiModelProperty(value = "id")
    private Long id;

    @Column(name = "is_health")
    @ApiModelProperty(value = "是否健康")
    private String isHealth;

    @OneToOne(fetch = FetchType.LAZY, mappedBy = "heart")
    private Body body;

}

注意:

@OneToOne(fetch = FetchType.LAZY, mappedBy = "heart")

这里就不再需要@PrimaryKeyJoinColumn进行定义关联,需要用mappedBy 来确定关系由谁来维护。mappedBy="heart"说明在两个关联的实体Bean中,body这一端是关系的拥有者。如果mappedBy没有写的话,hibernate会自动在heart表中生成body_id字段(关联表名_id),否则运行代码就会报错:Unknown column 'heart0_.body_id' in 'field list'

其它

查询body

查询heart

3、外键关联

通过外键关联需要区别主表和副表(要求主表的非主键列(如果它是主键的话,就是”共享主键“)是副表的主键),当然它们是可以对调角色的,只是观察的角度不同。

单向关联

entity:Person
@Entity
@Data
@Table(name = "jei_person")
public class Person implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    @ApiModelProperty(value = "id")
    private Long id;

    @Column(name = "name")
    @ApiModelProperty(value = "姓名")
    private String name;

    @Column(name = "card_id")
    @ApiModelProperty(value = "身份证id")
    private Long cardId;

    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "card_id", referencedColumnName = "id", insertable = false, updatable = false)
    private Card card;

}

注意:

@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "card_id", referencedColumnName = "id", insertable = false, updatable = false)

这里的name=“card_id”, 指的当前表的字段(可以是任意名字的字段),referencedColumnName = "id"是副表的主键id,其它这里可以不写referencedColumnName ,因为它默认而且必须是副表的主键id。

双向关联

entity:Card
@Entity
@Data
@Table(name = "jei_card")
public class Card implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    @ApiModelProperty(value = "id")
    private Long id;

    @Column(name = "county_name")
    @ApiModelProperty(value = "县、市辖区、县级市、自治县、旗、自治旗、特区、林区名称")
    private String countyName;

    @Column(name = "detail")
    @ApiModelProperty(value = "身份证明细")
    private String detail;

    @OneToOne(fetch = FetchType.LAZY, mappedBy = "card")
    private Person person;

}

注意:

@OneToOne(fetch = FetchType.LAZY, mappedBy = "card")

这里副表就不再需要@JoinColumn进行声明关联,需要用mappedBy 来确定关系由谁来维护。mappedBy="card"说明在两个关联的实体Bean中,person这一端是关系的拥有者,person一方的表中生成到关联类的外键。

其它

它们分别关联查询的sql截图。

查询person

查询card

4、关联表

通过关联表来保存两个实体之间的连接关系,也许是最另类的,也是很常见的。

单向关联

entity:Customer
@Entity
@Data
@Table(name = "jei_customer")
public class Customer implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    @ApiModelProperty(value = "id")
    private Long id;

    @Column(name = "name")
    @ApiModelProperty(value = "姓名")
    private String name;

    @Column(name = "gender")
    @ApiModelProperty(value = "性别")
    private Integer gender;

    @OneToOne(fetch = FetchType.LAZY)
    @JoinTable(name = "jei_customer_and_passport",
            joinColumns = @JoinColumn(name = "customer_id"),
            inverseJoinColumns = @JoinColumn(name = "passport_id"))
    private Passport passport;

}

注意:

@OneToOne(fetch = FetchType.LAZY)

@JoinTable(name = "jei_customer_and_passport",joinColumns = @JoinColumn(name = "customer_id"),inverseJoinColumns = @JoinColumn(name = "passport_id"))

Customer通过名为 jei_customer_and_passport表和 Passport关联,该关联表(jei_customer_and_passport)拥有名为passport_id的外键列,该 外键指向Passport,该信息定义为inverseJoinColumn的属性值,而customer_id外键列指向Customer, 该信息定义为 joinColumns的属性值。

双向关联

entity:Passport
@Entity
@Data
@Table(name = "jei_passport")
public class Passport implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    @ApiModelProperty(value = "id")
    private Long id;

    @Column(name = "country")
    @ApiModelProperty(value = "国家")
    private String country;

    @Column(name = "is_effect")
    @ApiModelProperty(value = "是否有效")
    private Integer isEffect;

    @OneToOne(fetch = FetchType.LAZY, mappedBy = "passport")
    private Customer customer;

}

注意:

@OneToOne(fetch = FetchType.LAZY, mappedBy = "passport")

这里不需要@JoinTable进行声明关联,需要用mappedBy 来确定关系由谁来维护。mappedBy="passport"说明在两个关联的实体Bean中,customer这一端是关系的拥有者。

其它

查询customer

查询passport

5、只是普通字段关联

它其实也是一种外键关联,只是说关联字段没有一个是主键;这样的关联关系,推荐只做单向关联。

单向关联

entity:Teacher
@Entity
@Data
@Table(name = "jei_teacher")
public class Teacher implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    @ApiModelProperty(value = "id")
    private Long id;

    @Column(name = "name")
    @ApiModelProperty(value = "姓名")
    private String name;

    @Column(name = "course")
    @ApiModelProperty(value = "课程")
    private String course;

    @Column(name = "student_relation_id")
    @ApiModelProperty(value = "关系id")
    private Long studentRelationId;

    @OneToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "student_relation_id", referencedColumnName = "teacher_relation_id", insertable = false, updatable = false)
    @NotFound(action = NotFoundAction.IGNORE)
    private Student student;

}

注意:

@OneToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "student_relation_id", referencedColumnName = "teacher_relation_id", insertable = false, updatable = false)
@NotFound(action = NotFoundAction.IGNORE)

这里的name=“student_relation_id”, 指的当前表的字段,referencedColumnName = "teacher_relation_id"是关联表的字段,推荐要加上@NotFound(action = NotFoundAction.IGNORE),这时一定是@OneToOne(fetch = FetchType.EAGER),否则有会警告。

双向关联

entity:Student
@Entity
@Data
@Table(name = "jei_student")
public class Student implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    @ApiModelProperty(value = "id")
    private Long id;

    @Column(name = "name")
    @ApiModelProperty(value = "姓名")
    private String name;

    @Column(name = "address")
    @ApiModelProperty(value = "地址")
    private String address;

    @Column(name = "teacher_relation_id")
    @ApiModelProperty(value = "关系id")
    private Long teacherRelationId;

    @OneToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "teacher_relation_id", referencedColumnName = "student_relation_id", insertable = false, updatable = false)
    @NotFound(action = NotFoundAction.IGNORE)
    private Teacher teacher;

//    这种是要报错的
//    @OneToOne(fetch = FetchType.LAZY, mappedBy = "student")
//    private Teacher teacher;

}

注意:

@OneToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "teacher_relation_id", referencedColumnName = "student_relation_id", insertable = false, updatable = false)
@NotFound(action = NotFoundAction.IGNORE)

这里的name=“teacher_relation_id”, 指的当前表的字段,referencedColumnName = "student_relation_id"是关联表的字段,推荐要加上@NotFound(action = NotFoundAction.IGNORE),这时一定是@OneToOne(fetch = FetchType.EAGER),否则有会警告。

其它

查询teacher
select teacher0_.id as id1_10_, teacher0_.course as course2_10_, teacher0_.name as name3_10_, teacher0_.student_relation_id as student_4_10_ from jei_teacher teacher0_ where teacher0_.id=1 and (teacher0_.name like ?) and (teacher0_.course like ?) and teacher0_.student_relation_id=100

select student0_.id as id1_9_2_, student0_.address as address2_9_2_, student0_.name as name3_9_2_, student0_.teacher_relation_id as teacher_4_9_2_, teacher1_.id as id1_10_0_, teacher1_.course as course2_10_0_, teacher1_.name as name3_10_0_, teacher1_.student_relation_id as student_4_10_0_, student2_.id as id1_9_1_, student2_.address as address2_9_1_, student2_.name as name3_9_1_, student2_.teacher_relation_id as teacher_4_9_1_ from jei_student student0_ left outer join jei_teacher teacher1_ on student0_.teacher_relation_id=teacher1_.student_relation_id left outer join jei_student student2_ on teacher1_.student_relation_id=student2_.teacher_relation_id where student0_.teacher_relation_id=?

select teacher0_.id as id1_10_2_, teacher0_.course as course2_10_2_, teacher0_.name as name3_10_2_, teacher0_.student_relation_id as student_4_10_2_, student1_.id as id1_9_0_, student1_.address as address2_9_0_, student1_.name as name3_9_0_, student1_.teacher_relation_id as teacher_4_9_0_, teacher2_.id as id1_10_1_, teacher2_.course as course2_10_1_, teacher2_.name as name3_10_1_, teacher2_.student_relation_id as student_4_10_1_ from jei_teacher teacher0_ left outer join jei_student student1_ on teacher0_.student_relation_id=student1_.teacher_relation_id left outer join jei_teacher teacher2_ on student1_.teacher_relation_id=teacher2_.student_relation_id where teacher0_.student_relation_id=?
查询student
select student0_.id as id1_9_, student0_.address as address2_9_, student0_.name as name3_9_, student0_.teacher_relation_id as teacher_4_9_ from jei_student student0_ where student0_.id=1 and (student0_.name like ?) and (student0_.address like ?) and student0_.teacher_relation_id=100

select teacher0_.id as id1_10_2_, teacher0_.course as course2_10_2_, teacher0_.name as name3_10_2_, teacher0_.student_relation_id as student_4_10_2_, student1_.id as id1_9_0_, student1_.address as address2_9_0_, student1_.name as name3_9_0_, student1_.teacher_relation_id as teacher_4_9_0_, teacher2_.id as id1_10_1_, teacher2_.course as course2_10_1_, teacher2_.name as name3_10_1_, teacher2_.student_relation_id as student_4_10_1_ from jei_teacher teacher0_ left outer join jei_student student1_ on teacher0_.student_relation_id=student1_.teacher_relation_id left outer join jei_teacher teacher2_ on student1_.teacher_relation_id=teacher2_.student_relation_id where teacher0_.student_relation_id=?

select student0_.id as id1_9_2_, student0_.address as address2_9_2_, student0_.name as name3_9_2_, student0_.teacher_relation_id as teacher_4_9_2_, teacher1_.id as id1_10_0_, teacher1_.course as course2_10_0_, teacher1_.name as name3_10_0_, teacher1_.student_relation_id as student_4_10_0_, student2_.id as id1_9_1_, student2_.address as address2_9_1_, student2_.name as name3_9_1_, student2_.teacher_relation_id as teacher_4_9_1_ from jei_student student0_ left outer join jei_teacher teacher1_ on student0_.teacher_relation_id=teacher1_.student_relation_id left outer join jei_student student2_ on teacher1_.student_relation_id=student2_.teacher_relation_id where student0_.teacher_relation_id=?

标签:hibernate,name,映射,teacher,_.,relation,student,id,OneToOne
From: https://www.cnblogs.com/jspider/p/16815692.html

相关文章

  • ASP.net EF动态映射实体
    1、配置EF与建立实体模型这里不做过多介绍、主要介绍如何动态映射实体模型1.1、实现过程有很多种方式我们这里使用接口、然后扫描所有继承了该接口的实体类然后映射(也可......
  • 静态资源映射
    web开发中,不可避免地是对静态资源的访问,SpringBoot默认的静态资源映射为三样:classpath:/META-INF/resources/classpath:/resources/classpath:/static/classpath:/pu......
  • springMvc路径参数映射原理
     一、springMvc 执行流程图 二、springMvc中url映射接口关键点2.1:AbstractHandlerMappingorg.springframework.web.servlet.handler.AbstractHandlerMapping#getHa......
  • Hibernate的关键API详解
    在Java中使用Hibernate的步骤​开始Hibernate开发​​......
  • Hibernate无语句面向对象查询(Criteria)
    一、基本查询。1、使用Session对象创建一个Criteria实例。Criteriacriteria=session.createCriteria(Customer.class);(查询所有的Customer对象)2、调用Criteria对象......
  • 多对一映射处理
    查询员工信息以及员工所对应的部门信息a>级联方式处理映射关系<resultMapid="empDeptMap"type="Emp"><idcolumn="eid"property="eid"></id><resultcolumn="ename......
  • [答疑精选]通过序列图可以映射系统用例,这个系统用例肯定不全(2014/12/30)
    统计分析不在序列图中,但是我们需要通过需求去补齐系统用例阳光(908***55)10:10:38 通过序列图可以映射系统用例,这个系统用例肯定不全,那么其他的系统用例通过什么方式得到......
  • Hibernate的HQL查询语法
    一、HQL语法:(一)基础语法1、创建sql查询语句。简单写法:Stringsql="fromCustomer";完整写法:Stringsql="fromcn.xxx.bean.Customer;2、获取Query查询对象。使......
  • Hibernate自定义注解类
    •介绍Hibernate对PO类上支持的注解类是有限的,而且我用的这个版本的Hibernate还不支持在生成数据库表(通过hibernate.hbm2ddl.auto)时生成字段注释(comment)。本文通过扩展Ann......
  • [教你做小游戏] 车炮能移动17个位置,针对90种出发点,如何建立0-16和目标点的映射?
    背景兄弟们,之前我开发了支持联机对战的五子棋、斗地主、UNO。在大家的呼吁之下,我准备开发「象棋」啦!......