1.数据对象三种关系
Hibernate框架基于ORM设计思想,它将关系型数据库中的表与我们JAVA中的类进行映射,一个对象就对应着表中的一条记录,而表中的字段对应类的属性。数据库中表与表之间存在着三种关系,也就是系统设计中三种实体关系。
- 一对一
原则有两种:
1.唯一外键对应:在任意一方来添加一个外键描述对应关系。
2.主键对应。
class Employee{
private Archives archives;
}
class Archives{
private Employee employee;
}
- 一对多:我们在建表时原则:在多的一方添加外键来描述他们的对应关系。
class Customer{
Private Set<order> orders;
}
Class Order{
private Customer c;
}
- 多对多:对于多对多关系,在描述时会通过一张中间表来描述其对应关系。
Class student{
private Set<Techer> ts;
}
Class Techer{
Set<student> ss;
}
2.一对多、多对一
1.Customer
public class Customer {
private Integer id;
private String name;
// 描述客户可以有多个订单
private Set<Order> orders = new HashSet<Order>();
<hibernate-mapping>
<class name="oneToMany.Customer" table="t_customer">
<id name="id" column="c_id">
<generator class="identity"></generator>
</id>
<property name="name" column="c_name" length="20" not-null="true"></property>
<!-- 一个客户关联多个订单 -->
<set name="orders">
<key column="c_customer_id" />
<one-to-many class="cn.itheima.onrToMany.Order"/>
</set>
<!--
使用set来描述在一的一方中关联的多 set<Order>, 它的name属性就是set集合的名称。
key:主要是描述关联的多的一方产生的外键的名称,注意要与多的一方定义的外键名称相同
one-to-many 描述集合中的类型。
-->
</class>
</hibernate-mapping>
2.Order
public class Order {
private Integer id;
private Double money;
private String receiverInfo;
private Customer customer;//描述订单属于某一个客户。
<hibernate-mapping>
<class name="oneToMany.Order" table="t_order">
<id name="id" column="c_id">
<generator class="identity"></generator>
</id>
<property name="money" column="c_name" ></property>
<property name="receiverInfo" column="c_receiverInfo" length="50"></property>
<!-- 多对一 -->
<many-to-one name="customer" class="cn.itheima.oneToMany.Customer" column="c_customer_id"></many-to-one>
<!--
name属性它描述的是Order类中的一方的属性名称 Customer customer
class代表一的一方的类型
column描述的是一对多或者多对一的外键的名称c_customer_id
-->
</class>
</hibernate-mapping>
2.一对多测试
@Test
public void test01(){
Session session = hibernateUtils.openSession();
session.beginTransaction();
// 创建一个用户
Customer customer = new Customer();
customer.setName("hans");
// 创建两个订单
Order order = new Order();
order.setMoney(1000d);
order.setReceiverInfo("china");
Order order2 = new Order();
order.setMoney(5000d);
order.setReceiverInfo("shanghai");
// 建立关系
// 订单关系客户
order.setCustomer(customer);
order2.setCustomer(customer);
// 客户关联订单
customer.getOrders().add(order);
customer.getOrders().add(order2);
session.save(order);
session.save(order2);
session.save(customer);
// 事务提交和关闭
session.getTransaction().commit();
session.close();
}
3.单向关联:
问题:我们可不可以只保存订单或者只保存客户完成保存操作?
报异常:org.hibernate.TransientObjectException:
一个持久化对象关联了一个瞬时态对象。
## 我们可以使用级联操作来解决上述问题,我们现在要做的是保存订单时保存客户,需要在订单的hbm配置文件中修改 ##
设置cascade=save-update,那么在保存订单时就可以自动将客户保存。
<many-to-one name="customer" class="cn.itheima.oneToMany.Customer" column="c_customer_id" cascade="save-update"></many-to-one>
如果要完成保存客户时,保存订单
<set name="orders" cascade="save-update">
4.双向关联配置
配置中,可以进行双向关联配置。--可以通过任意一方来操作对方
在操作中,避免双向操作。尽量进行单向关联。--减少资源浪费。
在双向关联中,会存在多于的Update语句。
我们可以使用inverse属性来设置,双线关联时由哪一方来维护表与表之间的关系。
<set name="orders" inverse="true">
inverse的值如果为true,由对方来维护外键。
inverse的值如果为false,由本方来进行维护外键。
关于inverse的取值:
*外键在哪一个表中,我们就让哪一方来维护外键。
5.级联删除。
我们在删除客户时,也要删除订单,如果没有做级联,那么这个操作时不允许的。
为了维护是数据完整性。
想要完成操作:我们可以在客户中添加cascade=”delete“
<set name="Customer" inverse="true" cascade="delete">
@Test
public void test03(){
Session session = hibernateUtils.openSession();
session.beginTransaction();
Customer customer = session.get(Customer.class, 1);
session.delete(customer);
// 事务提交和关闭
session.getTransaction().commit();
session.close();
}
@Test
public void test04(){
Session session = hibernateUtils.openSession();
session.beginTransaction();
Customer customer = session.get(Customer.class, 1);
Order order = session.get(Order.class, 2);
customer.getOrders().remove(order);
// 事务提交和关闭
session.getTransaction().commit();
session.close();
}
6.cascade总结
使用cascade可以完成级联操作。
它可常用取值:
none:这是一个默认值
save-update:当我们配置它时,底层使用save update 或save-update完成操作,级联保存临时对象,如果是托管对象,会执行update。
delete:级联删除
delete-ophan:删除与当前对象解决关系的对象;
All:包含了save-update delete操作
All-delete-orphan:它包含了delete-orphan与All操作
Casscade与inverse的区别?
Cascade完成级联操作。
Inverse只有在双向关联情况下有作用,它来指定由哪一方来维护。