1.比较运算符
HQL运算符 QBC(Query By Criteria)运算符 含义
= Restrictions.eq() 等于
<> Restrictions.not(Exprission.eq()) 不等于
> Restrictions.gt() 大于
>= Restrictions.ge() 大于等于
< Restrictions.lt() 小于
<= Restrictions.le() 小于等于
is null Restrictions.isnull() 等于空值
is not null Restrictions.isNotNull() 非空值
like Restrictions.like() 字符串模式匹配
and Restrictions.and() 逻辑与
and Restrictions.conjunction() 逻辑与
or Restrictions.or() 逻辑或
or Restrictions.disjunction() 逻辑或
not Restrictions.not() 逻辑非
in(列表) Restrictions.in() 等于列表中的某一个值
ont in(列表) Restrictions.not(Restrictions.in())不等于列表中任意一个值
between x and y Restrictions.between() 闭区间xy中的任意值
not between x and y Restrictions.not(Restrictions..between()) 小于值X或者大于值y
2. 实体类:
- public class DocumentInfo implements Serializable {
- private Integer documentId;
- private String documentUrl;
- private String documentName;
- private String documentDescription;
- private Date uploadTime;
- private Set<DocumentToRole> documentToRoles= new HashSet<DocumentToRole>();
- private Set<DocumentToDepartment> documentToDepartments = new HashSet<DocumentToDepartment>();
- private Set<UserVisitedDocument> userVisitedDocuments = new HashSet<UserVisitedDocument>();
- //setter和getter方法....
- }
public class DocumentInfo implements Serializable { private Integer documentId; private String documentUrl; private String documentName; private String documentDescription; private Date uploadTime; private Set<DocumentToRole> documentToRoles= new HashSet<DocumentToRole>(); private Set<DocumentToDepartment> documentToDepartments = new HashSet<DocumentToDepartment>(); private Set<UserVisitedDocument> userVisitedDocuments = new HashSet<UserVisitedDocument>(); //setter和getter方法.... }
映射文件DocumentInfo.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">
- <hibernate-mapping package="com.reiyendms.model.pojo">
- <class name="DocumentInfo" table="document_info" >
- <id name="documentId" column="document_id" unsaved-value="null">
- <generator class="native" />
- </id>
- <property name="documentUrl" column="document_url" length="200" not-null="true" unique="true"/>
- <property name="documentName" column="document_name" length="100" />
- <property name="documentDescription" column="document_description" />
- <property name="uploadTime" column="upload_time" type="timestamp"/>
- <set name="documentToRoles" cascade="all" inverse="true">
- <key column="document_id" />
- <one-to-many class="DocumentToRole" />
- </set>
- <set name="documentToDepartments" cascade="all" inverse="true" >
- <key column="document_id" />
- <one-to-many class="DocumentToDepartment" />
- </set>
- <set name="userVisitedDocuments" cascade="all" inverse="true" >
- <key column="document_id" />
- <one-to-many class="UserVisitedDocument" />
- </set>
- </class>
- </hibernate-mapping>
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.reiyendms.model.pojo"> <class name="DocumentInfo" table="document_info" > <id name="documentId" column="document_id" unsaved-value="null"> <generator class="native" /> </id> <property name="documentUrl" column="document_url" length="200" not-null="true" unique="true"/> <property name="documentName" column="document_name" length="100" /> <property name="documentDescription" column="document_description" /> <property name="uploadTime" column="upload_time" type="timestamp"/> <set name="documentToRoles" cascade="all" inverse="true"> <key column="document_id" /> <one-to-many class="DocumentToRole" /> </set> <set name="documentToDepartments" cascade="all" inverse="true" > <key column="document_id" /> <one-to-many class="DocumentToDepartment" /> </set> <set name="userVisitedDocuments" cascade="all" inverse="true" > <key column="document_id" /> <one-to-many class="UserVisitedDocument" /> </set> </class> </hibernate-mapping>
3.一些查询实例
1).使用DetachedCriteria,在Service层构建好DetachedCriteria后,传入到Dao层进行查询:
- private DetachedCriteria getDocQueryDC(DocumentSearchBean searchBean,
- boolean isSortResult) {
- DetachedCriteria dc = DetachedCriteria.forClass(DocumentInfo.class);
- //去除重复记录
- dc.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
- if (searchBean.getName() != null && !searchBean.getName().isEmpty()) {
- dc.add(Restrictions.ilike("documentName", searchBean.getName(),
- MatchMode.ANYWHERE));
- }
- if (searchBean.getDescription() != null
- && !searchBean.getDescription().isEmpty()) {
- dc.add(Restrictions.ilike("documentDescription", searchBean
- .getDescription(), MatchMode.ANYWHERE));
- }
- if (searchBean.getSatrtDate() != null) {
- dc
- .add(Restrictions.between("uploadTime", searchBean
- .getSatrtDate(), searchBean
- .getEndDate()));
- }
- if (searchBean.getRoleInfo() != null) {
- dc.setFetchMode("documentToRoles", FetchMode.JOIN); //1
- dc.createCriteria(("documentToRoles")).add( Restrictions.eq("roleInfo", searchBean.getRoleInfo())); //2
- // dc.createAlias("documentToRoles",
- // "dtr").add(Restrictions.eq("dtr.roleInfo",
- // searchBean.getRoleInfo())); //3
- }
- if (searchBean.getDeparts() != null
- && searchBean.getDeparts().size() > 0) {
- dc.setFetchMode("documentToDepartments", FetchMode.JOIN);
- dc.createCriteria(("documentToDepartments")).add(
- Restrictions.in("departmentInfo", searchBean
- .getDeparts()));
- }
- //是否要排序
- if (isSortResult) {
- String sortName = searchBean.getSortName().trim();
- if (sortName != null && !sortName.isEmpty()) {
- if (searchBean.getSortOrder().equalsIgnoreCase("asc")) {
- dc.addOrder(Order.asc(sortName));
- }
- else {
- dc.addOrder(Order.desc(sortName));
- }
- }
- else {
- dc.addOrder(Order.desc("documentId"));
- }
- }
- return dc;
- }
private DetachedCriteria getDocQueryDC(DocumentSearchBean searchBean, boolean isSortResult) { DetachedCriteria dc = DetachedCriteria.forClass(DocumentInfo.class); //去除重复记录 dc.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); if (searchBean.getName() != null && !searchBean.getName().isEmpty()) { dc.add(Restrictions.ilike("documentName", searchBean.getName(), MatchMode.ANYWHERE)); } if (searchBean.getDescription() != null && !searchBean.getDescription().isEmpty()) { dc.add(Restrictions.ilike("documentDescription", searchBean .getDescription(), MatchMode.ANYWHERE)); } if (searchBean.getSatrtDate() != null) { dc .add(Restrictions.between("uploadTime", searchBean .getSatrtDate(), searchBean .getEndDate())); } if (searchBean.getRoleInfo() != null) { dc.setFetchMode("documentToRoles", FetchMode.JOIN); //1 dc.createCriteria(("documentToRoles")).add( Restrictions.eq("roleInfo", searchBean.getRoleInfo())); //2 // dc.createAlias("documentToRoles", // "dtr").add(Restrictions.eq("dtr.roleInfo", // searchBean.getRoleInfo())); //3 } if (searchBean.getDeparts() != null && searchBean.getDeparts().size() > 0) { dc.setFetchMode("documentToDepartments", FetchMode.JOIN); dc.createCriteria(("documentToDepartments")).add( Restrictions.in("departmentInfo", searchBean .getDeparts())); } //是否要排序 if (isSortResult) { String sortName = searchBean.getSortName().trim(); if (sortName != null && !sortName.isEmpty()) { if (searchBean.getSortOrder().equalsIgnoreCase("asc")) { dc.addOrder(Order.asc(sortName)); } else { dc.addOrder(Order.desc(sortName)); } } else { dc.addOrder(Order.desc("documentId")); } } return dc; }
程序中标记为1,2的两句话与与被注释的标记为3的程序的效果是一样的,都会用inner join去查询,产生的sql语句如下:Hibernate: selectthis_.document_id as document1_1_1_, this_.document_url as document2_1_1_, this_.document_name as document3_1_1_,this_.document_description as document4_1_1_, this_.upload_time as upload5_1_1_, documentto1_.id as id3_0_, documentto1_.role_id
as role2_3_0_, documentto1_.document_id as document3_3_0_ from document_info this_ inner join document_to_role documentto1_ on this_.document_id=documentto1_.document_id where documentto1_.role_id=? order by this_.document_id desc limit ?
Dao层代码如下所示,使用了Spring的HibernateTemplate进行分布显示:
- public List<DocumentInfo> getDocListForPage(final DetachedCriteria dc,
- final int offset, final int length) {
- List<DocumentInfo> list = hibernateTemplate
- .executeFind(new HibernateCallback() {
- public Object doInHibernate(Session session)
- throws HibernateException,
- SQLException {
- Criteria criteria = dc
- .getExecutableCriteria(session);
- criteria.setFirstResult(offset);
- criteria.setMaxResults(length);
- return criteria.list();
- }
- });
- return list;
- }
public List<DocumentInfo> getDocListForPage(final DetachedCriteria dc, final int offset, final int length) { List<DocumentInfo> list = hibernateTemplate .executeFind(new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException, SQLException { Criteria criteria = dc .getExecutableCriteria(session); criteria.setFirstResult(offset); criteria.setMaxResults(length); return criteria.list(); } }); return list; }
如果是要得到总记录数的话,可以使用投影,如下所示:
- Criteria criteria = dc.getExecutableCriteria(session);
- riteria.setProjection(Projections.rowCount());
Criteria criteria = dc.getExecutableCriteria(session); criteria.setProjection(Projections.rowCount());
2). Restrictions.or操作:
两个条件或查询:
//相当于查找documentName like %str1% or uploadTime between date1 and date2
- criteria.add(Restrictions.or(Restrictions.ilike("documentName", str1,MatchMode.ANYWHERE),Restrictions.between("uploadTime", date1,date2)));
criteria.add(Restrictions.or(Restrictions.ilike("documentName", str1,MatchMode.ANYWHERE),Restrictions.between("uploadTime", date1,date2)));
三个或多个条件查询:(使用嵌套方式)
//相当于查找documentName like %str1% or uploadTime between date1 and date2 or documentId =4
- criteria.add(Restrictions.or(Restrictions.ilike("documentName", str1,MatchMode.ANYWHERE),Restrictions.or(Restrictions.between("uploadTime", date1,date2), Restrictions.idEq(4))));
criteria.add(Restrictions.or(Restrictions.ilike("documentName", str1,MatchMode.ANYWHERE),Restrictions.or(Restrictions.between("uploadTime", date1,date2), Restrictions.idEq(4))));
3).Restrictions.not操作: Restrictions.not(Restrictions.in())不等于列表中任意一个值
- criteria.add(Restrictions.not(Restrictions.in("documentId", list)));
criteria.add(Restrictions.not(Restrictions.in("documentId", list)));
它转换成sql 语句时,如下所示:
where not (this_.document_id in (?, ?, ?))
与我们一般的习惯写示: this_.document_id not in (?,?,?)有些区别,但效果是一样.
也可以直接使用Restrictions提供的sqlRestriction来达到同样的目的,sqlRestriction有三个重载类型:如下所示:
1.static Criterion sqlRestriction(String sql) :Apply a constraint expressed in SQL.
2.static Criterion sqlRestriction(String sql, Object[] values, Type[] types): Apply a constraint expressed in SQL, with the given JDBC parameters.
3.static Criterion sqlRestriction(String sql, Object value, Type type): Apply a constraint expressed in SQL, with the given JDBC parameter.
直接在Criteria中使用sql时,一定要特别注意使用别名,否则你会遇到一些异常:
如下所示:
- DetachedCriteria dc = DetachedCriteria.forClass(DocumentInfo.class);
- if (list != null && list.size() != 0) {
- String ids = list.toString().substring(1,
- list.toString().length() - 1);
- String sql = " document_id not in (" + ids + ") ";
- dc.add(Restrictions.sqlRestriction(sql));
- }
- Set<RoleInfo> roleInfos = searchBean.getRoleInfos();
- if (roleInfos != null && roleInfos.size() != 0) {
- dc.setFetchMode("documentToRoles", FetchMode.JOIN);
- dc.createCriteria(("documentToRoles")).add(
- Restrictions.in("roleInfo", roleInfos));
- }
- ........
DetachedCriteria dc = DetachedCriteria.forClass(DocumentInfo.class); if (list != null && list.size() != 0) { String ids = list.toString().substring(1, list.toString().length() - 1); String sql = " document_id not in (" + ids + ") "; dc.add(Restrictions.sqlRestriction(sql)); } Set<RoleInfo> roleInfos = searchBean.getRoleInfos(); if (roleInfos != null && roleInfos.size() != 0) { dc.setFetchMode("documentToRoles", FetchMode.JOIN); dc.createCriteria(("documentToRoles")).add( Restrictions.in("roleInfo", roleInfos)); } ........
你会遇到如下异常:Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'document_id' in where clause is ambiguous
因为你进行关联查询时,它不知道document_id是document_info表中的 document_id还是document_to_role表中的,这时你就得使用别名,改成如下形式,就不会报错了:
- DetachedCriteria dc = DetachedCriteria.forClass(DocumentInfo.class,"doc");
- if (list != null && list.size() != 0) {
- String ids = list.toString().substring(1,
- list.toString().length() - 1);
- String sql = " doc.document_id not in (" + ids + ") ";
- dc.add(Restrictions.sqlRestriction(sql));
- }
DetachedCriteria dc = DetachedCriteria.forClass(DocumentInfo.class,"doc"); if (list != null && list.size() != 0) { String ids = list.toString().substring(1, list.toString().length() - 1); String sql = " doc.document_id not in (" + ids + ") "; dc.add(Restrictions.sqlRestriction(sql)); }
但是如果你没有进行多表关联查询(也就是没有与其他对象进行关联查询),而只是进行了document_info表(DocumentInfo)的查询,那它就不会报前面的异常.
4.Subqueryes对象的使用:
复杂的查询使用criteria和subqueries可以达到很好的效果,先看看subquery:Factory class for criterion instances that represent expressions involving subqueries,使用Subquery时还有一个类一定会用到DetachedCriteria:
目标:统计某一专业的学生毕业人数
由于毕业涉及到学生课程学分的问题,所以就是课程表中的学分数值总数相等或则大于毕业要求学分,毕业学分这一栏在学生这一张表中。
首先生成一个DetachedCriteria实例:
- DetachedCriteria dc=DetachedCriteria.forClass(Course.class);
- dc.setProjection(Projections.count("CCredites"));
DetachedCriteria dc=DetachedCriteria.forClass(Course.class); dc.setProjection(Projections.count("CCredites"));
之后生成一个criteria:
- List<Student> l=session.createCriteria(Student.class,"s").add(Restrictions.eq("stuField", stuField)).add(Subqueries.propertyLe("graduateCount", dc)).list();
List<Student> l=session.createCriteria(Student.class,"s").add(Restrictions.eq("stuField", stuField)).add(Subqueries.propertyLe("graduateCount", dc)).list();
最后我们看看这个发放的完整的形式:
- @SuppressWarnings("unchecked")
- @Override
- public int countGraduateStudents(String stuField)//通过学生的专业查询一个专业的毕业人数
- {
- Session session=sessionFactory.openSession();
- DetachedCriteria dc=DetachedCriteria.forClass(Course.class);
- dc.setProjection(Projections.count("CCredites"));//获得一个DetachedCriteria
- List<Student> l=session.createCriteria(Student.class).add(Restrictions.eq("stuField", stuField)).add(Subqueries.propertyLe("graduateCount", dc)).list();//得到一个学生集合
- int inte=l.size();
- return inte;
- }
@SuppressWarnings("unchecked") @Override public int countGraduateStudents(String stuField)//通过学生的专业查询一个专业的毕业人数 { Session session=sessionFactory.openSession(); DetachedCriteria dc=DetachedCriteria.forClass(Course.class); dc.setProjection(Projections.count("CCredites"));//获得一个DetachedCriteria List<Student> l=session.createCriteria(Student.class).add(Restrictions.eq("stuField", stuField)).add(Subqueries.propertyLe("graduateCount", dc)).list();//得到一个学生集合 int inte=l.size(); return inte; }
SQL:
Hibernate:
select
this_.ID_STU as ID1_0_0_,
this_.STU_NAME as STU2_0_0_,
this_.ID_STUDENTS as ID3_0_0_,
this_.STU_PSD as STU4_0_0_,
this_.STU_SIX as STU5_0_0_,
this_.STU_FORM as STU6_0_0_,
this_.STU_CLASS as STU7_0_0_,
this_.STU_FIELD as STU8_0_0_,
this_.STU_DATE_ENTER as STU9_0_0_,
this_.STU_PUNISH as STU10_0_0_,
this_.STU_GRADUATE as STU11_0_0_
from
students_course.student this_
where
this_.STU_FIELD=?
and this_.STU_GRADUATE <= (
select
count(this0__.C_CREDITES) as y0_
from
students_course.course this0__
)
由于使用了subqueries,我们就一次性的到数据库中查询,其实也可以用2个语句得到这个结果,但是那样的性能不是很好。
相关推荐
本资源“Hibernate QBC高级查询”聚焦于Hibernate Query by Criteria(QBC)的高级用法,旨在帮助开发者深入理解并熟练运用这一强大的查询机制。 Query by Criteria是Hibernate提供的另一种查询方式,与HQL...
标题"Hibernate_QBC和Hibernate_QBE"提及了两个关于Hibernate的查询方式,即Query By Criteria(QBC)和Query By Example(QBE)。Hibernate是Java领域中一个广泛使用的对象关系映射(ORM)框架,它允许开发者以面向...
本篇文章将深入探讨Hibernate中的QBC(Query By Example)条件查询与传统的HQL(Hibernate Query Language)查询的对比,帮助开发者更好地理解和选择适合的查询方式。 QBC(Query By Example)是Hibernate提供的一...
本篇将详细介绍如何使用Hibernate的Query By Criteria (QBC)方式进行分页查询。 首先,我们需要了解QBC的基本概念。QBC是Hibernate提供的一种基于对象的查询方式,与HQL(Hibernate Query Language)类似,但更接近...
它支持多种查询方式,包括面向对象的查询语言(HQL)、条件查询(Query By Criteria, QBC)、示例查询(Query By Example, QBE)以及原生SQL查询等。 #### 二、面向对象查询语言 (HQL) HQL是一种类似SQL的语言,但...
Criteria 查询机制主要包括 QBE(Query By Example)、QBC(Query By Criteria)和 HQL(Hibernate Query Language)三种方式。 QBE(Query By Example) QBE 是一种基于示例的查询机制,它可以根据一个示例对象来...
标题中的“Hibernate-HQL-QBC-QBE”涵盖了四个重要的Java持久化框架Hibernate中的概念,分别是Hibernate Query Language(HQL)、Query By Criteria(QBC)、Query By Example(QBE)以及相关的库文件。以下是对这些...
Hibernate QBC(Query By Criteria)查询是Hibernate框架中一种面向对象的查询方式,它通过提供Criteria API使得开发者能够更方便地构建和执行SQL查询。QBC查询的优势在于它允许程序员用更加面向对象的方式处理...
QBC(Query By Criteria)是另一种查询方式,它提供了一种基于Java API的查询方法,适合于不熟悉HQL的开发者。QBC允许通过构建Criteria对象来创建查询,然后执行查询获取结果。 总的来说,HQL提供了强大的面向对象...
2. **Query By Criteria (QBC)** QBC更加强大,因为它允许通过`Criteria`、`Criterion`、`Order`和`Restrictions`类来精确地构建查询。例如: ```java Criteria cri = session.createCriteria(JdItemSerialnumber...
QBC的相关讲义和例题 QBC(Query By Criteria)查询方式是Hibernate提供的“更加面向对象”的一种检索方式。QBC在条件查询上比HQL查询更为灵活,而且支持运行时动态生成查询语句。
本教程将深入探讨Hibernate中的两种查询方式:HQL(Hibernate Query Language)和QBC(Query By Example)。通过实例开发,我们将了解这两种查询方法的使用和它们之间的差异。 首先,HQL是Hibernate专门设计的一种...
QBC,全称为Query By Criteria,是Java世界中一种基于对象的查询方式,主要用于简化Hibernate框架中的数据查询操作。QBC提供了一种面向对象的方式来构建查询条件,与SQL语句相比,它更易于理解和维护,尤其在处理...
2. Query By Criteria (QBC) QBC是Criteria API的核心,它使用`Criteria`、`Criterion`、`Order`和`Restrictions`类来构建查询。以下是一个示例: ```java Criteria cri = session.createCriteria...
QBC(Query By Example)和QBE(Query By Example)是两种在ORM(Object-Relational Mapping)框架中,特别是Hibernate中使用的查询方法。这两种查询方式都是为了简化SQL语句的编写,使得开发者能更专注于业务逻辑,...
Hibernate QBC(Query By Criteria)查询是Criteria查询的另一种表达方式,其本质与Criteria查询相同,都是通过构建对象化的查询条件执行SQL。在QBC中,`Expression`类的角色被`Restrictions`类取代,但工作方式类似...
1. **标准查询简介(QBC:Query By Criteria)** Criteria API 的核心在于`Criteria`对象,它是通过`Session`的`createCriteria()`方法创建的。以下是一个简单的例子,查询所有`Employee`类的实例: ```java ...
根据提供的文件信息,我们可以推断出此文档主要讨论了QBC(Query By Criteria)查询方法在Hibernate框架中的应用。下面将对文档中的几个关键点进行详细的解析与扩展。 ### QBC查询简介 QBC(Query By Criteria)是...