美文网首页Java
Hibernate知识体系总结(二)

Hibernate知识体系总结(二)

作者: 半岛铁盒1979 | 来源:发表于2019-11-05 22:43 被阅读0次

    前言:上一篇文章给大家介绍了Hibernate的简单使用,这里给大家介绍Hibernate相关部分的详细讲解。

一、持久化对象三种状态:

1、瞬时态:无id,未与session关联
2、持久态:有id,与session有关联
3、游离|托管态:有id,未与session关联

public class TestState {

    /**
     * 通过代码展示对象状态的转换过程
     */
    @Test
    public  void fun1() {
        Session session = HibernateUtil.openSession();
        Transaction transaction = session.beginTransaction();

        Grades grades = new Grades();//瞬时态  无id,与session未关联
        grades.setS_class("302");//瞬时态

        //save方法可以理解成将瞬时态转为持久态,生成id
        session.save(grades);//持久态  有id,与session有关联

        transaction.commit();
        session.close();//托管|游离态  有id,与session未关联
    }

    /**
     * 持久态特点:能自动更新数据库
     */
    @Test
    public void fun2() {
        Session session = HibernateUtil.openSession();
        Transaction transaction = session.beginTransaction();

        //根据主键去获取对象,此时的对象是持久化状态
        Grades grades = session.get(Grades.class, 2L);
        //这里并没有调用update方法,但是却能更新数据库,这里面因为Hibernate存在一级缓存
        grades.setS_name("new name");

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

对象状态.png
二、Hibernate的一级缓存:

    即session的缓存,是一块内存空间,用来存放对应的java对象。通过hibernate查询对象时,优先根据OID从缓存中查找,减少对数据库的访问次数。
特点:
    1、当调用session的save(),update(),saveOrUpdate()方法时,如果缓存中没有对应的对象,就会从数据库中查对应的数据并存到一级缓存中;
    2、当调用session接口的load(),get()或者Query接口的list(),iterator()方法时,会先从缓存中找该对象,有则返回,没有就查找数据库,并存在一级缓存中;
    3、当调用session的close()方法时,session缓存将被清空

/**
 * 测试Hibernate的一级缓存
 */
public class TestSession {

    @Test
    public void fun1() {
        Session session = HibernateUtil.openSession();
        Transaction transaction = session.beginTransaction();

        Grades grades1 = session.get(Grades.class, 1L);//通过sql查询数据库,并将该对象存到session缓存中
        System.out.println(grades1);

        Grades grades2 = session.get(Grades.class, 1L);//直接从session缓存中获取
        System.out.println(grades2);

        System.out.println(grades1 == grades2);//true  一级缓存存的是对象地址

        transaction.commit();
        session.close();
    }
}
日志.png

一级缓存的内部结构:(快照区)
    当Hibernate向一级缓存存入数据时,会同时存入相同数据到快照区,这个时候会通过对象进行一些操作。当提交事务后,会通过OID去判断缓存中的数据和快照区的是否一致(判断对象是否有修改,是否需要更新数据库),如果对象的属性发生了变化,这个时候就需要执行update语句,将缓存中的数据同步到数据库,并更新快照;否则不做任何操作。快照的作用就是为了确保一级缓存中的数据和数据库保持一致,并且减少了了数据库的访问次数。

image.png
三、Hibernate中的事务

1、事务特性:
   a)原子性:事务中所有的操作是一个不可分割的单元,要么全部执行,要么全部不执行
   c)一致性:事务完成时,所有的数据都保持一致的状态
   i)隔离性:并发执行的各个事务之间不能相互干扰
   d)持久性:事务提交后,对数据库的数据改变是永久性的,提交后的其他操作或故障不会对其有影响
2、事务的并发问题:
   a)脏读 :一个事务读取到另一个事务未提交的数据
   b)不可重复读:一个事务读到了另一个事务应该提交的update数据,导致同一事务中多次查询结果不一致
   c)虚读|幻读 :一个事务读到了另一个事务应该提交的insert数据,导致同一事务中多次查询结果不一致
3、事务的隔离级别:
  为了避免事务并发问题,SQL定义了4个事务隔离级别
   a)读未提交 1 READ_UNCOMMITTED:可以读取还未提交的事务的数据,会产生a,b,c并发问题
   b)读已提交 2 READ_COMMITTED:可以读取事物提交后的数据,会产生b,c并发问题
   c)可重复读 4(mysql默认隔离级别,实际开发中选择 )REPEATABLE_READ:可以读取其他事物提交的新插入的数据,会产生c并发问题
   d)序列化/串行化 8 SERIALIZABLE: 不会出现并发问题
