Lam*_*bda 160 java hibernate jpa
在TopLink JPA Annotation Reference的这些示例中:
例1-59 @OneToMany - 使用泛型的客户类
@Entity
public class Customer implements Serializable {
...
@OneToMany(cascade=ALL, mappedBy="customer")
public Set<Order> getOrders() {
return orders;
}
...
}
Run Code Online (Sandbox Code Playgroud)
例1-60 @ManyToOne - 带有泛型的订单类
@Entity
public class Order implements Serializable {
...
@ManyToOne
@JoinColumn(name="CUST_ID", nullable=false)
public Customer getCustomer() {
return customer;
}
...
}
Run Code Online (Sandbox Code Playgroud)
在我看来,该Customer
实体是该协会的所有者.但是,在mappedBy
同一文档中对属性的解释中,写成:
如果关系是双向的,则将关联的反向(非拥有)侧的mappedBy元素设置为拥有该关系的字段或属性的名称,如示例1-60所示.
但是,如果我没有错,看起来在示例中,mappedBy
实际上是在关联的拥有方指定,而不是非拥有方.
所以我的问题基本上是:
在双向(一对多/多对一)关联中,哪个实体是所有者?我们如何指定一方作为所有者?我们如何指定多方作为所有者?
什么是"关联的反面"?我们怎样才能将一面指定为反面?我们如何将多边指定为反面?
Aar*_*lla 296
要理解这一点,你必须退后一步.在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;
}
Run Code Online (Sandbox Code Playgroud)
反面是对象的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;
}
Run Code Online (Sandbox Code Playgroud)
这解释了"外键"多对一设计的作用.还有第二种方法使用另一个表来维持关系.这意味着,对于我们的第一个示例,您有三个表:一个包含客户,一个包含订单,另一个包含两对主表(customerPK,orderPK).
这种方法比上面的方法更灵活(它可以轻松处理一对一,多对一,一对多甚至多对多).价格是这样的
这就是我很少推荐这种方法的原因.
小智 40
令人难以置信的是,在3年内,没有人用两种方式来回答你的优秀问题.
如其他人所述,"所有者"一侧包含数据库中的指针(外键).您可以指定任何一方作为所有者,但是,如果您将一方指定为所有者,则该关系将不是双向的(反向又称"许多"方将不知道其"所有者").这对封装/松耦合来说是理想的:
// "One" Customer owns the associated orders by storing them in a customer_orders join table
public class Customer {
@OneToMany(cascade = CascadeType.ALL)
private List<Order> orders;
}
// if the Customer owns the orders using the customer_orders table,
// Order has no knowledge of its Customer
public class Order {
// @ManyToOne annotation has no "mappedBy" attribute to link bidirectionally
}
Run Code Online (Sandbox Code Playgroud)
唯一的双向映射解决方案是让"many"端拥有指向"one"的指针,并使用@OneToMany"mappedBy"属性.如果没有"mappedBy"属性,Hibernate将期望双重映射(数据库将同时具有连接列和连接表,这是冗余的(通常是不合需要的)).
// "One" Customer as the inverse side of the relationship
public class Customer {
@OneToMany(cascade = CascadeType.ALL, mappedBy = "customer")
private List<Order> orders;
}
// "many" orders each own their pointer to a Customer
public class Order {
@ManyToOne
private Customer customer;
}
Run Code Online (Sandbox Code Playgroud)
小智 34
在数据库中具有带有外键的表的实体是拥有实体,而指向的另一个表是反向实体.
Ken*_*ock 13
简单的双向关系规则:
对于多对一的双向关系,许多方面始终是关系的拥有方.示例:1个房间有很多人(一个人只属于一个房间) - >拥有方是人
2.对于一对一的双向关系,拥有方对应于包含相应外键的一侧.
3.对于多对多双向关系,任何一方都可能是拥有方.
希望可以帮到你.
归档时间: |
|
查看次数: |
110864 次 |
最近记录: |