数据库中的表之间的关系
- 1对多:
一方表(主表)、多方表(从表)。从表提供外键字段,添加约束主外键约束。
从表的外键,与主表的主键,形成主外键关系。 - 多对多:
两个多表,都是主表
提供第三张表(中间表),时从表
提供两个字段,这两个字段分别对象两个主表的外键
建议:两个字段合并在一起,生成联合主键 - 一对一:略
关联关系:1对多
实例:客户(1) -- (*)订单
示例代码编写:
1.订单表映射关系设置:
①PO类(Order.java)
public class Order {
private Integer xid;
private String price;
//多对一:多个订单 属于 【一个客户】
private Customer customer;
...
}
② hbm.xml配置(Order.hbm.xml)
<hibernate-mapping>
<class name="cn.itcast.b_onetomany.Order" table="t_order">
<id name="xid">
<generator class="native"></generator>
</id>
<property name="price"></property>
<!-- 多对一:多个订单 属于 【一个客户】 -->
<many-to-one name="customer"
class="cn.itcast.b_onetomany.Customer"
column="customer_id"></many-to-one>
</class>
</hibernate-mapping>
2. 客户表映射关系设置:
①PO类(Customer.java)
public class Customer {
private Integer cid;
private String cname;
//一对多:一个客户 拥有 【多个订单】
private Set<Order> orderSet = new HashSet<Order>(); //建议:容器实例化,方便使用
...
}
② hbm.xml配置(Customer.hbm.xml)
<hibernate-mapping>
<class name="cn.itcast.b_onetomany.Customer" table="t_customer">
<id name="cid">
<generator class="native"></generator>
</id>
<property name="cname"></property>
<!-- 一对多:一个客户 拥有 【多个订单】 ,确定容器、确定外键、确定类型-->
<set name="orderSet">
<key column="customer_id"></key>
<one-to-many class="cn.itcast.b_onetomany.Order"/>
</set>
</class>
</hibernate-mapping>
以上即表创建成功,接下来为对表的操作
3.api操作
@Test
public void demo01(){
//保存客户 -- 成功保存
Session session = factory.openSession();
Transaction transaction = session.beginTransaction();
Customer customer = new Customer();
customer.setCname("jack");
session.save(customer);
transaction.commit();
session.close();
}
@Test
public void demo02(){
//保存订单 -- 成功保存,外键值为null
Session session = factory.openSession();
Transaction transaction = session.beginTransaction();
Order order = new Order();
order.setPrice("998");
session.save(order);
transaction.commit();
session.close();
}
@Test
public void demo03(){
/* 提供一个新的客户和新的订单,客户关联订单,只保存客户 -- 抛异常
* org.hibernate.TransientObjectException: object references an unsaved transient instance
* 瞬时对象异常,持久的customer,关联(引用) 瞬时order,将抛异常。保存客户时,订单在数据库中不存在,将无法执行update语句进行更新。
* * 解决方案1:将order由瞬时转换持久--save
*/
Session session = factory.openSession();
Transaction transaction = session.beginTransaction();
// 1 创建对象
Customer customer = new Customer();
customer.setCname("rose");
Order order = new Order(); //--order瞬时
order.setPrice("123");
// 2 客户关联订单
customer.getOrderSet().add(order);
// 3保存客户
session.save(customer); //--customer持久
session.save(order);
transaction.commit();
session.close();
}
@Test
public void demo04(){
/* 双向关联
* 多方Order,必须维护外键信息,如果已经有数据将不进行update更新
* 一方Customer,默认只要关联就进行维护。但可以通过inverse进行设置,
* inverse="true" 一方将放弃对外键数据维护。此时将减少一条update语句
*/
Session session = factory.openSession();
Transaction transaction = session.beginTransaction();
// 1 创建对象
Customer customer = new Customer();
customer.setCname("rose");
Order order = new Order();
order.setPrice("123");
// 2 双向关联 : 关联就是对外键数据的维护
// 2.1 客户关联订单
customer.getOrderSet().add(order);
// 2.2 订单关联客户
order.setCustomer(customer);
// 3保存客户
session.save(customer); //customer 只要关联,默认进行数据维护。
session.save(order); //order必须维护数据,如果customer已经有OID,将不执行update
transaction.commit();
session.close();
}