Cha*_*nya 15 java hibernate jpa
我试图理解JPA mappedBy
中@OneToMany
注释的属性.我创建了以下示例,其中Customer有一个Orders列表:
@Entity
public class Customer {
@Id @GeneratedValue public Integer getId() { return id; }
public void setId(Integer id) { this.id = id; }
private Integer id;
@OneToMany(mappedBy="customer")
@OrderColumn(name="orders_index")
public List<Order> getOrders() { return orders; }
public void setOrders(List<Order> orders) { this.orders = orders; }
private List<Order> orders;
}
@Entity
@Table(name="TBL_ORDER")
public class Order {
@Id @GeneratedValue public Integer getId() { return id; }
public void setId(Integer id) { this.id = id; }
private Integer id;
public int getOrderNumber() { return orderNumber; }
public void setOrderNumber(int orderNumber) { this.orderNumber = orderNumber; }
private int orderNumber;
@ManyToOne
public Customer getCustomer() { return customer; }
public void setCustomer(Customer customer) { this.customer = customer; }
private Customer customer;
}
Run Code Online (Sandbox Code Playgroud)
现在,当我使用Hibernate生成表时,我发现Hibernate只创建了2个表:
Hibernate: create table Customer (id number(10,0) not null, primary key (id))
Hibernate: create table TBL_ORDER (id number(10,0) not null, orderNumber number(10,0) not null, customer_id number(10,0), orders_index number(10,0), primary key (id))
Hibernate: alter table TBL_ORDER add constraint FK_nt24krtgqwcsynosqgk4jkvfv foreign key (customer_id) references Customer
Run Code Online (Sandbox Code Playgroud)
此外,如果我尝试保存客户和一些订单,我会在下面看到Hibernate生成的DML语句:
Hibernate: insert into Customer (id) values (?)
Hibernate: insert into TBL_ORDER (customer_id, orderNumber, id) values (?, ?, ?)
Hibernate: update TBL_ORDER set orders_index=? where id=?
Run Code Online (Sandbox Code Playgroud)
为什么hibernate尝试在TBL_ORDER中插入和更新记录而不是仅运行单个插入查询?
现在,如果我删除mappedBy属性并尝试生成表,这次我看到3个表:
Hibernate: create table Customer (id number(10,0) not null, primary key (id))
Hibernate: create table Customer_TBL_ORDER (Customer_id number(10,0) not null, orders_id number(10,0) not null, orders_index number(10,0) not null, primary key (Customer_id, orders_index))
Hibernate: create table TBL_ORDER (id number(10,0) not null, orderNumber number(10,0) not null, customer_id number(10,0), primary key (id))
Hibernate: alter table Customer_TBL_ORDER add constraint UK_sw94jktvh72tripj876s31052 unique (orders_id)
Hibernate: alter table Customer_TBL_ORDER add constraint FK_sw94jktvh72tripj876s31052 foreign key (orders_id) references TBL_ORDER
Hibernate: alter table Customer_TBL_ORDER add constraint FK_f03up2h945cg0dcbo2pdb1d3c foreign key (Customer_id) references Customer
Hibernate: alter table TBL_ORDER add constraint FK_nt24krtgqwcsynosqgk4jkvfv foreign key (customer_id) references Customer
Run Code Online (Sandbox Code Playgroud)
为什么hibernate会在这种情况下创建一个额外的表?mappedBy属性如何控制它?为什么我们在Customer_TBL_ORDER表中的orders_id列上有一个额外的唯一键约束?
现在,如果我尝试保存客户及其订单,我将接受DML操作:
Hibernate: insert into Customer (id) values (?)
Hibernate: insert into TBL_ORDER (customer_id, orderNumber, id) values (?, ?, ?)
Hibernate: insert into Customer_TBL_ORDER (Customer_id, orders_index, orders_id) values (?, ?, ?)
Run Code Online (Sandbox Code Playgroud)
与我声明mappedBy属性的情况相比,为什么我们在这种情况下没有额外的更新查询?
NoD*_*und 23
这很正常.
使用mappedBy
,您直接告诉Hibernate/JPA一个表拥有该关系,因此它存储为该表的列.
没有,关系是外部的,Hibernate/JPA需要创建另一个表来存储关系.
例:
Question
有几个Answer
.Answer
由一个且仅一个拥有Question
.在纯JDBC中,您将创建两个表:
Questions(Question_ID, ...);
Answers(Answer_ID, Question_ID, ...);
Run Code Online (Sandbox Code Playgroud)
Question_ID
外键引用在哪里Question.Question_ID
.
至于另一种情况,我没有一个真实的案例,因为几乎每次都有许多具有独特约束的人(例如:a Question
可能有几个Answer
,并且Answer
可能有几个Question
,但对于任何只出现一次Question
).
Chr*_*ris 13
A OneToMany
有两种主要方式可以在数据库中完成.
如果您保留OneToMany
映射并将其设置为默认值,则默认情况下将使用关系表,这是您似乎想要的.如果您不想使用连接表,您可以指定一个JoinColumn
设置外键关系的方式,就像a OneToOne
,但方向相反 - 它告诉提供者目标表中的哪个字段指向该实体的主要键.但通常目标外键映射在目标实体中 - 它ManyToOne
毕竟是 - 因此mappedby
用于指定它OneToMany
应该使用已在目标实体中定义的关系.
在这种情况下,mappedBy=customer
告诉它查看customer
Order实体中的属性映射.在那里,它发现客户有一个ManyToMany
映射,其默认的joinColumn customer_id
也用于OneToMany
.因为它已经在Order实体中映射,所以它OneToMany
是只读的.这确保了如果两个关系不同步,JPA
则一方始终信任并用于设置数据库字段.
归档时间: |
|
查看次数: |
26233 次 |
最近记录: |