Hibernate查询

概述:数据查询与检索是Hibernate中的一个亮点。相对其他ORM实现而言,Hibernate提供了灵活多样的查询机制。
Hibernate语言查询( Hibernate Query Language,HQL) :它是完全面向对象的查询语句,查询功能非常强大,具备继承、多态和关联等特性 。Hibernate官方推荐使用HQL进行查询。
标准化对象查询(Query By Criteria):以对象的方式进行查询,将查询语句封装为对象操作。优点:可读性好,符合Java 程序员的编码习惯。
Native SQL Queries (原生SQL查询):直接使用数据库提供的SQL方言进行查询。

HQL ——(Hibernate Query Language,)

HQL 概述

Hibernate查询语言(HQL)是面向对象的查询语言,其结构与SQL查询相似,不同的是,HQL查询的主体是持久化类而不是数据表。
HQL提供了一种应用和数据库之间的抽象,提高了可移植性。
HQL子句本身大小写无关,但是其中出现的类名和属性名必须注意大小写。

HQL基本查询

HQL属性查询
1.使用HQL查询最简单的例子,就是查询指定类对应表格的所有记录
例如:
Query query = session.createQuery(“from User”);
List users = query.list();
for(int i=0;i<users.size();i++)
{
user =(User)users.get(i);
System.out.println(i+"–"+user.getUsername());
}

//1、基本的HQL查询,查询所有属性
	public void testQueryUser(){
		Configuration cfg =null;
		SessionFactory sf=null;
		Session session=null;
		Transaction ts=null;
		try {
			sf=HibernateUtil.getSessionFactory();//SessionFactory单态模式
			session=sf.getCurrentSession();//保证每个读写线程有唯一的session实例
			ts=session.beginTransaction();
			Query query=session.createQuery("from User");
			List<User> users=query.list();
			for(int i=0;i<users.size();i++)
			{
				User u =users.get(i);
				System.out.println(u.getName()+" "+u.getAge());
			}
//			for(User u: users)
//			{
//				System.out.println(u.getId()+" "+u.getName()+" "+u.getAge());
//			}
//			for(int i=0;i<users.size();i++)
//			{
//				User u =users.get(i);
//				System.out.println(u.toString());
//			}
//			Iterator iterator = users.iterator();
//			while(iterator.hasNext()) {
//				User u=(User)iterator.next();
//				System.out.println(u.toString());
//			}
			ts.commit();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			if(ts !=null) {
				ts.rollback();
			}
		}finally {
		}
	}

在这里插入图片描述
在查询类对应的表格时,需注意到继承的问题,Hibernate会自动判定继承关系,如果查询的类是某类的父类,则会返回与父类、子类对应的所有表格记录。
例如如果查询java.lang.Object,由于Object在Java中是所有类的父类别,所以下面这个查询会返回数据库中所有表格的记录:
Query query = session.createQuery(“from java.lang.Object”);

2.针对某个属性作查询
例子如下:
Query query = session.createQuery(“select u.username from User u”);
List usernames = query.list();
for(int i=0;i<usernames.size();i++)
{
username =(String)usernames.get(i);
System.out.println(i+"–"+username);
}

//2、基本的HQL查询,查询某个属性
	public void testQueryUserOneAttribute(){
		Configuration cfg =null;
		SessionFactory sf=null;
		Session session=null;
		Transaction ts=null;
		try {
			sf=HibernateUtil.getSessionFactory();//SessionFactory单态模式
			session=sf.getCurrentSession();//保证每个读写线程有唯一的session实例
			ts=session.beginTransaction();
			Query query=session.createQuery("select u.name from User u");
			List names=query.list();
			for(int i=0;i<names.size();i++)
			{
				String name =(String)names.get(i);
				System.out.println(name);
			}
			ts.commit();
		} catch (HibernateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			if(ts !=null) {
				ts.rollback();
			}
		}finally {
		}
	}

