Hibernate[二]
2019-10-21 / JAVA / 1477 次围观 / 0 次吐槽 /1、Hibernate 实体的状态
1.1、状态介绍
² 实体Entity有三种状态,瞬时状态、持久状态、脱管状态
² 瞬时状态:transient, session没有缓存,数据库也没有记录,oid没有值
² 持久状态:persistent, session有缓存,数据库也有记录,oid有值
² 脱管状态/游离状态:detached,session没有缓存,数据库有记录,oid有值
1.2、瞬时 转 持久
² 新创建的一个对象,经过save,或者savaOrUpdate调用后,会变成持久状态
1.3、持久 转 脱管
v load,get返回的对象是持久状态的,当session关闭或者清除后,对象变成脱管状态
1.4、总结状态的转换过程
² 查询操作:get、load、createQuery、createCriteria 等 获得都是持久态
² 瞬时状态执行save、update、saveOrUpdate之后变成持久状态
² 持久态 转换 脱管态
Ø session.close () 关闭
Ø session.clear() 清除所有
Ø session.evict(obj) 清除指定的PO对象
2、一级缓存
2.1、概念
一级缓存:又称为session级别的缓存。当获得一次会话(session),hibernate在session中创建多个集合(map),用于存放操作数据(PO对象),为程序优化服务,如果之后需要相应的数据,hibernate优先从session缓存中获取,如果有就使用;如果没有再查询数据库。当session关闭时,一级缓存销毁。
2.2、证明一级缓存
2.3、移除缓存
2.4、一级缓存快照【掌握】
快照:与一级缓存存放位置是一样,对一级缓存数据备份。保证数据库的数据与 一级缓存的数据必须一致。如果一级缓存修改了,在执行commit提交时,将自动刷新一级缓存,执行update语句,将一级缓存的数据更新到数据库。
2.5、快照演示(一级缓存刷新)
2.6一级缓存的细节
² HQL的结果会进行一级缓存,SQL的结果不会添加到一级缓存
3、其它API
save和persist方法 区别
save方法:瞬时态 转换 持久态 ,会初始化OID
1.执行save方法,立即触发insert语句,从数据库获得主键的值(OID值)
2.执行save方法前,设置OID将忽略。
3.如果执行查询,session缓存移除了,在执行save方法,将执行insert
persist方法:瞬时态 转换 持久态
² persist保存的对象,在保存前,不能设置id,否则会报错
² save和persist都是持久化对象的作用
² save 因为需要返回一个主键值,因此会立即执行 insert 语句,而 persist 在事务外部调用时则不会立即执行 insert 语句,在事务内调用还是会立即执行 insert 语句的。
Update方法
saveOrUpdate
判断是否有OID,如果没有OID,将执行insert语句,如果有OID,将执行update语句。
Delete 方法
4、Hibernate的多表关联关系映射
4.1、多表关系
² 表之间关系存在3种:一对多、多对多、一对一。
多对多关系:(老师与学生) 主表的主键 与 从表外键 形成 主外键关系
一对多关系:(客户与订单) 提供中间表(从表),提供2个字段(外键)分别对应两个主表。
一对一: 主外键关系
4.2、案例:一对多、多对一
v 客户和定单的关系是一对多的关系,定单和客户的关系是多对一的
实体类的编写
v 注意:set集合一定要定义的时候初始化对象,需要提供属性的get/set方法
映射文件的编写
Customer.hbm.xml
<hibernate-mapping package="com.cheug.hibernate.domain"> <class name="Customer" table="t_customer"> <id name="id" column="id"> <generator class="native"></generator> </id> <property name="name" length="20"></property> <!-- 一个客户有多个定单,Hibernate可以双向描述一对多的关系 set中 name写的是实例的属性 --> <set name="orders"> <!-- column指的是Order表中的外键 --> <key column="customer_id"></key> <one-to-many class="Order"/> </set> </class> </hibernate-mapping>
Order.hbm.xml
<hibernate-mapping package="com.cheug.hibernate.domain"> <class name="Order" table="t_order"> <id name="id" column="id"> <generator class="native"></generator> </id> <!-- 定单名称 --> <property name="name"></property> <!-- 多个定单对应一个客户,Hibernate可以双向描述一对多的关系 set中 name写的是实例的属性 --> <many-to-one name="customer" class="Customer" column="customer_id"></many-to-one> </class> </hibernate-mapping>
@Test public void test1(){ Session session = HibernateUtils.openSession(); session.beginTransaction(); //客户 Customer customer = new Customer(); customer.setName("cheug"); //定单 Order order1 = new Order(); order1.setName("iphone8"); Order order2 = new Order(); order2.setName("iphonex"); //维护客户与定单的关系 customer.getOrders().add(order1); customer.getOrders().add(order2); //维护定单与客户的关系 order1.setCustomer(customer); order2.setCustomer(customer); session.save(customer);//执行三条insert sql语句 session.save(order1);//执行一条update sql语句,维护外键关系 session.save(order2);//执行一条update sql语句,维护外键关系 session.getTransaction().commit(); session.close(); }
设置外键维护的方式
² 修改Customer的配置文件,添加一个inverse选项
² inverse是hibernate双向关系中的基本概念。inverse的真正作用就是指定由哪一方来维护之间的关联关系。当一方中指定了“inverse=false”(默认),那么那一方就有责任负责之间的关联关系。
<!-- inverse:反转 true为另一方来维护外键关系 --> <set name="orders" inverse="true"> <key column="customer_id" /> <one-to-many class="com.cheug.model.Orders"></one-to-many> </set>
查询一对多和删除
一对多的查询,会执行两条sql语句
4.3、cascade级联
save-update
级联保存,级联修改. 保存A(客户)时,同时保存B(定单)
delete
级联删除,删除A时,同时删除B.
delete-orphan孤儿删除
孤儿删除,解除关系,同时将B删除,A存在的。
级联组合:
如果需要配置多项,使用逗号分隔。<set cascade="save-update,delete">
all-delete-orphan : 三个整合
- 上一篇:Hibernate[一]
- 下一篇:Hibernate[三]
Powered By Cheug's Blog
Copyright Cheug Rights Reserved.