hql查询代码实例

Hibernate hql查询代码实例,hibernatehql

本文研究的主要是Hibernate hql查询的相关内容,具体如下。

       HQL(Hibernate QueryLanguage) 是面向对象的查询语言,它和SQL查询语言有些相似。

HQL介绍

Hibernate语言查询(Hibernate Query Language,HQL)它是完全面向对象的查询语句,查询功能非常强大;具备多态、关联等特性,HQL查询也是Hibernate官方推荐使用的查询方法。

下面我们通过一个案例我分析相关查询方法

Classes.java:

public class Classes {
 /*班级ID*/
 private int id;
 /*班级名称*/
 private String name;
 /*班级和学生的关系*/
 private Set<Student> students;
 //省略setter和getter方法
}

Student.java:

public class Student {
 /*学生ID*/
 private int id;
 /*学生姓名*/
 private String name;
 /*学生和班级的关系*/
 private Classes classes;
 //省略setter和getter方法
}

Classes.hbm.xml:

<?xml version="1.0"?> 
<!DOCTYPE hibernate-mapping PUBLIC  
  "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 
  "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 
<hibernate-mapping package="com.lixue.bean"> 
  <!-- 设置lazy为false --> 
  <class name="Classes" table="t_classes" lazy="false"> 
    <id name="id"> 
      <generator class="native"/> 
    </id> 
    <property name="name"/> 
    <!-- 一对多映射 ,inverse="true"表示交给对端维护关系--> 
    <set name="students" inverse="true"> 
       <key column="classesid"/> 
      <one-to-many class="Student"/> 
    </set> 
  </class> 
</hibernate-mapping> 

Student.hbm.xml:

<?xml version="1.0"?> 
<!DOCTYPE hibernate-mapping PUBLIC  
  "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 
  "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 
<hibernate-mapping package="com.lixue.bean"> 
  <class name="Student" table="t_student"> 
    <id name="id"> 
      <generator class="native"/> 
    </id> 
    <!-- 映射普通属性 --> 
    <property name="name"/> 
    <!-- 多对一 映射,在多的一端加上外键--> 
    <many-to-one name="classes" column="classesid"/> 
  </class> 
</hibernate-mapping> 

 

1.查询单一属性:

/*返回结果集属性列表,元素类型和实体类中的属性类型一致*/ 
      List<String> students = session.createQuery("select name from Student").list(); 
      /*遍历*/ 
      for (Iterator<String> iter=students.iterator(); iter.hasNext();) { 
        String name = (String)iter.next(); 
        System.out.println(name); 
      } 

注:查询单一属性的时候,返回的是一个集合,集合元素的类型是该属性的类型。

1、Select/update/delete…… from …… where …… group by …… having ……order by …… asc/desc

2.查询多个属性,返回对象数组:

/*查询多个属性,返回的是对象数组*/ 
      List<Object[]> students = session.createQuery("select id, name from Student").list(); 
      /*遍历*/ 
      for (Iterator<Object[]> iter=students.iterator(); iter.hasNext();) { 
        Object[] obj = (Object[])iter.next(); 
        System.out.println(obj[0] + ", " + obj[1]); 
      } 

注:查询多个属性返回的是一个类型为对象数组的集合,这个很好理解,当查询单一属性是返回的集合元素类型就是属性的类型,但是多个类型呢?那必须是对象数组来处理啊即Object[]。

2、select语句

3.查询多个属性,返回对象类型的集合:

/*我们给实体对象设置对应的构造函数,然后通过查询对象的方式就可以返回一个实体对象类型的集合*/ 
      List students = session.createQuery("select new Student(id, name) from Student").list(); 
      /*遍历*/ 
      for (Iterator iter=students.iterator(); iter.hasNext();) { 
        Student student = (Student)iter.next(); 
        System.out.println(student.getId() + ", " + student.getName()); 
      } 

注:除了我们第二种方式返回的是一个对象数组,我们还可以给实体对象设置对应的构造函数,然后通过查询对象的方式进行查询,然后返回的就是实体类型的集合。

1、查询出来整个映射对象

4.使用别名进行查询:

/*可以使用别名*/ 
      List<Object[]> students = session.createQuery("select s.id, s.name from Student s").list(); 
      /*遍历*/ 
      for (Iterator<Object[]> iter=students.iterator(); iter.hasNext();) { 
        Object[] obj = (Object[])iter.next(); 
        System.out.println(obj[0] + ", " + obj[1]); 
      } 

        String hql = "from Users";  