在这里插入图片描述
3.查询两个以上的属性,查询的结果会以数组的方式返回
例子如下:
Query query = session.createQuery(“select u.username, u.password from User as u”);
List users = query.list();
for(int i=0;i<users.size();i++)
{
Object obj[] =(Object[])users.get(i);
System.out.println(obj[0]+“的密码为:”+obj[1]);
}

	//3、基本的HQL查询,查询多个属性
	public void testQueryUserSeveralAttributes(){
		Configuration cfg =null;
		SessionFactory sf=null;
		Session session=null;
		Transaction ts=null;
		try {
			sf=HibernateUtil.getSessionFactory();//SessionFactory单态模式
			session=sf.getCurrentSession();//保证每个读写线程有唯一的session实例
			ts=session.beginTransaction();
			Query query=session.createQuery("select u.name,u.age from User u");
			//Query query=session.createQuery("select u.name,u.birthday from User u");
			List<Object[]> attributes=query.list();//加了类型
//				for(int i=0;i<attributes.size();i++)
//				{
//					Object obj[] =(Object[])attributes.get(i);
//					System.out.println(obj[0]+"的年龄"+obj[1]);
//				}
			for(int i=0;i<attributes.size();i++)
			{
				Object obj[] =attributes.get(i);
				System.out.println(obj[0]+"的年龄"+obj[1]);
			}
			ts.commit();
		} catch (HibernateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			if(ts !=null) {
				ts.rollback();
			}
		}finally {
		}
	}

在这里插入图片描述
4.使用distinct去除资料重复的记录
例子:
Query query = session.createQuery(“select distinct u.username from User as u”);
List usernames = query.list();
for(int i=0;i<usernames.size();i++)
{
username =(String)usernames.get(i);
System.out.println(i+"–"+username);
}

	//4、基本的HQL查询,distinct去除重复
	public void testQueryUserSeveralAttributesByDistinct(){
		Configuration cfg =null;
		SessionFactory sf=null;
		Session session=null;
		Transaction ts=null;
		try {
			sf=HibernateUtil.getSessionFactory();//SessionFactory单态模式
			session=sf.getCurrentSession();//保证每个读写线程有唯一的session实例
			ts=session.beginTransaction();
			Query query=session.createQuery("select distinct u.age from User u");
			List attributes=query.list();
			for(int i=0;i<attributes.size();i++)
			{
				int age=(int)attributes.get(i);
				System.out.println(age);
			}
			ts.commit();
		} catch (HibernateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			if(ts !=null) {
				ts.rollback();
			}
		}finally {
		}
	}

在这里插入图片描述
HQL实例化查询
5.如果User类提供有适当的构建方法,则可以在使用HQL时直接指定新建一个对象传回
Query query = session.createQuery(“select new User(u.username,u.password) from User as u”);
List users = query.list();
for(int i=0;i<users.size();i++)
{
User user =(User)users.get(i);
System.out.println(user.getUsername()+“的密码为:”+user.getPassword());
}
注意,这个返回的User实例并未与数据库有任何关联,可以试着取得id属性,可以发现它的值是0,如果试图使用Session的saveOrupdate()方法,则会新增一条记录而不是更新原有的记录。

	//5、基本的HQL查询,实例化查询
	public void testQueryUserByExample(){
		Configuration cfg =null;
		SessionFactory sf=null;
		Session session=null;
		Transaction ts=null;
		try {
			sf=HibernateUtil.getSessionFactory();
			session=sf.getCurrentSession();
			ts=session.beginTransaction();
			Query query=session.createQuery("select new User(u.name,u.age) from User u");
			List<User> users=query.list();
			for(int i=0;i<users.size();i++)
			{
				User u =(User)users.get(i);
				System.out.println(u.getName()+" "+u.getAge());
//				if(u.getAge()==100) {
//					session.saveOrUpdate(u);
//				}
			}
			ts.commit();
		} catch (HibernateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			if(ts !=null) {
				ts.rollback();
			}
		}finally {
		}
	}

在这里插入图片描述saveOrupdate():
在这里插入图片描述
HQL统计函数查询
6.可以在HQL中使用函数,经常使用的函数有如下几个:
count():统计记录条数。
min():求最小值。
max():求最大值。
sum():求和。
avg():求平均值。
例如取得记录集的大小:
例子:
Query query = session.createQuery(“select count(*) from User”);
Object count = (Object)query.uniqueResult();
System.out.println(“共有”+count+“条记录”);
使用avg()取得属性的平均值:
例子
Query query = session.createQuery(“select avg(u.age) from User u”);
//Object average =(Object)query.uniqueResult();
Number average =(Number)query.uniqueResult();
System.out.println(“平均年龄为:”+average);

