Hibernate之查询操作

目录

Hibernate查询操作

HQL查询(多表查询,但不复杂时使用)

Query接口

完整查询

基本查询

条件查询(无参数绑定)

条件查询(参数绑定)

投影查询

聚合查询 

分组与排序

分页查询

多表查询

Criteria查询(单表条件查询)

Restrictions类

基本查询

条件查询 

分页查询

排序查询

统计查询

离线查询(DetachedCriteria)

原生SQLQuery查询(复杂的业务查询)

SQLQuery

记录查询

 条件查询

分页查询


Hibernate查询操作

  • HQL查询(多表查询,但不复杂时使用)

HQL 查询语句是面向对象的, Hibernate 负责解析 HQL 查询语句, 然后根据对象-关系映射文件中的映射信息, 把 HQL 查询语句翻译成相应的 SQL 语句。HQL 查询语句中的主体是域模型中的类及类的属性。

Query接口

Query代表面向对象的一个Hibernate查询操作,在Hibernate中,通常使用如下方法接收一个HQL语句

Query query = session.createQuery("HQL语句");  //接收HQL语句

 然后再调用Query的list或uniqueResult方法执行查询

List<实体类> list = query.list();   //返回多条记录

实体类  实体类对象 = (实体类)query.uniqueResult();  //返回唯一记录

完整查询

select  ...  from  ...  where  ...  group by  ...  having  ...  order by  ...  asc/desc 

基本查询

最简单实体查询例子:

String hql = "From User"; //简单写法
           String hql = "From com.mark.domain.User"; //完整写法

上面的HQL语句将取出User的所有对应记录为

select user0_.U_ID as U_ID1_0_,user0_.U_NAME as U_NAME2_0_,user0_.U_AGE as U_AGE3_0_ from USERS user0_

在HQL语句中,本身大小写无关,但是其中出现的类名和属性名必须注意大小写区分。同时,在Hibernate中,查询的目标实体存在继承关系的判定,如果from User将返回所有User以及User子类的记录。假设系统中存在User的两个子类:SysAdmin和SysOperator,那么该hql语句返回的记录将包含这两个子类的所有数据,即使SysAdmin和SysOperator分别对应了不同的库表。

条件查询(无参数绑定)

Where子句: 如果我们想取出名为“mark”的用户记录,可以通过Where子句加以限定(其中AS可以省略)

FROM User AS user WHERE user.name='mark'

where子句中,我们可以通过比较操作符指定甄选条件,如: =, , <, >, <=, >=, between, not between, in ,not in, is, like等。同时,在where子句中可以使用算术表达式。 几个简单实例:

FROM User user WHERE user.age<20
           FROM User user WHERE user.name IS null
           FROM User user WHERE user.name LIKE 'Mk%'
           FROM User user WHERE (user.age % 2 = 1)
           FROM User user WHERE (user.age<20) AND (user.name LIKE '%Mk')

条件查询(参数绑定)

顺序占位符  ?

String hql = "from User user WHERE user.name = ? AND user.age = ?";
           Query query= session.createQuery(hql);

/*query.setString(0, "mark");
           query.setInteger(1, 10);*/

query.setParameter(0, "mark");   //第一个参数为?索引,第二个参数为索引值

query.setParameter(1, "mark");

引用占位符  :name

 String hql = "FROM User user WHERE user.uName = :name AND user.uAge = :age";
            Query query= session.createQuery(hql);

query.setParameter("name", "mark");   //第一个参数为引用名,第二个参数为值

query.setParameter("age", "mark"); 

投影查询

有时,我们需要的数据可能仅仅是实体对象的某个属性(库表记录中的某个字段信息)。我们指定了只需要获取User的name属性。此时返回的list数据结构中,每个条目都是一个String类型的name数据

SELECT user.name,user.telephone FROM User user

 String hql = "SELECT user.name FROM User user";
             List list = session.createQuery(hql).list();

聚合查询 

我们也可以在HQL的select子句中使用统计函数或者利用DSITINCT关键字,剔除重复记录

 SELECT COUNT(*),MIN(user.age) FROM User user
            SELECT DISTINCT user.name FROM User user

分组与排序

Order by子句,默认情况下是按照升序排序,当然我们可以指定排序策略

FROM User user ORDER BY user.name

FROM User user ORDER BY user.name DESC

通过Group by可进行分组统计,如果下例中,我们通过Group by子句实现了同龄用户的统计

SELECT COUNT(user),user.age FROM User user GROUP BY user.age

通过该语句,我们获得了一系列的统计数据。对于Group by子句获得的结果集而言,我们可以通过Having子句进行筛选。例如,在上例中,我们对同龄用户进行了统计,获得了每个年龄层次中的用户数量,假设我们只对超过10人的年龄组感兴趣,可用以下语句实现

SELECT COUNT(user),user.age FROM User user GROUP BY user.age HAVING COUNT(user) > 10

分页查询

String hql ="From Student";

Query query = session.createQuery(hql);

