Hibernate学习(5)数据查询

Hibernate Query Language(HQL)

Criteria Query

Native SQL

下面对其分别进行解释

Hibernate Query Language:

HQL提供了是十分强大的功能,它是针对持久化对象,用取得对象,而不进行update,delete和insert等操作。而且HQL是面向对象的,具备继承,多态和关联等特性。

from子句:

from子句是最简单的HQL,例如from Student,也可以写成 select s from Student s。它简单的返回Student类的所有实例。

值得注意的是除了JAVA类和属性的名称外,HQL语句对大小写不敏感。

select子句:

有时并不需要取得对象的所有属性,这时可以使用select子句进行属性查询,如select s.name from Student s。

例:

public void HQLselectDEMO()

    {

        TRegister user = new TRegister();

        Session session = HibernateUtil.currentSession();

        Query query = session.createQuery("select u.userName from TRegister u");

        List list = query.list();

        for(int i = 0 ; i < list.size(); i++)

        {

            String name = (String)list.get(i);

            System.out.println(name);

        }

    }

如果要查询两个以上的属性桧以数组的方式返回,如下:

public void HQLselectDEMO()

    {

        TRegister user = new TRegister();

        Session session = HibernateUtil.currentSession();

        Query query = session.createQuery("select u.userName ,u.sex from TRegister u");

        List list = query.list();

        for(int i = 0 ; i < list.size(); i++)

        {

            Object obj[] = (Object[])list.get(i);

            System.out.println(obj[0]+"    的性别是:"+obj[1]);

        }

    }

在使用属性查询时,由于使用对象数组,操作和理解不太方便,如果将 一个object[]中所有成员封装成一个对象就方便多了。下面的程序做了示例:

public void HQLselectDEMO()

    {

        Session session = HibernateUtil.currentSession();

        Query query = session.createQuery("select new TRegister(u.userName,u.sex) from TRegister u");

        List list = query.list();

        for(int i = 0 ; i < list.size(); i++)

        {

            //Object obj[] = (Object[])list.get(i);

            TRegister user = (TRegister)list.get(i);

            System.out.println(user.getUserName()+"    的性别是:"+user.getSex());

        }

        /** *//**要正确运行以上程序,需要在TRegister类中加入一个相应的构造函数

         public TRegister(String userName,String sex) {

                this.userName = userName;

                this.sex = sex;

            }

          */

    }

统计函数查询

可以在HQL中使用函数,经常使用的函数如下:

count():统计记录条数。

min():求最小值。

max():求最大值。

sum():求和。

avg():求平均值。

例如,要取得Student实例的数量,可以编写如下HQL语句:

select count(*) from Student

取得Student平均年龄的HQL语句:

select avg(s.age) from Student as s

可以使用distinct去除重复的数据:

select distinct s.age from Student as s

where子句:

HQL也支持子查询,它通过where子句实现这一机制。where子句可以让用户缩小要返回的实例的列表范围。例如下面语句会返回所有名字为"Bill"的Student实例:

Query query = session.createQuery("from Student as s where s.name=‘Bill‘");

where子句允许出现的表达式包括了SQL中可以使用的大多数情况。

数学操作:+,-,*,/

真假比较操作:=, >=, <=, <>, !=, like

逻辑操作:and ,or, not

字符串连接:||

SQL标题函数 :如upper()和lower()

如果查询返回多条记录,可以用以下关键字来量化

all:表示所有的记录。

any:表示所有记录中的任意一条。

some:与any相同。

in:与any等价。

exists:表示子查询至少要返回一条记录。

例如,下面语句返回所有学生年龄都大于18的班级对象

from Group g where 18<all  (select s.age from g.students s)

下列语句返回在所有学生中有一个学生的年龄等于22的班级:

from Group g where 22 = any (select s.age from g.students s)

或者

from Group g where 22= some(select s.age from g.students s)

或者

from Group g where 22 in (select s.age from g.students s)

order by子句

查询返回列表可以按照任何返回的类或者组件的属性排序

from Student s order by s.name asc

连接查询

与SQL一样,HQL也支持连接查询,如内连接,外连接和交叉连接:

inner join:内连接

left outer join:左外连接

rigth outer join:右外连接

full join:全连接,但不常用

下面我重点介绍下内连接查询,左外连接和或外连接和内连接大同小异,而全连接几乎没有使用得到的地方。

