您的位置:首页 > 其它

Hibernate检索(抓取)策略

2014-04-15 00:01 162 查看

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);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: