Hibernate检索(抓取)策略
class 标签中lazy=false 立即检索
class 标签中lazy=true 延迟检索
2)区分类级别和关联级别的检索
类级别检索:直接加载目标对象
Customer c = session.get(Customer.class,1);
关联级别:由加载到的对象导航到其他对象
Customer c = session.get(Customer.class,1);
Set<Order> orders = c.getOrders();
3)配置关联级别检索
* 在Customer.hbm.xml中配置<set name="orders" fetch="" lazy="">
fetch取值:join select subselect------决定sql语句的形式
lazy取值:true false extra------决定sql语句发出的时机
* fetch="join" lazy将被忽略:当查询客户对象时,会立即查询此客户关联的订单,sql形式为左外连接查询left outer join
* fetch="select"
lazy="true":当查询客户对象时,不会立即查询客户关联的订单,当使用订单属性或者size()时,才查询订单信息,sql形式为多条sql
lazy="false":当查询客户对象时,会立即查询客户关联的订单,sql形式为多条sql
lazy="extra":当查询客户对象时,不会立即查询客户关联的订单,
当访问size()方法时,发出select count(id) from orders where customerId = ?
当访问订单属性时,才发出sql查询订单真实信息
* fetch="subselect"
lazy="true":当查询客户对象时,不会立即查询客户关联的订单,当使用订单属性或者size()时,才查询订单信息,sql形式为子查询
lazy="false":当查询客户对象时,会立即查询客户关联的订单,sql形式为子查询
lazy="extra":当查询客户对象时,不会立即查询客户关联的订单,
当访问size()方法时,发出select count(*) from orders where customerId = ?
当访问订单属性时,才发出sql查询订单真实信息
Query query = session.createQuery("FROM XX WHERE ...");
query.list();
当使用query.list()方法查询时,会忽略fetch="join" ,关联的订单是否立即查询,要看lazy
* 在Order.hbm.xml中配置<many-to-one fetch="" lazy="">
fetch取值:join select ------决定sql语句的形式
lazy取值:false proxy------决定sql语句发出的时机
* fetch="join" lazy将被忽略:当查询订单对象时,会立即查询订单关联的客户,sql形式为左外连接查询
* fetch="select"
lazy="false":当查询订单对象时,会立即查询订单关联的客户,sql形式为多条sql
lazy="proxy":
当查询订单对象时,如果对方(客户)类级别检索策略lazy=true,不会立即查询订单关联的客户
当查询订单对象时,如果对方(客户)类级别检索策略lazy=false,会立即查询订单关联的客户
当使用query.list()方法查询时,会忽略fetch="join" ,关联的客户是否立即查询,要看lazy
4)批量检索
* 在一方(客户)方的<set name="orders" batch-size="10">---- 一次最多可以查询10个客户的订单
* 在一方(客户)方的<class name="cn.itcast.Customer" batch-size="10">----一次最多可以查询10个订单的客户
* 多个事务并发运行时的并发问题
1)脏读:一个事务读取到了另一个事务没有提交的数据
2)幻读:一个事务读取到了另一个事务提交的数据(插入)
3)不可重复读:一个事务读取到了另一个事务提交的数据(更新)
4)丢失更新:后一个事务覆盖了前一个事务提交的数据
* 解决丢失更新问题
1)悲观锁:使用数据库底层的锁机制,防止事务并发
2)乐观锁:在实体类中和hbm映射文件中使用一个版本字段,当提交事务时同时按照id和版本字段进行匹配,如果版本字段匹配不上,就抛出异常,阻止修改
* 二级缓存
* 配置二级缓存(EHCache)
1)导入缓存的jar包(3个)
2)在类路径下提供一个ehcache的核心配置文件ehcache.xml
3)在hibernate.cfg.xml中配置开启二级缓存
<property name="hibernate.cache.use_second_level_cache">true</property>
4)在hibernate.cfg.xml中指定缓存提供商
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
5)在hibernate.cfg.xml中指定哪些类和集合使用二级缓存
<!-- 指定哪些类使用二级缓存 -->
<class-cache usage="read-only" class="cn.itcast.domain.User"/>
<class-cache usage="read-only" class="cn.itcast.fetch.Customer"/>
<class-cache usage="read-only" class="cn.itcast.fetch.Order"/>
<!-- 指定哪些集合使用二级缓存 -->
<collection-cache usage="read-only" collection="cn.itcast.fetch.Customer.orders"/>
* 查询缓存(建立在二级缓存基础之上)
1)将二级缓存配置好
2)在hibernate核心配置文件中开启查询缓存
<property name="hibernate.cache.use_query_cache">true</property>
3)在程序中指定查询出的数据放入查询缓存中
query.setCachable(true);
4)在程序中指定使用查询缓存中的数据
query.setCachable(true);