@OneToOne注释只能确定实体与实体的关系是一对一的关系,不能指定数据库表中的保存的关联字段。所以此时要结合@JoinColumn标记来指定保存实体关系的配置。
@JoinColumn与@Column注释类似,它的定义如下代码所示。
@Target({METHOD, FIELD}) @Retention(RUNTIME)
public @interface JoinColumn {
String name() default "";
String referencedColumnName() default "";
boolean unique() default false;
boolean nullable() default true;
boolean insertable() default true;
boolean updatable() default true;
String columnDefinition() default "";
String table() default "";
}
在使用@JoinColumn注释时,应注意以下几个问题。
l @JoinColumn与@Column标记一样,是用于注释表中的字段的。它的属性与@Column属性有很多相同之处,这里就不详细讲述。请读者参阅5.2.2小节中有关@Column属性的部分。
l @JoinColumn与@Column相区别的是:@JoinColumn注释的是保存表与表之间关系的字段,它要标注在实体属性上。而@Column标注的是表中不包含表关系的字段。
l 与@Column标记一样,name属性是用来标识表中所对应的字段的名称。例如customer表中存在字段addr_id,标识的代码如下所示。
@OneToOne
@JoinColumn(name = "addr_id")
public AddressEO getAddress() {
return address;
}
若此时,不设置name的值,则在默认情况下,name的取值遵循以下规则:
name=关联表的名称+“_”+ 关联表主键的字段名
例如,CustomerEO实体中,如果不指定name的值,默认将对应name=address_id;因为@JoinColumn注释在实体 AddressEO属性上,实体AddressEO对应的表名为“address”;表address的主键是“id”,所以此时对应的默认的字段名称为 “address_id”。
提示:此规则只适用于与@OneToOne标记同时使用时。若与@ManyToOne或@ManyToMany标记同时使用时,将遵循其他的规则。
l 默认情况下,关联的实体的主键一般是用来做外键的。但如果此时不想主键作为外键,则需要设置referencedColumnName属性。例如,将address表中增加一个字段“ref_id”,address表的建表SQL变为以下所示。
CREATE TABLE address (
id int(20) NOT NULL auto_increment,
ref_id int int(20) NOT NULL,
province varchar(50) ,
city varchar(50) ,
postcode varchar(50) ,
detail varchar(50) ,
PRIMARY KEY (id)
)
此时,通过customer表中的“address_id”字段关联的是address表中的“ref_id”,而“ref_id”并不是address表中的主键,则实体中标注如代码下所示。
@OneToOne
@JoinColumn(name = "address_id",referencedColumnName="ref_id")
public AddressEO getAddress() {
return address;
}
属性referencedColumnName标注的是所关联表中的字段名,若不指定则使用的所关联表的主键字段名作为外键。
2.person和phone的一对多单向关系:
phone中没有特别的注释。
person中:
@OneToMany(cascade=CascadeType.ALL)
@JoinColumn(name="personID")//注释的是另一个表指向本表的外键。
public List<Phone> getPhones() {
return phones;
}
我们可以在Person类里面发现@JoinColumn(name="personID")
它代表是一对多,一是指类本身,多是指这个成员,也就是一个类可以对应多个成员.
在一对多里面,无论是单向还是双向,映射关系的维护端都是在多的那一方,也就是Phone那里,因为要在数据库面表现的话,也只有让Phone起一个指向Person的外键,不可能在Person里面指向Phone,这一点和一对一不一样,一对一可以在任意一方起一个外键指向对方.可是一对多却不行了.
在这里@JoinColumn这个注释指的却是在Phone里面的外键的列的名字,
它并不像在一对一里面的注释指的是自己表里面的外键列名.这一点要特别注意一下.
如果是一对多的双向关系,那么这个注释就要应用到多的那边去了,虽然注释还在Person类里面,但是它起的效果却是在Phone里面起一个叫personID的外键, 因为多的那边要有外键指向少的这边.
如果你不加 @JoinColumn(name="personID")这个注释的话,那么JBOSS就会自动帮你生成一张中间表,
它负现Person和Phone表之间的联系.它将会做如下事情:
CREATE TABLE PERSON_PHONE
(
PERSON_id INT,
PHONE_id INT
);
ALTER TABLE PERSON_PHONE ADD CONSTRAINT person_phone_unique
UNIQUE (PHONE_id);
ALTER TABLE PERSON_PHONE ADD CONSTRAINT personREFphone
FOREIGN KEY (PERSON_id) REFERENCES PERSON (id);
ALTER TABLE PERSON_PHONE ADD CONSTRAINT personREFphone2
FOREIGN KEY (PHONE_id) REFERENCES PHONE (id);
所以我们最好还是指定一下,以让程序产生更加确定的行为,不过一般是推荐另外生成一个中间表好一些,因为这样的话,对原来两张表的结构不对造成任何影响。在遗留系统的时候很多用,有些时候,一些表都是以前就建好了的,要改表的结构是不太可能的,所以这个时候中间的表就显得很重要了,它可以在不侵入原来表的情况下构建出一种更清淅更易管理的关系。
所以一对多的单向关联,我们还是推荐使用一张中间表来建立关系。
---------------------------------------------------------------------------------------------------------------------------------------------
3.person和country的多对一单向关系:
country中无特别的注解。
而person注解如下:
@ManyToOne
@JoinColumn(name="countryID")
public Country getCountry() {
return country;
}
在一对多,多对一的关系里面,关系的维护端都是在多的那一面,多的一面为主控方,拥有指向对方的外键。
因为主控端是Person .外键也是建在Person上面,因为它是多的一面。当然我们在这里也可以省掉@JoinColumn,那样的话会怎么样呢,会不会像一对多单向一样生成中间的表呢?事实是不会的,在这里如果我们去掉@JoinColumn的话,那么一样会在Person表里面生成一列指向
Country的外键,这一点和一对多的单向是不一样,在一对多的单向里面,如果我们不在Person 里面加上@JoinColumn这个注释,那么JBOSS将会为我们生成一个中间的表,这个表会有一个列指向Person主键,一个列指向Phone主键。所以说为了程序有一定的行为,有些东西我们还是不要省的好。
其实多对一单向是有点向一对一单向的,在主控端里面,也就是从Person的角度来看,也就是对应了一个Country而已,只不过这个Country是很多Person所共用的,而一对一却没有这一点限制。
------------------------------------------------------------------
4.person和project的多对多单向关系:
project没有特殊的注解。
person:
@ManyToMany
public List<Project> getProjects() {
return projects;
}
它需要设置中间表来维护关系,在数据库上跟多对多双向,只不过在编程的逻辑中不一样而已。
//类似这个:@JoinTable(name = "PersonANDFlight", joinColumns = {@JoinColumn(name = "personID")},
//inverseJoinColumns = {@JoinColumn(name = "flightID")})
其实这个声明不是必要的,当我们不用@JoinTable来声明的时候,JBOSS也会为我们自动生成一个连接用的表,
表名默认是主控端的表名加上下划线"_"再加上反转端的表名.
类似
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "PersonANDFlight",
joinColumns = {@JoinColumn(name = "personID")},
inverseJoinColumns = {@JoinColumn(name = "flightID")})
public List<Flight> getFlights() {
return flights;
}
********************************************************************************************************
在单向关系中没有mappedBy,主控方相当于拥有指向另一方的外键的一方。
1.一对一和多对一的@JoinColumn注解的都是在“主控方”,都是本表指向外表的外键名称。
2.一对多的@JoinColumn注解在“被控方”,即一的一方,指的是外表中指向本表的外键名称。
3.多对多中,joinColumns写的都是本表在中间表的外键名称,
inverseJoinColumns写的是另一个表在中间表的外键名称。
本文转载与:
http://blog.csdn.net/yingevil/article/details/6875421
分享到:
相关推荐
通过以上内容的介绍,我们了解到在Hibernate中,`@OneToMany`注解是实现一对多关系的重要手段。正确使用`mappedBy`属性和其他相关属性,可以有效地管理实体类之间的关联关系,提高代码的可读性和可维护性。希望本文...
本文将详细介绍 JPA 中四种常见的映射关系:一对一(One-to-One)、一对多(One-to-Many)、多对一(Many-to-One)以及多对多(Many-to-Many)。 #### 1. OneToOne 关系建立 一对一关系是指两个实体之间的关系,...
一、Hibernate注解介绍 Hibernate通过注解简化了Java类与数据库表之间的映射配置。在Java类上使用特定的注解,可以明确地定义实体类与数据库表之间的关联关系。`@OneToMany`和`@ManyToOne`就是用于处理关联关系的两...
以上只是Java实体关系映射的基本介绍。在实际开发中,还需要考虑数据的级联操作(CascadeType)、懒加载(Lazy Fetching)以及缓存策略等高级特性。同时,为了保持数据一致性,还需要理解并合理使用`@PrePersist`, `...
在本文中,我们将介绍如何使用@IdClass创建联合主键,并实现外部关联。 首先,我们需要创建三个实体类:DataCenter、Build和Device。DataCenter实体类对应数据中心表,Build实体类对应建筑表,Device实体类对应设备...
以上是一对一关联的三种形式,下面介绍多对一关联。 多对一(Many-to-One) 使用@ManyToOne批注来实现多对一关联。 @ManyToOne批注有一个名为targetEntity的参数,该参数定义了目标实体名,通常不需要定义该参数...
本篇文章主要介绍了 Hibernate 中关系映射的基本概念和实现方法。通过上述示例可以看出,Hibernate 提供了丰富的注解来支持不同类型的实体关系映射。理解这些关系对于有效地设计数据库模型和进行数据操作至关重要。...
博客链接中提到的iteye博客文章可能详细介绍了这个例子的实现步骤和注意事项,包括如何配置Hibernate,如何编写SQL语句创建关联表,以及如何测试和验证数据的正确存储和检索。如果想要深入学习和实践这个例子,建议...
以上就是关于Toplink JPA注解的一些基本介绍,虽然这个文档可能有些陈旧,但它仍然能够帮助理解JPA的核心概念和常用注解。在实际开发中,JPA已经发展了许多新特性,比如Spring Data JPA的Repository抽象,以及更现代...
本文将详细介绍这些关联配置以及如何解决可能出现的错误。 **一对一关联(OneToOne)**: 一对一关联意味着两个实体之间存在唯一的对应关系。在Hibernate中,可以通过`@OneToOne`注解来实现。例如,`Person`类可能与`...
本文将围绕“我的经典表结构”这一主题,深入探讨如何进行有效的表结构设计,并重点介绍多表关联设置在Hibernate框架中的应用技巧。通过本篇文章的学习,读者可以更好地理解经典表结构的设计原则以及如何在实际项目...
本文详细介绍了Hibernate中的几种常见对象关系映射类型,包括一对一、一对多和多对多关联,并通过具体的代码示例进行了说明。这些基本的映射方式为开发者提供了灵活的解决方案,使得开发者可以根据不同的业务需求...
2.1 JPQL 介绍 JPQL 是 HQL(Hibernate Query Language)的扩展,由 JPA 规范定义,而 Hibernate 是其具体实现。JPQL 使用类名和属性名代替 SQL 中的表名和字段名,使得查询更加直观。 2.2 Query 接口 `javax....
当继承的列定义不符合现有数据模型时,可以通过该批注来调整关联映射中的 `@JoinColumn` 配置。 - **适用场景**:当子类继承父类的关联映射但需要改变默认的行为时使用。 **2. 属性介绍** - **`joinColumns`**:此...
#### 一、概念介绍 在面向对象编程中,对象之间的关系是非常重要的,特别是在持久化这些对象到数据库时。Hibernate作为一款流行的Java持久层框架,提供了强大的功能来处理这些对象关系,特别是关联和集合的映射。...
本文旨在详细介绍 JPA 中常用的批注,帮助开发者更好地理解和使用它们。 #### 二、实体定义 1. **`@Entity`**:此批注用于标识一个 Java 类作为 JPA 实体,即可以被持久化的对象。当一个类被标记为此批注后,它的...
Hibernate 3 注解介绍 在Hibernate 3之前,实体类和它们与数据库表之间的映射通常通过XML配置文件(如hibernate.cfg.xml和.hbm.xml)来定义。然而,随着注解的引入,这些信息可以直接在Java类上声明,使得代码更加...
本文档旨在详细介绍 JPA 批注的不同方面,包括它们的用途、应用场景以及如何使用它们来定制实体的行为。 #### 二、实体批注 ##### 1. `@Entity` - **功能**:`@Entity` 批注用于标记一个类为 JPA 实体,意味着该类...
以上就是 Hibernate 组件之间的关联关系及其配置方法的详细介绍。了解并熟练运用这些关联,能够帮助开发者更高效地进行数据库操作,提高代码的可维护性和灵活性。在实际开发中,要根据业务需求选择合适的关联类型,...
本文将详细介绍如何在Java EE中实现N-N连接,并通过具体的代码示例进行解释。 #### 二、N-N连接概述 多对多(N-N)关系是指两个实体类型之间可能存在多个实例与多个实例之间的关联。例如,在学生和课程的例子中,...