如果您想了解什么是双向JPAOneToMany/ManyToOne关联中的“关联的反面”?的相关知识,那么本文是一篇不可错过的文章,我们将对双向关联是什么意思进行全面详尽的解释,并且为您提供关于@Ma
如果您想了解什么是双向 JPA OneToMany/ManyToOne 关联中的“关联的反面”?的相关知识,那么本文是一篇不可错过的文章,我们将对双向关联是什么意思进行全面详尽的解释,并且为您提供关于@ ManyToMany / @ OneToMany mappingby属性用于双向关联、@ManyToOne JPA 关联的 CascadeType.ALL 是什么意思、@ManyToOne JPA关联和级联…不确定删除对象会发生什么、@OneToMany、@ManyToOne以及@ManyToMany讲解的有价值的信息。
本文目录一览:- 什么是双向 JPA OneToMany/ManyToOne 关联中的“关联的反面”?(双向关联是什么意思)
- @ ManyToMany / @ OneToMany mappingby属性用于双向关联
- @ManyToOne JPA 关联的 CascadeType.ALL 是什么意思
- @ManyToOne JPA关联和级联…不确定删除对象会发生什么
- @OneToMany、@ManyToOne以及@ManyToMany讲解
什么是双向 JPA OneToMany/ManyToOne 关联中的“关联的反面”?(双向关联是什么意思)
在@OneToMany
JPA
注释参考的示例部分:
示例 1-59 @OneToMany - 带有泛型的客户类
@Entitypublic class Customer implements Serializable { ... @OneToMany(cascade=ALL, mappedBy="customer") public Set<Order> getOrders() { return orders; } ...}
示例 1-60 @ManyToOne - 带有泛型的订单类
@Entitypublic class Order implements Serializable { ... @ManyToOne @JoinColumn(name="CUST_ID", nullable=false) public Customer getCustomer() { return customer; } ...}
在我看来,该Customer
实体是该协会的所有者。但是,在mappedBy
同一文档中对属性的解释中,写道:
如果关系是双向的,则将关联的反向(非拥有)侧的 mappedBy 元素设置为拥有该关系的字段或属性的名称,如示例 1-60 所示。
但是,如果我没记错的话,在示例中,mappedBy
实际上是在关联的拥有方指定的,而不是在非拥有方。
所以我的问题基本上是:
在双向(一对多/多对一)关联中,哪个实体是所有者?我们如何将 One 指定为所有者?我们如何将多方指定为所有者?
“关联的反面”是什么意思?我们如何将一侧指定为反面?我们如何将多面指定为反面?
答案1
小编典典要理解这一点,你必须退后一步。在 OO 中,客户拥有订单(订单是客户对象中的列表)。没有客户就不可能有订单。因此,客户似乎是订单的所有者。
但在 SQL 世界中,一项实际上包含指向另一项的指针。由于 N 个订单有 1
个客户,因此每个订单都包含一个指向其所属客户的外键。这是“连接”,这意味着订单“拥有”(或字面上包含)连接(信息)。这与 OO/模型世界完全相反。
这可能有助于理解:
public class Customer { // This field doesn''t exist in the database // It is simulated with a SQL query // "OO speak": Customer owns the orders private List<Order> orders;}public class Order { // This field actually exists in the DB // In a purely OO model, we could omit it // "DB speak": Order contains a foreign key to customer private Customer customer;}
反面是对象的OO“所有者”,在这种情况下是客户。客户在表中没有用于存储订单的列,因此您必须告诉它可以在订单表中的哪个位置保存此数据(通过
发生mappedBy
)。
另一个常见的例子是树的节点既可以是父母也可以是孩子。在这种情况下,这两个字段在一个类中使用:
public class Node { // Again, this is managed by Hibernate. // There is no matching column in the database. @OneToMany(cascade = CascadeType.ALL) // mappedBy is only necessary when there are two fields with the type "Node" private List<Node> children; // This field exists in the database. // For the OO model, it''s not really necessary and in fact // some XML implementations omit it to save memory. // Of course, that limits your options to navigate the tree. @ManyToOne private Node parent;}
这就解释了“外键”多对一的设计作品。还有第二种方法,它使用另一个表来维护关系。这意味着,对于我们的第一个示例,您有三个表:一个包含客户,一个包含订单,以及一个包含一对主键(customerPK、orderPK)的两列表。
这种方式比上面的方式更加灵活(可以轻松处理一对一、多对一、一对多甚至多对多)。价格是这样
- 它有点慢(必须维护另一个表并且连接使用三个表而不是两个),
- 连接语法更复杂(如果您必须手动编写许多查询,例如当您尝试调试某些东西时,这可能会很乏味)
- 它更容易出错,因为当管理连接表的代码出现问题时,您可能会突然得到太多或太少的结果。
这就是为什么我很少推荐这种方法。
@ ManyToMany / @ OneToMany mappingby属性用于双向关联
我正在为我的实习工作开发JPA兼容套件…该套件的一部分涉及测试极端情况的正确实现。
@ManyToMany
具有mapedBy属性。JPA指出:
字符串mappingBy-拥有关系的字段或属性。除非关系是单向的,否则为必需。
没有给出默认值-默认列为空。
给定双向@ManyToMany
-此示例来自JPA 2.0 JSR-317规范本身!
顾客
@ManyToMany@JoinTable(name="CUST_PHONES")public Set<PhoneNumber> getPhones() { return phones; }
电话号码
@ManyToMany(mappedBy="phones")public Set<Customer> getCustomers() { return customers; }
尚未在@ManyToMany
of的中定义mapledBy属性Customer
!我不知道的双向映射有默认值吗?
我查看了类似的情况,发现: @OneToOne
-mappingBy是可选的,没有默认值@OneToMany
-完全相同@ManyToMany
(mappedBy对于双向是可选的,没有默认值)
简而言之,我的问题是:
对于@ManyToMany
和@OneToMany
,应在关系的拥有方(Customer
例如)中将其放置在mappedBy属性中?
答案1
小编典典这绝不是一个极端的情况。每个双向关联都有一个所有者方和一个反向方。
JPA使用拥有方来确定两个实体之间是否存在关联。另一侧被忽略。
拥有方定义了如何映射关联(使用JoinColumn,JoinTable等批注)。它没有任何mappedBy
属性。
反面使用该mappedBy
属性说:“嘿,我只是由以下属性映射的那个的逆关联”。
因此,根据定义,拥有方没有mappedBy
属性。如果有一个,它就不会是拥有者。
JPA规范对此做了很好的解释。如果您需要为此规范构建兼容套件,则最好阅读并理解它。
我真的看不出编写这种兼容工具包的意义,因为正如在JPA2
JSR主页上所写的那样,
- 根据Java规范参与协议(JSPA)的要求,Java Persistence API版本2.0
- TCK将免费获得许可,无需支持合格的非营利实体。此类资格将由兼容性测试奖学金计划进行验证。经奖学金委员会批准,也可以免费提供支持。有关更多信息,请访问:http
- //java.sun.com/scholarship/。
@ManyToOne JPA 关联的 CascadeType.ALL 是什么意思
我想我误解了在关系中级联的含义@ManyToOne
。
案子:
public class User {
@OneToMany(fetch = FetchType.EAGER)
protected Set<Address> userAddresses;
}
public class Address {
@ManyToOne(fetch = FetchType.LAZY,cascade = CascadeType.ALL)
protected User addressOwner;
}
的含义是cascade = CascadeType.ALL
什么?例如,如果我从数据库中删除某个地址,我添加的事实如何cascade =
CascadeType.ALL
影响我的数据(User
我猜是)?
@ManyToOne JPA关联和级联…不确定删除对象会发生什么
对于删除操作中级联的工作方式,我仍然不太清楚。我想知道如果我有这个会发生什么:
class myBean{
@ManyToOne(fetch = FetchType.LAZY,cascade = CascadeType.ALL)
public Cliente getClienteDiAppartenenza() {
return clienteDiAppartenenza;
}
}
class Cliente{
@OneToMany(cascade = CascadeType.ALL,orphanRemoval = true,fetch = FetchType.LAZY)
public List<myBean> getMyBeans() {
return myBeans;
}
}
如果我删除具有此属性的myBean,我不确定链接的Cliente是否也会被删除(很奇怪),或者Cliente内部的集合将被更新,并且myBean的实例将被删除,然后保存。
会发生什么??Hibernato文档对此不太清楚…
@OneToMany、@ManyToOne以及@ManyToMany讲解
一、一对多(@OneToMany)
1、单向一对多模型
假设通过一个客户实体可以获得多个地址信息。
对于一对多的实体关系而言,表结构有两种设计策略,分别是外键关联和表关联。
(1) 映射策略---外键关联
在数据库中表customer和表结构address定义,如下:
create table customer (
id int(20) not null auto_increment,
name varchar(100),
primary key(id)
)
create table address (
id int(20) not null auto_increment,
province varchar(50),
city varchar(50),
postcode varchar(50),
detail varchar(50),
customer_id int(20),
primary key (id)
)
注意此时外键定义在多的一方,也就是address表中。
此时,表customer映射为实体CustomerEO,代码如下:
@Entity
@Table (name="customer")
public class CustomerEO implements java.io.Serializable {
@OneToMany(cascade={ CascadeType.ALL })
@JoinColumn(name="customer_id")
private Collection<AddressEO> addresses = new ArrayList<AddressEO>();
...
}
注释@OneToMany的定义代码如下:
@Target({METHOD, FIELD}) @Retention(RUNTIME)
public @interface OneToMany {
Class targetEntity() default void.class;
CascadeType[] cascade() default {};
FetchType fetch() default LAZY;
String mappedBy() default "";
}
使用时要注意一下几点问题:
a、targetEntity属性表示默认关联的实体类型。如果集合类中指定了具体类型了,不需要使用targetEntity.否则要指定targetEntity=AddressEO.class。
b、mappedBy属性用于标记当实体之间是双向时使用。
(2) 映射策略---表关联
在上面address表中去掉customer_id字段,在增加一个表ref_customer_address,如下:
--客户地址关系表
create table ref_customer_address (
customer_id int(20) not null,
address_id int(20) not null unique
)
此时表customer映射为CustomerEO实体,代码如下:
@Entity
@Table(name = "customer")
public class CustomerEO implements java.io.Serializable {
...
@OneToMany(cascade = { CascadeType.ALL })
@JoinTable(name="ref_customer_address",
joinColumns={ @JoinColumn(name="customer_id",referencedColumnName="id")},
inverseJoinColumns={@JoinColumn(name="address_id",referencedColumnName="id")})
private Collection<AddressEO> addresses = new ArrayList<AddressEO>();
...
}
表关联@JoinTable,定义如下:
@Target({METHOD,FIELD})
public @interface JoinTable {
String name() default "";
String catalog() default "";
String schema() default "";
JoinColumn[] joinColumns() default {};
JoinColumn[] inverseJoinColumns() default {};
UniqueConstraint[] uniqueConstraints default {};
}
其中:
a、该标记和@Table相似,用于标注用于关联的表。
b、name属性为连接两张表的表名。默认的表名为:“表名1”+“-”+“表名2”,上面例子默认的表名为customer_address。
c、joinColumns属性表示,在保存关系中的表中,所保存关联的外键字段。
d、inverseJoinColumns属性与joinColumns属性类似,不过它保存的是保存关系的另一个外键字段。
(3) 默认关联
在数据库底层为两张表添加约束,如下:
create table customer_address (
customer_id int(20) not null,
address_id int(20) not null unique
)
alter table customer_address add constraint fk_ref_customer foreign key (customer_id) references customer (id);
alter table customer_address add constraint fk_ref_address foreign key (address_id) references address (id);
这样,在CustomerEO中只需要在标注@OneToMany即可!
二、多对一@ManyToOne
1、单向多对一模型。
(1) 外键关联
配置AddressEO实体如下:
@Entity
@Table(name="address")
public class AddressEO implements java.io.Serializable {
@ManyToOne(cascade = { CascadeType.ALL })
@JoinColumn(name="customer_id")
private CustomerEO customer;
// ...
}
@ManyToOne定义如下:
@Target({METHOD,FIELD}) @Retention(RUNTIME)
public @interface ManyToOne {
Class targetEntity() default void.class;
CascadeType[] cascade() default {};
FetchType fatch() default EAGER;
boolean optional() default true;
}
(2) 默认关联
数据库脚本定义的相关字段的约束,创建外键后,直接使用@ManyToOne
三、高级一对多和多对一映射
即双向关联模型,确定了双向关联后,多的一方AddressEO不变使用@ManyToOne,而CustomerEO实体修改为:
@Entity
@Table(name="customer")
public class CustomerEO {
@OneToMany(mappedBy="customer")
private Collection<AddressEO> addresses = new ArrayList<AddressEO>();
// ...
}
其中,@OneToMany标记中的mappedBy属性的值为AddressEO实体中所引用的CustomerEO实体的属性名。
四、多对多(@ManyToMany)
和一对多类型,不在赘述。@ManyToMany标记的定义如下:
@Target({METHOD, FIELD}) @Retention(RUNTIME)
public @interface ManyToMany {
Class targetEntity() default void.class;
CascadeType[] cascade() default {};
FetchType fecth() default LAZY;
String mappedBy() default "";
}
五、最后,谈谈关于集合类的选择
在映射关系中可以使用的集合类有Collection、Set、List和Map,下面看下如何选择。
1、定义时使用接口,初始化使用具体的类。
如Collection可以初始化为ArrayList或HashSet;
Set可以初始化为HashSet;
List可以初始化为ArrayList;
Map可以初始化为HashMap.
2、集合类的选择
Collection类是Set和List的父类,在未确定使用Set或List时可使用;
Set集合中对象不能重复,并且是无序的;
List集合中的对象可以有重复,并且可以有排序;
Map集合是带有key和value值的集合。
我们今天的关于什么是双向 JPA OneToMany/ManyToOne 关联中的“关联的反面”?和双向关联是什么意思的分享已经告一段落,感谢您的关注,如果您想了解更多关于@ ManyToMany / @ OneToMany mappingby属性用于双向关联、@ManyToOne JPA 关联的 CascadeType.ALL 是什么意思、@ManyToOne JPA关联和级联…不确定删除对象会发生什么、@OneToMany、@ManyToOne以及@ManyToMany讲解的相关信息,请在本站查询。
本文标签: