10 07Hibernate之数据查询

本文详细介绍了Hibernate中的数据查询方法,包括Session查询、Query查询及其子类操作,如数据查询、更新操作、SQL查询、查询占位符、配置文件中的HQL以及Criteria接口的使用。特别强调了get()和load()的区别,Query接口中的分页、统计和HQL与SQL的混合使用,以及Criteria接口在对象模式查询中的应用。
摘要由CSDN通过智能技术生成

1 Session查询

Session接口里面本身所定义的数据查询只有一个根据ID查询的操作方法,但是这个方法却有两个定义:
(1)根据主键查询:public <T> T get(Class<T> entityType, Serializable id)
(2)根据主键查询:public <T> T load(Class<T> theClass, Serializable id)
两个操作方法上只差了一个单词,那么使用上有差别吗?
范例:使用get()查询

package org.lks.test;

import org.lks.dbc.HibernateSessionFactory;
import org.lks.pojo.News;

public class TestNewsGet {
   

	public static void main(String[] args) {
   
		News vo = HibernateSessionFactory.getSession().get(News.class, 100);
		System.out.println(vo);
		HibernateSessionFactory.closeSession();
	}
}
Hibernate: 
    select
        news0_.nid as nid1_0_0_,
        news0_.ntitle as ntitle2_0_0_,
        news0_.nvisits as nvisits3_0_0_,
        news0_.nitem as nitem4_0_0_ 
    from
        hedb.news news0_ 
    where
        news0_.nid=?
null
package org.lks.test;

import org.lks.dbc.HibernateSessionFactory;
import org.lks.pojo.News;

public class TestNewsGet {
   

	public static void main(String[] args) {
   
		News vo = HibernateSessionFactory.getSession().load(News.class, 100);
		System.out.println(vo);
		HibernateSessionFactory.closeSession();
	}
}

Hibernate: 
    select
        news0_.nid as nid1_0_0_,
        news0_.ntitle as ntitle2_0_0_,
        news0_.nvisits as nvisits3_0_0_,
        news0_.nitem as nitem4_0_0_ 
    from
        hedb.news news0_ 
    where
        news0_.nid=?
Exception in thread "main" org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [org.lks.pojo.News#100]

使用load()查询的时候如果指定的ID不存在,那么就会出现异常。
面试题:请问Hibernate中get()与load()方法有什么区别?
(1)get()与load()方法都是在Session接口中定义的根据主键查询的操作;
(2)get()方法查询时,如果主键不存在,则返回null;
(3)load()方法查询时,如果主键不存,则抛出异常。

2 Query查询

面对数据操作中,数据的查询部分永远都是最为复杂的部分,所以来讲如果要进行更加合理的查询操作,那么必须依靠Query接口来实现,而如果要想取得此接口的实例化对象,必须依靠Session接口完成,在Session接口中定义有如下方法:
(1)取得Query接口对象:public Query createQuery(String queryString)
|————此处表示传入一个hql语法进行数据查询(Hibernate Query Language)
在Query接口里面主要定义了如下几个操作方法:
(1)设置要操作的数据:【Deprecated】default Query<R> setXxx(int position, 数据类型 val)
|————(since 5.2) use setParameter(int, Object) or setParameter(int, Object, Type) instead
Bind a positional float-valued parameter.
(2)设置参数:public Query<R> setParameter(int position, Object value)
(3)取得单个查询结果:public R uniqueResult()
(4)查询全部数据:public List<R> list()
(5)数据更新:public int executeUpdate()

2.1 数据查询

在Hibernate里面Session查询不能够胜任于复杂查询,所以现在的所有查询都通过Query接口完成,那么在这个接口里面要使用hql语言(极其类似于SQL语句)。
范例:查询全部数据

package org.lks.test;

import java.util.Iterator;
import java.util.List;

import org.hibernate.Query;
import org.lks.dbc.HibernateSessionFactory;
import org.lks.pojo.News;

public class QueryDemoA {
   

	public static void main(String[] args) {
   
		String hql = "FROM News AS n"; //hql查询全部
		Query query = HibernateSessionFactory.getSession().createQuery(hql);
		List<News> all = query.list();
		Iterator<News> iter = all.iterator();
		while(iter.hasNext()){
   
			System.out.println(iter.next());
		}
		HibernateSessionFactory.closeSession();
	}
}

现在通过以上的代码可以发现如下几点:
(1)在Hibernate里面使用的都是HQL,但是在使用HQL的时候一定要注意,FROM子句之后跟的是POJO类的名字,必须注意大小写News.java(News),而AS指的就是别名,一般情况下可以省略。
(2)在使用Hibernate进行数据查询的时候,发现所有的内容都会自动以POJO类的形式返回,所有的实例化的操作部分都由Hibernate自动帮助用户处理了;

所谓的HQL其语法的结构非常类似于SQL语法结构,那么也可以编写SELECT语句,但是大部分人不会这么写。
范例:查询指定的数据列

package org.lks.test;

import java.util.Iterator;
import java.util.List;

import org.hibernate.Query;
import org.lks.dbc.HibernateSessionFactory;

public class QueryDemoA {
   

	public static void main(String[] args) {
   
		String hql = "SELECT n.ntitle,n.nitem FROM News AS n"; //hql查询全部
		Query query = HibernateSessionFactory.getSession().createQuery(hql);
		List<Object[]> all = query.list();
		Iterator<Object[]> iter = all.iterator();
		while(iter.hasNext()){
   
			Object[] obj = iter.next();
			System.out.println(obj[0] + ", " + obj[1]);
		}
		HibernateSessionFactory.closeSession();
		System.exit(0);
	}
}

此时的代码的确是进行了数据列的操作限制,但是其结果发现为了保证查询,那么返回的数据不再自动转化为News这个POJO类,而是以对象数组的形式返回,相比较自动匹配POJO类型,以上的操作明显不方便。

Hibernate在设计的时候考虑到了以上的情况,所以在Hibernate里面提供有一个专门负责转换处理的类(org.hibernate.transform.AliasToBeanResultTransformer),但是即便转换了你也需要做一些辅助性的操作。随后在Query接口里面使用如下的转换操作方法明确设置:
(1)设置结果转换:【Deprecated】default Query<R> setParameters(Object[] values, Type[] types)
范例:手工转换

package org.lks.test;

import java.util.Iterator;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.transform.AliasToBeanResultTransformer;
import org.lks.dbc.HibernateSessionFactory;
import org.lks.pojo.News;

public class QueryDemoC {
   

	public static void main(String[] args) {
   
		String hql = "SELECT n.ntitle AS ntitle,n.nitem AS nitem FROM News AS n"; //hql查询全部
		Query query = HibernateSessionFactory.getSession().createQuery(hql);
		query.setResultTransformer(new AliasToBeanResultTransformer(News.class));
		List<News> all = query.list();
		Iterator<News> iter = all.iterator();
		while(iter.hasNext()){
   
			System.out.println(iter.next());
		}
		HibernateSessionFactory.closeSession();
		System.exit(0);
	}
}

在本代码之中实际上只是一个功能的演示,如果真查询,就查询全部数据,千万别做部分数据的查询。

那么既然可以实现查询全部的操作,就一定可以实现根据ID查询的操作,也就是说使用限定查询。
范例:在Query中实现限定查询

package org.lks.test;

import java.util.Iterator;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.transform.AliasToBeanResultTransformer;
import org.lks.dbc.HibernateSessionFactory;
import org.lks.pojo.News;

public 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值