Hibernate的基本使用

Hibernate基本配置,工具类

Hibernate基本配置,工具类

CURD操作

save()

save() 为Hibernate的API,用于持久化
例:

    @Test
    public void testSave(){
       Session session = HibernateUtil.getSession();
       try{
        //开启事物
        session.beginTransaction();
        //4.保存对象
        Student stu = new Student();
        stu.setAge(12);
        stu.setName("fafa败");
        stu.setScores(55);
        session.save(stu);
        session.beginTransaction().commit();
       } catch (Exception e) {
         e.printStackTrace();
         session.beginTransaction().rollback();
       }
    }

persist()

persist()为JPA的API,用于持久化
例:

    @Test
    public void testPersist() {
        Session session = HibernateUtil.getSession();
        try {
            //开启事务
            session.beginTransaction();
            Student stu = new Student();
            stu.setAge(12);
            stu.setName("阿斯达");
            stu.setScores(55);
            session.persist(stu);
            session.beginTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.beginTransaction().rollback();
        }
    }

delete()

必须要指定删除对象的ID
例:

@Test
    public void testDelete() {
        Session session = HibernateUtil.getSession();
        try {
            //开启事务
            session.beginTransaction();
            Student stu = new Student();
            stu.setId(6);
            stu.setAge(12);
            stu.setName("asfaa");
            stu.setScores(55);
            //只与ID有关.与其他属性无关
            session.delete(stu);
            session.beginTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

update()

更新操作,需要指定ID
例:

 @Test
    public void testUpdate() {
        Session session = HibernateUtil.getSession();
        try {
            //开启事务
            session.beginTransaction();
            Student stu = new Student();
            stu.setId(5);
            stu.setAge(12);
            stu.setName("asfaa");
            stu.setScores(55);
            //只与ID有关.与其他属性无关
            session.update(stu);
            session.beginTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

saveOrUpdate()

通过参数对象是否具有ID值来判断实质性save()操作还是update().
若参数对象具有ID,但该ID在DB中不存在,则会抛出异常
例:

@Test
    public void testSaveOrUpdate() {
        Session session = HibernateUtil.getSession();
        try {
            //开启事务
            session.beginTransaction();
            Student stu = new Student();
            stu.setId(7);
            stu.setAge(12);
            stu.setName("aaaaa");
            stu.setScores(55);
            //只与ID有关.与其他属性无关
            session.saveOrUpdate(stu);
            session.beginTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

get()

查询无果时,放回null,但不会抛出异常.而且查询的时候要开启事务
例:

@Test
    public void testGet() {
        Session session = HibernateUtil.getSession();
        try {
            session.beginTransaction();
            //查到数据
            //Student student = session.get(Student.class, 1);
            //查不到数据返回null
            Student student = session.get(Student.class, 6666);
            System.out.println(student);
            session.beginTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.beginTransaction().rollback();
        }
    }

load()

查不到数据时,会抛出异常
例:

    @Test
    public void testLoad() {
        Session session = HibernateUtil.getSession();
        try {
            session.beginTransaction();
            //查到数据
            //Student student = session.load(Student.class, 1);
            //查不到数据抛出异常
            Student student = session.load(Student.class, 999);
            System.out.println(student);
            session.beginTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.beginTransaction().rollback();
        }
    }

注意

1.对于不同操作对象的增 删 改操作,无论代码的书写语句顺序是怎样的,底层SQL的执行都是 insert update delete
若要修改其底层的执行顺序,则可通过Session的flush()方法刷新Session完成
例:

 @Test
    public void testSaveDeleteUpdate() {
        Session session = HibernateUtil.getSession();
        try {
            //开启事务
            session.beginTransaction();
            //删除对象
            Student deleteStudent = new Student();
            deleteStudent.setId(2);
            //添加对象
            Student saveStudent = new Student();
            saveStudent.setAge(11);
            saveStudent.setName("adada");
            //修改对象
            Student updateStudent = session.get(Student.class, 4);
            updateStudent.setName("修改");

            session.delete(deleteStudent);
            //此处可以刷新session的执行顺序
            //session.flush();
            session.save(saveStudent);
            session.update(updateStudent);

            session.load(Student.class, 9999);
            session.beginTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.beginTransaction().rollback();
        }
    }

getCurrentSession() 和 openSession() 获取Session的区别

方法名获取的对象对象的关闭环境的注册查询对事物的支持
getCurrentSession()无论执行多少 次 该 方 法 ,只要是在同一线程中,获取的都是同一个session自动关闭Session,无需手工关闭需要注册Session的运行环境查询必须在事务内执行
openSession()每执行一次该方法,获取到的都是一个新的session对象必须手工关闭Session对象无需注册查询可以不在事务内执行

Hibernate 对象持久化状态管理

一 . Hibernate 的对象状态
对象的状态一般是指对象的一组属性的值。而这里的状态是指对象处于什么存储介 质 中。用于存放对象的存储介质有三个:普通内存(与 Hibernate 无关)、 Session 缓存、数据 库。对象处于不同的介质,就将处于不同的状态。

二 . 状态转换
1.状态转换图
状态转换图
2、对象状态
(1)暂时态:transient 状态,对象在内存中存在,但 DB 中无记录,与 Session 无关,是个 过渡状态。
(2)持久态:persistent 状态,在内存中存在,DB中有记录,与Session 相关在 Session 中有对象的副本。
(3)游离态:detached 状态,在内存中存在,在 DB 中有记录,与 Session 无关。
(4)无 名态:在内存中不存在,但在 DB 中有记录,与 Session 无关。

3、状态转换常用方法
save( ):将暂时态对象同步到 DB 中。
update( ):将游离态对象同步到 DB 中。
delete( ):将指定的对象从 session 中删除,同时也删除 DB 中的该数 据。
close( ):关闭 Session 对象。
clear( ):清空 Session 的缓存。
saveOrUpdate( ):根据参数对象的 id 属性是否为 null 来判断是执行保存还是更 新操作。
evict():将指定对象仅仅从 session 中删除,但不删除 DB 中的该数 据。
load( )与 get( ):将无名态对象转换为持久态对象

4、Hibernate 的同步机制 Hibernate 中的同步是指刷新缓存,以使缓存与 DB 中数据保持一致。当调用不 同的状 态转换方法后,Session 能够在某些时间点完成缓存的刷新,将缓存中的 持久化对象同步更 新到 DB。这些时间点是执行以下方法: (1)Session 的 flush() (2)事务的 commit()

一、API

1、Query 接口 Hibernate 进行 HQL 查询的接口,支持动态绑定参数的功能。使用 Session 对象 的 createQuery 方法可获取 Query 对象。 Query query = session.createQuery(hql);

2、SQLQuery 接口 Hibernate 进行 SQL 原生查询的接口,支持动态绑定参数的功能,是 Query 接 口的子接 口。使用 Session 对象的 createSQLQuery()方法可获取 SQLQuery 对 象。 SQLQuery sqlQuery = session.createSQLQuery(sql); 其查询出的结果对象默 认为 Object,当然,若结果为 List,则其元素为 Object。使用 SQLQuery 的 addEntity(Xxx.class)方法,可以将其结果泛型设定为指定类型。

3、Criteria 接口 Criteria,标准、准则,Hibernate 进行 Criteria 查询的接口,与 Query 接口无 关。使用 Session 对象的 createCriteria()方法可获取 Criteria 对象。 Criteria criteria = session.createCriteria(Xxx.class);

二、查询示例

Hibernate 是 DAO 层技术,对数据的使用,查询是最为重要的。Hibernate 的 查询技术非常强大,支持原始 SQL 语句查询,支持 QBC 查询及 Hibernate 特 有的 HQL 查询。 HQL,Hibernate Query Language,Hibernate 查询语言,它与 SQL 非常相 似。但,HQL 是面向对象的查询语言,而 SQL 是面向二维表的。HQL 查询语句 中使用的是类名与属性名,而 SQL 语句使用的是表名与字段名。

查询结果list

1.SQL

	@Test
    public void testSQL1() {
        Session session = HibernateUtil.getSession();
        try {
            session.beginTransaction();
            String sql = "select * from t_student1";
            List<Student> list = session.createSQLQuery(sql).addEntity(Student.class).list();
            for (Student stu : list) {
                System.out.println(stu.toString());
            }
            session.beginTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.beginTransaction().rollback();
        }
    }

2.HQL

	@Test
    public void testHQL1() {
        Session session = HibernateUtil.getSession();
        try {
            session.beginTransaction();
            String hql = "from Student";
            List<Student> list = session.createQuery(hql).list();
            for (Student stu : list) {
                System.out.println(stu.toString());
            }
            session.beginTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.beginTransaction().rollback();
        }
    }

3.QBC

	@Test
    public void testQBC1() {
        Session session = HibernateUtil.getSession();
        try {
            session.beginTransaction();
            List<Student> list = session.createCriteria(Student.class).list();
            for (Student stu : list) {
                System.out.println(stu.toString());
            }
            session.beginTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.beginTransaction().rollback();
        }
    }

查询结果排序

1.SQL

	@Test
    public void testSQL2() {
        Session session = HibernateUtil.getSession();
        try {
            session.beginTransaction();
            String sql = "select * from t_student1 order by tname desc";
            List<Student> list = session.createSQLQuery(sql).addEntity(Student.class).list();
            for (Student stu : list) {
                System.out.println(stu.getName());
            }
            session.beginTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.beginTransaction().rollback();
        }
    }

2.HQL

	@Test
    public void testHQL2() {
        Session session = HibernateUtil.getSession();
        try {
            session.beginTransaction();
            String hql = "from Student order by name desc";
            List<Student> list = session.createQuery(hql).list();
            for (Student stu : list) {
                System.out.println(stu.getName());
            }
            session.beginTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.beginTransaction().rollback();
        }
    }

3.QBC

	@Test
    public void testQBC2() {
        Session session = HibernateUtil.getSession();
        try {
            session.beginTransaction();
            List<Student> list = session.createCriteria(Student.class).addOrder(Order.desc("name")).list();
            for (Student stu : list) {
                System.out.println(stu.getName());
            }
            session.beginTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.beginTransaction().rollback();
        }
    }

动态参数绑定

1.SQL

	//使用"?"占位符占位,setXxx绑定参数,SetXxx(int position,Object value)
    //方法名中的Xxx表示该位置参数的类型,position表示第几个占位符,从0开始
    @Test
    public void testSQL3() {
        Session session = HibernateUtil.getSession();
        try {
            session.beginTransaction();
            String sql = "select * from t_student1 where tage > ? and tscores < ?";
            List<Student> list = session.createSQLQuery(sql).addEntity(Student.class).setInteger(0, 3).setDouble(1, 50).list();
            for (Student stu : list) {
                System.out.println(stu.toString());
            }
            session.beginTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.beginTransaction().rollback();
        }
    }

	//使用setParamter(String name,Object value)方法动态参数绑定,根据别名
    @Test
    public void testSQL3setParameterByName() {
        Session session = HibernateUtil.getSession();
        try {
            session.beginTransaction();
            String sql = "select * from t_student1 where tage > :age and tscores < :score";
            List<Student> list = session.createSQLQuery(sql).addEntity(Student.class).setParameter("age", 3).setParameter("score", 50).list();
            for (Student stu : list) {
                System.out.println(stu.toString());
            }
            session.beginTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.beginTransaction().rollback();
        }
    }

	//使用setParamter(int position,Object value)方法动态参数绑定,根据占位符
    @Test
    public void testSQL3setParameter() {
        Session session = HibernateUtil.getSession();
        try {
            session.beginTransaction();
            String sql = "select * from t_student1 where tage > ? and tscores < ?";
            List<Student> list = session.createSQLQuery(sql).addEntity(Student.class).setParameter(0, 3).setParameter(1, 50).list();
            for (Student stu : list) {
                System.out.println(stu.toString());
            }
            session.beginTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.beginTransaction().rollback();
        }
    }

2.HQL

	//以上三种方式均可实现,用法相同
    @Test
    public void testHQL3() {
        Session session = HibernateUtil.getSession();
        try {
            session.beginTransaction();
            String hql = "from Student where age > ? and scores < ?";
            List<Student> list = session.createQuery(hql).setParameter(0, 2).setParameter(1, 59.2).list();
            for (Student stu : list) {
                System.out.println(stu.toString());
            }
            session.beginTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.beginTransaction().rollback();
        }
    }

3.QBC

	//需要向Criteria对象添加限制条件 Restrictions,即添加查询条件
    //Restriction 中文意思:限制,约束 Restrictions具有很多静态方法可用于
    //表示关系比较
    @Test
    public void testQBC3() {
        Session session = HibernateUtil.getSession();
        try {
            session.beginTransaction();
            List<Student> list = session.createCriteria(Student.class).add(Restrictions.gt("age", 2)).add(Restrictions.lt("scores", 50.0)).list();
            for (Student stu : list) {
                System.out.println(stu.toString());
            }
            session.beginTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.beginTransaction().rollback();
        }
    }

分页查询

1.SQL

	@Test
    public void testSQL4() {
        Session session = HibernateUtil.getSession();
        try {
            session.beginTransaction();
            String sql = "select * from t_student1 limit ? , ?";
            List<Student> list = session.createSQLQuery(sql).addEntity(Student.class).setParameter(0, 3).setParameter(1, 5).list();
            for (Student stu : list) {
                System.out.println(stu.toString());
            }
            session.beginTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.beginTransaction().rollback();
        }
    }

2.HQL

	//Query 接口中具有 setFirstResult()方法
    //用于设置从总查询结果集的第几条记录 作为本查询结果子集的开始
    //即本页的开始。总查询结果集从 0 开始记数。
    //而 setMaxResults()方法用于设置该页所包含的记录数。
    @Test
    public void testHQL4() {
        Session session = HibernateUtil.getSession();
        try {
            session.beginTransaction();
            String hql = "from Student";
            List<Student> list = session.createQuery(hql).setFirstResult(3).setMaxResults(5).list();
            for (Student stu : list) {
                System.out.println(stu.toString());
            }
            session.beginTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.beginTransaction().rollback();
        }
    }

3.QBC

	//Criteria 接口中也有 setFirstResult()与 setMaxResults()方法,
    //其用法与意义与 Query 接口中的完全相同。
    //由于 Criteria 与 Query 接口无关,
    //所以这两组完全相 同的方法也是没有关系的,仅仅是写法与用法相同而已
    @Test
    public void testQBC4() {
        Session session = HibernateUtil.getSession();
        try {
            session.beginTransaction();
            List<Student> list = session.createCriteria(Student.class).setFirstResult(3).setMaxResults(5).list();
            for (Student stu : list) {
                System.out.println(stu.toString());
            }
            session.beginTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.beginTransaction().rollback();
        }
    }

模糊查询

1.SQL

	 @Test
    public void testSQL5() {
        Session session = HibernateUtil.getSession();
        try {
            session.beginTransaction();
            String sql = "select * from t_student1 where tname like :sname";
            List<Student> list = session.createSQLQuery(sql).addEntity(Student.class).setParameter("sname", "%萧%").list();
            for (Student stu : list) {
                System.out.println(stu.toString());
            }
            session.beginTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.beginTransaction().rollback();
        }
    }

2.HQL

	@Test
    public void testHQL5() {
        Session session = HibernateUtil.getSession();
        try {
            session.beginTransaction();
            String hql = "from Student where name like :sname";
            List<Student> list = session.createQuery(hql).setParameter("sname", "%萧%").list();
            for (Student stu : list) {
                System.out.println(stu.toString());
            }
            session.beginTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.beginTransaction().rollback();
        }
    }

3.QBC

	@Test
    public void testQBC5() {
        Session session = HibernateUtil.getSession();
        try {
            session.beginTransaction();
            List<Student> list = session.createCriteria(Student.class).add(Restrictions.like("name", "%萧%")).list();
            for (Student stu : list) {
                System.out.println(stu.toString());
            }
            session.beginTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.beginTransaction().rollback();
        }
    }

唯一性查询

1.SQL

	//SQLQuery 接口的uniqueResult()方法表示其查询结果为一条数据,其返回值为Object
    @Test
    public void testSQL6() {
        Session session = HibernateUtil.getSession();
        try {
            session.beginTransaction();
            String sql = "select * from t_student1 where tid = ?";
            Student student = (Student) session.createSQLQuery(sql).addEntity(Student.class).setParameter(0, 3).uniqueResult();
            System.out.println(student.toString());
            session.beginTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.beginTransaction().rollback();
        }
    }

2.HQL

	 @Test
    public void testHQL6() {
        Session session = HibernateUtil.getSession();
        try {
            session.beginTransaction();
            String sql = "from Student where id = ?";
            Student student = (Student) session.createQuery(sql).setParameter(0, 3).uniqueResult();
            System.out.println(student.toString());
            session.beginTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.beginTransaction().rollback();
        }
    }

3.QBC

	@Test
    public void testQBC6() {
        Session session = HibernateUtil.getSession();
        try {
            session.beginTransaction();
            Student student = (Student) session.createCriteria(Student.class).add(Restrictions.eq("id", 5)).uniqueResult();
            System.out.println(student.toString());
            session.beginTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.beginTransaction().rollback();
        }
    }

聚合函数查询

1.SQL

	@Test
    public void testSQL7() {
        Session session = HibernateUtil.getSession();
        try {
            session.beginTransaction();
            String sql = "select count(*) from t_student1";
            Object o = session.createSQLQuery(sql).uniqueResult();
            System.out.println(o);
            session.beginTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.beginTransaction().rollback();
        }
    }

2.HQL

	@Test
    public void testHQL7() {
        Session session = HibernateUtil.getSession();
        try {
            session.beginTransaction();
            String sql = "select count(*) from Student";
            Object o = session.createQuery(sql).uniqueResult();
            System.out.println(o);
            session.beginTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.beginTransaction().rollback();
        }
    }

3.QBC

	//Projection 中文意思:投影 Projections中包含很多聚合函数的静态方法
    @Test
    public void testQBC7() {
        Session session = HibernateUtil.getSession();
        try {
            session.beginTransaction();
            Object id = session.createCriteria(Student.class).setProjection(Projections.count("id")).uniqueResult();
            System.out.println(id);
            session.beginTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.beginTransaction().rollback();
        }
    }

投影查询

1.SQL

	//要求查询的字段别名要与实体类的属性名相同,这样才能将结果转换为相应类的对象
    @Test
    public void testSQL8() {
        Session session = HibernateUtil.getSession();
        session.beginTransaction();
        String sql = "select tname name,tage age from t_student1";
        List<Student> list = session.createSQLQuery(sql).setResultTransformer(Transformers.aliasToBean(Student.class)).list();
        //aliasToBean()方法首先创建一个空的Student对象,然后会将别名
        //与Student属性名对比,再用查询出的值初始化创建的Student对象
        for (Student student : list) {
            System.out.println(student.toString());
        }
        session.beginTransaction().commit();
    }

2.HQL

	//HQL查询要求实体类中具有相同投影作为参数的带参构造器,所以,首先要
    //在Student类中添加相应的带参构造器
    @Test
    public void testHQL8() {
        Session session = HibernateUtil.getSession();
        session.beginTransaction();
        String sql = "select new Student(name,age) from Student";
        List<Student> list = session.createQuery(sql).list();
        for (Student student : list) {
            System.out.println(student.toString());
        }
        session.beginTransaction().commit();
    }

3.QBC

	@Test
    public void testQBC8() {
        Session session = HibernateUtil.getSession();
        session.beginTransaction();
        //指定name和age属于为投影
        ProjectionList projectionList = Projections.projectionList()
                .add(Projections.alias(Projections.property("name"), "name"))
                .add(Projections.alias(Projections.property("age"), "age"));
        List<Student> list = session.createCriteria(Student.class).setProjection(projectionList)
                .setResultTransformer(Transformers.aliasToBean(Student.class)).list();
        //setResultTransformer()的方法参数Transformers.aliasToBean()会根据别名
        //自动创建指定类型对象
        for (Student student : list) {
            System.out.println(student.toString());
        }
        session.beginTransaction().commit();
    }

分组查询

1.SQL

	//实现查询所有年龄段,及人数多于1人的年龄段
    @Test
    public void testSQL9() {
        Session session = HibernateUtil.getSession();
        session.beginTransaction();
        String sql = "select tage from t_student1 group by tage";
        List<Object> list = session.createSQLQuery(sql).list();
        for (Object o : list) {
            System.out.println(o);
        }
        
        System.out.println("============");
        
        String sql1 = "select tage from t_student1 group by tage having count(tage)>?";
        List<Object> list1 = session.createSQLQuery(sql1).setParameter(0, 1).list();
        for (Object o : list1) {
            System.out.println(o);
        }

        session.beginTransaction().commit();
    }

2.HQL

	@Test
    public void testHQL9() {
        Session session = HibernateUtil.getSession();
        session.beginTransaction();
        String hql = "select age from Student group by age";
        List<Object> list = session.createQuery(hql).list();
        for (Object o : list) {
            System.out.println(o);
        }
        
        System.out.println("============");
        
        String hql1 = "select age from Student group by age having count(age)> ?";
        //此处有一个疑问setParameter无法使用
        List<Object> list1 = session.createQuery(hql1).setInteger(0, 1).list();
        for (Object o : list1) {
            System.out.println(o);
        }

        session.beginTransaction().commit();
    }

3.QBC

	@Test
    public void testQBC9() {
        //QBC不支持having
        Session session = HibernateUtil.getSession();
        session.beginTransaction();
        List<Object> age = session.createCriteria(Student.class).setProjection(Projections.groupProperty("age")).list();
        for (Object o : age) {
            System.out.println(o);
        }
        session.beginTransaction().commit();
    }

Query的list()和iterate()的区别

list和iterate的区别
使用Query接口的list()与iterate()进行查询,查看其控制台的SQL语句的输出情况,可以看到它们的区别主要有两点:
    1.使用list()会一次性将所有符合条件的记录查询出来,而使用iterate(),则会先查询出所有符合条件的记录的id,然后再根据id逐个查询出记录的具体内容。
    2.使用list(),不会使用缓存机制,即每次执行一次查询代码,控制天均会执行一次SQL查询语句,而使用iterate(),则会使用缓存机制,只有第一次会执行SQL查询,再往后的查询会直接从缓存中读取。

N+1问题
    使用Query的iterate()方法虽然使用了Hibernate 的缓存机制,但同时也出现了N+1问题在第一次查询出了所有满足条件的 id 后,会根据这些id逐条从缓存中进行详情查询。
    在逐条查询时,缓存中肯定没,然后会到 DB 中查询。在第二次查询时,仍会先执行一次满足条件的id的查询。
    然后再到缓存中根据id查询详情这就是N+1问题,N+1问题其实是指,与 list()查询相比多执行了多少次查询:
    多执行了N+1次。N次根据id所进行的查询,1次第二次进行的满足条件的id查询。

N+1问题的避免
    要避免N+1问题,就要保证缓存中有数据,这样即可以利用缓存,又可以避免N+1问题。
    所以,可以在第一次查询时使用 list(),而以后的查询则使用iterate()。

Query的list()查询

	@Test
    public void testHQL10_list() {
        Session session = HibernateUtil.getSession();
        session.beginTransaction();
        String hql = "from Student";
        //第一次查询
        List<Student> list = session.createQuery(hql).list();
        for (Student student : list) {
            System.out.println(student.toString());
        }
        //第二次查询
        List<Student> list1 = session.createQuery(hql).list();
        for (Student student : list1) {
            System.out.println(student.toString());
        }
        session.beginTransaction().commit();
    }

Query的iterate()查询

	@Test
    public void testHQL10_list_iterate() {
        Session session = HibernateUtil.getSession();
        session.beginTransaction();
        String hql = "from Student";
        //第一次查询
        Iterator<Student> list = session.createQuery(hql).iterate();
        while (list.hasNext()) {
            Student student = list.next();
            System.out.println(student.toString());
        }
        //第二次查询
        Iterator<Student> list1 = session.createQuery(hql).iterate();
        while (list1.hasNext()) {
            Student student = list1.next();
            System.out.println(student.toString());
        }
        session.beginTransaction().commit();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值