5.查询实体对象:

/*返回的是实体对象类型的集合*/ 
      List<Student> students = session.createQuery("from Student").list(); 
      /*遍历*/ 
      for (Iterator<Student> iter=students.iterator(); iter.hasNext();) { 
        Student student = (Student)iter.next(); 
        System.out.println(student.getName()); 
      }

注:查询实体可以直接使用from 类名的形式。

/*使用select就必须使用别名*/ 
      List<Student> students = session.createQuery("select s from Student s").list(); 
      /*遍历*/ 
      for (Iterator<Student> iter=students.iterator(); iter.hasNext();) { 
        Student student = (Student)iter.next(); 
        System.out.println(student.getName()); 
      }

注:如果要使用select关键字,那么就必须使用别名。另外一点千万要注意:hql不支select * 的形式。

        Query query = session.createQuery(hql);  

6.N+1问题:

/** 
       * 采用list查询实体对象会发出一条查询语句,取得实体对象数据 
       * 
       * Hibernate: select student0_.id as id0_, student0_.name as name0_, 
       * student0_.createTime as createTime0_, student0_.classesid as classesid0_ 
       * from t_student student0_ 
       */ 
      List<Student> students = session.createQuery("from Student").list(); 
      /*遍历*/ 
      for (Iterator<Student> iter=students.iterator(); iter.hasNext();) { 
        Student student = (Student)iter.next(); 
        System.out.println(student.getName()); 
      }

注:使用.list()的方式进行对象查询,只会发出一条语句,即取得实体对象数据的语句。

/** 
       * 会出现N+1问题,所谓的N+1指的是发出了N+1条sql语句 
       * 
       * 1:发出一条查询id列表的语句 
       * Hibernate: select student0_.id as col_0_0_ from t_student student0_ 
       * 
       * N:根据id发出N条sql语句,加载相关的对象 
       * Hibernate: select student0_.id as id0_0_, student0_.name as name0_0_, 
       * student0_.createTime as createTime0_0_, student0_.classesid as classesid0_0_ 
       * from t_student student0_ where student0_.id=? 
       * 
       */ 
      Iterator<Student> iter = session.createQuery("from Student").iterate(); 
      /*遍历*/ 
      while (iter.hasNext()) { 
        Student student = (Student)iter.next(); 
        System.out.println(student.getName()); 
      } 

注:通过iterator()方式进行对象查询,会发出N+1条语句,首先会发出一条语句查询出实体对象的ID,然后在根据各自的ID发出N条语句去查询N个对象,这中形式性能是比较差的。

/*通过List查询把查询出的集合存放在一级缓存即session级缓存中*/ 
      List<Student> students = session.createQuery("from Student").list(); 
      /*遍历*/ 
      for (Iterator<Student> iter=students.iterator(); iter.hasNext();) { 
        Student student = (Student)iter.next(); 
        System.out.println(student.getName()); 
      } 
      System.out.println("-----------------------------------------------------"); 
      /** 
       * 避免了N+1问题 
       * 
       * 因为执行list操作后会将数据放到session的缓存中(一级缓存),所以采用iterate的时候 
       * 首先会发出一条查询id列表的语句,再根据id到缓存中加载相应的数据,如果缓存中存在与之匹配的数据 
       * 则不再发出根据id查询的sql语句,直接使用缓存中的数据 
       * 
       * Iterate方法如果缓存中存在数据,它可以提高性能,否则出现N+1问题 
       * 
       */ 
      Iterator<Student> iter = session.createQuery("from Student").iterate(); 
      /*遍历*/ 
      while (iter.hasNext()) { 
        Student student = (Student)iter.next(); 
        System.out.println(student.getName()); 
      } 

注:其实Hibernate提供iterator()的方式查询是为了提高性能的,那为什么反而帮了倒忙呢?原因是iterator()是从一级缓存中取数据的,如果缓存中有数据,那么它的效率毫无疑问会相当的给力,但是当我第一次查询的时候缓存中怎么可能会有数据呢,所以就导致了所谓的N+1问题。上面这段代码可以避免N+1问题,它的思路是先用list()进行查询,因为list()查询出来以后,在一级缓存汇总就存在了数据,使用iterator()的时候,效率就会非常的高。

        List<Users> users = query.list();  

7.条件查询:

