Hibernate中@Embedded和@Embeddable注解
在使用实体类生成对应的数据库表时,很多的时候都会遇到这种情况:在一个实体类中引用另外的实体类,一般遇上这种情况,我们使用@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注解的更多相关文章
- hibernate中.hbm.xml和注解方式自动生成数据表的简单实例(由新手小白编写,仅适用新手小白)
绝逼新手小白,so 请大神指点! 如果真的错的太多,错的太离谱,错的误导了其他小伙伴,还望大神请勿喷,大神请担待,大神请高抬贵嘴......谢谢. 好了,正题 刚接触ssh,今天在搞使用.hbm.xm ...
- hibernate中多对多的注解配置
hibernate多对多的注解配置中的自动生成中间表的配置: @Entity@Table(name="test_student")public class Students { @ ...
- hibernate 中一对多的注解配置
//一方@Entity@Table(name="test_classinfo")public class ClassInfo { @Id @SequenceGenerator(na ...
- Hibernate @Embeddable注解
在hibernate中实现自己定义类型,仅仅要实现UserType接口就可以或者以Component的形式提供.JPA的@Embedded有点类似,通过此凝视能够在你的Entity中使用一般的java ...
- Annotation(二)——Hibernate中注解的开发
在利用注解开发数据库持久层以前,需要学习一个规范JPA(Java Persistence API),这也是SUN公司提出的数据库的持久化规范.就类似于JDBC,Servlet,JSP等规范一样.而Hi ...
- Hibernate中使用@Lob 注解保存String[] 问题
Hibernate中使用@Lob 注解保存String[] 问题 在Hibernate注解中怎样你想保存一个字段为String数组类型.假设你想尝试保存为clob类型的话,普通情况下为定义为: @En ...
- hibernate中1对1的注解配置
hibernate中1对1的注解配置分为:外键关联映射和主键关联映射 1.外键配置 //一方@Entity@Table(name="test_classinfo")public c ...
- Hibernate中注解的开发
转自:https://blog.csdn.net/liujiahan629629/article/details/22335563 在利用注解开发数据库持久层以前,需要学习一个规范JPA(JavaPe ...
- hibernate中many-to-one的not-found属性和@notfound注解
如果在Hibernate项目里面配了很多many-to-one的关联,即使后台在查询数据时已经作了健全性判断,但还是会经常抛出对象找不到异常:org.hibernate.ObjectNotFoundE ...
随机推荐
- js excel导出 前端实现(转载)
本文为转载,本人亲测可用,感谢原作者,原文在这里. 一.由于公司项目需要,需要将表格数据导出为EXCEL表格数据. 环境React+Ant Design 二.安装插件js-export-excel ...
- TeX Live & TeXstudio 安装手记
数据库课上又看到了那位用 beamer 做 slides 的师兄,想到自己一拖再拖的LaTeX入门,决定赶快动手装个环境再说~在经过一番搜索和研究之后决定先在 windows 底下试用,选择 TeX ...
- jquery datatable的详细用法
1,首先需要引用下面两个文件 <link rel="stylesheet" href="https://cdn.datatables.net/1.10.16/css ...
- day4 装饰器深入解析
Python装饰器 装饰器是在不修改源码给代码添加功能的常用方法.@是装饰的标志.我们知道,在给代码增加功能的时候,要遵循开放封闭的原则,不能随便更改原码,因此装饰器的功能就显示出来了,只需要在函数前 ...
- day1 作业二:多级菜单操作
作业二:多级菜单 (1)三级菜单 (2)可以次选择进入各子菜单 (3)所需新知识点:列表.字典 要求:输入b返回上一层,输入q退出整个程序 思路:三级菜单第一级别是省,第二级别是市,第三级别是县,用户 ...
- 【LOJ】#2006. 「SCOI2015」小凸玩矩阵
题解 又是美好的一天,我今天的小目标是LOJ刷题数名次前进两名(虽然巨佬们都是BZOJ千题啊这样的><,我就在LOJ划划水吧,我永远喜欢LOJ 这道题要求K大值最小,又是什么什么大值最小, ...
- loadrunner获取毫秒及字符串替换实现
loadrunner获取毫秒及字符串替换实现 今天做一个性能测试,参数化要求创建用户名不可以重复,想来想不没有什么好的办法来避免用户名字的重复.所以就想用时间+随机数来实现,但是实现中遇到一个问题. ...
- SQLyog-12.0.9-0.x64
SQLyog-12.0.9-0.x64 下载地址 链接:https://pan.baidu.com/s/1AjC2rdx8Bgtns1sYmN5NEw 提取码:icko 注册码: 姓名(Name):c ...
- 图片热点的使用,html <area> 的用法
<area>标记主要用于图像地图,通过该标记可以在图像地图中设定作用区域(又称为热点),这样当用户的鼠标移到指定的作用区域点击时,会自动链接到预先设定好的页面.其基本语法结构如下: < ...
- Hibernate (开源对象关系映射框架)
一.基本介绍1.它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm(对象关系映射)框架,hibernate可以自动生成SQL语句,自动执行: Hibern ...