inner join可以简写为join,例如在查询得到的Group对象时,内连接取得对应的Student对象,实现的程序代码如下:

Student stu = null;

        Group group = null;

        Query query = session.createQuery("from Group g join g.students");

        List list = query.list();

        Object obj[] = null;

        for(int i = 0 ; i < list.size(); i++)

        {

            obj = (Object[])list.get(i);

            group = (Group)obj[0];//group是数组是第一个对象

            stu = (Student)obj[1];//stu是数组的第二个对象

            System.out.println(stu.getName()+"属于"+group.getName());

        }

Criteria Query方式

当查询数据时,往往需要设置查询条件。在SQL或HQL语句中,查询条件常常放在where子句中。此处Hibernate还支持Criteria查询,这种查询方式把查询条件封装为一个Criteria对象。在实际应用中,可以使用Session的createCriteria()方法构建一个org.hibernate.Criteria实例,然后把具体的查询条件通过Criteria的add方法加入到Criteria实例中。这样程序员可以在不使用SQL甚至HQL的情况下进行数据查询。如下:

    public void criteriaDEMO()

    {

        Session session = HibernateUtil.currentSession();

        Criteria criteria = session.createCriteria(TRegister.class);//生成一个Criteria实例

        criteria.add(Restrictions.eq("userName","fengyan"));//等价于where name = ‘fengyan‘

        List list = criteria.list();

        TRegister user = (TRegister)list.get(0);

        System.out.println(user.getUserName());

    }

常用的查询限制方法

上面代码中 Restrictions.eq()方法表示equal,即等于的情况。Restrictions类提供了查询限制机制。它提供了许多方法,以实现查询限制

Restrictions.eq():equal,=

Restrictions.allEq(): 参数为Map对象,使用key/value进行多个等于的对比,相当于多个                                          Restrictions.eq()的效果

Restrictions.gt():greater-than,<

Restrictions.lt():less-than,<

Restrictions.le:less-equal,<=

Restrictions.between():对应SQL的between子句。

Restrictions.like():对应SQL的like子句。

Restrictions.in():对应SQL的in子句。

Restrictions.and():and 关系。

Restrictions.or():or 关系。

Restrictions.isNull():判断属性是否为空,为空返回true,否则返回false。

Restrictions.isNoyNull():与上面的相反。

Order.asc():根据传入的字段进行升序排序。

Order.desc():与上相反

MatchMode.EXACT:字符串中精确匹配,相当于like ‘value‘

MatchMode.ANYWHERE:字符串在中间位置,相当于like‘%value%‘

MatchMode.START:字符串在最前面,相当于like‘value%‘

MatchMode.END:字符串在最后,相当于like‘%value‘

下面是几个查询限制的例子:

查询学生名字以t开关的所有Student对象

Criteria criertia = session.createCriteria(Student.class);

criteria.add(Restrictions.like("name", "t%"));

List list = criteria.list();

Student stu = (Student)list.get(0);

或者:

Criteria criertia = session.createCriteria(Student.class);

criteria.add(Restrictions.like("name", "t",MatchMode.START));

List list = criteria.list();

Student stu = (Student)list.get(0);

查询学生姓名在Bill,Jack和Tom之间所有的Student对象

String[] names = {"Bill","Jack","Tom"};

Criteria criertia = session.createCriteria(Student.class);

criteria.add(Restrictions.in("name", names));

List list = criteria.list();

Student stu = (Student)list.get(0);

查询学生年龄(age)等于22或为空(null)的所有学生对象

Criteria criertia = session.createCriteria(Student.class);

criteria.add(Restrictions.eq("age", new Integer(22)));

criteria.add(Restrictions.isNull("age"));

List list = criteria.list();

Student stu = (Student)list.get(0);

查询学生姓名以字母F开头的所有Student对象,并按姓名升序排序

Criteria criertia = session.createCriteria(Student.class);

criteria.add(Restrictions.like("name", "F%"));

criteria.addOrder(Order.asc("name"));

List list = criteria.list();

Student stu = (Student)list.get(0);

注意调用Order.asc的方法应该是Criteria.addOrder()方法。

连接限制

Criteria查询中使用FetchMode来实现连接限制。在HQL语句中,可以通过fetch关键字来表示预先抓取(Eager fetching),如下:

from Group g

left join fetch g.students s

where g.name like ‘%2005‘

可以使用Criteria的API完成同样的功能,如下:

