加强hibernate的criteria查询中的使用Example查询的
来源:互联网 发布:stm32烧录软件 编辑:程序博客网 时间:2024/05/21 10:46
有人说Query更强大,但我人个比较喜欢用criteria,觉得使用criteria才符合Java开发的规范。
但criteria在使用example进行关联的对象查询时,会得到非预期的结果。
举个例子:
两个简单实体类Department:(部门)
以及另一个类Employee:(员工)
这两个表的关联关系我就不多说了,这行都应该都懂,呵呵。。。
此时,我需要通过一些特定的条件去查找employee,当然分页什么的就不说了,因为查询条件会根据客户需求不同而不同,所以直接使用Example进行操作
[code=java]
Criteria criteria = getSession().createCriteria(Employee.class);
if (empoyee != null) {
criteria.add(Example.create(empoyee ));//这里会忽略关联
}
//.....中间是分页等处理
List<?> result = criteria.list();
[/code]
注意上面的注释,Example进行查询是会忽略所有的null值以及关联的对象,故,如果我想根据empoyee 的department来查询empoyee 的话,就会将所有的empoyee 都查询出来,因为department被忽略了。
遇到这个问题有两种解决方法:
一、我的做法如下:
[code=java]
Criteria criteria = getSession().createCriteria(Employee.class);
if (empoyee != null) {
criteria.add(Example.create(empoyee ));//这里会忽略关联
//加强后的Example查寻,不再忽略关联对象
criteria.createCriteria("dpartment").add(Restrictions.eq("id",empoyee .getDepartment.getId()));
}
//.....中间是分页等处理
List<?> result = criteria.list();
[/code]
二、下面是我在网上看到别人的做法,个人感觉有点麻烦:
(转)那么这个问题怎么解决呢,查看了Example类的源码后,我决定动手修改——当然不能直接去改它的源码,在参考了hibernate官方论坛后,新建了类:
[code=java]
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.hibernate.Criteria;
import org.hibernate.EntityMode;
import org.hibernate.HibernateException;
import org.hibernate.criterion.CriteriaQuery;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Restrictions;
import org.hibernate.criterion.SimpleExpression;
import org.hibernate.engine.TypedValue;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.type.AbstractComponentType;
import org.hibernate.type.Type;
import org.hibernate.util.StringHelper;
/**
* A copy of Hibernate's Example class, with modifications that allow you to
* include many-to-one and one-to-one associations in Query By Example (QBE)
* queries.
* association class </a>
*/
public class AssociationExample implements Criterion {
private final Object entity;
private final Set excludedProperties = new HashSet();
private PropertySelector selector;
private boolean isLikeEnabled;
private boolean isIgnoreCaseEnabled;
private MatchMode matchMode;
private boolean includeAssociations = true;
/**
* A strategy for choosing property values for inclusion in the query
* criteria
*/
public static interface PropertySelector {
public boolean include(Object propertyValue, String propertyName, Type type);
}
private static final PropertySelector NOT_NULL = new NotNullPropertySelector();
private static final PropertySelector ALL = new AllPropertySelector();
private static final PropertySelector NOT_NULL_OR_ZERO = new NotNullOrZeroPropertySelector();
static final class AllPropertySelector implements PropertySelector {
public boolean include(Object object, String propertyName, Type type) {
return true;
}
}
static final class NotNullPropertySelector implements PropertySelector {
public boolean include(Object object, String propertyName, Type type) {
return object!=null;
}
}
static final class NotNullOrZeroPropertySelector implements PropertySelector {
public boolean include(Object object, String propertyName, Type type) {
return object!=null && (
!(object instanceof Number) || ( (Number) object ).longValue()!=0
);
}
}
/**
* Set the property selector
*/
public AssociationExample setPropertySelector(PropertySelector selector) {
this.selector = selector;
return this;
}
/**
* Exclude zero-valued properties
*/
public AssociationExample excludeZeroes() {
setPropertySelector(NOT_NULL_OR_ZERO);
return this;
}
/**
* Don't exclude null or zero-valued properties
*/
public AssociationExample excludeNone() {
setPropertySelector(ALL);
return this;
}
/**
* Use the "like" operator for all string-valued properties
*/
public AssociationExample enableLike(MatchMode matchMode) {
isLikeEnabled = true;
this.matchMode = matchMode;
return this;
}
/**
* Use the "like" operator for all string-valued properties
*/
public AssociationExample enableLike() {
return enableLike(MatchMode.EXACT);
}
/**
* Ignore case for all string-valued properties
*/
public AssociationExample ignoreCase() {
isIgnoreCaseEnabled = true;
return this;
}
/**
* Exclude a particular named property
*/
public AssociationExample excludeProperty(String name) {
excludedProperties.add(name);
return this;
}
/**
* Create a new instance, which includes all non-null properties
* by default
* @param entity
* @return a new instance of <tt>Example</tt>
*/
public static AssociationExample create(Object entity) {
if (entity==null) throw new NullPointerException("null AssociationExample");
return new AssociationExample(entity, NOT_NULL);
}
protected AssociationExample(Object entity, PropertySelector selector) {
this.entity = entity;
this.selector = selector;
}
public String toString() {
return "example (" + entity + ')';
}
private boolean isPropertyIncluded(Object value, String name, Type type) {
return
!excludedProperties.contains(name) &&
selector.include(value, name, type) &&
(!type.isAssociationType() ||
(type.isAssociationType() &&
includeAssociations &&
!type.isCollectionType()));
}
public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery)
throws HibernateException {
StringBuffer buf = new StringBuffer().append('(');
EntityPersister meta = criteriaQuery.getFactory().getEntityPersister( criteriaQuery.getEntityName(criteria) );
String[] propertyNames = meta.getPropertyNames();
Type[] propertyTypes = meta.getPropertyTypes();
//TODO: get all properties, not just the fetched ones!
Object[] propertyValues = meta.getPropertyValues( entity, getEntityMode(criteria, criteriaQuery) );
for (int i=0; i<propertyNames.length; i++) {
Object propertyValue = propertyValues[i];
String propertyName = propertyNames[i];
boolean isPropertyIncluded = i!=meta.getVersionProperty() &&
isPropertyIncluded( propertyValue, propertyName, propertyTypes[i] );
if (isPropertyIncluded) {
if ( propertyTypes[i].isComponentType() ) {
appendComponentCondition(
propertyName,
propertyValue,
(AbstractComponentType) propertyTypes[i],
criteria,
criteriaQuery,
buf
);
}
else {
appendPropertyCondition(
propertyName,
propertyValue,
criteria,
criteriaQuery,
buf
);
}
}
}
if ( buf.length()==1 ) buf.append("1=1"); //yuck!
return buf.append(')').toString();
}
private static final Object[] TYPED_VALUES = new TypedValue[0];
public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery)
throws HibernateException {
EntityPersister meta = criteriaQuery.getFactory()
.getEntityPersister( criteriaQuery.getEntityName(criteria) );
String[] propertyNames = meta.getPropertyNames();
Type[] propertyTypes = meta.getPropertyTypes();
//TODO: get all properties, not just the fetched ones!
Object[] values = meta.getPropertyValues( entity, getEntityMode(criteria, criteriaQuery) );
List list = new ArrayList();
for (int i=0; i<propertyNames.length; i++) {
Object value = values[i];
Type type = propertyTypes[i];
String name = propertyNames[i];
boolean isPropertyIncluded = i!=meta.getVersionProperty() &&
isPropertyIncluded(value, name, type);
if (isPropertyIncluded) {
if ( propertyTypes[i].isComponentType() ) {
addComponentTypedValues(name, value, (AbstractComponentType) type, list, criteria, criteriaQuery);
}
else {
addPropertyTypedValue(value, type, list);
}
}
}
return (TypedValue[]) list.toArray(TYPED_VALUES);
}
private EntityMode getEntityMode(Criteria criteria, CriteriaQuery criteriaQuery) {
EntityPersister meta = criteriaQuery.getFactory()
.getEntityPersister( criteriaQuery.getEntityName(criteria) );
EntityMode result = meta.guessEntityMode(entity);
if (result==null) {
throw new ClassCastException( entity.getClass().getName() );
}
return result;
}
protected void addPropertyTypedValue(Object value, Type type, List list) {
if ( value!=null ) {
if ( value instanceof String ) {
String string = (String) value;
if (isIgnoreCaseEnabled) string = string.toLowerCase();
if (isLikeEnabled) string = matchMode.toMatchString(string);
value = string;
}
list.add( new TypedValue(type, value, null) );
}
}
protected void addComponentTypedValues(
String path,
Object component,
AbstractComponentType type,
List list,
Criteria criteria,
CriteriaQuery criteriaQuery)
throws HibernateException {
if (component!=null) {
String[] propertyNames = type.getPropertyNames();
Type[] subtypes = type.getSubtypes();
Object[] values = type.getPropertyValues( component, getEntityMode(criteria, criteriaQuery) );
for (int i=0; i<propertyNames.length; i++) {
Object value = values[i];
Type subtype = subtypes[i];
String subpath = StringHelper.qualify( path, propertyNames[i] );
if ( isPropertyIncluded(value, subpath, subtype) ) {
if ( subtype.isComponentType() ) {
addComponentTypedValues(subpath, value, (AbstractComponentType) subtype, list, criteria, criteriaQuery);
}
else {
addPropertyTypedValue(value, subtype, list);
}
}
}
}
}
protected void appendPropertyCondition(
String propertyName,
Object propertyValue,
Criteria criteria,
CriteriaQuery cq,
StringBuffer buf)
throws HibernateException {
Criterion crit;
if ( propertyValue!=null ) {
boolean isString = propertyValue instanceof String;
SimpleExpression se = ( isLikeEnabled && isString ) ?
Restrictions.like(propertyName, propertyValue) :
Restrictions.eq(propertyName, propertyValue);
crit = ( isIgnoreCaseEnabled && isString ) ?
se.ignoreCase() : se;
}
else {
crit = Restrictions.isNull(propertyName);
}
String critCondition = crit.toSqlString(criteria, cq);
if ( buf.length()>1 && critCondition.trim().length()>0 ) buf.append(" and ");
buf.append(critCondition);
}
protected void appendComponentCondition(
String path,
Object component,
AbstractComponentType type,
Criteria criteria,
CriteriaQuery criteriaQuery,
StringBuffer buf)
throws HibernateException {
if (component!=null) {
String[] propertyNames = type.getPropertyNames();
Object[] values = type.getPropertyValues( component, getEntityMode(criteria, criteriaQuery) );
Type[] subtypes = type.getSubtypes();
for (int i=0; i<propertyNames.length; i++) {
String subpath = StringHelper.qualify( path, propertyNames[i] );
Object value = values[i];
if ( isPropertyIncluded( value, subpath, subtypes[i] ) ) {
Type subtype = subtypes[i];
if ( subtype.isComponentType() ) {
appendComponentCondition(
subpath,
value,
(AbstractComponentType) subtype,
criteria,
criteriaQuery,
buf
);
}
else {
appendPropertyCondition(
subpath,
value,
criteria,
criteriaQuery,
buf
);
}
}
}
}
}
public boolean isIncludeAssociations()
{
return includeAssociations;
}
public void setIncludeAssociations(boolean includeAssociations)
{
this.includeAssociations = includeAssociations;
}
}
[/code]
注意包名,之后,再使用Example的时候,就可以使用这个来实现查询中不忽略关联对象,修改后的代码:
[code=java]
Criteria criteria = getSession().createCriteria(Reqmt.class);
if (reqmt != null) {
// criteria.add(Example.create(reqmt));//这里会忽略关联
criteria.add(AssociationExample.create(reqmt));// 使用了自己建立的扩展example类
}
// 分页处理。。。。
List<?> result = criteria.list();
[/code]
- 加强hibernate的criteria查询中的使用Example查询的
- hibernate Example、Criteria 查询
- Hibernate的Criteria查询
- Hibernate中Criteria的使用(条件查询)
- hibernate中的Query查询和criteria查询的区别
- Hibernate 中的 Criteria 查询。
- Hibernate 中的 Criteria 查询。
- hibernate中的Criteria查询
- Hibernate Criteria的嵌套查询
- hibernate的Criteria作连表查询
- Hibernate的Criteria查询总结
- 关于Hibernate的Criteria查询
- 了解hibernate的Criteria查询
- Hibernate的查询 标准(Criteria)查询
- Hibernate的查询 标准(Criteria)查询
- Hibernate的查询 标准(Criteria)查询
- (3) Hibernate的查询 标准(Criteria)查询
- 使用hibernate的criteria分页查询后得到数组对象
- ★【模拟退火】Texas Trip
- android 操作系统源代码 下载编译
- 设计模式纵谈1
- HttpAccessModule
- 把时间当做朋友——学习笔记
- 加强hibernate的criteria查询中的使用Example查询的
- Java程序员从笨鸟到菜鸟之(三十一)大话设计模式之设计模式遵循的七大原则
- VS2008 LINK : fatal error LNK1000: Internal error during IncrBuildImage
- linux编程的108种奇淫巧计-4(编译展开)
- oracle 10g 初次登陆提示scott账户被锁定的解决方法
- apache下ab网站压力测试命令的参数、输出结果的中文注解
- 他和她
- 隐形的同党
- 内人,我会幸福给你看