• Hibernate是DAO层技术,对数据的使用,查询是最为重要的。Hibernate的查询技术非常强大,支持原始SQL语句查询,支持QBC查询以及Hibernate特有的HQL查询。
  • HQL,Hibernate Query Language,Hibernate查询语言,它和SQL非常相似,但是,HQL是面向对象的查询语言,而SQL是面向二维表的。HQL查询语句中使用的是类名和属性名,而SQL语句使用的是表名和字段名。
  • 需要注意的是,在不使用类的别名的情况下,在HQL中直接使用字段名也是可以通过的。但是若使用“类别名.属性名"的形式,则不能够使用字段名。
  • QBC,Query By Criteria,标准查询,一种比HQL更为面向对象的查询方法。

    1 API

    1.1 Query接口

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

    1.2 SQLQuery接口

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

    1.3 Criteria接口

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

    2 分类查询

    2.1 查询测试前的准备工作

    2.1.1 定义查询的实体

  • 下面查询举例,均是对实体类Student进行操作,其映射关系如下:

    
    
    
    
        
            
        
        
        
        
    
    

    2.1.2 定义主配置文件

    
        
        com.mysql.jdbc.Driver
        jdbc:mysql://localhost:3306/test
        root
        02000059
    
        org.hibernate.dialect.MySQL5Dialect
        thread
        update
        true
        true   
        
    

    2.1.3 定义Hibernate工具类

    public class HbnUtils {
        private static SessionFactory sessionFactory;
        public static Session getSession() {
            return getSessionFactory().getCurrentSession();
        }
    
        private static SessionFactory getSessionFactory() {
            if(sessionFactory == null || sessionFactory.isClosed()) {
                sessionFactory = new Configuration().configure().buildSessionFactory();
            }
            return sessionFactory;
        }
    }

    2.1.4 定义测试类的setUp()

  • 创建好测试类MyTest后,完成初始化方法setUp():
    public class MyTest {
    private Session session;
    @Before
    public void setUp() {
        session = HbnUtils.getSession();
    }
    }

    2.1.5 准备测试数据

    //完成数据插入
    @Test
    public void test00() {
        try {
            session.beginTransaction();
            for(int i = 0; i < 10; i ++) {
                Student student = new Student("n_" + i, 15 +i , 75 + i);
                session.save(student);
            }
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }
    }

    2.2 查询所有

  • 查询所有的特点是,其查询结果为List集合。

    2.2.1 SQL查询

    //使用SQLQuery查询所有
    @Test
    public void test02_SQL() {
        try {
            session.beginTransaction();
            String sql = "select * from t_student";
            List students = session.createSQLQuery(sql).addEntity(Student.class).list();
            for(Student student : students) {
                System.out.println(student);
            }
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }
    }

    2.2.2 HQL查询

    //使用HQL查询所有
    @Test
    public void test02_HQL() {
        try {
            session.beginTransaction();
            String hql = "from Student";
            List students = session.createQuery(hql).list();
            for(Student student : students) {
                System.out.println(student);
            }
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }
    }

    2.2.3 QBC查询

    //使用QBC查询所有
    @Test
    public void test02_QBC() {
        try {
            session.beginTransaction();
            List students = session.createCriteria(Student.class).list();
            for(Student student : students) {
                System.out.println(student);
            }
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }
    }

    2.3 查询结果排序

  • 排序,即order by,asc表示升序,desc表示降序。

    2.3.1 SQL查询

    //使用SQLQuery查询所有,并排序
    @Test
    public void test03_SQL() {
        try {
            session.beginTransaction();
            String sql = "select * from t_student order by sscore desc";
    
            List students = session.createSQLQuery(sql).addEntity(Student.class).list();
            for(Student student : students) {
                System.out.println(student);
            }
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }
    }

    2.3.2 HQL查询

    //使用HQL查询所有,并排序
    @Test
    public void test03_HQL() {
        try {
            session.beginTransaction();
            String hql = "from Student order by score desc";
    
            List students = session.createQuery(hql).list();
            for(Student student : students) {
                System.out.println(student);
            }
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }
    }

    2.3.3 QBC查询

  • 通过addOrder()方法可以向Criteria对象添加排序功能。Order类有两个静态方法desc()和asc(),分别用于降序和升序功能,它们的参数为排序属性名,注意非字段名。
    //使用QBC查询所有,并排序
    @Test
    public void test03_QBC() {
        try {
            session.beginTransaction();
            List students = session.createCriteria(Student.class).addOrder(Order.desc("score")).list();
            for(Student student : students) {
                System.out.println(student);
            }
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }
    }

    2.4 动态参数绑定查询

  • 动态参数绑定查询,即参数的值是由代码传递来的,而非固定在查询中。

    2.4.1 SQL查询

  • 方式一:使用”?"占位符占位,setXxx()方法绑定参数:setXxx(int position, Object value)。方法名中的Xxx表示该位置参数的类型。position表示第几个占位符,从0开始计数。
        //使用SQLQuery查询年龄大于20岁,成绩小于98分的学生
        @Test
        public void test04_SQL_setXxx() {
            try {
                session.beginTransaction();
                String sql = "select * from t_student where sage > ? and sscore < ?";
                List students = session.createSQLQuery(sql)
                        .addEntity(Student.class).setInteger(0, 20).setDouble(1, 98).list();
                for(Student student : students) {
                    System.out.println(student);
                }
                session.getTransaction().commit();
            } catch (Exception e) {
                e.printStackTrace();
                session.getTransaction().rollback();
            }
        }
  • 方式二:使用别名占位,setXxx()绑定参数:setXxx (String name, Object value)。别名的命名规则为:冒号后跟别名,别名可以是任意名称。
    //使用SQLQuery查询年龄大于20岁,成绩小于98分的学生
    @Test
    public void test04_SQL_setXxx2() {
        try {
            session.beginTransaction();
            String sql = "select * from t_student where sage > :tage and sscore < :tscore";
            List students = session.createSQLQuery(sql)
                    .addEntity(Student.class).setInteger("tage", 20).setDouble("tscore", 98).list();
            for(Student student : students) {
                System.out.println(student);
            }
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }
    }
  • 方式三:使用“?”占位符占位,setParameter()绑定参数:SetParameter(int position, Object value)。position表示第几个占位符,从0开始计数。
    //使用SQLQuery查询年龄大于20岁,成绩小于98分的学生
    @Test
    public void test04_SQL_setParameter() {
        try {
            session.beginTransaction();
            String sql = "select * from t_student where sage > ? and sscore < ?";
            List students = session.createSQLQuery(sql)
                    .addEntity(Student.class).setParameter(0, 20).setParameter(1, 98).list();
            for(Student student : students) {
                System.out.println(student);
            }
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }
    }
  • 方式四:使用别名占位,setParameter()绑定参数:SetParameter(String name, Object value)。别名的命名规则为:冒号后跟别名,别名可以是任意名称。
    //使用SQLQuery查询年龄大于20岁,成绩小于98分的学生
    @Test
    public void test04_SQL_setParameter2() {
        try {
            session.beginTransaction();
            String sql = "select * from t_student where sage > :tage and sscore < :tscore";
            List students = session.createSQLQuery(sql)
                    .addEntity(Student.class).setParameter("tage", 20).setParameter("tscore", 98).list();
            for(Student student : students) {
                System.out.println(student);
            }
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }
    }

    2.4.2 HQL查询

  • 使用HQL查询时,以上四种为动态参数赋值的方式均可成立,其用法相同。
    //使用HQL查询年龄大于20岁,成绩小于98分的学生
    @Test
    public void test04_HQL() {
        try {
            session.beginTransaction();
            String hql = "from Student where sage > :tage and sscore < :tscore";
            List students = session.createQuery(hql)
                    .setParameter("tage", 20).setParameter("tscore", 98).list();
            for(Student student : students) {
                System.out.println(student);
            }
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }
    }

    2.4.3 QBC查询

  • 需要向Criteria对象添加限制条件Restrictions,即添加查询条件。(Restriction,中文意思:限制,约束。)Restrictions具有很多静态方法可用于表示关系比较。
  • 注意double类型数据的写法。

    //使用QBC查询年龄大于20岁,成绩小于98分的学生
    @Test
    public void test04_QBC() {
        try {
            session.beginTransaction();
            List students = session.createCriteria(Student.class)
                    .add(Restrictions.gt("age", 20))
                     //需要注意,这里不能够写成98
                    .add(Restrictions.lt("score", 98.0)).list();
    
            for(Student student : students) {
                System.out.println(student);
            }
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }
    }

    2.5 分页查询

  • 分页查询的SQL语句:select * from … where …limit startIndex, pageSize。
  • 其中,startIndex为开始索引,设置从总查询结果集的第几条记录作为本查询结果子集的开始,即本页的开始。总查询结果集从0开始计数。pageSize为该页所包含的记录数。

    2.5.1 SQL查询

    //使用SQLQuery查询出所有学生中从第4条开始的5名学生信息
    @Test
    public void test05_SQL() {
        try {
            session.beginTransaction();
            String sql = "select * from t_student limit ?, ?";
            List students = session.createSQLQuery(sql)
                    .addEntity(Student.class).setParameter(0, 3).setParameter(1, 5).list();
            for(Student student : students) {
                System.out.println(student);
            }
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }
    }

    2.5.2 HQL查询

  • Query接口中具有setFirstResult()方法,用于设置从总查询结果集的第几条记录作为本查询结果子集的开始,即本页的开始。总查询结果集从0开始计数。而setMaxResults()方法用于设置该页所包含的记录数。
    //使用HQL查询出所有学生中从第4条开始的5名学生信息
    @Test
    public void test5_HQL() {
        try {
            session.beginTransaction();
            String hql = "from Student";
            List students = session.createQuery(hql)
                    .setFirstResult(3).setMaxResults(5).list();
            for(Student student : students) {
                System.out.println(student);
            }
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }
    }

    2.5.3 QBC查询

  • Criteria接口中也有setFirstResult()与setMaxResults()方法,其用法与意义和Query接口中的完全相同。由于Criteria与Query接口无关,所以这两组完全相同的方法也是没有关系的,仅仅是用法和写法上得相同而已。
    //使用QBC查询出所有学生中从第4条开始的5名学生信息
    @Test
    public void test05_QBC() {
        try {
            session.beginTransaction();
            List students = session.createCriteria(Student.class)
                    .setFirstResult(3).setMaxResults(5).list();
            for(Student student : students) {
                System.out.println(student);
            }
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }
    }

    2.6 模糊查询

    2.6.1 SQL查询

    //使用SQLQuery查询出所有姓名中包含字符n的学生
    @Test
    public void test06_SQL() {
        try {
            session.beginTransaction();
            String sql = "select * from t_student where sname like :tname";
            List students = session.createSQLQuery(sql)
                    .addEntity(Student.class).setParameter("tname", "%n%")
                    .list();
            for(Student student : students) {
                System.out.println(student);
            }
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }
    }

    2.6.2 HQL查询

    //使用HQL查询出所有姓名中包含字符n的学生
    @Test
    public void test06_HQL() {
        try {
            session.beginTransaction();
            String hql = "from Student where name like :tname";
            List students = session.createQuery(hql)
                    .setParameter("tname", "%n%")
                    .list();
            for(Student student : students) {
                System.out.println(student);
            }
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }
    }

    2.6.3 QBC查询

    //使用QBC查询出所有姓名中包含字符n的学生
    @Test
    public void test06_QBC() {
        try {
            session.beginTransaction();
            List students = session.createCriteria(Student.class)
                    .add(Restrictions.like("name", "%n%")).list();
            for(Student student : students) {
                System.out.println(student);
            }
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }
    }

    2.7 唯一性查询

    2.7.1 SQL查询

  • SQLQuery接口的uniqueResult()方法表示其查询结果为一条数据,其返回值为Object。
    //使用SQLQuery查询id为5的学生
    @Test
    public void test07_SQL() {
        try {
            session.beginTransaction();
            String sql = "select * from t_student where sid = ?";
            Student student = (Student) session.createSQLQuery(sql)
                    .addEntity(Student.class).setInteger(0, 5).uniqueResult();
            System.out.println(student);
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }
    }

    2.7.2 HQL查询

    //使用HQL查询id为5的学生
    @Test
    public void test07_HQL() {
        try {
            session.beginTransaction();
            String hql = "from Student where id = ?";
            Student student = (Student) session.createQuery(hql)
                    .setInteger(0, 5).uniqueResult();
            System.out.println(student);
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }
    }

    2.7.3 QBC查询

    //使用QBC查询id为5的学生
    @Test
    public void test07_QBC() {
        try {
            session.beginTransaction();
            Student student = (Student) session.createCriteria(Student.class)
                    .add(Restrictions.eq("id", 5)).uniqueResult();
            System.out.println(student);
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }
    }

    2.8 聚合函数查询

    2.8.1 SQL查询

  • 注意区分count()与count(name)的不同。count()与count(id)等价,均表示未空记录数,而count(name)则表示字段name的非空记录数。

    //查询记录总数以及姓名非空的记录数
    @Test
    public void test08_SQL() {
        try {
            session.beginTransaction();
            String sql1 = "select count(*) from t_student";
            Object total1 = session.createSQLQuery(sql1).uniqueResult();
            System.out.println(total1);
            String sql2 = "select count(sname) from t_student";
            Object total2 = session.createSQLQuery(sql2).uniqueResult();
            System.out.println(total2);
    
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }
    }

    2.8.2 HQL查询

    //查询记录总数以及姓名非空的记录数
    @Test
    public void test08_HQL() {
        try {
            session.beginTransaction();
            String hql1 = "select count(*) from Student";
            Object total1 = session.createQuery(hql1).uniqueResult();
            System.out.println(total1);
            String hql2 = "select count(sname) from Student";
            Object total2 = session.createQuery(hql2).uniqueResult();
            System.out.println(total2);
    
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }
    }

    2.8.3 QBC查询

  • Projection,中文意思:投影。Projection中包含很多聚合函数的静态方法。

    //查询记录总数以及姓名非空的记录数
    @Test
    public void test08_QBC() {
        try {
            session.beginTransaction();
            Object total1 = session.createCriteria(Student.class)
                    .setProjection(Projections.count("id")).uniqueResult();
            System.out.println(total1);
    
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }
    }

    2.9 投影查询

    2.9.1 SQL查询

  • 要求查询的字段的别名要与实体类的属性名相同,这样才能将结果转换为相应类的对象。
    //使用SQLQuery查询所有学生的姓名与年龄
    @Test
    public void test09_SQL() {
        try {
            session.beginTransaction();
            String sql = "select sname name, sage age from t_student";
            List students = session.createSQLQuery(sql)
                    .setResultTransformer(Transformers.aliasToBean(Student.class)).list();
            for(Student student: students) {
                System.out.println(student);
            }
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }
    }
  • aliasToBean()方法首先会创建一个空的Student对象,然后会将别名和Student属性名对比,再用查询出的值初始化创建的Student对象。

    2.9.2 HQL查询

  • 该查询要求实体类中具有相同投影作为参数的带参构造器。所以,首先要在Student类中添加相应的带参构造器。
    public Student(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
    //使用HQL查询所有学生的姓名与年龄
    @Test
    public void test09_HQL() {
        try {
            session.beginTransaction();
            String hql = "select new Student(name, age) from Student";
            List students = session.createQuery(hql).list();
            for(Student student: students) {
                System.out.println(student);
            }
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }
    }

    2.10 分组查询

    2.10.1 SQL查询

  • having,对分组结果进行筛选。下面代码实现的功能是,查询出所有年龄段,以及人数多于1人的年龄段。
    //查询出所有的年龄段,以及人数大于1人的年龄段
    @Test
    public void test10_SQL() {
        try {
            session.beginTransaction();
            String sql = "select sage from t_student group by sage";
            List result1 = session.createSQLQuery(sql).list();
            for(Object object: result1) {
                System.out.println(object);
            }       
            System.out.println("------------------");
            String sql2 = "select sage from t_student group by sage having count(sage) > ?";
            List result2 = session.createSQLQuery(sql2).setInteger(0, 1).list();
            for(Object object: result2) {
                System.out.println(object);
            }       
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }
    } 

    2.9.2 HQL查询

    //查询出所有的年龄段,以及人数大于1人的年龄段
    @Test
    public void test10_HQL() {
        try {
            session.beginTransaction();
            String hql1 = "select age from Student group by age";
            List result1 = session.createQuery(hql1).list();
            for(Object object: result1) {
                System.out.println(object);
            }       
            System.out.println("------------------");
            String hql2 = "select age from Student group by age having count(age) > ?";
            List result2 = session.createQuery(hql2).setInteger(0, 1).list();
            for(Object object: result2) {
                System.out.println(object);
            }       
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }
    } 

    2.9.3 QBC查询

  • Hibernate不直接支持having操作。

    //查询出所有的年龄段
    @Test
    public void test10_QBC() {
        try {
            session.beginTransaction();
            List result1 = session.createCriteria(Student.class).
                    setProjection(Projections.groupProperty("age")).list();
            for(Object object: result1) {
                System.out.println(object);
            }       
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }
    } 

    2.11 Query的list()与iterator()

    2.11.1 Query的list()查询

    //使用Query的list()查询所有
    @Test
    public void test11_HQL_list() {
        try {
            session.beginTransaction();
            String hql = "from Student";
    
            //第一次查询
            List students1 = session.createQuery(hql).list();
            for(Student student : students1) {
                System.out.println(student);
            }
            //第二次查询
            List students2 = session.createQuery(hql).list();
            for(Student student : students2) {
                System.out.println(student);
            }
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }
    }

    2.10.2 Query的iterate()查询

    //使用Query的iterate()查询所有
    @Test
    public void test11_HQL_list_iterate() {
        try {
            session.beginTransaction();
            String hql = "from Student";
    
            //第一次查询
            Iterator it1 = session.createQuery(hql).iterate();
            while(it1.hasNext()) {
                Student student = it1.next();
                System.out.println(student);
            }
            //第二次查询
            Iterator it2 = session.createQuery(hql).iterate();
            while(it2.hasNext()) {
                Student student = it2.next();
                System.out.println(student);
            }
    
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }
    }

    2.10.3 Query的list()与iterator()的区别

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

    2.10.4 N + 1问题

  • 使用Query的iterate()方法虽然使用了Hibernate的缓存机制,但是同时也出现了N+1问题。
  • 所谓N+1问题是指,从查询出有效数据角度来说,若要查询符合某条件的对象时,使用list(),则一次性即可查询出所有。而若使用iterate(),则会先查询出所有满足条件的对象的id,然后再逐个id进行select查询,即需要经过N+1次才能得出有效结果。这就是N+1问题。

    2.10.5 N + 1问题的避免

  • 若想要使用Hibernate缓存,即使用iterate()方法,还想要避免N + 1问题,就要保证在执行iterate()时,缓存中已经有数据,这样既可利用缓存,有可以避免N+1问题。所以,可以在第一次查询时使用list(),而以后的查询则使用iterate()。

    //N + 1问题的避免
    @Test
    public void test11_HQL_list_iterate() {
        try {
            session.beginTransaction();
            String hql = "from Student";
    
            //第一次查询
            List students = session.createQuery(hql).list();
            for(Student student : students) {
                System.out.println(student);
            }
            //第二次查询
            Iterator it2 = session.createQuery(hql).iterate();
            while(it2.hasNext()) {
                Student student = it2.next();
                System.out.println(student);
            }
    
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }
    }

    SSH框架之Hibernate5专题3:单表查询_第1张图片

    2.12 命名查询namedQuery

  • 所谓namedQuery,是指HQL语句不直接写在Java代码中,而写入到映射文件。Java代码从映射文件中将被命名的HQL,通过名称读出执行。
  • 将HQL写入到配置文件中的好处是,在项目真正上线后,若只需要修改HQL就可进行检索优化,则需修改配置文件中的HQL后,重启服务器即可,无需再次编译项目。
  • 在映射文件中通过通过命名定义HQL,该标签写到哪个映射文件均可。
    from Student where id = ?
  • java代码中通过Sesion的getNamedQuery()方法可以将映射文件中指定的HQL读取出来。

    //命名查询
    @Test
    public void test12() {
        try {
            session.beginTransaction();
            Student student = (Student) session.getNamedQuery("queryById").setInteger(0, 5).uniqueResult();
            System.out.println(student);
    
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }
    }
  • 你可能感兴趣的:(Query接口,SQLQuery接口,Criteria接口,javaFrame)