Criteria criertia = session.createCriteria(Group.class);

        criteria.setFetchMode("students", FetchMode.EAGER);

        criteria.add(Restrictions.like("name", "2005",MatchMode.END));

        List list = criteria.list();

以上两种方式编写的代码都使用相同的SQL语句来完成它们的功能,如下:

select  g.*, s.* from Group g

left outer join Student s

on g.id = s.group_id

where g.name like ‘%2005‘

Native SQL查询

本地SQL查询指的是直接使用本地数据库的SQL语言进行查询。这样做对于将 原来的SQL/JDBC程序迁移到Hibernate应用很有用

创建一个基于SQL的Query

Native SQL查询是通过SQLQuery接口来控制的,它通过调用Session.createSQLQuery()方法来获得。如:

String sql = "select {s.*} from t_student s where s.age>22";

//{}用来引用数据表的别名,{s.*}表示使用s来做为t_student表的别名

SQLQuery sqlQuery = session.createSQLQuery(sql);

sqlQuery.addEntity("s",Student.class);

List list = sqlQuery.list();

for(int i = 0 ; i < list.size(); i++)

{

    Student stu = (Student)list.get(i);

}

//createSQLQuery(String sql)利用传入的sql参数构造一个SQLQuery实例。使用该方法时,还需要传入查询的实体类,因此在配合使用SQLQuery的addEntity()方法一起使用。

命名SQL查询

与HQL的命名查询相似,也可以将 本地的SQK查询语句定义在映射文件中,然后像调用一个命名HQL查询一样专题报道调用命名SQL查询。

如:

  </class>

    <sql-query name="QueryStudents">

        <![CDATA[

                    select {s.*} from t_student s where s.age > 22

        ]]>

            <return alias="s" class="Student" />

    </sql-query>

</hibernate-mapping>

配合以上配置我们可以如下编写代码来查询

Query query = session.getNamedQuery("QueryStudents");

List list = query.list();

for(int i = 0 ; i < list.size();i++)

{

    Student stu = (Student)list.get(i);

}

也可以在命名查询是设定参数,如下:

 <sql-query name="QueryStudents">

        <![CDATA[

                    select {s.*} from t_student s where s.age > :age

        ]]>

            <return alias="s" class="Student" />

    </sql-query>

</hibernate-mapping>

程序代码:

Query query = session.getNamedQuery("QueryStudents");

query.setInteger("age",22);

List list = query.list();

for(int i = 0 ; i < list.size();i++)

{

    Student stu = (Student)list.get(i);

}

自定义insert , update和delete语句:

Hibernate 3.x的映射文件中新添加<sql_insert>,<sql_update>,<sql-delete>3个标记。可以使用这3个标记自定义自己的insert ,update,delete语句,如:

</class>

    <sql-insert>

        insert into t_student(name,age,id) values(?,?,?)

    </sql-insert>

    <sql-update>

        update t_student set name=?,age=? where id=?

    </sql-update>

    <sql-delete>

        delete from t_student where id = ?

    </sql-delete>

</hibernate-mapping>

对于以上自定义的SQL语句,要注意以下几点

1:insert 和update语句中定义的字段必须和映射文件声明的属性相应,一个都不能少。

2:在insert 和update语句中,属性出现的顺序必须和映射文件中的顺序一样。

3:在insert语句中,主键id总是放在最后。

在程序中实现以上自定义的insert语句如下:

Student stu = new Student();

stu.setName("Bill");

stu.setAge(22);

session.save(stu);

如果不想在insert或update语句中包括所有属性,则可以在属性定义时 加上insert ="false"或update="false"如下:

<property name = "name" type="string" insert = "false" update="false"/>

<sql-insert>

    insert into t_student(age,id) values(?,?)

</sql-inert>

版权声明:欢迎转载,希望在你转载的同时,添加原文地址,谢谢配合

时间: 2024-10-05 12:35:04

Hibernate学习(5)数据查询的相关文章

MySQL基础学习之数据查询

一般查询 SELECT * FROM 表名 SELECT 属性名  FROM  表名 条件查询 SELECT 属性名 FROM 表名  WHERE 条件表达式 查询数据值1,数据值2的表单 SELECT *  FROM  表名  WHERE  属性名 [NOT] IN(数据值1,数据值2....) 查询数值1,数据2的表单 SELECT *  FROM  表名  WHERE  属性=值  AND 属性1=值1 查询数值1到数值2之间的表单 SELECT *  FROM  表名  WHERE  属

