`
zouxue7
  • 浏览: 20628 次
  • 性别: Icon_minigender_2
  • 来自: 成都
社区版块
存档分类
最新评论

hibernate实体关联注解版

阅读更多

      以前用ssh做小项目的时候都是先建数据库再来写Model层,但是总觉得这样就太浪费别人hibernate创始人的初衷,原原本本的ORM框架被我那么一用,面对对象的思想压根就没体现出来,于是今天就试了一把先建Model层,然后直接用 hibernate自带的工具hbm2ddl生成数据库表。其中最难搞的就是实体之间的关联关系,什么一对一,一对多,多对多,又是单向关联又是多向关联的,弄得自己头晕乎乎的,想着还是把它记下来,留着以后看看,俗话说“发表是最好的记忆”。

    一对一

   使用@OneToOne注解可以建立实体bean之间的一对一的关联. 一对一关联有三种情况:

   ①关联的实体都共享同样的主键

   ②是其中一个实体通过外键关联到另一个实体的主键 (注意要模拟一对一关联必须在外键列上添加唯一约束).

   ③过关联表来保存两个实体之间的连接关系 (注意要模拟一对一关联必须在每一个外键上添加唯一约束).

   

    共享主键来进行一对一关联映射

@Entity
public class Body {
@Id
public Long getId() { return id; }

@OneToOne(cascade = CascadeType.ALL)
@PrimaryKeyJoinColumn
public Heart getHeart() {
return heart;
}
@Entity
public class Heart {
    @Id
    public Long getId() { ...}
}
  
...
}

    表模型

    mysql> DESCRIBE heart;
    +-------+------------+------+-----+---------+----------------+
    | Field | Type       | Null | Key | Default | Extra          |
    +-------+------------+------+-----+---------+----------------+
    | id    | bigint(20) | NO   | PRI | NULL    | auto_increment |
    +-------+------------+------+-----+---------+----------------+

 

    mysql> desc body;
  +-------+------------+------+-----+---------+-------+
  | Field | Type       | Null | Key | Default | Extra |
  +-------+------------+------+-----+---------+-------+
  | id    | bigint(20) | NO   | PRI | NULL    |       |
  +-------+------------+------+-----+---------+-------+

   生成的SQL脚本

   create table Body (
        id bigint not null,
        primary key (id)
    )

    create table Heart (
        id bigint not null auto_increment,
        primary key (id)
    )

 

    外键列进行实体的关联

@Entity
public class Customer implements Serializable {
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name="passport_fk")
public Passport getPassport() {
...
}

@Entity
public class Passport implements Serializable {
@OneToOne(mappedBy = "passport")
public Customer getOwner() {
...
}

    表模型

    mysql>  DESCRIBE customer;
    +-------------+--------------+------+-----+---------+----------------+
    | Field       | Type         | Null | Key | Default | Extra          |
    +-------------+--------------+------+-----+---------+----------------+
    | id          | bigint(20)   | NO   | PRI | NULL    | auto_increment |
    | name        | varchar(255) | YES  |     | NULL    |                |
    | passport_fk | bigint(20)   | YES  | MUL | NULL    |                |
   +-------------+--------------+------+-----+---------+----------------+

 

  mysql>  DESCRIBE passport;
  +-------+------------+------+-----+---------+----------------+
  | Field | Type       | Null | Key | Default | Extra          |
  +-------+------------+------+-----+---------+----------------+
  | id    | bigint(20) | NO   | PRI | NULL    | auto_increment |
  +-------+------------+------+-----+---------+----------------+  生成的sql脚本

  create table Customer (
        id bigint not null auto_increment,
        name varchar(255),
        passport_fk bigint,
        primary key (id)
    )

  create table Passport (
        id bigint not null auto_increment,
        primary key (id)
    )

  alter table Customer
        add index FK27FBE3FEDB47C7A (passport_fk),
        add constraint FK27FBE3FEDB47C7A
        foreign key (passport_fk)
        references Passport (id)

  上面这个例子中,Customer 通过Customer 表中名为的passport_fk 外键列和 Passport关联. @JoinColumn注解定义了联接列(join column). 该注解和@Column注解有点类似, 但是多了一个名为referencedColumnName的参数. 该参数定义了所关联目标实体中的联接列. 注意,当referencedColumnName关联到非主键列的时候, 关联的目标类必须实现Serializable, 还要注意的是所映射的属性对应单个列(否则映射无效).

一对一关联可能是双向的.在双向关联中, 有且仅有一端是作为主体(owner)端存在的:主体端负责维护联接列(即更新). 对于不需要维护这种关系的从表则通过mappedBy属性进行声明. mappedBy的值指向主体的关联属性. 在上面这个例子中,mappedBy的值为 passport. 最后,不必也不能再在被关联端(owned side)定义联接列了,因为已经在主体端进行了声明.

如果在主体没有声明@JoinColumn,系统自动进行处理: 在主表(owner table)中将创建联接列, 列名为:主体的关联属性名+下划线+被关联端的主键列名. 在上面这个例子中是passport_id, 因为Customer中关联属性名为passport, Passport的主键是id.

   关联表方式

 

@Entity
public class Customer implements Serializable {
@OneToOne(cascade = CascadeType.ALL)
@JoinTable(name = "CustomerPassports",
joinColumns = @JoinColumn(name="customer_fk"),
inverseJoinColumns = @JoinColumn(name="passport_fk")
)
public Passport getPassport() {
...
}
@Entity
public class Passport implements Serializable {
@OneToOne(mappedBy = "passport")
public Customer getOwner() {
...
}

   表模型
   mysql>  DESCRIBE CustomerPassports;
  +-------------+------------+------+-----+---------+-------+
  | Field       | Type       | Null | Key | Default | Extra |
  +-------------+------------+------+-----+---------+-------+
  | passport_fk | bigint(20) | YES  | MUL | NULL    |       |
  | customer_fk | bigint(20) | NO   | PRI | NULL    |       |
  +-------------+------------+------+-----+---------+-------+

 

 mysql>  DESCRIBE customer;
 +-------+--------------+------+-----+---------+----------------+
 | Field | Type         | Null | Key | Default | Extra          |
 +-------+--------------+------+-----+---------+----------------+
 | id    | bigint(20)   | NO   | PRI | NULL    | auto_increment |
 | name  | varchar(255) | YES  |     | NULL    |                |
 +-------+--------------+------+-----+---------+----------------+

 

 mysql>  DESCRIBE passport;
 +-------+------------+------+-----+---------+----------------+
 | Field | Type       | Null | Key | Default | Extra          |
 +-------+------------+------+-----+---------+----------------+
 | id    | bigint(20) | NO   | PRI | NULL    | auto_increment |
 +-------+------------+------+-----+---------+----------------+

 

 

Customer通过名为 CustomerPassports的关联表和 Passport关联; 该关联表拥有名为passport_fk的外键列,该 外键指向Passport表,该信息定义为inverseJoinColumn的属性值, 而customer_fk外键列指向Customer表, 该信息定义为 joinColumns的属性值.

这种关联可能是双向的.在双向关联中, 有且仅有一端是作为主体端存在的:主体端负责维护联接列(即更新). 对于不需要维护这种关系的从表则通过mappedBy属性进行声明. mappedBy的值指向主体的关联属性. 在上面这个例子中,mappedBy的值为 passport. 最后,不必也不能再在被关联端(owned side)定义联接列了,因为已经在主体端进行了声明.

你必须明确定义关联表名和关联列名.

 

一对多,多对多的关联基本上都是这三类方式关联,而单向还是双向则看是否持有对方的引用。在双向关联中, 有且仅有一端是作为主体端存在的:主体端负责维护联接列(即更新). 对于不需要维护这种关系的从表则通过mappedBy属性进行声明. mappedBy的值指向主体的关联属性。注意在一对多的关系都是在多端负责维护,一端则通过mappedBy,再设置fetch的属性为fetch.LAZY则可以尽量避免1+n的问题。

暂时写这么多吧,更详细的请参考hibernate官网 。。


 

分享到:
评论

相关推荐

    Hibernate双向一对一关联映射(注解版)

    本主题聚焦于“Hibernate双向一对一关联映射”的注解实现,这是一种高级的数据库设计模式,用于处理两个实体之间一对一的关系。 在Hibernate中,一对一关联映射分为单向和双向。单向一对一映射通常涉及一个实体持有...

    hibernate单向一对多关联映射(注解版)

    在Java的持久化框架Hibernate中,单向一对多关联映射是常见的数据关系处理方式,尤其是在处理数据库中的实体类和表之间的关系时。本主题主要关注如何使用注解来实现这种映射。Hibernate通过注解使得对象关系映射...

    hibernate双向一对多关联映射(注解版)

    在这个注解版的实现中,我们将深入探讨如何使用Hibernate的注解配置来设置这种关联。 首先,我们需要了解一对多关联的基本概念。在数据库设计中,一对多关系意味着一个表(父表)的记录可以与多个其他表(子表)的...

    hibernate4全注解例子

    常见的注解包括@Entity(定义实体类)、@Table(指定表名)、@Id(主键)、@GeneratedValue(生成策略)、@Column(字段映射)、@OneToMany、@ManyToOne、@OneToOne和@ManyToMany(关联映射)等。 3. **环境设置**...

    hibernate双向多对多关联映射(注解版)

    在这个“hibernate双向多对多关联映射(注解版)”的主题中,我们将深入探讨如何使用Hibernate的注解配置来处理数据库中的双向多对多关联关系。 首先,多对多关联在数据库设计中是指两个实体之间存在多个对应关系,...

    hibernate实体生成工具

    **hibernate实体生成工具**是开发者在使用Hibernate框架时常用的一种辅助工具,它能够自动生成与数据库表对应的Java实体类,大大节省了手动编写代码的时间,提高了开发效率。Hibernate是一个强大的对象关系映射(ORM...

    hibernate一对一主键关联(注解版)

    本知识点主要讲解的是使用Hibernate实现一对一主键关联(Primary Key Join)的方式,通过注解进行配置。 一对一的关联在数据库设计中并不常见,但当两个实体之间确实存在一对一的关系时,如用户和其个人资料,这种...

    Spring+SpringMVC+Hibernate(纯注解版本)

    在纯注解版本中,我们可以用`@Entity`注解定义一个实体类,表示数据库中的表;`@Table`注解指定对应的表名;`@Id`定义主键;`@GeneratedValue`处理主键自增;`@Column`定义列属性。ORM(Object-Relational Mapping)...

    hibernate 中文注解

    - **翻译说明:** 该文档为Hibernate中文版注解文档的翻译版本,由满江红翻译团队完成。文档旨在帮助中文用户更好地理解Hibernate注解的使用方法,虽然翻译版本可能存在与原版文档的一些细微差异,但整体上保持了...

    hibernate自身关联一对多实例(树形结构)

    然后,使用Hibernate的注解来声明这些关联,如`@OneToMany`和`@ManyToOne`。 在配置文件中,我们还需要为这个关联定义映射规则,包括fetch策略(选择是懒加载还是立即加载子项)、级联操作(如删除时是否一同删除...

    hibernate单向多对多映射(注解版)

    在注解版的Hibernate中,我们不再需要传统的XML配置文件,而是直接在实体类上使用注解来定义映射关系。以下是对"hibernate单向多对多映射(注解版)"的详细解释。 首先,我们需要理解多对多关系的概念。在数据库设计...

    hibernate _annotation 注解编程

    - **实体关联映射**:通过 `@OneToOne`、`@OneToMany`、`@ManyToOne` 和 `@ManyToMany` 注解来映射实体间的关联关系。 - **复合主键映射**:使用 `@EmbeddedId` 或 `@IdClass` 来映射复合主键。 - **次级表映射**...

    基于spring+springmvc+hibernate的全注解开发

    在全注解开发中,我们不再需要编写大量的Hibernate配置文件,而是通过在实体类上使用`@Entity`声明为数据库表,`@Table`定义表名,`@Id`标识主键,`@GeneratedValue`处理主键生成策略。对于字段,`@Column`注解用于...

    SSH2 annotation 实现struts2.1.6 spring2.5.6 hibernate3.3 全注解开发

    当你声明一个实体的一对多或一对一关系为“懒加载”时,不会在获取主对象时立即加载关联对象,而是在第一次访问这些关联对象时才发起数据库查询。这样可以提高程序的运行效率,避免大数据量的加载导致的性能问题。 ...

    Hibernate注解jar包

    在Hibernate中,注解用于定义实体类、属性、关系等,替代了传统的Hibernate XML配置文件。 2. **Hibernate核心注解**: - `@Entity`:标记一个类为Hibernate的持久化实体类,对应数据库中的一个表。 - `@Table`:...

    Hibernate多对一映射(注解版)

    本教程将重点讲解如何在Hibernate中实现多对一的映射关系,采用的是注解方式进行配置。 **一、多对一关系** 在数据库设计中,多对一关系表示一个实体可以与另一个实体的多个实例相关联。例如,一个部门可以有多名...

    springmvc+spring+hibernate整合(注解)

    1. 创建实体类,使用Hibernate注解定义属性和关联关系。 2. 创建DAO接口和实现类,使用@Autowired注入SessionFactory,编写基本的CRUD操作。 3. 创建Service接口和实现类,定义业务逻辑,使用@Autowired注入DAO层。 ...

    hibernate注解中英文版

    1. `@Entity`:标记一个类为Hibernate实体类,表示这个类将被映射到数据库中的一个表。 2. `@Table`:定义实体类所对应的数据库表名,以及一些额外的表属性如schema和catalog。 3. `@Id`:标识实体类的主键字段,...

    Hibernate+JPA注解教程.doc

    对于多对多关系,使用`@ManyToMany`注解来关联两个实体类。 接下来,我们可以利用JPA的注解实现CRUD操作,比如: - 使用`@OneToMany`或`@ManyToOne`注解处理一对多或多对一的关系。 - 使用`@OneToOne`注解处理一对...

    SpringBoot整合Hibernate纯注解版

    以上就是Spring Boot整合Hibernate纯注解版的基本配置和使用。通过这种方式,开发者可以专注于业务逻辑,而不必关心繁琐的数据访问层实现。此外,Spring Boot的自动配置和Hibernate的注解方式,使得整个项目结构更加...

Global site tag (gtag.js) - Google Analytics