当前位置: 首页 > news >正文

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

 

相关文章:

  • Spring MVC使用@RestController生成JSON示例
  • Tyrion中文文档(含示例源码)
  • 控制域名忘记续费,三星数百万台手机陷入“任人宰割”境地
  • 【趣味题】够买餐具
  • 《大道至简》第一章读后感(伪代码)
  • 新态势感知系列(1):从态势感知到全方位态势感知
  • [noip模拟]计蒜姬BFS
  • Android零基础入门第63节:过时但仍值得学习的选项卡TabHost
  • 「vmware」虚拟机与主机共享目录
  • 找出潜在威胁 端点侦测与反制系统
  • Oracle 自适应游标
  • 读《自控力》| 时刻明确你真正想要什么
  • js面向对象
  • 【转载】xtrabackup原理及实施
  • 在Android应用程序中实现推送通知
  • 「译」Node.js Streams 基础
  • 【跃迁之路】【477天】刻意练习系列236(2018.05.28)
  • GDB 调试 Mysql 实战(三)优先队列排序算法中的行记录长度统计是怎么来的(上)...
  • Java反射-动态类加载和重新加载
  • React 快速上手 - 07 前端路由 react-router
  • spring cloud gateway 源码解析(4)跨域问题处理
  • Vue.js源码(2):初探List Rendering
  • 不发不行!Netty集成文字图片聊天室外加TCP/IP软硬件通信
  • 创建一个Struts2项目maven 方式
  • 推荐一款sublime text 3 支持JSX和es201x 代码格式化的插件
  • 我感觉这是史上最牛的防sql注入方法类
  • 一、python与pycharm的安装
  • 怎么将电脑中的声音录制成WAV格式
  • hi-nginx-1.3.4编译安装
  • raise 与 raise ... from 的区别
  • Semaphore
  • #我与Java虚拟机的故事#连载13:有这本书就够了
  • (12)Hive调优——count distinct去重优化
  • (173)FPGA约束:单周期时序分析或默认时序分析
  • (c语言版)滑动窗口 给定一个字符串,只包含字母和数字,按要求找出字符串中的最长(连续)子串的长度
  • (阿里巴巴 dubbo,有数据库,可执行 )dubbo zookeeper spring demo
  • (读书笔记)Javascript高级程序设计---ECMAScript基础
  • (二)linux使用docker容器运行mysql
  • (附源码)spring boot公选课在线选课系统 毕业设计 142011
  • (黑马出品_高级篇_01)SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式
  • (每日持续更新)信息系统项目管理(第四版)(高级项目管理)考试重点整理 第13章 项目资源管理(七)
  • (免费领源码)python+django+mysql线上兼职平台系统83320-计算机毕业设计项目选题推荐
  • (七)c52学习之旅-中断
  • (转)程序员技术练级攻略
  • *1 计算机基础和操作系统基础及几大协议
  • .gitignore
  • .Mobi域名介绍
  • .NET 服务 ServiceController
  • .net 桌面开发 运行一阵子就自动关闭_聊城旋转门家用价格大约是多少,全自动旋转门,期待合作...
  • 。Net下Windows服务程序开发疑惑
  • @manytomany 保存后数据被删除_[Windows] 数据恢复软件RStudio v8.14.179675 便携特别版...
  • @transactional 方法执行完再commit_当@Transactional遇到@CacheEvict,你的代码是不是有bug!...
  • @Transient注解
  • [ web基础篇 ] Burp Suite 爆破 Basic 认证密码
  • [ 隧道技术 ] 反弹shell的集中常见方式(二)bash反弹shell