SSH框架之Hibernate进阶持久化对象及事务管理(二)

2019-03-27  本文已影响0人  Seapp

第一节: 持久化类的编写规则

1.1 什么是持久化类

1.2 持久化类的编写规则

1.3 Hibernate中主键生成策略

<id name="cust_id" column="cust_id">
            <!--主键生成策略-->
            <!--
            * increment:Hibernate中提供的自动增长的机制,适用于long,short或int类型的主键。在单线程中使用,
                在集群下不要使用(存在线程安全的问题);
            * identity:适用于short,int,long类型的主键,使用的是数据库底层的自动增长机制,适用于有自动增
                长机制的数据库(MySql,MSSQL),Oracle不适用。
            * sequence:适用于short,int,long类型的主键,采用的是序列的方式。Oracle支持。
            * uuid:适用于字符串类型的主键,使用hibernate中的随机方式生成字符串主键。
            * native:本地策略,可以在identity和sequence之间自动切换。
            * assigned:hibernate放弃主键的管理,需要用户自行设定
            * foreigen:使用另外一个相关联的对象的标识符。它通常和 <one-to-one> 联合起来使用。
            -->
            <generator class="native"/>
        </id>

第二节:持久化类的三种状态

Hibernate是持久层框架,通过持久化类完成ORM操作。Hibernate为了更好的管理之间化类,将持久化类分成三种状态。

2.1 如何区分这三种状态?

瞬时态对象,没有唯一标识OID,没有被session管理。
持久态对象,拥有唯一标识OID且被session管理。
脱管态对象,拥有唯一标识OID,但没有被session管理。

2.2 持久化对象的三种状态转换

image.png

第三节 Hibernate的一级缓存

缓存是计算机领域非常通用的概念。它介于应用程序和永久性数据存储源(如硬盘上的文件或者数据库)之间,其作用是降低应用程序直接读写永久性数据存储源的频率,从而提供应用的运行性能。缓存汇总的数据是数据存储源中数据的拷贝。缓存的物理介子通常是内存。
Hibernate的缓存分为一级缓存和二级缓存,Hibernate的这两级缓存都位于持久化层,存储的都是数据库数据的备份。其中第一级缓存为Hibernate的内置缓存,不能被卸载。

3.1 什么是Hibernate的一级缓存

Hibernate的一级缓存就是指Session缓存,Session缓存是一块内存空间,用来存放相互管理的Java对象,在使用Hibernate查询对象的时候,首先会使用对象属性的OID值在Hibernate的一级缓存中进行查找,如果找到匹配的OID值的对象,就直接将该对象从一级缓存中取出使用。不会再查询数据库。如果没有找到相同OID值的对象,则会去数据库中查找相应数据。当从数据库中查询到所需数据时,该数据信息也会放置到一级缓存中。Hibernate的一级缓存的作用就是减少对数据库的访问次数。
在Session接口的实现中包含一系列的Java集合,这些Java集合构成了Session缓存。只要Session实例没有结束生命周期,存放在它缓存中的对象也不会结束生命周期。固一级缓存也被称为Session基本的缓存。

3.2 Hibernate的一级缓存特点:

①当应用程序调用Session接口的save()、update()、saveOrUpdate时,如果Session缓存中没有相应的对象,Hibernate就会自动把从数据库中查询到的相应对象信息加入到一级缓存中去。
②当调用Session接口的load()、get()方法,以及Query接口的list()、iterator()方法时,会判断缓存中是否存在该对象,有则返回,不会查询数据库,如果缓存中没有要查询对象,再去数据库中查询对应对象,并添加到一级缓存中。
③当调用session的close()方法时,Session缓存会被清空。

3.3 Hibernate一级缓存的特殊区域(快照区)

image.png

第四节 Hibernate的事务管理

4.1 数据库事务的回顾

4.2 Hibernate中事务隔离级别的设置

在hibernate配置文件中配置如下属性:

   <!--设置事务的隔离级别-->
        <!--
            隔离级别取值对应关系:
            1 : Read uncommitted isolation
            2 : Read committed isolation
            4 : Repeatable read isolation
            8 : Serializable isolation
        -->
        <property name="hibernate.connection.isolation">4</property>

4.3 Service层事务管理

Service业务层的复杂业务对DAO层的调用必须保证连接对象是同一个,通常的解决方案有:
①:向下传递
②:使用ThreadLocal对象进行绑定,将连接对象绑定到当前线程中,在DAO的方法调用中,通过当前线程来获取连接对象。

4.5 Hibernate中针对Service层事务的管理方法

Hibernate框架内部已经绑定了ThreadLocal,在SessionFactory中提供了一个方法getCurrentSession()来获取连接对象。但这个方法的调用前提需修改Hibernate的属性,如下

 <!--配置Hibernate对Session事务的管理方式-->
        <!--
            用于指定session管理方式
            * thread : Session对象的生命周期与本地线程绑定。
            * jta:Session对象的生命周期与JTA事务绑定
            * managed: Hibernate委托程序来管理Session对象的生命周期
        -->
        <property name="hibernate.current_session_context_class">thread</property>

则session连接对象的获取方式:该连接对象在执行完成后无需手动关闭。

/**
     * currentSission对象的获取
     * @return
     */
    public static Session getCurrentSission(){
        return sessionFactory.getCurrentSession();
    }

第五节:Hibernate中的查询对象简介

5.1 Query

Query代表面向对象的一个Hibernate查询操作。在Hibernate中,通常使用session.createQuery()方法接受一个HQL语句,然后调用Query的list()或uniqueResult()方法执行查询。所谓的HQL是Hibernate Query Language缩写,其语法很像SQL语法,但它是完全面向对象的。

在Hibernate中使用Query对象的步骤:

    @Test
    public void findByQuery(){
        Session currentSission = HibernateUtil.getCurrentSission();
        Transaction transaction = currentSission.beginTransaction();
        //查询所有人员数据
//        String hql = "from Customer";
        //条件查询(使用命名参数的方式)
//        String hql = "SELECT c from Customer c where c.cust_name like :name ";
        //分页查询
        String hql = "from Customer";

        Query query = currentSission.createQuery(hql);
        //插入检索条件
//        query.setParameter("name","小%");
        //插入分页查询条件
        query.setFirstResult(0);//从第i条开始
        query.setMaxResults(1);//每页展示的数据为0条
        List<Customer> list = query.list();
        for (Customer customer: list) {
            System.out.println(customer.toString());
        }
        transaction.commit();
    }

5.2 criteria

Query by Criteria 是更加面向对象的一种查询方式。

 @Test
    public void findByCriteria(){
        Session currentSission = HibernateUtil.getCurrentSission();
        Transaction transaction = currentSission.beginTransaction();
        //通过criteria进行查询
//        Criteria criteria = currentSission.createCriteria(Customer.class);已过时
        //1.import javax.persistence.criteria.CriteriaQuery;获取Criteria对象
        CriteriaQuery<Customer> query = currentSission.getCriteriaBuilder().createQuery(Customer.class);
        //2.指定根条件
        query.from(Customer.class);
        //3.执行查询
//        List<Customer> resultList = currentSission.createQuery(query).getResultList();
        //3.1 执行分页查询
        List<Customer> resultList = currentSission.createQuery(query)
                .setFirstResult(0)//设置开始位置
                .setMaxResults(1)//设置每页条数
                .getResultList();
        for (Customer customer: resultList) {
            System.out.println(customer.toString());
        }
        transaction.commit();
    }

5.3 SQL Query

SQLQuery用于结束sql,特别复杂的情况下使用SQL。

上一篇下一篇

猜你喜欢

热点阅读