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 ...
随机推荐
- 小程序canvasu真机上数据图片不能使用
canvas遇到的坑 1.文字换行 2.真机不能使用网络数据图片(真坑) 点击显示效果我就不写了,你们可以自己加一下 全部代码贴出来 css #preview { width: 100%; heigh ...
- UI自动化的痛点
解决UI自动化难点痛点: 解决从安装过程中跳出的提示框以及操作过程中任意提示框的操作,来提高用例成功率: 公用用例及业务用例分离,便于维护和多人使用,提高脚本编写效率: 解决用android wind ...
- [loj6038]「雅礼集训 2017 Day5」远行 lct+并查集
给你 n 个点,支持 m 次操作,每次为以下两种:连一条边,保证连完后是一棵树/森林:询问一个点能到达的最远的点与该点的距离.强制在线. n≤3×10^5 n≤3×10^5 ,m≤5×10^5 m≤5 ...
- python正则表达式教程
原文这里,非常实用,转载一下 再来一篇,两篇一起看,美滋滋 本文介绍了Python对于正则表达式的支持,包括正则表达式基础以及Python正则表达式标准库的完整介绍及使用示例.本文的内容不包括如何编写 ...
- ASP.NET WebAPI 02-Action的选择(一)
在WebAPI对于Action的选择主要经过:Action方法名匹配,Http方法匹配,参数匹配三步. Http方法匹配 WebAPI提供了三种Http方法的选择方式,分别是:方法前缀,AcceptV ...
- Node.js 的异步机制由事件和回调函数——循环中的回调函数
var fs=require('fs'); var files =['a.txt','b.txt','c.txt']; // for (var i = 0; i < files.length; ...
- bzoj 2326 矩阵快速幂
思路:矩阵快速幂搞一搞. #include<bits/stdc++.h> #define LL long long #define fi first #define se second # ...
- Node.js的Buffer那些你可能不知道的用法
在大多数介绍Buffer的文章中,主要是围绕数据拼接和内存分配这两方面的.比如我们使用fs模块来读取文件内容的时候,返回的就是一个Buffer: fs.readFile('filename', fun ...
- MySQL 之 多表查询
一.多表联合查询 #创建部门CREATE TABLE IF NOT EXISTS dept ( did int not null auto_increment PRIMARY KEY, dname V ...
- [BZOJ5010][FJOI2017]矩阵填数(状压DP)
5010: [Fjoi2017]矩阵填数 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 90 Solved: 45[Submit][Status][ ...