双向一对多关联映射
所谓一对多就是:一个对应多个,如一个班级有多个学生。一个客户有多个订单。。
这种关联关系在hibernate中主要在映射文件中体现:
我们可以试着写个小例子:一个客户customer类,一个订单类
/*
* 客户类
*/
private Long id;//主键id
private String name;//客户名称
private Set<Order> orders;//一对多,通过该变量可以引用到对应的Order集合对象
public Set<Order> getOrders() {
return orders;
}
public void setOrders(Set<Order> orders) {
this.orders = orders;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
private Long id;//主键id
private String OrderNumber;//订单号
private Customer customer;//多对一,通过该变量可以引用到关联的customer对象。
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getOrderNumber() {
return OrderNumber;
}
public void setOrderNumber(String orderNumber) {
OrderNumber = orderNumber;
}
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
然后是在两个映射文件中配置这种关联关系,这是最关键的地方。
<class name="com.test.bean.Customer" table="customes">
<id name="id" column="id" type="long">
<generator class="increment"/>
</id>
<property name="name" column="name" type="string"></property>
<!--一对多的关联关系-->
<!-- cascade:表示级联:对这张表的操作可能就会关系到另一张表的操作,
save-update表示当对当前这个对象进行保存或更新的时候,就会关联到需要保存的或更新的对象,如果是none表示操作的是当前对象不会与其他对象产生关联关系-->
<!-- inverser:true:表示多的这个方来维护这个关联关系,false:由一这方来维护这种关联关系 -->
<set name="orders" cascade="save-update" inverse="true">
<!-- order表中的customer_id是外键来对应customer表中的id主键 -->
<key column="customer_id"></key>
<!-- set集合对应的类型是订单项 -->
<one-to-many class="com.test.bean.Order" />
</set>
</class>
<class name="com.test.bean.Order" table="Orders">
<id name="id" column="id" type="long">
<generator class="increment"/>
</id>
<property name="OrderNumber" column="order_number" type="string"></property>
<!-- 多对一。name:订单类的客户对象,column:当前table对应的外键 -->
<many-to-one name="customer" class="com.test.bean.Customer" column="customer_id"/>
</class>
当然首先应该建表的:
custommers表
orders表。
最后测试:
private static SessionFactory sessionfactory;
static{
try {
//创建会话工厂
sessionfactory=new Configuration().configure().buildSessionFactory();
} catch (Exception e) {
// TODO: handle exception
}
}
/**
* @param args
*/
public static void main(String[] args) {
Session session=sessionfactory.openSession();
Transaction tx=session.beginTransaction();
try {
Customer customer=new Customer();
customer.setName("张三");
customer.setOrders(new HashSet<Order>());
Order order1=new Order();
order1.setOrderNumber("order1");
Order order2=new Order();
order2.setOrderNumber("order2");
Order order3=new Order();
order3.setOrderNumber("order3");
order1.setCustomer(customer);
order2.setCustomer(customer);
order3.setCustomer(customer);
customer.getOrders().add(order1);
customer.getOrders().add(order2);
customer.getOrders().add(order3);
session.save(customer);
tx.commit();
} catch (Exception e) {
if(null!=tx)
tx.rollback();
e.printStackTrace();
}finally{
session.close();
}
最后我们可以发现:我们只保存了客户对象。但是订单也同时保存了。这就是因为我们实现了两者之间的双向关联关系。
看看控制台的显示sql语句:
Hibernate:
select
max(id)
from
customes
Hibernate:
select
max(id)
from
Orders
Hibernate:
insert
into
customes
(name, id)
values
(?, ?)
Hibernate:
insert
into
Orders
(order_number, customer_id, id)
values
(?, ?, ?)
Hibernate:
insert
into
Orders
(order_number, customer_id, id)
values
(?, ?, ?)
Hibernate:
insert
into
Orders
(order_number, customer_id, id)
values
(?, ?, ?)