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 ...
随机推荐
- oracle 12C wmsys.wm_concat()函数
http://blog.itpub.net/31392094/viewspace-2149577/
- C++ 字符串基本操作
C++ 规定,不能直接进行数组名的赋值,因为数组名是一个常量,而结构类型的变量可以赋值,不同结构体的变量不允许相互赋值,即使这两个变量可能具有相同的成员.在程序中不能同时出现无参构造函数和带有全部默认 ...
- ZOJ 3613 Wormhole Transport
斯坦纳树,$dp$. 先求出每个状态下连通的最小花费,因为可以是森林,所以$dp$一下. #include<bits/stdc++.h> using namespace std; int ...
- scrapy抓取拉勾网职位信息(七)——数据存储(MongoDB,Mysql,本地CSV)
上一篇完成了随机UA和随机代理的设置,让爬虫能更稳定的运行,本篇将爬取好的数据进行存储,包括本地文件,关系型数据库(以Mysql为例),非关系型数据库(以MongoDB为例). 实际上我们在编写爬虫r ...
- java中Dao模式
什么是DAO 1.Data Access Object(数据存取对象) 2.位于业务逻辑和持久化数据之间 3.实现对持久化数据的访问 DAO模式的作用 1隔离业务逻辑代码和数据访问代码 2.隔离不 ...
- hibernate4日志配置
在平时运行程序时控制台有很对的日志打印,本文说明如何控制这些日志打印. 1.确定要使用日志的实现,我在这使用的是log4j. 2.加入log4j的api包slf4j-api.jar,log4j的转换包 ...
- HDU 6166 Spfa
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6166 题意:给出一个n个点的有向图.然后给你k个点,求这k个点任意两点之间的最短路的最小值.思路: 以 ...
- [BZOJ4373]算术天才⑨与等差数列(线段树)
[l,r]中所有数排序后能构成公差为k的等差数列,当且仅当: 1.区间中最大数-最小数=k*(r-l) 2.k能整除区间中任意两个相邻数之差,即k | gcd(a[l+1]-a[l],a[l+2]-a ...
- HDU 1057 What Are You Talking About trie树 简单
http://acm.hdu.edu.cn/showproblem.php?pid=1075 题意 : 给一个单词表然后给一些单词,要求翻译单词表中有的单词,没有则直接输出原单词. 翻译文段部分get ...
- 【lct】poj2763 Housewife Wind
题意:给你一棵树,边带权,支持两种操作:修改某条边的权值:查询两点之间的最短路. lct主要实现单点修改和路径和. 修改x结点的值只需将x Splay到其所在辅助树的根,然后修改其值,再maintai ...