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 {
		}
	}

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值