/*根据条件进行查询(这里通常都使用别名,比较方便 )*/ 
      List<Object[]> students = session.createQuery("select s.id, s.name from Student s where s.name like '%0%'").list(); 
      /*遍历*/ 
      for (Iterator<Object[]> iter=students.iterator(); iter.hasNext();) { 
        Object[] obj = (Object[])iter.next(); 
        System.out.println(obj[0] + ", " + obj[1]); 
      }

注:条件查询和原生的sql相同,都是where关键字。另外通常使用别名比较方便,上述程序是查询多个属性,所以返回的是对象数组类型的集合,对象数组中的元素就是对应的属性。

 

8.占位符的形式查询:

/*链式编程*/ 
      List<Object[]> students = session.createQuery("select s.id, s.name from Student s where s.name like ?") 
          .setParameter(0, "%0%") 
          .list(); 
      /*遍历*/ 
      for (Iterator<Object[]> iter=students.iterator(); iter.hasNext();) { 
        Object[] obj = (Object[])iter.next(); 
        System.out.println(obj[0] + ", " + obj[1]); 
      } 

注:可以通过占位符的形式进行传参,这种方式可以防止SQL注入。

2、查询对应的字段

9.自定义参数的形式:

/*链式编程*/ 
      List<Object[]> students = session.createQuery("select s.id, s.name from Student s where s.name like :myname") 
          .setParameter("myname", "%0%") 
          .list(); 
      /*对象数组*/ 
      for (Iterator<Object[]> iter=students.iterator(); iter.hasNext();) { 
        Object[] obj = (Object[])iter.next(); 
        System.out.println(obj[0] + ", " + obj[1]); 
      } 

注:like :myname冒号后面是没有空格的,否则会出错。

        //查询其中几个字段  

10.查询条件为in的形式:

[java] view plain copy
/*采用in的方式,形参只要一个即可*/ 
      List<Object[]> students = session.createQuery("select s.id, s.name from Student s where s.id in(:ids)") 
          .setParameterList("ids", new Object[]{1, 2, 3, 4, 5}) 
          .list(); 
      /*遍历*/ 
      for (Iterator<Object[]> iter=students.iterator(); iter.hasNext();) { 
        Object[] obj = (Object[])iter.next(); 
        System.out.println(obj[0] + ", " + obj[1]); 
      }

注:in后面的括号中只要有一个形参即可,我们设置参数值的时候,可以通过对象数组就行传值。

        String hql = " select name,passwd from Users";  

11.使用数据库个性化函数:

/*查询2009-08的学生,可以调用mysql的日期格式化函数*/ 
      List<Object[]> students = session.createQuery("select s.id, s.name from Student s where date_format(s.createTime, '%Y-%m')=?") 
          .setParameter(0, "2009-08") 
          .list(); 
      /*遍历*/ 
      for (Iterator<Object[]> iter=students.iterator(); iter.hasNext();) { 
        Object[] obj = (Object[])iter.next(); 
        System.out.println(obj[0] + ", " + obj[1]); 
      } 

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
      /*查询2009-08-01 到2009-08-20的学生,可以调用mysql的日期格式化函数*/ 
      List<Object[]> students = session.createQuery("select s.id, s.name from Student s where s.createTime between ? and ?") 
          .setParameter(0, sdf.parse("2009-08-01 00:00:00")) 
          .setParameter(1, sdf.parse("2009-08-20 23:59:59")) 
          .list(); 
      /*遍历*/ 
      for (Iterator<Object[]> iter=students.iterator(); iter.hasNext();) { 
        Object[] obj = (Object[])iter.next(); 
        System.out.println(obj[0] + ", " + obj[1]); 
      }

        Query query = session.createQuery(hql);  

12.使用原生态的SQL语句:

/*使用select * 必须使用原生态的SQL语句,另外它类似于hql查询多个属性,所以返回的是一个对象数组类型的集合*/ 
      List<Object[]> students = session.createSQLQuery("select * from t_student").list(); 
      /*遍历*/ 
      for (Iterator<Object[]> iter = students.iterator(); iter.hasNext();) { 
        Object[] obj = (Object[]) iter.next(); 
        System.out.println(obj[0] + ", " + obj[1]); 
      }

注:hql不支持select * 的查询形式,但是Hibernate支持原生态的SQL语句,我们可以利用SQL语句进行查询,另外它类似于HQL的查询多个属性,所以返回的是一个对象数组类型的集合。

        //默认查询出来的list里存放的是一个Object数组  

