Hibernate检索(抓取)策略

Hibernate检索(抓取)策略


1)区分立即检索和延迟检索
    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);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值