//7、基本的HQL查询,统计函数查询
	public void testQueryAge(){
		Configuration cfg =null;
		SessionFactory sf=null;
		Session session=null;
		Transaction ts=null;
		try {
			sf=HibernateUtil.getSessionFactory();
			session=sf.getCurrentSession();
			ts=session.beginTransaction();
			Query query=session.createQuery("select max(u.age) from User u");
			Object age0=(Object)query.uniqueResult();
			System.out.println("最大年龄"+age0);
			query=session.createQuery("select min(u.age) from User u");
			Object age1=(Object)query.uniqueResult();
			System.out.println("最小年龄"+age1);
			query=session.createQuery("select avg(u.age) from User u");
			Object age2=(Object)query.uniqueResult();
			System.out.println("平均年龄"+age2);
			query=session.createQuery("select count(*) from User u");
			Object cnt=(Object)query.uniqueResult();
			System.out.println("一共有"+cnt+"用户");
			ts.commit();
		} catch (HibernateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			if(ts !=null) {
				ts.rollback();
			}
		}finally {
		}
	}

在这里插入图片描述
HQL条件查询——where子句
7.可以使用where子句来限定查询的条件,除了 = 运算之外,还有 >、>=、<、<=、!= 或 <>等比较运算
例如:
SQuery query = session.createQuery(“from User u where u.username=‘小明’”);
List users = query.list();
for(int i=0;i<users.size();i++)
{
User user =(User)users.get(i);
System.out.println(user.getUsername()+“的密码为:”+user.getPassword());
}
在where子句上进行表达式
例如:Query query = session.createQuery(“from User user where (user.age / 10 = 3)”);
在where子句上使用and、or
例如:Query query = session.createQuery(“from User user where (user.age > 20) and (user.name = ‘小明’)");
is not nullL与is null则可以测试字段值是否为空值
例如: Query query = session.createQuery(“from User user where user.name is not null”);
between可以测试字段值是否在指定的范围之内
例如: Query query = session.createQuery(“from User user where user.age between 20 and 30”);
使用in或not in来测试字段值是否在您指定的集合中
例如: Query query = session.createQuery("from User u where u.username in(‘小明’,‘李小白’) “);
like或not like可以让您进行模糊条件搜寻
例如想搜寻名称中含有’大’开头的资料:Query query = session.createQuery(“from User user where user.name like ‘大%’”);

//8、基本的HQL查询,where
	public void testQueryUserBywhere(){
		Configuration cfg =null;
		SessionFactory sf=null;
		Session session=null;
		Transaction ts=null;
		try {
			sf=HibernateUtil.getSessionFactory();
			session=sf.getCurrentSession();
			ts=session.beginTransaction();
			//Query query=session.createQuery("from User u where u.name='李白'");
			//Query query=session.createQuery("from User u where u.age between 20 and 30");
			//Query query=session.createQuery("from User u where u.name like '%李%'");
			Query query=session.createQuery("from User");
			List<User> users=query.list();
			for(int i=0;i<users.size();i++)
			{
				User u =(User)users.get(i);
				System.out.println(u.toString());
			}
			ts.commit();
		} catch (HibernateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			if(ts !=null) {
				ts.rollback();
			}
		}finally {
		}
	}

Query query=session.createQuery(“from User u where u.name=‘李白’”);
在这里插入图片描述
Query query=session.createQuery(“from User u where u.age between 20 and 30”);
在这里插入图片描述
在这里插入图片描述
8.对于支持子查询的数据库来说,Hibernate支持在查询中嵌套子查询
例如: Query query = session.createQuery(“from User u where u.age>(select avg(age) from User)”);
List users = query.list();
for(int i=0;i<users.size();i++)
{
user =(User)users.get(i);
System.out.println(i+"–姓名:"+user.getUsername()+"–年龄"+user.getAge());
}

//9、嵌套子查询
		public void testEmbededSonQuery(){
			Configuration cfg =null;
			SessionFactory sf=null;
			Session session=null;
			Transaction ts=null;
			try {
				sf=HibernateUtil.getSessionFactory();
				session=sf.getCurrentSession();
				ts=session.beginTransaction();
				Query query=session.createQuery("from User u where u.age>(select avg(age) from User)");
				List<User> users=query.list();
				for(int i=0;i<users.size();i++)
				{
					User u =(User)users.get(i);
					System.out.println(u.toString());
				}
				ts.commit();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				if(ts !=null) {
					ts.rollback();
				}
			}finally {
			}
		}

在这里插入图片描述
9.对查询结果使用order by进行排序
例子:Query query = session.createQuery(“from User user order by user.age”);
可使用desc反排序
例子:Query query = session.createQuery(“from User user order by user.age desc”);
同时指定两个以上的排序方式
例如先按照"age"反序排列,如果"age"相同,则按照“username"顺序排列:Query query = session.createQuery(“from User user order by user.age desc, user.username”);

//10、Orderby,按照年龄降序,名字升序
			public void testOrderByQuery(){
				Configuration cfg =null;
				SessionFactory sf=null;
				Session session=null;
				Transaction ts=null;
				try {
					sf=HibernateUtil.getSessionFactory();
					session=sf.getCurrentSession();
					ts=session.beginTransaction();
					Query query=session.createQuery("from User u order by u.age desc,u.name");
					List<User> users=query.list();
					for(int i=0;i<users.size();i++)
					{
						User u =(User)users.get(i);
						System.out.println(u.toString());
					}
					ts.commit();
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					if(ts !=null) {
						ts.rollback();
					}
				}finally {
				}
			}

在MySQL中,GBK编码默认以中文拼音排序,可以将数据库编码改为GBK解决(可以针对于想中文排序的表更改编码,无需整个库都修改),这样OrderBy出来直接就是按中文拼音排序的了。
注意一点,更改数据库编码后,并不会将原有数据编码转换,还需要将数据进行转码。
alter table 表名 convert to character set gbk;

10.使用GROUP BY子句,自动将指定的字段依相同的内容群组
例如依字段“password"分组并作平均:Query query = session.createQuery(“select avg(user.age) from User user group by user.password”);

//11、分组查询group by
	public void testGroupByQuery(){
		Configuration cfg =null;
		SessionFactory sf=null;
		Session session=null;
		Transaction ts=null;
		try {
			sf=HibernateUtil.getSessionFactory();
			session=sf.getCurrentSession();
			ts=session.beginTransaction();
			Query query=session.createQuery("select u.gender,avg(u.age) from User u group by u.gender");
			List<Object[]> list=query.list() ;
			for(int i=0;i<list.size();i++) {
				Object[] object =(Object[])list.get(i);
				System.out.println(object[0]+"的平均年龄"+object[1]);
			}
			ts.commit();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			if(ts !=null) {
				ts.rollback();
			}
		}finally {
		}
	}

在这里插入图片描述
结合having子句,对查询出来的组进行限制
例如只将平均年龄大于20的记录分组显示出来:Query query = session.createQuery(“select user.password, avg(user.age) from User user group by user.password having avg(user.age) > 20");
Query query = session.createQuery(“select u.gender, avg(u.age) from User u group by u.gender having avg(u.age) > 25”);
在这里插入图片描述
不再输出分组后平均年龄小于25的分组
11、参数绑定查询
在HQL语句中使用“?”占位符,使用query的setXXX方法给“?”绑定参数
例如
Query query = session.createQuery(“from User u where u.username=?”);
query.setString(0,“李小白”);
List users = query.list();

//12、参数绑定查询
	public void testQueryUserByParameter(){
		Configuration cfg =null;
		SessionFactory sf=null;
		Session session=null;
		Transaction ts=null;
		try {
			sf=HibernateUtil.getSessionFactory();
			session=sf.getCurrentSession();
			ts=session.beginTransaction();
			Query query=session.createQuery("from User u where u.name=?");
			//query.setString(0,"李白");
			query.setParameter(0, "李白");
			List<User> users=query.list();
			for(int i=0;i<users.size();i++)
			{
				User u =(User)users.get(i);
				System.out.println(u.toString());
			}
			ts.commit();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			if(ts !=null) {
				ts.rollback();
			}
		}finally {
		}
	}

在这里插入图片描述
“?”参数以外,还可以使用命名参数来表示参数。同一个命名参数可以在一个查询中出现多次。
例如:
Query query = session.createQuery(“from User u where u.username=:name");
query.setString(“name”,“李小白”);
List users = query.list();

Query query=session.createQuery(“from User u where u.name=:name”);
query.setParameter(“name”, “李白”);
12、分页查询
控制分页Query有两个方法
一是:setFirstResult(int firstResult):设定从那个对象开始检索。
二是:setMaxResults(int maxResult):设置一次最多能检索出对象的数目。
例如:
//从第一行开始,提取前5个对象(记录)
Query query=session.createQuery(“from User”);
query.setFirstResult(0);
query.setMaxResults(5);
List result=query.list();

	//13、分页查询
		public void testQueryPage(){
			Configuration cfg =null;
			SessionFactory sf=null;
			Session session=null;
			Transaction ts=null;
			try {
				sf=HibernateUtil.getSessionFactory();
				session=sf.getCurrentSession();
				ts=session.beginTransaction();
				Query query=session.createQuery("from User u");
				query.setFirstResult(0);
				query.setMaxResults(5);
				List<User> users=query.getResultList();
				for(int i=0;i<users.size();i++)
				{
					User u =(User)users.get(i);
					System.out.println(u.toString());
				}
				ts.commit();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				if(ts !=null) {
					ts.rollback();
				}
			}finally {
			}
		}

在这里插入图片描述

//14、分页查询
	public void testQueryByPage() {
		QueryPage(3);
	}
	public void QueryPage(int pageSize){
		Configuration cfg =null;
		SessionFactory sf=null;
		Session session=null;
		Transaction ts=null;
		try {
			sf=HibernateUtil.getSessionFactory();
			session=sf.getCurrentSession();
			ts=session.beginTransaction();
			Query query=session.createQuery("select count(*) from User u");
			Number cnts = (Number)query.uniqueResult();
			int userCount=cnts.intValue();
			int pageCount=0;
			pageCount=userCount/pageSize;
			if(userCount%pageSize!=0) {
				pageCount++;
			}
			Query query1=session.createQuery("from User u");
			for(int i=0;i<pageCount;i++)
			{
				System.out.println("第"+i+"页");
				System.out.println("---------------------------------------------------------------");
				query1.setFirstResult(i*pageSize);
				query1.setMaxResults(pageSize);
				List<User> us=query1.list();
				for(User u : us) {
					System.out.println(u.toString());
				}
			}
			ts.commit();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			if(ts !=null) {
				ts.rollback();
			}
		}finally {
		}
	}

在这里插入图片描述
13、在映射文件中定义命名查询语句(HQL)
映射文件中的配置
<hibernate-mapping package=“my.hibernate.domainEntity”>
<class name=“User”table=“t_user”>
……


<![CDATA[ from User u where u.username=:name ]]>

</hibernate-mapping>
  在程序中使用
Query query=session.getNamedQuery(“findUserByName”);
query.setString(“name”, “Tom”);
List list=query.list();

//15、基本的HQL查询,在user.hbm.xml中定义查询标签
		public void testQueryByQueryTag(){
			Configuration cfg =null;
			SessionFactory sf=null;
			Session session=null;
			Transaction ts=null;
			try {
				sf=HibernateUtil.getSessionFactory();//SessionFactory单态模式
				session=sf.getCurrentSession();//保证每个读写线程有唯一的session实例
				ts=session.beginTransaction();
				Query query=session.getNamedQuery("findUserByName");
				query.setParameter("username", "李白");
				List<User> users=query.list();
				for(int i=0;i<users.size();i++)
				{
					User u =users.get(i);
					System.out.println(u.toString());
				}
				ts.commit();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				if(ts !=null) {
					ts.rollback();
				}
			}finally {
			}
		}

在这里插入图片描述
14、使用HQL更新和删除记录
在Hibernate 3中,HQL新增了update与delete语句,可以直接使用HQL指定更新或删除
例如使用update子句进行更新:
ts = session.beginTransaction();
Query query = session.createQuery(“update User set username=‘小糊涂’ where username=‘小明白’”);
query.executeUpdate();
ts.commit();

//16、基本的HQL更新,使用HQL更新把李四改成四里
	public void testQueryUpdate(){
		Configuration cfg =null;
		SessionFactory sf=null;
		Session session=null;
		Transaction ts=null;
		try {
			sf=HibernateUtil.getSessionFactory();//SessionFactory单态模式
			session=sf.getCurrentSession();//保证每个读写线程有唯一的session实例
			ts=session.beginTransaction();
			Query query = session.createQuery("update User u set u.name='四里' where u.name='李四'");
			query.executeUpdate();
			ts.commit();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			if(ts !=null) {
				ts.rollback();
			}
		}finally {
		}
	}

在这里插入图片描述

使用delete子句进行资料删除
例子:
ts = session.beginTransaction();
Query query = session.createQuery(“delete User u where u.username=‘赵二’”);
query.executeUpdate();
ts.commit();

	//17、基本的HQL删除,使用HQL删除记录、删除王三
		public void testDelete(){
			Configuration cfg =null;
			SessionFactory sf=null;
			Session session=null;
			Transaction ts=null;
			try {
				sf=HibernateUtil.getSessionFactory();//SessionFactory单态模式
				session=sf.getCurrentSession();//保证每个读写线程有唯一的session实例
				ts=session.beginTransaction();
				Query query = session.createQuery("delete User u where u.name='王三'");
				query.executeUpdate ();
				ts.commit();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				if(ts !=null) {
					ts.rollback();
				}
			}finally {
			}
		}

在这里插入图片描述

QBC——(Query By Criteria)

Criteria基本查询

Criteria是一个通过组装不同查询条件来获取持久对象的条件类对象,代表特定持久类的一个查询。
Criteria对SQL进行封装,让开发人员可以用对象的方式来对数据库进行操作,
例如下面的查询User表格中的所有记录:
Criteria criteria = session.createCriteria(User.class);
List users = criteria.list();
for(int i=0;i<users.size();i++)
{
user =(User)users.get(i);
System.out.println(i+"–"+user.getUsername());
}

Criteria实际上只是个容器,如果想要设定查询条件,则要使用add()方法加入Restrictions的条件限制,
例如查询age大于30且小于40的资料:
Criteria criteria = session.createCriteria(User.class);
criteria.add(Restrictions.gt(“age”, 30));
criteria.add(Restrictions.lt(“age”, 40));
List users = criteria.list();

查询名字开头为“大”的所有User
Criteria criteria = session.createCriteria(User.class);
criteria.add(Restrictions.like(“username”,“大%”));
List users = criteria.list();
查询姓名在李白和李小白之间的User
String userscope[]={“李白”,“李小白”};
Criteria criteria = session.createCriteria(User.class);
criteria.add(Restrictions.in(“username”, userscope));
List users = criteria.list();
Restrictions.allEq,参数为Map对象,使用key/value进行多个等于的比对,相当于多个Restrictions.eq的效果。
Criteria criteria = session.createCriteria(User.class);
Map cons = new HashMap();
cons.put(“name”,“李小白”) ;
cons.put(“password”,“123”);
criteria.add(Restrictions.allEq(cons));
List users = criteria.list();
也可以使用逻辑组合来进行查询
例如结合age等于(eq)20或(or)age为空(isNull)的条件:
Criteria criteria = session.createCriteria(User.class);
criteria.add(Restrictions.or(
Restrictions.eq(“age”, 40), Restrictions.eq(“username“,”王二”)
));
List users = criteria.list();
可以使用sqlRestriction()方法来提供SQL语法作限定查询
例如查询username以”大”开头的资料:
Criteria criteria = session.createCriteria(User.class);
criteria.add(Restrictions.sqlRestriction(“{alias}.username LIKE (?)”, “大%",Hibernate.STRING));
List users = criteria.list();
其中alias将被替换为与User类相关的名称,而?将被替换为大%,也就是第二个参数所提供的值

在SQL撰写时,不必再写WHERE
如果有多个查询条件,例如BETWEEN子句的查询,则可以如下:
Criteria criteria = session.createCriteria(User.class);
Integer[] ages = {new Integer(20), new Integer(40)};
Type[] types = {Hibernate.INTEGER, Hibernate.INTEGER};
criteria.add(Restrictions.sqlRestriction("{alias}.age BETWEEN (?) AND (?)", ages, types));
List users = criteria.list();
Restrictions的几个常用限定查询方法如下表所示:
在这里插入图片描述

Criteria高级查询

您可以使用Criteria进行查询,并使用Order对结果进行排序
例如使用Order.asc()由小到大排序(反之则使用desc()):
Criteria criteria = session.createCriteria(User.class);
criteria.addOrder(Order.asc(“age”));
List users = criteria.list();
setMaxResults()方法可以限定查询回来的记录数,setFirstResult()设定传回查询结果第一个记录的位置
这两个配合起来,就可以实现简单的分页。
例如返回第5条记录之后的10条记录(如果有的话):
Criteria criteria = session.createCriteria(User.class);
criteria.setFirstResult(5);
criteria.setMaxResult(10);
List users = criteria.list();
Criteria接口的Projections类主要用于帮助Criteria接口完成数据的分组查询和统计功能 。
通过Criteria的setProjection()方法应用投影到一个查询。
您可以对查询结果进行统计动作,使用Projections的avg()、rowCount()、count()、max()、min()、countDistinct()等方法。
例如对查询结果的“age”作平均:
Criteria criteria = session.createCriteria(User.class);
criteria.setProjection(Projections.avg(“age”));
Number avgage = (Number)criteria.uniqueResult();
System.out.println(“平均年龄为:”+avgage);

还可以配合Projections的groupProperty()来对结果进行分组。
例如以“age”进行分组,也就是如果资料中“age”如果有20、20、25、30,则以下会显示20、25、30:
Criteria criteria = session.createCriteria(User.class);
criteria.setProjection(Projections.groupProperty(“age”));
List ages = criteria.list();
for(int i=0;i<ages.size();i++)
{
System.out.println("–"+ages.get(i));
}
如果想结合统计与分组功能,则可以使用ProjectionList
例如下面的程序会计算每个年龄各有多少个人:
Criteria criteria = session.createCriteria(User.class);
criteria.setProjection(
Projections.projectionList().
add(Projections.count(“age”)).
add(Projections.groupProperty(“age”)));
List ages = criteria.list();
for(int i=0;i<ages.size();i++)
{
Object obj[]=(Object [])ages.get(i);
System.out.println("–"+obj[1]+":"+obj[0]);
}
使用Example对象,可以将一个已知的对象作为查询的依据,看看是否有属性与之类似的对象,也叫QBE查询。
例如:
Criteria criteria = session.createCriteria(User.class);
User user = new User();
user.setName(“大”);
user.setAge(55);
Example exampleUser =Example.create(user);
//enableLike():标识对模板类中所有的String属性进行like模糊匹配
exampleUser.enableLike(MatchMode.ANYWHERE);
criteria.add(exampleUser);
List users = criteria.list();
for(int i=0;i<users.size();i++)
{ everyuser =(User)users.get(i); System.out.println("–"+everyuser.getName()+":"+everyuser.getAge());}

DetchedCriteria高级查询

Criteria与Session绑定,其生命周期跟随着Session结束而结束,使用Criteria时进行查询时,每次都要于执行时期动态建立对象,并加入各种查询条件,随着Session的回收,Criteria也跟着回收。
在Hibernate 3.0中新增了DetchedCriteria对象,可以先建立DetchedCriteria实例,并加入各种查询条件,并于需要查询时再与Session绑定,获得一个绑定Session的Criteria对象。
DetachedCriteria类使你在一个session范围之外创建一个查询,并且可以使用任意的 Session来执行它。可以实现查询和查询条件的构造的解耦。


DetachedCriteria detachedcriteria = DetachedCriteria.forClass(User.class);
   	String name="大";
detachedcriteria.add(Restrictions.like("name",name,MatchMode.ANYWHERE));
List users = findRecordByDetachedCriteria(detachedcriteria);
     for(int i=0;i<users.size();i++)
	 {everyuser =(User)users.get(i); 
     	System.out.println("--"+everyuser.getName()+":"+everyuser.getAge());}

 public List findRecordByDetachedCriteria(DetachedCriteria detchedCriteria){
		Session s = null;
		List list = null;
		try {        s = HibernateUtil.getSession();
			Criteria criteria = detchedCriteria.getExecutableCriteria(s);
			list = criteria.list();
		} catch (HibernateException e) {
			e.printStackTrace();
		} finally{
			if(s!=null)  HibernateUtil.closeSession();
		}
		return list;
	}

高级查询的一些技巧

例如:
在实际中,经常会根据用户在客户界面的输入各种查询条件来返回结果
客户界面如下
在这里插入图片描述

HQL适合于静态查询(编程时已经确定查询字段)
QBC适合于动态查询(编程时无法确定要查询的字段,比如组合查询,往往需要查询的项很多,但不是每个项都必需)
1.查询全部属性

	//1、基本的criteria查询,查询所有属性
	public void testQueryUser(){
		Configuration cfg =null;
		SessionFactory sf=null;
		Session session=null;
		Transaction ts=null;
		try {
			sf=HibernateUtil.getSessionFactory();//SessionFactory单态模式
			session=sf.getCurrentSession();//保证每个读写线程有唯一的session实例
			ts=session.beginTransaction();
			CriteriaQuery cq=session.getCriteriaBuilder().createQuery(User.class);
			cq.from(User.class);
			List users=session.createQuery(cq).list();
			for(int i=0;i<users.size();i++)
			{
				Object u =users.get(i);
				System.out.println(u.toString());
			}
			ts.commit();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			if(ts !=null) {
				ts.rollback();
			}
		}finally {
		}
	}

在这里插入图片描述

2.根据某个属性查询
//2、基本的criteria查询,条件查询1
	public void testWhere1QueryUser(){
		Configuration cfg =null;
		SessionFactory sf=null;
		Session session=null;
		Transaction ts=null;
		try {
			sf=HibernateUtil.getSessionFactory();//SessionFactory单态模式
			session=sf.getCurrentSession();//保证每个读写线程有唯一的session实例
			ts=session.beginTransaction();
			CriteriaBuilder cb = session.getCriteriaBuilder();
			CriteriaQuery cq=cb.createQuery(User.class);
			Root<User> root=cq.from(User.class);
			//创建查询条件
			Predicate username = cb.equal(root.get("name"),"李白");
			//cq.from(User.class);
			cq.where(username);
			List users=session.createQuery(cq).list();
			for(int i=0;i<users.size();i++)
			{
				Object u =users.get(i);
				System.out.println(u.toString());
			}
			ts.commit();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			if(ts !=null) {
				ts.rollback();
			}
		}finally {
		}
	}

在这里插入图片描述
3.两个条件的查询

//3、基本的criteria查询,条件查询2
	public void testWhere2QueryUser(){
		Configuration cfg =null;
		SessionFactory sf=null;
		Session session=null;
		Transaction ts=null;
		try {
			sf=HibernateUtil.getSessionFactory();//SessionFactory单态模式
			session=sf.getCurrentSession();//保证每个读写线程有唯一的session实例
			ts=session.beginTransaction();
			CriteriaBuilder cb = session.getCriteriaBuilder();
			CriteriaQuery cq=cb.createQuery(User.class);
			Root<User> root=cq.from(User.class);
			//创建查询条件
			Predicate age1 = cb.ge(root.get("age"), 20);
			Predicate age2 = cb.le(root.get("age"), 40);
			//cq.from(User.class);
			cq.where(cb.and(age1,age2));
			List users=session.createQuery(cq).list();
			for(int i=0;i<users.size();i++)
			{
				Object u =users.get(i);
				System.out.println(u.toString());
			}
			ts.commit();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			if(ts !=null) {
				ts.rollback();
			}
		}finally {
		}
	}

在这里插入图片描述
4.模糊查询

//4、基本的criteria查询,条件查询3
		public void testWhere3QueryUser(){
			Configuration cfg =null;
			SessionFactory sf=null;
			Session session=null;
			Transaction ts=null;
			try {
				sf=HibernateUtil.getSessionFactory();//SessionFactory单态模式
				session=sf.getCurrentSession();//保证每个读写线程有唯一的session实例
				ts=session.beginTransaction();
				CriteriaBuilder cb = session.getCriteriaBuilder();
				CriteriaQuery cq=cb.createQuery(User.class);
				Root<User> root=cq.from(User.class);
				//创建查询条件
				Predicate username = cb.like(root.get("name"),"%李");
				//cq.from(User.class);
				cq.where(username);
				List users=session.createQuery(cq).list();
				for(int i=0;i<users.size();i++)
				{
					Object u =users.get(i);
					System.out.println(u.toString());
				}
				ts.commit();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				if(ts !=null) {
					ts.rollback();
				}
			}finally {
			}
		}

在这里插入图片描述
5.多个条件的查询

//5、基本的criteria查询,条件查询4
	public void testWhere4QueryUser(){
		Configuration cfg =null;
		SessionFactory sf=null;
		Session session=null;
		Transaction ts=null;
		try {
			sf=HibernateUtil.getSessionFactory();//SessionFactory单态模式
			session=sf.getCurrentSession();//保证每个读写线程有唯一的session实例
			ts=session.beginTransaction();
			CriteriaBuilder cb = session.getCriteriaBuilder();
			CriteriaQuery cq=cb.createQuery(User.class);
			Root<User> root=cq.from(User.class);
			//创建查询条件
			Predicate username = cb.like(root.get("name"),"%李%");
			Predicate gender = cb.equal(root.get("gender"),"男");
			Predicate age = cb.le(root.get("age"),50);
			//cq.from(User.class);
			cq.where(cb.and(username,cb.and(age,gender)));
			List users=session.createQuery(cq).list();
			for(int i=0;i<users.size();i++)
			{
				Object u =users.get(i);
				System.out.println(u.toString());
			}
			ts.commit();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			if(ts !=null) {
				ts.rollback();
			}
		}finally {
		}
	}

在这里插入图片描述
6.统计查询

//6、基本的criteria查询,条件查询5
	public void testWhere5QueryUser(){
		Configuration cfg =null;
		SessionFactory sf=null;
		Session session=null;
		Transaction ts=null;
		try {
			sf=HibernateUtil.getSessionFactory();//SessionFactory单态模式
			session=sf.getCurrentSession();//保证每个读写线程有唯一的session实例
			ts=session.beginTransaction();
			CriteriaBuilder cb = session.getCriteriaBuilder();
			CriteriaQuery<Object[]> cq=cb.createQuery(Object[].class);
			Root<User> root=cq.from(User.class);
			//创建查询条件
			cq.multiselect(root.get("gender"),cb.avg(root.get("age")));
			cq.groupBy(root.get("gender"));
			Query query = session.createQuery(cq);
			List users=session.createQuery(cq).getResultList();
			for(int i=0;i<users.size();i++)
			{
				Object[] objs =(Object[])users.get(i);
				System.out.println(objs[0]+" "+objs[1]);
			}
			ts.commit();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			if(ts !=null) {
				ts.rollback();
			}
		}finally {
		}
	}

在这里插入图片描述

Native SQL Queries

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值