13.分页查询

/*分页查询,setFirstResult(1)表示从第一条数据开始查询;setMaxResult(2)表示每页显示2条数据*/ 
      List students = session.createQuery("from Student") 
            .setFirstResult(1) 
            .setMaxResults(2) 
            .list(); 
      /*遍历*/ 
      for (Iterator iter=students.iterator(); iter.hasNext();) { 
        Student student = (Student)iter.next(); 
        System.out.println(student.getName()); 
      } 

        List<Object[]> list = query.list();

14.导航查询

/*导航查询,s.classes.name从学生导航到班级在导航到班级名称(这是从多的一端导航到少的一端,反过来也可以)*/ 
      List<Student> students = session.createQuery("from Student s where s.classes.name like '%2%'") 
            .list(); 
      /*遍历*/ 
      for (Iterator<Student> iter=students.iterator(); iter.hasNext();) { 
        Student student = (Student)iter.next(); 
        System.out.println(student.getName()); 
      }

注:上述查询语句中的s.classes.name是从学生导航到班级classes在获取班级的名称name。也可以反过来导航:从班级导航到学生在得到某个属性。另外程序中查询语句的意思是要查询班级名称中含有2的所有学生。

 

15.内连接查询

/*内连接,使用join关键字即可*/ 
    List<Object[]> students = session.createQuery("select c.name, s.name from Student s join s.classes c") 
          .list(); 
    /*遍历*/ 
    for (Iterator<Object[]> iter=students.iterator(); iter.hasNext();) { 
      Object[] obj = (Object[])iter.next(); 
      System.out.println(obj[0] + ", " + obj[1]); 
    } 

注:内连接关键字为join,另外还是用了别名和导航进行连接。上述查询语句的意思为:从学生表和班级表中查询中班级名称和学生名称(内连接是查询出必须有值得属性,比如没有班级没有学生或者学生没有班级是查询不出来的)。

3、修改默认查询结果(query.list())不以Object[]数组形式返回,以List形式返回

16.左连接

/*左连接使用关键字left join*/ 
      List<Object[]> students = session.createQuery("select c.name, s.name from Student s left join s.classes c") 
            .list(); 
      /*遍历*/ 
      for (Iterator<Object[]> iter=students.iterator(); iter.hasNext();) { 
        Object[] obj = (Object[])iter.next(); 
        System.out.println(obj[0] + ", " + obj[1]); 
      }

注:使用左连接的关键字为left join。上述查询语句的意思为:从学生和班级表中,查询出班级名称和学生名称,因为是左连接,所以没有班级的学生也会被查询出来。

        //查询其中几个字段,添加new list(),注意list里的l是小写的。也不需要导入包,这样通过query.list()出来的list里存放的不再是默认的Object数组了,而是List集合了 

17.右连接

[java] view plain copy
/*右连接关键字为right join*/ 
      List<Object[]> students = session.createQuery("select c.name, s.name from Student s right join s.classes c") 
            .list(); 
      /*遍历*/ 
      for (Iterator<Object[]> iter=students.iterator(); iter.hasNext();) { 
        Object[] obj = (Object[])iter.next(); 
        System.out.println(obj[0] + ", " + obj[1]); 
      }

注:使用右连接的关键字为right join。上述查询语句的意思为:从学生和班级表中,查询出班级名称和学生名称,因为是右连接,所以没有学生的班级会被查询出来。

         String hql = " select new list(name,passwd) from Users";  

18.统计查询

Long count = (Long)session.createQuery("select count(*) from Student").uniqueResult();

注:hql中唯有统计查询才可以带*号。uniqueResult()表示只有一条结果集,返回的是Long类型。

        Query query = session.createQuery(hql);  

19.复合查询

/*查询语句*/ 
      String hql = "select c.name, count(s) from Classes c join c.students s group by c.name order by c.name"; 

      List<Object[]> students = session.createQuery(hql).list(); 
      /*遍历*/ 
      for (int i=0; i<students.size(); i++) { 
        Object[] obj = (Object[])students.get(i); 
        System.out.println(obj[0] + ", " + obj[1]); 
      }

注:hql同样支持分组、排序等等。上述语句的意思是:查询每个班级的名称并且查询出每个班级的学生人数,按班级名称分组,按班级名称排序

        //默认查询出来的list里存放的是一个Object数组,但是在这里list里存放的不再是默认的Object数组了,而是List集合了  

