在使用实体类生成对应的数据库表时,很多的时候都会遇到这种情况:在一个实体类中引用另外的实体类,一般遇上这种情况,我们使用@OneToOne@OneToMany@ManyToOne@ManyToMany这4个注解比较多,但是好奇害死猫,除了这四个有没有别的使用情况,尤其是一个实体类要在多个不同的实体类中进行使用,而本身又不需要独立生成一个数据库表,这就是需要@Embedded@Embeddable的时候了,下面分成4类来说明在一个实体类中引用另外的实体类的情况,具体的数据库环境是MySQL 5.7。

使用的两个实体类如下:

Address类

public class Address implements Serializable{
private static final long serialVersionUID = 8849870114128959929L; private String country;
private String province;
private String city;
private String detail; //setter、getter
}

Person类:

@Entity
public class Person implements Serializable{
private static final long serialVersionUID = 8849870114127659929L; @Id
@GeneratedValue
private Long id; @Column(nullable = false)
private String name; @Column(nullable = false)
private Integer age; private Address address; //setter、getter
}

1、 两个注解全不使用

当这两个注解都不使用时,那么两个实体类和上面的相同,那么生成的表结构如下: 

Address属性字段会映射成tinyblob类型的字段,这是用来存储不超过255字符的二进制字符串的数据类型,显然我们通常不会这么使用。

2、 只使用@Embeddable

我们在Address实体类上加上@Embeddable注解,变成如下类:

@Embeddable
public class Address implements Serializable{
private static final long serialVersionUID = 8849870114128959929L; private String country;
private String province;
private String city;
private String detail; //setter、getter
}

而Person实体类不变,生成的数据库表结构如下: 

可以看出这次是把Address中的字段映射成数据库列嵌入到Person表中了,而这些字段的类型和长度也使用默认值。如果我们在Address中的字段中设置列的相关属性,则会按照我们设定的值去生成,如下Address类:

@Embeddable
public class Address implements Serializable{
private static final long serialVersionUID = 8849870114128959929L; @Column(nullable = false)
private String country;
@Column(length = 30)
private String province;
@Column(unique = true)
private String city;
@Column(length = 50)
private String detail;
//setter、getter
}

生成的表结构如下:

 

我们在Address中配置的属性全部成功映射到Person表中。

3、 只使用@Embedded

这里我们只在Person中使用@Embedded,如下:

@Entity
public class Person implements Serializable{
private static final long serialVersionUID = 8849870114127659929L; @Id
@GeneratedValue
private Long id; @Column(nullable = false)
private String name; @Column(nullable = false)
private Integer age; @Embedded
private Address address; //setter、getter
}

Adddress类和最开始的不同POJO类相同,此时生成的表结构如下: 

可以看出这个表结构和在Address中只使用@Embeddable注解时相同,在进入深一步试验,我们在Address中加入列属性,但是不使用@Embeddable注解会发生什么? 
Address类如下:

public class Address implements Serializable{
private static final long serialVersionUID = 8849870114128959929L; @Column(nullable = false)
private String country;
@Column(length = 30)
private String province;
@Column(unique = true)
private String city;
@Column(length = 50)
private String detail;
//setter、getter
}

生成数据表结构如下: 

所以只使用@Embedded和只使用@Embeddable产生的效果是相同的。

4、 两个注解全使用

既然单独使用@Embedded或者只使用@Embeddable都会产生作用,那么这两个都使用效果也一定是一样的,我们平时也是这么用的。所以在这部分我们就不演示和上面相同的效果了,而是说两个深入的话题。

4.1 覆盖@Embeddable类中字段的列属性

这里就要使用另外的两个注解@AttributeOverrides@AttributeOverride,这两个注解是用来覆盖@Embeddable类中字段的属性的。

  • @AttributeOverrides:里面只包含了@AttributeOverride类型数组;
  • @AttributeOverride:包含要覆盖的@Embeddable类中字段名name和新增的@Column字段的属性;

使用如下: 
Person类如下:

@Entity
public class Person implements Serializable{
private static final long serialVersionUID = 8849870114127659929L; @Id
@GeneratedValue
private Long id; @Column(nullable = false)
private String name; @Column(nullable = false)
private Integer age; @Embedded
@AttributeOverrides({@AttributeOverride(name="country", column=@Column(name = "person_country", length = 25, nullable = false)),
@AttributeOverride(name="city", column = @Column(name = "person_city", length = 15))})
private Address address; //setter、getter
}

Address类如下:

@Embeddable
public class Address implements Serializable{
private static final long serialVersionUID = 8849870114128959929L; @Column(nullable = false)
private String country;
@Column(length = 30)
private String province;
@Column(unique = true)
private String city;
@Column(length = 50)
private String detail;
//setter、getter
}

生成的数据表如下:

可以看出我们的@AttributeOverrides@AttributeOverride两个注解起作用了。

4.2 多层嵌入实体类属性

上面所有的例子都是使用两层实体类嵌入,其实这种实体类的嵌入映射是可以使用多层的,具体的例子如下。 
我们新建立一个类Direction表示方位如下:

@Embeddable
public class Direction implements Serializable{ @Column(nullable = false)
private Integer longitude;
private Integer latitude;
}

Address如下:

@Embeddable
public class Address implements Serializable{
private static final long serialVersionUID = 8849870114128959929L; @Column(nullable = false)
private String country;
@Column(length = 30)
private String province;
@Column(unique = true)
private String city;
@Column(length = 50)
private String detail; @Embedded
private Direction direction;
}

Person类如下:

@Entity
public class Person implements Serializable{
private static final long serialVersionUID = 8849870114127659929L; @Id
@GeneratedValue
private Long id; @Column(nullable = false)
private String name; @Column(nullable = false)
private Integer age; @Embedded
@AttributeOverrides({@AttributeOverride(name="direction.latitude", column=@Column(name = "person_latitude")),
@AttributeOverride(name="direction.longitude", column = @Column(name = "person_longitude"))})
private Address address;
}

生成的数据表如下:

在上面需要注意如下几点:

  • 在Person中定义Direction中的属性时,需要用”.”将所有相关的属性连接起来;
  • 在Direction中longitude属性定义为not null,但是由于使用了@AttributeOverride注解,其中虽然没有定义null属性,但是这时使用的是默认的nullable属性,默认为true;

转载于:http://blog.csdn.net/lmy86263/article/details/52108130

Hibernate中@Embedded和@Embeddable注解的更多相关文章

  1. hibernate中.hbm.xml和注解方式自动生成数据表的简单实例(由新手小白编写,仅适用新手小白)

    绝逼新手小白,so 请大神指点! 如果真的错的太多,错的太离谱,错的误导了其他小伙伴,还望大神请勿喷,大神请担待,大神请高抬贵嘴......谢谢. 好了,正题 刚接触ssh,今天在搞使用.hbm.xm ...

  2. hibernate中多对多的注解配置

    hibernate多对多的注解配置中的自动生成中间表的配置: @Entity@Table(name="test_student")public class Students { @ ...

  3. hibernate 中一对多的注解配置

    //一方@Entity@Table(name="test_classinfo")public class ClassInfo { @Id @SequenceGenerator(na ...

  4. Hibernate @Embeddable注解

    在hibernate中实现自己定义类型,仅仅要实现UserType接口就可以或者以Component的形式提供.JPA的@Embedded有点类似,通过此凝视能够在你的Entity中使用一般的java ...

  5. Annotation(二)——Hibernate中注解的开发

    在利用注解开发数据库持久层以前,需要学习一个规范JPA(Java Persistence API),这也是SUN公司提出的数据库的持久化规范.就类似于JDBC,Servlet,JSP等规范一样.而Hi ...

  6. Hibernate中使用@Lob 注解保存String[] 问题

    Hibernate中使用@Lob 注解保存String[] 问题 在Hibernate注解中怎样你想保存一个字段为String数组类型.假设你想尝试保存为clob类型的话,普通情况下为定义为: @En ...

  7. hibernate中1对1的注解配置

    hibernate中1对1的注解配置分为:外键关联映射和主键关联映射 1.外键配置 //一方@Entity@Table(name="test_classinfo")public c ...

  8. Hibernate中注解的开发

    转自:https://blog.csdn.net/liujiahan629629/article/details/22335563 在利用注解开发数据库持久层以前,需要学习一个规范JPA(JavaPe ...

  9. hibernate中many-to-one的not-found属性和@notfound注解

    如果在Hibernate项目里面配了很多many-to-one的关联,即使后台在查询数据时已经作了健全性判断,但还是会经常抛出对象找不到异常:org.hibernate.ObjectNotFoundE ...

随机推荐

  1. WP主题模板制作修改教程

    WP主题模板制作修改教程 实际上,当我们打开某个主题的文件夹时,看到的并不止这两个文件,而是更多.但一般来说,在一个完整的 WP 主题文件夹中都应该包含下列文件(也称为模板文件):页面 模板文件 用途 ...

  2. 如何修改WP文章字体格式、字号大小、字体颜色

    在使用wordpress编辑文章的时候,很多朋友会像小编一样,发现它并没有像word文档一样有修改字体样式.字体大小.字体颜色.分页符等功能按钮,对我们写文章极为不便,原因是wordpress默认使用 ...

  3. Java学习(简介,软件安装)

    1. Java概述: Java的发展可以归纳如下的几个阶段. (1)第一阶段(完善期):JDK 1.0 ( 1995年推出)一JDK 1.2 (1998年推出,Java更名为Java 2): (2)第 ...

  4. C#窗体内嵌外部程序(cmd.exe)的显示【转载】

    [DllImport("User32.dll ", EntryPoint = "SetParent")] private static extern IntPt ...

  5. python中的计时器:timeit

    python中的计时器:timeit timeit 通常在一段程序的前后都用上time.time(),然后进行相减就可以得到一段程序的运行时间,不过python提供了更强大的计时库:timeit #导 ...

  6. 如何使用Bootstrap4显示和隐藏元素

    如何使用Bootstrap4显示和隐藏元素 为了更快地进行移动设备开发,请使用响应式显示类来按设备显示和隐藏元素.避免创建相同站点的完全不同版本,而是相应地为每个屏幕大小隐藏元素. 要隐藏元素,只需使 ...

  7. Maven下载安装步骤

    Maven下载安装步骤 1.下载maven 进入Maven官网的下载页面:http://maven.apache.org/download.cgi,如下图所示: 选择当前最新版本:"apac ...

  8. SASS详解之混合(mixins)

    SASS详解之混合(mixins)可以出现在SASS的任何地方.有很多类名具有相同或者相似的样式,就可以用SASS中的混合(mixins)来进行编写,然后针对不同类名的不同样式逐一编写. 定义一个混合 ...

  9. linux网络管理----网络命令

    1 Linux网络命令之网络环境查看命令  ifconfig  2 Linux网络命令之网络测试命令  telnet 基本已经被ssh替代了,telnet是明文传递,不安全

  10. 数据准备<1>:数据质量检查-理论篇

    数据行业有一句很经典的话--"垃圾进,垃圾出"(Garbage in, Garbage out, GIGO),意思就是,如果使用的基础数据有问题,那基于这些数据得到的任何产出都是没 ...