4、Hibernate的事务管理 :
    在hibernate.cfg.xml中配置:

<!--
            指定hibernate操作数据库时的隔离级别
            ## specify a JDBC isolation level
            #hibernate.connection.isolation 1|2|4|8
            0001   1    读未提交
            0010   2    读已提交
            0100   4    可重复读
            1000   8    串行化
        -->
        <property name="hibernate.connection.isolation">4</property>

    为了确保Service层和Dao层使用的是同一个Session对象,可以通过getCurrentSession()来获取,获取的session不用关闭,线程执行结束后,会自动关闭。Hibernate通过ThreadLocal将Session绑定到了当前线程中,需要在hibernate.cfg.xml中添加配置:

<!--指定session与当前线程绑定-->
        <property name="hibernate.current_session_context_class">thread</property>
四、Hibernate中的批量查询

1、HQL(多表,但不复杂时使用):Hibernate创建的面向对象查询语句

/**
 * HQL查询
 */
public class TestHqlQuery {

    /**
     * 基本查询
     */
    @Test
    public void hql() {
        String hql = "from Grades";

        Session currentSession = HibernateUtil.getCurrentSession();
        Transaction transaction = currentSession.beginTransaction();
        try {
            Query query = currentSession.createQuery(hql);
            List<Grades> list = query.list();
            System.out.println(list.size());
        } catch (Exception e) {
            e.printStackTrace();
            transaction.rollback();
        }
        transaction.commit();
    }

    /**
     * 通过命名占位符进行条件查询
     */
    @Test
    public void hql2() {
        String hql = "from Grades where id = :id";

        Session currentSession = HibernateUtil.getCurrentSession();
        Transaction transaction = currentSession.beginTransaction();
        try {
            Query query = currentSession.createQuery(hql);
            //设置查询参数
            query.setParameter("id", 1l);
            Grades grades = (Grades) query.uniqueResult();
            System.out.println(grades.getS_name());
        } catch (Exception e) {
            e.printStackTrace();
            transaction.rollback();
        }
        transaction.commit();
    }

    /**
     * 模糊查询
     */
    @Test
    public void hql3() {
        String queryName = "小周";
        String hql = "from Grades g where g.s_name like :name ";

        Session currentSession = HibernateUtil.openSession();
        Transaction transaction = currentSession.beginTransaction();
        try {
            Query query = currentSession.createQuery(hql);
            query.setParameter("name", "%" + queryName+"%");
            List<Grades> grades = query.list();
            System.out.println(grades.toString());
        } catch (Exception e) {
            e.printStackTrace();
            transaction.rollback();
        }
        transaction.commit();
        currentSession.close();
    }

    /**
     * 分页查询
     */
    @Test
    public void hql4() {
        String hql = "from Grades";

        Session currentSession = HibernateUtil.getCurrentSession();
        Transaction transaction = currentSession.beginTransaction();
        try {
            Query query = currentSession.createQuery(hql);
            //设置分页查询参数
            query.setFirstResult(0);
            query.setMaxResults(5);
            List<Grades> grades = query.list();
            System.out.println(grades.toString());
        } catch (Exception e) {
            e.printStackTrace();
            transaction.rollback();
        }
        transaction.commit();
    }
}

2、Criteria(单表条件查询):Hibernate创建的无语句查询

/**
 * Criteria查询
 */
public class TestCriteria {

    /**
     * 基本查询
     */
    @Test
    public void fun1() {
        Session currentSession = HibernateUtil.getCurrentSession();
        Transaction transaction = currentSession.beginTransaction();

        Criteria criteria = currentSession.createCriteria(Grades.class);
        List<Grades> list = criteria.list();

        System.out.println(list);
        transaction.commit();
    }

    /**
     * 条件查询
     * 对应关系
     * >            gt
     * >=           ge
     * <            lt
     * <=           le
     * ==           eq
     * !=           ne
     * in           in
     * between and  between
     * like         like
     * is not null  isNotNull
     * is null      isNull
     * or           or
     * and          and
     */
    @Test
    public void fun2() {
        Session currentSession = HibernateUtil.getCurrentSession();
        Transaction transaction = currentSession.beginTransaction();

        Criteria criteria = currentSession.createCriteria(Grades.class);
        //添加查询条件,查询id=1的成绩
        criteria.add(Restrictions.eq("id", 1L));
        Grades grades = (Grades) criteria.uniqueResult();

        System.out.println(grades);
        transaction.commit();
    }

