• Hibernate 之强大的HQL查询


    Hibernate  配备了一种非常强大的查询语言,这种语言看上去很像  SQL。但是不要被语法结构上的相似所迷惑,HQL  是非常有意识的被设计为完全面向对象的查询,它可以理解如继承、多态和关联之类的概念。

    基本规则

    1. HQL语法类似于SQL,也是一种select from结构的语句。但是他后面跟的不是表名和字段名,而是类名和属性名。
    2. HQL基本查询语法跟SQL很类似
    3. HQL大小写不敏感。但是,设计java类名、包名、属性名时大小写敏感。
    4. 包名的使用情况。比如:如果注册的实体类Emp只有一个类,那么查询时可以不加包名,hibernate会自动检索到Emp类。但是如果注册多个实体类,名字都叫Emp。此时就要增加包名来区别多个实体类。

    第一个HQL查询

     1  1 package com.qcf.test;
     2  2 
     3  3 import java.util.List;
     4  4 
     5  5 
     6  6 import org.hibernate.Query;
     7  7 import org.hibernate.Session;
     8  8 import org.hibernate.SessionFactory;
     9  9 import org.hibernate.Transaction;
    10 10 import org.hibernate.cfg.Configuration;
    11 11 
    12 12 import com.qcf.po.User;
    13 13 
    14 14 public class TestHiber {
    15 15     public static void main(String[] args) {
    16 16         //读取配置文件中的信息
    17 17         Configuration con=new Configuration().configure();
    18 18         //获取sessionFactory对象
    19 19         SessionFactory factory=con.buildSessionFactory();
    20 20         //获取Session对象
    21 21         Session session=factory.openSession();
    22 22         String hql="from User";
    23 23         //创建HQL查询
    24 24         Query query= session.createQuery(hql);
    25 25         List list=query.list();
    26 26         //对查询的结果进行遍历
    27 27         for (int i = 0; i < list.size(); i++) {
    28 28             User user=(User) list.get(i);
    29 29             System.out.println(user.getName());
    30 30         }
    31 31         
    32 32         session.close();
    33 33     }
    34 34 }
    View Code

    查询结果:

    根据返回类型划分HQL查询

      1、单个对象

      在这里提醒一下,这个hql意识统计数据库的记录数,一般我们都知道count(1) 要比count(*) 快多了,但是这里必须使用count(*) 使用count(1)就会报错!

     1 1 package com.qcf.test;
     2  2 
     3  3 import java.util.List;
     4  4 
     5  5 
     6  6 import org.hibernate.Query;
     7  7 import org.hibernate.Session;
     8  8 import org.hibernate.SessionFactory;
     9  9 import org.hibernate.Transaction;
    10 10 import org.hibernate.cfg.Configuration;
    11 11 
    12 12 import com.qcf.po.User;
    13 13 
    14 14 public class TestHiber {
    15 15     public static void main(String[] args) {
    16 16         //读取配置文件中的信息
    17 17         Configuration con=new Configuration().configure();
    18 18         //获取sessionFactory对象
    19 19         SessionFactory factory=con.buildSessionFactory();
    20 20         //获取Session对象
    21 21         Session session=factory.openSession();
    22 22         String hql="select count(*) from User";
    23 23         //创建HQL查询
    24 24         Query query= session.createQuery(hql);
    25 25         Number n=(Number) query.uniqueResult();
    26 26         System.out.println(n.intValue());
    27 27         
    28 28         session.close();
    29 29     }
    30 30 }
    View Code

    2、List集合

             参考第一个HQL查询中的内容!

      3、Object[]数组
      有时候,我们不需要讲实体类的所有属性查找出来,只需要查找部分属性。这时,可以将返回的内容放入Object[]中,而不是实体对象中。

    1 1 String hql="select u.name,u.age from User u";
    2 2         //创建HQL查询
    3 3         Query q= session.createQuery(hql);
    4 4         List<Object[]> list=q.list();
    5 5         for (int i = 0; i < list.size(); i++) {
    6 6             Object[] os=list.get(i);
    7 7             System.out.println("用户名是:"+os[0]+"年龄是:"+os[1]);
    8 8         }
    View Code

    显示结果:

      Hibernate: select user0_.username as col_0_0_, user0_.userage as col_1_0_ from user user0_
      用户名是:哈哈年龄是:18
      用户名是:三个年龄是:18
      用户名是:张三年龄是:18
      用户名是:李四年龄是:18
      用户名是:王五年龄是:18
      用户名是:张柳 年龄是:18

      4、Map集合

      我们也可以将查询后的结果放到map中

    1 1 String hql="select new map(u.name as name,u.age as age) from User u";
    2 2         //创建HQL查询
    3 3         Query q= session.createQuery(hql);
    4 4         List<Map> list=q.list();
    5 5         for (int i = 0; i < list.size(); i++) {
    6 6             Map map=list.get(i);
    7 7             System.out.println("用户名"+map.get("name")+"年龄"+map.get("age"));
    8 8         }
    9 9         session.close();
    View Code

    显示结果:

      Hibernate: select user0_.username as col_0_0_, user0_.userage as col_1_0_ from user user0_
      用户名哈哈年龄18
      用户名三个年龄18
      用户名张三年龄18
      用户名李四年龄18
      用户名王五年龄18
      用户名张柳 年龄18

      5、实体对象

      对于只查询部分属性的情况,Object数组、Map都很方便。实际上,我们也可以通过构造方法,将查出的数据直接封装到实体对象中。

     1  1     新增构造方法:
     2  2 public Emp(Short empno, String ename) {
     3  3         super();
     4  4         this.empno = empno;
     5  5         this.ename = ename;
     6  6 }
     7  7 String hql = "select new Emp(e.empno,e.ename) from Emp e ";
     8  8 Query q = session.createQuery(hql);
     9  9             
    10 10 List<Emp> list = q.list();
    11 11 for(int i=0;i<list.size();i++){
    12 12     Emp e = list.get(i);
    13 13     System.out.println("雇员编号:"+e.getEmpno()+"-雇员名字"+e.getEname()); 
    14 14 }
    View Code

    6、Where子句和参数传递

     1  1 //            String hql = "from Emp  where ename=?";
     2  2             String hql = "from Emp where ename=:ename";   //使用参数名称动态绑定!(推荐使用!)
     3  3             Query q = session.createQuery(hql);
     4  4 //            q.setString(0, "SMITH");   //参数索引从0开始计数,而不像jdbc一样从1开始。
     5  5             q.setString("ename", "SMITH");
     6  6             List list = q.list();
     7  7             for(int i=0;i<list.size();i++){
     8  8                 Emp c = (Emp) list.get(i);
     9  9                 System.out.println(c.getEname()); 
    10 10             }
    View Code

     7、HQL分页查询

      分页显示是项目中必不可少的功能,不同的数据库有不同的分页方式,hibernate替我们屏蔽了数据库中之间的差异。我们通过如下简单的代码即可实现分页功能(如果分页的原  理和做法忘记了,可以参考之前讲授的项目内容)。

     1  1     String hql = "from Emp";
     2  2             Query q = session.createQuery(hql);
     3  3             q.setFirstResult(0);   //从第几条开始取数据
     4  4             q.setMaxResults(10);  //设置每页最多显示记录的个数
     5  5             
     6  6             List list = q.list();
     7  7             for(int i=0;i<list.size();i++){
     8  8                 Emp c = (Emp) list.get(i);
     9  9                 System.out.println(c.getEname()); 
    10 10             }
    View Code

    8、跨表查询和对象导航

      

      SQL中复杂的表连接查询,跨表操作。在HQL中进行了相当的简化,我们只需要简单的使用属性即可,类似于我们前面学过的EL表达式。这样,我们可以用简单的代码写出比较  复杂的查询。

    1 1             String hql = "from Emp e where e.dept.deptno=? ";
    2 2             Query q = session.createQuery(hql);
    3 3             q.setInteger(0, 10);
    View Code

    9、Join(内连接、外连接)

             SQL中我们有内连接、右外连接、左外连接、全外连接,在HQL中我们也有这些概念。不过,有如下几点不一致:

    1. 如果两个实体类之间没有任何关系,那么不能使用join
    2. 由于只有两个实体类之间有关联关系才能使用join,因此不需要像SQL那样通过on指明连接条件。

      代码示例如下:

    1 1 String hql = "select e.ename,d.dname from Emp e left join e.dept d ";
    2 2 
    3 3 Query q = session.createQuery(hql);
    View Code

    10、SQL原生查询(Native SQL)

      

      有时候HQL可能不能满足我们的要求。我们需要使用原始的SQL来完成我们的功能。我们可以通过如下方式,在hibernate中使用SQL查询:

     1  1             String sql = "select ename,sal from emp where empno=:id";
     2  2             SQLQuery q = session.createSQLQuery(sql);
     3  3             q.setInteger("id", 7369);
     4  4             List list = q.list();  //返回的结果为List<Object[]>
     5  5             for(int i=0;i<list.size();i++){
     6  6                 Object[] c = (Object[]) list.get(i);
     7  7                 System.out.println(c[0]+"-"+c[1]); 
     8  8             }
     9  9             String sql = "select * from emp where empno=:id";
    10 10             SQLQuery q = session.createSQLQuery(sql);
    11 11             q.setInteger("id", 7369);
    12 12             q.addEntity(Emp.class);
    13 13             List<Emp> list = q.list();
    14 14             for(int i=0;i<list.size();i++){
    15 15                 Emp c = list.get(i);
    16 16                 System.out.println(c.getEname()+"-"+c.getSal()); 
    17 17             }
    View Code
  • 相关阅读:
    头部布局,搜索验证和AJAX自动搜索提示,并封装成组件,提高代码复用性
    yii2 使用指定数据库执行createCommand
    yii2在控制器中调用另一个控制器方法
    yii2 命令行执行php命令 commands(命令)
    ArrayDataProvider数据分页
    Yii2 数据查询
    Yii2的Gridview应用技巧补充
    yii2 or查询
    SQL---mysql新增字段
    Yii2.0 安装使用报错:yiiwebRequest::cookieValidationKey must be configured with a secret key.
  • 原文地址:https://www.cnblogs.com/linjiaxin/p/6034461.html
Copyright © 2020-2023  润新知