总结

以上就是本文关于Hibernate hql查询代码实例的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!

hql查询代码实例,hibernatehql 本文研究的主要是Hibernate hql查询的相关内容,具体如下。 HQL介绍 Hibernate语言查询(Hibernate Query Language...

        List<List> list = query.list(); 

 

4、HQL语句执行写好的SQL语句

String sql="update Table set field = 'test'"

Session session = HibernateSessionFactory.getSession();

session.createSQLQuery(sql).executeUpdate();

ts.commit();

 

3、关联查询

一、连接

(前提是表之间的关系已经建好,由一对多的一方开始关联开始查起)

1、  隐式连接:

from Student s where s.room.id=1(这里的room其实是实体类Student 中的一对多建立的关联)

2、  显示连接

from Student s left join fetch s.room r where r.id=1

HQL的连接类型

inner join

内连接,可简写为join

left outer join

左外连接,可简写为left join

right outer join

右外连接,可简写为right join

full join

全连接,并不常用

 

 

 

 

 

使用显式连接时,还可通过HQL的关键字with来提供额外的连接条件,例如: 

 

Hibernate会将这种显式连接转换成SQL99多表连接的语法,所以HQL语句中的with关键字的作用基本等同于SQL99中的on关键字的作用:都用于指定连接条件。通过在HQL语句中使用with关键字,可以让HQL语句执行非等值连接查询。

 

对于隐式连接和显式连接还有如下两点区别:

① 隐式连接底层将转换成SQL99的交叉连接,显式连接底层将转换成SQL99的inner join、left join、right join等连接。

② 隐式连接和显式连接查询后返回的结果不同。

 

4、from子句

from关键字后紧跟持久化类的类名。例如: from Person 表明从Person持久化类中选出全部的实例。

from后还可同时出现多个持久化类,此时将产生一个笛卡尔积或跨表的连接,但实际上这种用法很少使用,因为通常当我们可能需要使用跨表的连接时,可以考虑使用隐式连接或显式连接,而不是直接在from后紧跟多个表名。

 

5、聚合函数

HQL也支持在选出的属性上,使用聚集函数。HQL支持的聚集函数与SQL的完全相同:

 

HQL的聚集函数

avg

计算属性平均值

count

统计选择对象的数量

max

统计属性值的最大值

min

统计属性值的最小值

sum

计算属性值的总和

 

 

 

 

 

 

6、批量函数

UPDATE | DELETE FROM ? <ClassName> [ WHERE WHERE_CONDITIONS ]

关于上面的语法格式有如下4点值得注意;

① 在FORM子句中,FROM关键字是可选的,即完全可以不写FROM关键字。

② 在FORM子句中只能有一个类名,该类名不能有别名。

③ 不能在批量HQL语句中使用连接,显式或隐式的都不行。但可以在WHERE子句中使用子查询。

④ 整个WHERE 子句是可选的。WHERE子句的语法和HQL子句的语法完全相同。

  Transaction txt=session.beginTransaction();  
  String hqlUpdate="update User set name=:newName";  
  int updatedEntities=session.createQuery(hqlUpdate).setString("newName","新名字").executeUpdate();  
  txt.commit();  
  session.close(); 

  Query.executeUpdate( )方法返回一个整型值,该值是受此操作影响的记录数量。我们知道,Hibernate的底层操作实际上是由JDBC完成的,因此,如果有批量的update或delete操作被转换成多条update或delete语句,该方法将只能返回最后一条SQL语句影响的记录行数。

7、绑定参数

A、 按参数名称绑定:

  在HQL语句中定义命名参数要用”:”开头,形式如下:

  Query query=session.createQuery(“from User user where user.name=:customername anduser:customerage=:age ”);

  query.setString(“customername”,name);

  query.setInteger(“customerage”,age);

  上面代码中用:customername和:customerage分别定义了命名参数customername和customerage,然后用Query接口的setXXX()方法设定名参数值,setXXX()方法包含两个参数,分别是命名参数名称和命名参数实际值。

 

B、 按参数位置邦定:

  在HQL查询语句中用”?”来定义参数位置,形式如下:

  Query query=session.createQuery(“from User user where user.name=? and user.age =? ”);

  query.setString(0,name);

  query.setInteger(1,age);

  同样使用setXXX()方法设定绑定参数,只不过这时setXXX()方法的第一个参数代表邦定参数在HQL语句中出现的位置编号(由0开始编号),第二个参数仍然代表参数实际值。

  注:在实际开发中,提倡使用按名称邦定命名参数,因为这不但可以提供非常好的程序可读性,而且也提高了程序的易维护性,因为当查询参数的位置发生改变时,按名称邦定名参数的方式中是不需要调整程序代码的。

 

C、 setParameter()方法:

  在Hibernate的HQL查询中可以通过setParameter()方法邦定任意类型的参数,如下代码:

  String hql=”from User user where user.name=:customername ”;

  Query query=session.createQuery(hql);

  query.setParameter(“customername”,name,Hibernate.STRING);

  如上面代码所示,setParameter()方法包含三个参数,分别是命名参数名称,命名参数实际值,以及命名参数映射类型。对于某些参数类型setParameter()方法可以根据参数值的Java类型,猜测出对应的映射类型,因此这时不需要显示写出映射类型,像上面的例子,可以直接这样写:

  query.setParameter(“customername”,name);但是对于一些类型就必须写明映射类型,比如java.util.Date类型,因为它会对应Hibernate的多种映射类型,比如Hibernate.DATA或者Hibernate.TIMESTAMP。

 

D、 setProperties()方法:(setEntity())

  在Hibernate中可以使用setProperties()方法,将命名参数与一个对象的属性值绑定在一起,如下程序代码:

  Customer customer=new Customer();

  customer.setName(“pansl”);

  customer.setAge(80);

  Query query=session.createQuery(“from Customer c where c.name=:name and c.age=:age ”);

  query.setProperties(customer);

  setProperties()方法会自动将customer对象实例的属性值匹配到命名参数上,但是要求命名参数名称必须要与实体对象相应的属性同名。

  这里还有一个特殊的setEntity()方法,它会把命名参数与一个持久化对象相关联,如下面代码所示:

  Customer customer=(Customer)session.load(Customer.class,”1”);

  Query query=session.createQuery(“from Order order where order.customer=:customer ”);

  query. setEntity(“customer”,customer);

  List list=query.list();

  上面的代码会生成类似如下的SQL语句:

  Select * from order where customer_ID=’1’;

 

E、 使用绑定参数的优势:

  我们为什么要使用绑定命名参数?任何一个事物的存在都是有其价值的,具体到绑定参数对于HQL查询来说,主要有以下两个主要优势:

  ①、 可以利用数据库实施性能优化,因为对Hibernate来说在底层使用的是PrepareStatement来完成查询,因此对于语法相同参数不同的SQL语句,可以充分利用预编译SQL语句缓存,从而提升查询效率。

  ②、 可以防止SQL Injection安全漏洞的产生:

  SQL Injection是一种专门针对SQL语句拼装的攻击方式,比如对于我们常见的用户登录,在登录界面上,用户输入用户名和口令,这时登录验证程序可能会生成如下的HQL语句:

  “from User user where user.name=’”+name+”’ and user.password=’”+password+”’ ”

  这个HQL语句从逻辑上来说是没有任何问题的,这个登录验证功能在一般情况下也是会正确完成的,但是如果在登录时在用户名中输入”zhaoxin or ‘x’=’x”,这时如果使用简单的HQL语句的字符串拼装,就会生成如下的HQL语句:

  “from User user where user.name=’zhaoxin’ or ‘x’=’x’ and user.password=’admin’ ”;

  显然这条HQL语句的where字句将会永远为真,而使用户口令的作用失去意义,这就是SQL Injection攻击的基本原理。

  而使用绑定参数方式,就可以妥善处理这问题,当使用绑定参数时,会得到下面的HQL语句:

  from User user where user.name=’’zhaoxin’’ or ‘’x=’’x’’ ‘ and user.password=’admin’;由此可见使用绑定参数会将用户名中输入的单引号解析成字符串(如果想在字符串中包含单引号,应使用重复单引号形式),所以参数绑定能够有效防止SQL Injection安全漏洞。

 

8、其他

子查询/Where/order by/groud by 基本与SQL无异

having子句用于对分组进行过滤,因此having子句只能在有group by子句时才可以使用。没有group by子句,不能使用having。

本文由365bet体育在线官网发布于关于计算机,转载请注明出处:hql查询代码实例

TAG标签:
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。