Hibernate中@Embedded和@Embeddable注解的使用
2016-08-03 22:20
381 查看
在使用实体类生成对应的数据库表时,很多的时候都会遇到这种情况:在一个实体类中引用另外的实体类,一般遇上这种情况,我们使用
使用的两个实体类如下:
Address类
Person类:
Address属性字段会映射成tinyblob类型的字段,这是用来存储不超过255字符的二进制字符串的数据类型,显然我们通常不会这么使用。
2、 只使用
我们在Address实体类上加上
而Person实体类不变,生成的数据库表结构如下:
可以看出这次是把Address中的字段映射成数据库列嵌入到Person表中了,而这些字段的类型和长度也使用默认值。如果我们在Address中的字段中设置列的相关属性,则会按照我们设定的值去生成,如下Address类:
生成的表结构如下:
我们在Address中配置的属性全部成功映射到Person表中。
3、 只使用
这里我们只在Person中使用
Adddress类和最开始的不同POJO类相同,此时生成的表结构如下:
可以看出这个表结构和在Address中只使用
Address类如下:
生成数据表结构如下:
所以只使用
4.1 覆盖
这里就要使用另外的两个注解
使用如下:
Person类如下:
Address类如下:
生成的数据表如下:
可以看出我们的
我们新建立一个类Direction表示方位如下:
Address如下:
Person类如下:
生成的数据表如下:
在上面需要注意如下几点:
在Person中定义Direction中的属性时,需要用”.”将所有相关的属性连接起来;
在Direction中longitude属性定义为
@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;
相关文章推荐
- Hibernate中@Embedded和@Embeddable注解的使用
- Hibernate中@Embedded和@Embeddable注解的使用
- 注解的力量 -----Spring 2.5 JPA hibernate 使用方法的点滴整理(三):通过 @Autowired的使用来消除 set ,get方法。
- 注解的力量 -----Spring 2.5 JPA hibernate 使用方法的点滴整理(五):使用@Component 来简化bean的配置
- 注解的力量 -----Spring 2.5 JPA hibernate 使用方法的点滴整理(二):进一步消除 hibernate.cfg.xml
- hibernate使用annotation(注解)测试/生成数据库表
- 注解的力量 -----Spring 2.5 JPA hibernate 使用方法的点滴整理(六): 一些常用的数据库 注解
- 注解的力量 -----Spring 2.5 JPA hibernate 使用方法的点滴整理(一):消除hibernate中<mapping resouce 的xxxx. hbm.xml文件
- 注解的力量 -----Spring 2.5 JPA hibernate 使用方法的点滴整理(三):通过 @Autowired的使用来消除 set ,get方法。
- 注解方式使用hibernate与spring
- 使用Hibernate注解时避免生成中间表
- 注解的力量 -----Spring 2.5 JPA hibernate 使用方法的点滴整理(一):消除hibernate中<mapping resouce 的xxxx. hbm.xml文件
- 注解的力量 -----Spring 2.5 JPA hibernate 使用方法的点滴整理(六): 一些常用的数据库 注解
- Hibernate3.5使用注解方式的bug
- 使用JPA 注解的Hibernate
- 注解的力量 -----Spring 2.5 JPA hibernate 使用方法的点滴整理(一):消除hibernate中
- 注解的力量 -----Spring 2.5 JPA hibernate 使用方法的点滴整理(四):使用 命名空间 简化配置
- Struts2+Spring2.5+JPA(Hibernate3)环境搭建,使用注解
- hibernate 使用hibernate 的注解做多对一双向映射
- 注解的力量 -----Spring 2.5 JPA hibernate 使用方法的点滴整理(三):通过 @Autowired的使用来消除 set ,get方法。