    /**
     * 条件查询,模糊查询
     */
    @Test
    public void fun3() {
        Session currentSession = HibernateUtil.getCurrentSession();
        Transaction transaction = currentSession.beginTransaction();

        Criteria criteria = currentSession.createCriteria(Grades.class);
        //添加查询条件,模糊匹配
        criteria.add(Restrictions.like("s_name", "%小周%"));
        List<Grades> list = criteria.list();

        System.out.println(list.toString());
        transaction.commit();
    }

    /**
     * 分页查询
     */
    @Test
    public void fun4() {
        Session currentSession = HibernateUtil.getCurrentSession();
        Transaction transaction = currentSession.beginTransaction();

        Criteria criteria = currentSession.createCriteria(Grades.class);
        //设置分页查询,相当于limit ?,?
        //查询前十条数据
        criteria.setFirstResult(0);
        criteria.setMaxResults(10);
        List<Grades> list = criteria.list();

        System.out.println(list.toString());
        transaction.commit();
    }

    /**
     * 查询总条数
     */
    @Test
    public void fun5() {
        Session currentSession = HibernateUtil.getCurrentSession();
        Transaction transaction = currentSession.beginTransaction();

        Criteria criteria = currentSession.createCriteria(Grades.class);
        //设置查询的聚合韩式->总行数
        criteria.setProjection(Projections.rowCount());
        Long count = (Long) criteria.uniqueResult();
        System.out.println(count);
        transaction.commit();
    }
}

3、原生SQL:复杂的业务查询

/**
 * SQL查询
 */
public class TestSqlQuery {
    /**
     * 通过命名参数查询
     */
    @Test
    public void sql1() {
        String hql = "select * from grades where id =:g_id";

        Session currentSession = HibernateUtil.getCurrentSession();
        Transaction transaction = currentSession.beginTransaction();
        try {
            NativeQuery query = currentSession.createSQLQuery(hql);
            query.setParameter("g_id", 1);
            //将结果集封装到对象中
            query.addEntity(Grades.class);
            List<Grades> grades = query.list();
            System.out.println(grades.toString());
        } catch (Exception e) {
            e.printStackTrace();
            transaction.rollback();
        }
        transaction.commit();
    }

    /**
     * 模糊查询
     */
    @Test
    public void sql2() {
        String hql = "select * from grades g where g.s_name like ?0";

        Session currentSession = HibernateUtil.getCurrentSession();
        Transaction transaction = currentSession.beginTransaction();
        try {
            NativeQuery query = currentSession.createSQLQuery(hql);
            query.setParameter(0, "%小周");
            //将结果集封装到对象中
            query.addEntity(Grades.class);
            List<Grades> grades = query.list();
            System.out.println(grades.toString());
        } catch (Exception e) {
            e.printStackTrace();
            transaction.rollback();
        }
        transaction.commit();
    }


    /**
     * 基本查询
     */
    @Test
    public void sql3() {
        String hql = "select * from Grades";

        Session currentSession = HibernateUtil.getCurrentSession();
        Transaction transaction = currentSession.beginTransaction();
        try {
            NativeQuery query = currentSession.createSQLQuery(hql);
            query.addEntity(Grades.class);
            List<Grades> grades = query.list();
            System.out.println(grades.toString());
        } catch (Exception e) {
            e.printStackTrace();
            transaction.rollback();
        }
        transaction.commit();
    }

    /**
     * 通过JPA占位符进行分页查询
     */
    @Test
    public void sql4() {
        String hql = "select * from Grades limit ?0,?1 ";

        Session currentSession = HibernateUtil.getCurrentSession();
        Transaction transaction = currentSession.beginTransaction();
        try {
            NativeQuery query = currentSession.createSQLQuery(hql);
            query.setParameter(0, 0);
            query.setParameter(1, 2);
            query.addEntity(Grades.class);
            List<Grades> grades = query.list();
            System.out.println(grades.toString());
        } catch (Exception e) {
            e.printStackTrace();
            transaction.rollback();
        }
        transaction.commit();
    }
}

相关文章

网友评论

    本文标题:Hibernate知识体系总结(二)

    本文链接:https://www.haomeiwen.com/subject/rlcybctx.html