Hibernate 之HQL数据查询

1. HQL简介 HQL是面向对象的查询语言,与SQL查询语言相比,虽然在语法上类似,都是运行时进行解析,但HQL并不像SQL那样操作的是数据表,列等数据库对象,HQL所操作的对象是类,对象,属性等.它也可以支持继承和多态等特征,在Hibernate 提供的各种检索方式中,HQL是使用最广泛的. 2. Query接口 Hibernate框架负责解析HQL语句,根据映射配置信息,把HQL查询语句解析成相应的SQL语句来执行数据库的查询操作.这一过程依赖的就是Query接口.Query的实例由Ses

Hibernate学习笔记--------4.查询

一.Get/Load Get方法是立即检索,而load是延迟检索,他们都是根据主键进行查询.在<class>标签中,若把lazy属性改为false,load方法就会立即检索,class中的lazy属性仅对load方法有效.在使用load时,当数据库没有找到数据时,会有ObjectNotFoundException,异常. 1 public void LazyTest() { 2 //lazy 改为false或者true,查看打印sql的时机 3 Tb_User u = session.load

hibernate学习---单表查询

我们都知道SQL是非常强大的,为什么这么说呢?相信学过数据库原理的同学们都深有体会,SQL语句变化无穷,好毫不夸张的说可以实现任意符合我们需要的数据库操作,既然前面讲到Hibernate非常强大,所以Hibernate也是能够实现SQL的一切数据库操作. 在SQL中,单表查询是最常用的语句,同理Hibernate最常用到的也是查询语句,所以今天就来讲讲Hibernate的单表查询: 今天要将的内容分以下几点: 查询所有 查询结果排序 为查询参数动态赋值 分页查询 模糊查询 唯一性查询 聚合函数查

hibernate框架学习之数据查询(QBC)

lQBC(Query By Criteria)是一种Hibernate中使用面向对象的格式进行查询的计数 lQBC查询方式步骤 ?获取Session对象 ?初始化Criteria对象(使用Session对象创建) ?由Session对象创建 ?传入要查询的数据模型类 ?添加各种查询条件 ?执行查询返回结果(返回单条数据或集合数据) lQBC查询格式非常简单,更符合编程人员的习惯 ?Criteria对象用于由Session对象创建,传入要查询的PO类 ?Criteria c = s.createC

hibernate框架学习之数据查询(QBC)helloworld

package cn.itcast.h3.query.hql; import java.util.List; import org.hibernate.Criteria; import org.hibernate.Session; import org.hibernate.criterion.DetachedCriteria; import org.hibernate.criterion.Order; import org.hibernate.criterion.Projection; impo

hibernate框架学习之数据查询(HQL)helloworld

package cn.itcast.h3.hql; import java.util.List; import org.hibernate.Query; import org.hibernate.Session; import cn.itcast.h3.hql.vo.StudentModel; import cn.itcast.h3.hql.vo.TeacherModel; import cn.itcast.h3.util.HibernateUtil; public class HQLApp {

Hibernate学习之hql查询语句

*  页面上数据的字段和数据库中字段差不多,这个时候,采用迫切连接  结构比较好,如果页面上的字段很少,要按照需求加载数据,采用带构造函数的select查询 实例讲解:转自:http://www.cnblogs.com/xiaoluo501395377/p/3376256.html 在这里通过定义了三个类,Special.Classroom.Student来做测试,Special与Classroom是一对多,Classroom与Student是一对多的关系,这里仅仅贴出这三个bean的属性代码:

Hibernate学习-11-几种查询详解

1)Get/load主键查询 //1)主键查询 // Dept dept = (Dept)session.load(Dept.class,1); // Dept dept = (Dept)session.get(Dept.class,1); System.out.println(dept); 结果 Hibernate: select dept0_.deptId as deptId0_0_, dept0_.deptName as deptName0_0_ from t_dept dept0_ wh

Hibernate学习笔记_查询

HQL vs EJBQL 1         NativeSQL >HQL.> EJBQL(JPQL 1.0) > QBC(Query By Criteria) > QBE(Query By Example)" 2         总结:QL应该和导航关系结合,共同为査询提供服务. @Test public void testHQL_01() { Session session = sf.openSession(); session.beginTransaction();