Criteria查询也叫做QBC查询(Query by Criteria),是完全面向对象的查询。
Criterion 是 Criteria 的查询条件。Criteria 提供了 add(Criterion criterion) 方法来添加查询条件。
Criterion 接口的主要实现包括: Example 、 Junction 和 SimpleExpression 。而Junction 的实际使用是它的两个子类 conjunction 和 disjunction ,分别是使用 AND 和 OR 操作符进行来联结查询条件集合。
Criterion 的实例可以通过 Restrictions 工具类来创建,Restrictions 提供了大量的静态方法,如 eq (等于)、 ge (大于等于)、 between 等来方法的创建 Criterion 查询条件(SimpleExpression 实例)。除此之外, Restrictions 还提供了方法来创建 conjunction 和disjunction 实例,通过往该实例的 add(Criteria) 方法来增加查询条件形成一个查询条件集合。
Example 的创建有所不同, Example 本身提供了一个静态方法 create(Objectentity) ,即根据一个对象(实际使用中一般是映射到数据库的对象)来创建。然后可以设置一些过滤条件:
Example exampleUser =Example.create(u)
.ignoreCase() // 忽略大小写
.enableLike(MatchMode.ANYWHERE); // 对 String 类型的属性,无论在那里值在那里都匹配。相当于 %value%
Project 主要是让 Criteria 能够进行报表查询,并可以实现分组。 Project 主要有SimpleProjection 、ProjectionList 和 Property 三个实现。其中SimpleProjection 和ProjectionList 的实例化是由内建的Projections 来完成,如提供的 avg 、count 、max 、min 、sum 可以让开发者很容易对某个字段进行统计查询。
Property 是对某个字段进行查询条件的设置,如通过Porperty.forName(“color”). in(new String[]{“black”,”red”,”write”}); 则可以创建一个 Project 实例。通过criteria 的 add(Project) 方法加入到查询条件中去。
案例:
卡号实体类:
package com.liuyongqi.MavenHibernateDemo7.entity;
import java.io.Serializable;
/**
* 卡号实体类
* @author Administrator
* @data 2018年8月6日
* @time 上午11:51:34
*/
public class Card implements Serializable {
/**
*
*/
private static final long serialVersionUID = -3229041685479626246L;
private Integer pid; //卡号编号
private String cname; //卡号名称
private Person person; //个人对象
public Card() {
super();
// TODO Auto-generated constructor stub
}
public Card(String cname, Integer pid) {
super();
this.cname = cname;
this.pid = pid;
}
public String getCname() {
return cname;
}
public void setCname(String cname) {
this.cname = cname;
}
public Integer getPid() {
return pid;
}
public void setPid(Integer pid) {
this.pid = pid;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
@Override
public String toString() {
return "Card [pid=" + pid + ", cname=" + cname + ", person=" + person + "]";
}
}
个人实体类:
package com.liuyongqi.MavenHibernateDemo7.entity;
import java.io.Serializable;
/**
* 个人实体类
* @author Administrator
* @data 2018年8月6日
* @time 上午11:49:17
*/
public class Person implements Serializable {
/**
*
*/
private static final long serialVersionUID = -2013313014914594043L;
private Integer pid; //个人编号
private String pname; //个人名称
private Card card; //卡号对象
public Person() {
super();
// TODO Auto-generated constructor stub
}
public Person(String pname) {
super();
this.pname = pname;
}
public Person(Integer pid, String pname) {
super();
this.pid = pid;
this.pname = pname;
}
public Integer getPid() {
return pid;
}
public void setPid(Integer pid) {
this.pid = pid;
}
public String getPname() {
return pname;
}
public void setPname(String pname) {
this.pname = pname;
}
public Card getCard() {
return card;
}
public void setCard(Card card) {
this.card = card;
}
@Override
public String toString() {
return "Person [pid=" + pid + ", pname=" + pname + "]";
}
}
Card.hbm.xml:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2018-8-8 11:44:35 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<class name="com.liuyongqi.MavenHibernateDemo7.entity.Card" table="card">
<id name="pid" type="java.lang.Integer">
<column name="pid" />
<generator class="foreign" >
<param name="property">person</param>
</generator>
</id>
<property name="cname" type="java.lang.String">
<column name="cname" />
</property>
<one-to-one name="person" class="com.liuyongqi.MavenHibernateDemo7.entity.Person"></one-to-one>
</class>
</hibernate-mapping>
Person.hbm.xml:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2018-8-8 11:44:35 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<class name="com.liuyongqi.MavenHibernateDemo7.entity.Person" table="person">
<id name="pid" type="java.lang.Integer">
<column name="pid" />
<generator class="native" />
</id>
<property name="pname" type="java.lang.String">
<column name="pname" />
</property>
<one-to-one name="card" class="com.liuyongqi.MavenHibernateDemo7.entity.Card" cascade="all-delete-orphan"></one-to-one>
</class>
<!-- query节点定义查询语句 -->
<query name="queryTest"><![CDATA[FROM Person p where p.pid > 2]]></query>
</hibernate-mapping>
SessionFactoryUtil工具类:
package com.liuyongqi.MavenHibernateDemo7.util;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
/**
* 提供了开启和关闭session的方法
* @author Administrator
* @data 2018年8月1日
* @time 下午3:32:56
*/
public class SessionFactoryUtil {
//ThreadLocal为每个线程提供一个单独的存储空间
private static ThreadLocal<Session> threadLocal=new ThreadLocal<Session>();
//私有化静态变量,静态变量只实例化一次
private static SessionFactory sessionFactory;
//实例化一次sessionFactory
static {
Configuration configure = new Configuration().configure();
sessionFactory=configure.buildSessionFactory();
}
//私有化构造方法
private SessionFactoryUtil() {
}
//打开session的方法
public static Session openSession() {
//从ThreadLocal中拿取一个session
Session session = threadLocal.get();
if(null==session) {
//sessionFactory打开一个session
session=sessionFactory.openSession();
//把session又放入ThreadLocal中
threadLocal.set(session);
}
return session;
}
//关闭资源
public static void closeSession() {
//从ThreadLocal中拿取一个session
Session session = threadLocal.get();
if(null==session) {
if(session.isOpen()) {
//关闭session
session.close();
}
threadLocal.set(null);
}
}
public static void main(String[] args) {
Session session = openSession();
System.out.println(session);
System.out.println("ok");
}
}
(1)查询所有:
测试代码:
Session session = SessionFactoryUtil.openSession();
Criteria criteria = session.createCriteria(Person.class);
List<Person> list = criteria.list();
System.out.println(list);
控制台结果:
Hibernate:
select
this_.pid as pid1_1_1_,
this_.pname as pname2_1_1_,
card2_.pid as pid1_0_0_,
card2_.cname as cname2_0_0_
from
person this_
left outer join
card card2_
on this_.pid=card2_.pid
[Person [pid=1, pname=王五], Person [pid=2, pname=刘三], Person [pid=3, pname=李四], Person [pid=5, pname=李四1]]
(2)条件查询
使用add方法,表示设置条件值,并在里面使用Restrictions类的方法实现条件设置
测试代码:
Session session = SessionFactoryUtil.openSession();
Transaction transaction = session.beginTransaction();
//(2)条件查询
//使用add方法,表示设置条件值,并在里面使用Restrictions类的方法实现条件设置
Criteria criteria = session.createCriteria(Person.class);
//criteria.add(Restrictions.eq("pid", 1)); //pid=1
//criteria.add(Restrictions.like("pname", "%王%")); //pname like '王'
criteria.add(Restrictions.between("pid", 1, 5)); //pid between 1 and 5
List<Person> list =criteria.list();
System.out.println(list);
控制台结果:
Hibernate:
select
this_.pid as pid1_1_1_,
this_.pname as pname2_1_1_,
card2_.pid as pid1_0_0_,
card2_.cname as cname2_0_0_
from
person this_
left outer join
card card2_
on this_.pid=card2_.pid
where
this_.pid between ? and ?
[Person [pid=1, pname=王五], Person [pid=2, pname=刘三], Person [pid=3, pname=李四], Person [pid=5, pname=李四1]]
(3)排序查询
使用addOrder方法和Order类
测试代码:
Session session = SessionFactoryUtil.openSession();
Transaction transaction = session.beginTransaction();
//(3)排序查询
//使用addOrder方法和Order类
Criteria criteria = session.createCriteria(Person.class);
criteria.addOrder(Order.desc("pname"));
List<Person> list =criteria.list();
System.out.println(list);
控制台结果:
Hibernate:
select
this_.pid as pid1_1_1_,
this_.pname as pname2_1_1_,
card2_.pid as pid1_0_0_,
card2_.cname as cname2_0_0_
from
person this_
left outer join
card card2_
on this_.pid=card2_.pid
order by
this_.pname desc
[Person [pid=1, pname=王五], Person [pid=5, pname=李四1], Person [pid=3, pname=李四], Person [pid=2, pname=刘三]]
(4)分页查询
测试代码:
Session session = SessionFactoryUtil.openSession();
Transaction transaction = session.beginTransaction(););
//(4)分页查询
Criteria criteria = session.createCriteria(Person.class);
criteria.setFirstResult(1);
criteria.setMaxResults(2);
List<Person> list =criteria.list();
System.out.println(list);
控制台结果:
Hibernate:
select
this_.pid as pid1_1_1_,
this_.pname as pname2_1_1_,
card2_.pid as pid1_0_0_,
card2_.cname as cname2_0_0_
from
person this_
left outer join
card card2_
on this_.pid=card2_.pid limit ?,
?
[Person [pid=2, pname=刘三], Person [pid=3, pname=李四]]
(5)统计查询(Projections)
测试代码:
Session session = SessionFactoryUtil.openSession();
Transaction transaction = session.beginTransaction();
//(5)统计查询(Projections)
Criteria criteria = session.createCriteria(Person.class);
//设置做统计行的操作
criteria.setProjection(Projections.rowCount());
//调用方法得到结果
Object result = criteria.uniqueResult();
int count=Integer.parseInt(result.toString());
System.out.println(count);
控制台结果:
Hibernate:
select
count(*) as y0_
from
person this_
4
(6)离线查询(DetachedCriteria)
即不用session对象也能查询到数据
测试代码:
Session session = SessionFactoryUtil.openSession();
Transaction transaction = session.beginTransaction();
//(6)离线查询(DetachedCriteria)
//即不用session对象也能查询到数据
DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Person.class);
Criteria criteria = detachedCriteria.getExecutableCriteria(session);
List<Person> list =criteria.list();
System.out.println(list);
控制台结果:
Hibernate:
select
this_.pid as pid1_1_1_,
this_.pname as pname2_1_1_,
card2_.pid as pid1_0_0_,
card2_.cname as cname2_0_0_
from
person this_
left outer join
card card2_
on this_.pid=card2_.pid
[Person [pid=1, pname=王五], Person [pid=2, pname=刘三], Person [pid=3, pname=李四], Person [pid=5, pname=李四1]]
今天的测试就到这里了,希望大家看完以后自己测试一下
如果大家想浏览我的下一篇文章,请留言
此文章属于原创,不准随意转载:https://blog.csdn.net/LYQ2332826438