query .setFirstResult(0);   //设置获取第一个记录的位置,从第几条记录开始查询,默认从0开始

query .setMaxResults(2);  //设置结果集的最大记录数

多表查询

 内连接(将两端关联对象分别放到数组中,返回一个数组)[Customer,Linkman]

 From Customer  c  inner  join   c.linkmans;  //linkmans是Customer中对另一个对象Linkman的Set封装

 迫切内连接fetch(将一个对象封装到另一个对象中,返回一个对象)Cutomer

 From Customer  c  inner  join  fetch  c.linkmans;  //linkmans是Customer中对另一个对象Linkman的Set封装

左外连接 

 From Customer  c  left  join   c.linkmans;  //linkmans是Customer中对另一个对象Linkman的Set封装

右外连接 

 From Customer  c  right  join   c.linkmans;  //linkmans是Customer中对另一个对象Linkman的Set封装

  • Criteria查询(单表条件查询)

Criteria是一个完全面向对象,可扩展的条件查询API,通过它完全不需要考虑数据库底层如何实现,以及SQL语句如何编写,它是Hibernate框架的核心查询对象,Criteria查询,又称为QBC查询(Query By  Criteria),它是Hibernate的另一种对象检索方式

Restrictions类

Restrictions的静态方法创建Criterion条件对象,Restrictions类中提供了一系列用于设定查询条件的静态方法,这些静态方法都返回Criterion实例,每个Criterion实例代表一个查询条件

基本查询

Criteria criteria  = session.createCriteria(Customer.class);

List<Customer> list = criteria.list();

条件查询 

Criteria criteria  = session.createCriteria(Customer.class);

criteria.add(Restrictions.eq("name","mark"));   //添加条件

criteria.add(Restrictions.eq("age","20"));     //添加条件

List<Customer> list = criteria.list();

分页查询

 Criteria criteria  = session.createCriteria(Customer.class);

 criteria.setFirstResult(3);  //起始索引

 criteria.setMaxResult(3);   //显示记录条数

 criteria.setProjection(Projections.rowCount());   //执行聚合函数,返回记录总条数

 Long count = (Long)criteria.uniqueResult();

排序查询

Criteria criteria  = session.createCriteria(Customer.class);

criteria.add(Order.desc("cust_id"));   //添加条件

统计查询

Criteria criteria  = session.createCriteria(Customer.class);

criteria.setProjection(Projections.rowCount());  

离线查询(DetachedCriteria)

DetachedCriteria可以脱离Session来使用的一种条件查询对象,Criteria对象必须由Session对象来创建,那么也就是说必须有Session才可以生成Criteria对象,而DetachedCriteria对象可以在其他层对条件进行封装

这个对象也是比较有用的,尤其在SSH整合以后经常会用到。它的主要优点是做一些特别复杂的条件查询的时候,往往会在Web层向业务层传递很多的参数,业务层又会将这些参数传递给DAO层,最后在DAO层拼接SQL完成查询。有了离线条件串对象后,我们可以在Web层将数据封装好,传递到业务层,再由业务层传递给DAO层完成查询

	public void fun(){
		//Web|Service层
		DetachedCriteria dc  = DetachedCriteria.forClass(Customer.class);
		
		dc.add(Restrictions.idEq(6l));//拼装条件(全部与普通Criteria一致)
		
		//----------------------------------------------------
		Session session = HibernateUtils.openSession();
		Transaction tx = session.beginTransaction();
		//----------------------------------------------------
		Criteria c = dc.getExecutableCriteria(session); //离线查询条件与Session绑定
		
		List list = c.list();
		
		//----------------------------------------------------
		tx.commit();
		session.close();
		
  • 原生SQLQuery查询(复杂的业务查询)

SQLQuery

SQLQuery接口用于接收一个sql语句进行查询,但是sql语句不会直接封装到实体对象中,需要我们调用以下代码进行封装,然后调用list或uniqueResult方法进行查询 

sqlQuery.addEntity(类.class);

记录查询

String sql  = "SELECT * FROM customer ";

SQLQuery sqlQuery = session.createSQLQuery(sql);

sqlQuery.addEntity(Customer.class);

List<Customer> list  = sqlQuery.list();

 条件查询

String sql  = "SELECT * FROM customer WHERE  cust_id = ?";

SQLQuery sqlQuery = session.createSQLQuery(sql);

sqlQuery.setParameter(0,1); //设置参数

sqlQuery.addEntity(Customer.class);  //封装到实体类

List<Customer> list  = sqlQuery.list(); //返回结果

分页查询

String sql  = "SELECT * FROM customer limit ?,?";

SQLQuery sqlQuery = session.createSQLQuery(sql);

//设置起始参数

sqlQuery.setParameter(0,0);

sqlQuery.setParameter(0,1);

sqlQuery.addEntity(Customer.class);  //封装到实体类

List<Customer> list  = sqlQuery.list(); //返回结果

猜你喜欢

转载自blog.csdn.net/mmake1994/article/details/81529907