Hibernate中查询实体对象的几种方法、二级缓存

Hibernate中查询实体对象的几种方法:get()、load()、createQuery()、CreateCriteria
使用HQL语句查询不再赘述,下面贴一下HQL语句进行分页查询的代码
HQL语句进行分页查询:

@SuppressWarnings("rawtypes")
@Test
    public void testHQL() throws Exception {
        Session session = sessionFactory.openSession();
        session.beginTransaction();

        List list = session.createQuery//
        ("FROM com.test.User ")//
                .setFirstResult(0)//
                .setMaxResults(10)//
                .list();
        for (Object obj : list) {
            System.out.println(obj);
        }

        session.beginTransaction().commit();
        session.close();
    }

使用CreateCriteria()查询:

@SuppressWarnings("rawtypes")
    @Test
    public void testCriteria() throws Exception {
        Session session = sessionFactory.openSession();
        session.beginTransaction();

        Criteria criteria = session.createCriteria(User.class);
        criteria.add(Restrictions.ge("id", 1));//过滤条件,ge表示大于,le表示小于
        criteria.add(Restrictions.le("id", 5));
        criteria.addOrder(Order.desc("id"));//排序条件,id降序输出
        List list = criteria.list();
        for (Object obj : list){
            if(obj.getClass().isArray()){//判断obj类型是否为Array类型并输出,或者直接使用增强for循环遍历输出
                System.out.println(Arrays.toString((Object[]) obj ));
            } else {
                System.out.println(obj);
            }
        }

        session.beginTransaction().commit();
        session.close();
    }

懒加载:不会在执行获取操作时马上生成SQL,而是在第一次使用时生成SQL

类级别的懒加载:class ….lazy=true
属性级别的懒加载:ser/list/map/bag … lazy = “true” bag的含义相当于口袋,可重复并且无序

在配置文件中配置lazy=”true\false\extra”
lazy=“extra”–增强的懒加载策略
Load()方法:获取数据,是持久化状态–会生成SQL语句–懒加载,不会马上执行SQL语句,而是在第一次使用非id或class属性时执行SQL–
如果对象不存在就报错–load返回的是一个代理对象,要求类不能是final类,否则不能生成代理对象

让懒加载失效的两种方式:
1.把实体写成final类
2.在hbm文件中,将lazy=”flase”加入到配置文件中

在使用懒加载特性时,要注意LazyIxxxxxx异常(懒加载异常),解决懒加载的简单方法:延迟关掉session(让session在加载后再关闭),或者关掉懒加载233
Hibernate.initialize(department.getEmpliyees());//这个方法立即加载指定的懒加载对象,在懒加载开启状态下立即加载指定对象

二级缓存(The Second Level Cache):在SessionFactory中的缓存
一级缓存:SessionCache,针对于一次操作所做的缓存,一级缓存对于性能的提升不大,因为事务的开启和关闭较频繁

使用SessionFactoryCache:
1)在映射文件hbm.xml中书写(映射关系使用映射文件的方式而非注解)

<class name="User" table="OwnuserTest" >
            <cache usage="read-only"/>
            <id name="id" column="id">      
                <generator class="native"></generator> 
            </id>           
        <property name="name" length="10"></property>   
        <property name="address" length="10"></property>            
    </class>

2)在hibernate配置文件cfg.xml中书写(推荐使用,解耦和)*

<!-- 使用SessionFactoryCache,默认是未打开的 -->
        <property name="cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>
        <mapping resource="com/test/User.hbm.xml"/> 
        <!-- 指定要使用二级缓存的实体类 -->
        <class-cache usage="read-write" class="com.test.User" />

PS:一级缓存和二级缓存都是在使用OID的方式获取对象时才有效;在使用HQL语句查询时,如果使用iterate()方法就会使用缓存,但该方法会有N+1查询的问题,对性能的提升有限

解决方法:打开查询缓存,并在测试中调用setCacheable()方法

@SuppressWarnings("rawtypes")
    @Test 
    public void testQueryCache() throws Exception {
        Session session = sessionFactory.openSession();
        session.beginTransaction();
        List list = session.createQuery("FROM com.test.User WHERE id <10")//
                .setCacheable(true)
                .list();
        for (Object obj : list) {
            System.out.println(obj);

        }
        session.beginTransaction().commit();
        session.close();
//开启第二个Session,将使用到二级缓存 
        Session session1 = sessionFactory.openSession();
        session1.beginTransaction();
        List list1 = session1.createQuery("FROM com.test.User WHERE id <10")//
                .setCacheable(true)
                .list();
        for (Object obj1 : list1) {
            System.out.println(obj1);

        }
        session1.beginTransaction().commit();
        session1.close();   
    }

并在配置文件cfg.xml中打开查询缓存

<!-- 开启使用查询缓存 -->
<property name="cache.use_query_cache">true</property>

注意查询缓存的查询条件需相同,因为h框架是将HQL放入二级缓存中,改变了HQL语句则要重新在数据库中查询,二级缓存无效

PS:在Session缓存中update和delete方法操作了数据库但未更新数据库,但在二级缓存中使用会让二级缓存中的数据失效,下次使用这些数据时会自动在数据库中重新加载

引用网上的资料–hibernate调优等
优化hibernate:
1、使用一对多的双向关联,尽量从多的一端维护。
2、不要使用一对一,尽量使用多对一。
3、配置对象缓存,不要使用集合缓存。
4、表字段要少,表关联不要怕多,有二级缓存撑腰。

Hibernate的调优方案:
1、制定合理的缓存策略;
2、尽量使用懒加载特性;
3、采用合理的Session管理机制;
4、使用批量抓取,设定合理的批处理参数(batch_size);
5、进行合理的O/R映射设计

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值