`

Hibernate的querybuilder

阅读更多
Hibernate的querybuilder

package net.esj.basic.dao.querybuilder;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.esj.basic.exception.MelonException;
import net.esj.basic.expression.formula.Formula;
import net.esj.basic.utils.Validators;
import net.esj.basic.utils.hibe.AndCriteria;
import net.esj.basic.utils.hibe.HiCriteria;
import net.esj.basic.utils.hibe.OrCriteria;
import net.esj.basic.utils.hibe.SymbolExpression;

import org.hibernate.FetchMode;
import org.hibernate.criterion.CriteriaSpecification;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projection;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.util.Assert;

public class HibernateQueryBuilder<T> implements QueryBuilder<T>, Serializable,
		Cloneable {

	/**
	 * 
	 */
	private static final long serialVersionUID = -2175149119127080340L;

	private DetachedCriteria root = null;

	private Map<String, DetachedCriteria> subCri = new HashMap<String, DetachedCriteria>();

	private Class<T> clazz = null;
	
	private List<HiCriteria> hiCriterias = new ArrayList<HiCriteria>();

	private HibernateQueryBuilder(Class<T> clazz) {
		this.clazz = clazz;
		root = DetachedCriteria.forClass(clazz);
	}

	@Override
	public HibernateQueryBuilder<T> clone() {
		HibernateQueryBuilder<T> qb = null;
		try {
			qb = (HibernateQueryBuilder<T>) super.clone();
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}
		return qb;
	}

	@Override
	public QueryBuilder<T> addCriterion(Criterion criterion) {
		root.add(criterion);
		return this;
	}

	@Override
	public QueryBuilder<T> allEq(Map propertyNameValues) {
		Assert.notNull(propertyNameValues, "传值不能为空!");
		root.add(Restrictions.allEq(propertyNameValues));
		return this;
	}

	@Override
	public QueryBuilder<T> between(String propertyName, Object lo, Object hi) {
		Assert.notNull(lo, "传值不能为空!");
		Assert.notNull(hi, "传值不能为空!");
		CriEntity cri = seekCriteria(propertyName,this);
		cri.getCri().add(Restrictions.between(propertyName, lo, hi));
		return this;
	}

	@Override
	public QueryBuilder<T> eq(String propertyName, Object value) {
		Assert.notNull(value, "传值不能为空!");
		CriEntity cri = seekCriteria(propertyName,this);
		cri.getCri().add(Restrictions.eq(cri.getPropertyName(), value));
		return this;
	}

	@Override
	public QueryBuilder<T> ge(String propertyName, Object value) {
		Assert.notNull(value, "传值不能为空!");
		CriEntity cri = seekCriteria(propertyName,this);
		cri.getCri().add(Restrictions.ge(cri.getPropertyName(), value));
		return this;
	}

	@Override
	public DetachedCriteria getDetachedCriteria() {
		return root;
	}

	@Override
	public QueryBuilder<T> gt(String propertyName, Object value) {
		Assert.notNull(value, "传值不能为空!");
		CriEntity cri = seekCriteria(propertyName,this);
		cri.getCri().add(Restrictions.gt(cri.getPropertyName(), value));
		return this;
	}

	@Override
	public QueryBuilder<T> ilike(String propertyName, String value,
			MatchMode matchMode) {
		Assert.notNull(value, "传值不能为空!");
		CriEntity cri = seekCriteria(propertyName,this);
		cri.getCri().add(
				Restrictions.ilike(cri.getPropertyName(), value, matchMode));
		return this;
	}

	@Override
	public QueryBuilder<T> ilike(String propertyName, Object value) {
		Assert.notNull(value, "传值不能为空!");
		CriEntity cri = seekCriteria(propertyName,this);
		cri.getCri().add(Restrictions.ilike(cri.getPropertyName(), value));
		return this;
	}

	@Override
	public QueryBuilder<T> in(String propertyName, Object[] values) {
		Assert.notNull(values, "传值不能为空!");
		CriEntity cri = seekCriteria(propertyName,this);
		cri.getCri().add(Restrictions.in(cri.getPropertyName(), values));
		return this;
	}

	@Override
	public QueryBuilder<T> in(String propertyName, Collection<T> values) {
		Assert.notNull(values, "传值不能为空!");
		CriEntity cri = seekCriteria(propertyName,this);
		cri.getCri().add(Restrictions.in(cri.getPropertyName(), values));
		return this;
	}

	@Override
	public QueryBuilder<T> isNotNull(String propertyName) {
		CriEntity cri = seekCriteria(propertyName,this);
		cri.getCri().add(Restrictions.isNotNull(cri.getPropertyName()));
		return this;
	}

	@Override
	public QueryBuilder<T> isNull(String propertyName) {
		CriEntity cri = seekCriteria(propertyName,this);
		cri.getCri().add(Restrictions.isNull(cri.getPropertyName()));
		return this;
	}

	@Override
	public QueryBuilder<T> le(String propertyName, Object value) {
		Assert.notNull(value, "传值不能为空!");
		CriEntity cri = seekCriteria(propertyName,this);
		cri.getCri().add(Restrictions.le(cri.getPropertyName(), value));
		return this;
	}

	@Override
	public QueryBuilder<T> like(String propertyName, Object value) {
		Assert.notNull(value, "传值不能为空!");
		CriEntity cri = seekCriteria(propertyName,this);
		cri.getCri().add(Restrictions.like(cri.getPropertyName(), value));
		return this;
	}

	@Override
	public QueryBuilder<T> like(String propertyName, String value,
			MatchMode matchMode) {
		Assert.notNull(value, "传值不能为空!");
		CriEntity cri = seekCriteria(propertyName,this);
		cri.getCri().add(
				Restrictions.like(cri.getPropertyName(), value, matchMode));
		return this;
	}

	@Override
	public QueryBuilder<T> lt(String propertyName, Object value) {
		Assert.notNull(value, "传值不能为空!");
		CriEntity cri = seekCriteria(propertyName,this);
		cri.getCri().add(Restrictions.lt(cri.getPropertyName(), value));
		return this;
	}

	@Override
	public QueryBuilder<T> notEq(String propertyName, Object value) {
		Assert.notNull(value, "传值不能为空!");
		CriEntity cri = seekCriteria(propertyName,this);
		cri.getCri().add(Restrictions.ne(cri.getPropertyName(), value));
		return this;
	}

	@Override
	public QueryBuilder<T> leProperty(String propertyName,
			String otherPropertyName) {
		root.add(Restrictions.leProperty(propertyName, otherPropertyName));
		return this;
	}

	@Override
	public QueryBuilder<T> ltProperty(String propertyName,
			String otherPropertyName) {
		root.add(Restrictions.ltProperty(propertyName, otherPropertyName));
		return this;
	}

	@Override
	public QueryBuilder<T> eqProperty(String propertyName,
			String otherPropertyName) {
		root.add(Restrictions.eqProperty(propertyName, otherPropertyName));
		return this;
	}

	@Override
	public Class<T> getClazz() {
		return clazz;
	}

	@Override
	public QueryBuilder<T> OrderByAsc(String propertyName) {
		CriEntity cri = seekCriteria(propertyName,this);
		cri.getCri().addOrder(Order.asc(cri.getPropertyName()));
		return this;
	}

	@Override
	public QueryBuilder<T> OrderByDesc(String propertyName) {
		CriEntity cri = seekCriteria(propertyName,this);
		cri.getCri().addOrder(Order.desc(cri.getPropertyName()));
		return this;
	}
	
	@Override
	public QueryBuilder<T> fetch(String propertyTable, FetchMode fetchMode) {
		CriEntity entity = seekCriteria(propertyTable,this);
		entity.getCri().setFetchMode(entity.getPropertyName(), fetchMode);
		return this;
	}
	
	//TODO in test
	public QueryBuilder<T> hi(String propertyTable,HiCriteria hi){
		DetachedCriteria c =  createSub(propertyTable,this);
		c.add(hi.getCriterion());
		return this;
	}
	
	@Override
	public QueryBuilder<T> not(String propertyTable,HiCriteria hi) {
		DetachedCriteria c =  createSub(propertyTable,this);
		 c.add(Restrictions.not(hi.getCriterion()));
		 return this;
	}
	
	@Override
	public QueryBuilder<T> or(String propertyName,
			SymbolExpression expressions, Object[] objects) {
		SymbolExpression[] se = new SymbolExpression[objects.length]; 
		for(int i=0;i<se.length;i++){
			se[i] = expressions;
		}
		return or(propertyName, se, objects);
	}
	
	@Override
	public QueryBuilder<T> or(String propertyName,	SymbolExpression[] expressions, Object[] objects) {

		String[] proStrings = new String[expressions.length];
		for(int i=0;i<proStrings.length;i++){
			proStrings[i] = propertyName;
		}
		
		return or(proStrings, expressions, objects);
	}
	
	@Override
	public QueryBuilder<T> or(String[] propertyNames,	SymbolExpression[] expressions, Object[] objects) {
		if(propertyNames.length != expressions.length
				&& propertyNames.length !=objects.length){
			throw new MelonException("error propertyNames, expressions or objects ");
		}
		
		if(propertyNames.length==1){
			SymbolExpression.append(this,expressions[0],propertyNames[0],objects[0]);
			return this;
		}
		
		List<OrEntity> list = new ArrayList<OrEntity>();
		for(int i=0;i<propertyNames.length;i++){
			CriEntity cri = seekCriteria(propertyNames[i],this);
			boolean in = false;
			for(OrEntity or : list){
				if(or.equal(cri.getCri())){
					or.add(cri.getPropertyName(),expressions[i], objects[i]);
					in = true;
					break;
				}
			}
			if(!in){
				OrEntity e = new OrEntity();
				e.setCriteria(cri.getCri());
				e.add(cri.getPropertyName(),expressions[i], objects[i]);
				list.add(e);
			}
		}
		
		for(OrEntity or : list){
			HiCriteria criteria = OrCriteria.createMe();
			int i = 1;
			HiCriteria tmpCri = AndCriteria.createMe();
			SymbolExpression.append(tmpCri, or.getExpressions()[0], or.getPropertyNames()[0], or.getValues()[0]);
			
			while(or.getExpressions().length>i){
				HiCriteria hc = AndCriteria.createMe();
				SymbolExpression.append(hc, or.getExpressions()[i], or.getPropertyNames()[i], or.getValues()[i]);
				tmpCri = criteria.add(hc, tmpCri);
				i++;
			}
			or.getCriteria().add(criteria.getCriterion());
		}
		
		return this;
	}
	
	@Override
	public CriteriaSpecification createCriteria(String associationPath) {
		return root.createCriteria(associationPath);
	}
	
	@Override
	public DetachedCriteria getRoot() {
		return root;
	}

	@Override
	public Map<String, DetachedCriteria> getSubCri() {
		return subCri;
	}

	public final static DetachedCriteria createSub(String propertyTable,QueryBuilder qb){
		if(!Validators.isEmpty(propertyTable)){
			String[] tmps = propertyTable.split("\\.");
				String subkey = "";
				String property = "";
				DetachedCriteria parent = qb.getRoot();
				for (int i = 0; i < tmps.length; i++) {
					if (i == 0) {
						subkey = tmps[i];
						property = tmps[i];
					} else {
						subkey = subkey + "." + tmps[i];
						property = tmps[i];
					}
					DetachedCriteria c = (DetachedCriteria) qb.getSubCri().get(subkey);
					if (c == null) {
						DetachedCriteria sub = createSub(parent, property);
						parent = sub;
						qb.getSubCri().put(subkey, parent);
					} else {
						parent = c;
					}
				}
				return (DetachedCriteria) qb.getSubCri().get(subkey);
		}
		return qb.getRoot();
	}

	public final static DetachedCriteria createSub(DetachedCriteria parent, String name) {
		return parent.createCriteria(name);
	}

	/**
	 * 根据key获得criteria节点,若不存在则创建
	 * 
	 * @param key
	 * @return
	 */
	public static final CriEntity seekCriteria(String propertyName,QueryBuilder qb) {
		String[] tmps = propertyName.split("\\.");
		if (tmps.length == 1) {
			return new CriEntity(qb.getRoot(), propertyName);
		}
		String subkey = "";
		String property = "";
		DetachedCriteria parent = qb.getRoot();
		for (int i = 0; i < tmps.length; i++) {
			if (i == 0) {
				subkey = tmps[i];
				property = tmps[i];
			} else {
				subkey = subkey + "." + tmps[i];
				property = tmps[i];
			}
			if (i < tmps.length - 1) {
				DetachedCriteria c = (DetachedCriteria) qb.getSubCri().get(subkey);
				if (c == null) {
					DetachedCriteria sub = createSub(parent, property);
					parent = sub;
					qb.getSubCri().put(subkey, parent);
				} else {
					parent = c;
				}
			}
		}
		return new CriEntity(parent, property);
	}

	public static <E> HibernateQueryBuilder forClass(Class<E> clazz) {
		return new HibernateQueryBuilder(clazz);
	}
	
	public static class CriEntity {
		private DetachedCriteria cri;
		private String propertyName;

		public CriEntity(DetachedCriteria cri, String propertyName) {
			super();
			this.cri = cri;
			this.propertyName = propertyName;
		}

		public DetachedCriteria getCri() {
			return cri;
		}

		public void setCri(DetachedCriteria cri) {
			this.cri = cri;
		}

		public String getPropertyName() {
			return propertyName;
		}

		public void setPropertyName(String propertyName) {
			this.propertyName = propertyName;
		}
	}

	private static class OrEntity{
		private DetachedCriteria criteria;
		private SymbolExpression[] expressions;
		private Object[] values;
		private String[] propertyNames;
		
		public DetachedCriteria getCriteria() {
			return criteria;
		}
		public void setCriteria(DetachedCriteria criteria) {
			this.criteria = criteria;
		}
		public SymbolExpression[] getExpressions() {
			return expressions;
		}
		public Object[] getValues() {
			return values;
		}
		public String[] getPropertyNames() {
			return propertyNames;
		}
		public void add(String propertyName,SymbolExpression expression,Object obj){
			if(expressions==null){
				expressions = new SymbolExpression[1];
				expressions[0] = expression;
				values = new Object[1];
				values[0] = obj;
				propertyNames = new String[1];
				propertyNames[0] = propertyName;
			}else{
				int len = expressions.length;
				SymbolExpression[] tmp = new SymbolExpression[len + 1];
				System.arraycopy(expressions, 0, tmp, 0, len);
				tmp[len] = expression;
				expressions = tmp;
				
				int len2 = values.length;
				Object[] tmp2 = new Object[len2 + 1];
				System.arraycopy(values, 0, tmp2, 0, len2);
				tmp2[len2] = obj;
				values = tmp2;
				
				int len3 = propertyNames.length;
				String[] tmp3 = new String[len3 + 1];
				System.arraycopy(propertyNames, 0, tmp3, 0, len3);
				tmp3[len3] = propertyName;
				propertyNames = tmp3;
			}
		}
		
		public boolean equal(DetachedCriteria cri){
			return criteria == cri;
		}
	}

}



支持使用方法:
entity:
class Foo{
String  id;
String name;
boo b; //在foo中做many-one映射

setter& getter
}

class boo{
String id;
String key;

setter&getter
}

QueryBuilder<Foo> qb = HibernateQueryBuilder.forClass(Foo.class);
qb.eq("name","123"); //查询foo中name是123的数据
qb.in({"id","name","b.id"},{SymbolExpression.EQUAL,SymbolExpression.LIKE,SymbolExpression.LIKE},{"1","2","3"});
//查询 id为1或name为2或left join   b的id为3 的数据

qb.eq("b.name","3");
//SELECT .... FROM   Foo  left join Boo WHERE b.id = f.id AND b.name='3
分享到:
评论

相关推荐

    Hibernate Search配置及简单应用

    **Hibernate Search配置及简单应用** Hibernate Search是Hibernate框架的一个扩展,它允许我们在应用程序中实现全文检索功能,使得数据库中的数据可以被快速、高效地搜索。这个功能尤其在处理大量文本数据时非常...

    hibernate-search-4.1.1.Final-dist.zip

    《Hibernate Search 4.1.1.Final:深入探索与应用》 Hibernate Search是Java世界中Hibernate ORM框架的一个强大扩展,它将全文搜索能力引入到持久化层,使得开发者能够轻松地在数据库中的数据上执行复杂的全文检索...

    hibernate-search-5.5.1.Final-dist.zip

    《Hibernate Search 5.5.1.Final:全面解析企业级数据检索的利器》 Hibernate Search,作为Hibernate ORM的一个扩展,提供了在Java应用中进行全文搜索和复杂索引的能力。这个压缩包“hibernate-search-5.5.1.Final-...

    hibernateSearch+demo

    4. **查询构造**:Hibernate Search 支持 Lucene 查询语法,你可以使用 QueryBuilder 来构建复杂的查询表达式,包括关键词搜索、短语搜索、模糊搜索、范围查询等。 5. **分词器和分析器**:为了处理文本数据,...

    hibernate-search-5.5.4 api docset for Dash

    例如,`org.hibernate.search.indexes.impl.IndexManager`负责管理索引,`org.hibernate.search.query.dsl.QueryBuilder`则用于构建复杂的查询表达式。 总之,"hibernate-search-5.5.4 api docset for Dash"是Java...

    hibernate-search-3.4.0.Final--1.rar

    - **查询构造**:利用QueryBuilder或QueryBuilder API构造复杂的全文搜索语句。 - **索引管理**:理解何时和如何重建索引,以及如何处理增量数据更新。 总的来说,Hibernate Search 3.4.0.Final版本为Java开发者...

    hibernate search源码

    `org.hibernate.search.query`包下包含了大量的查询构建类,如`FullTextQueryBuilder`和`QueryBuilder`。它们允许开发者通过JPA-like的API构造复杂的全文搜索查询,并提供了排序、过滤和高亮等高级功能。 **6. 分析...

    hibernate-search-5.1.1.Final-dist.zip

    4. **查询构建**:使用QueryBuilder构建复杂的搜索条件。 5. **执行搜索**:通过FullTextSession执行查询,返回结果集。 6. **结果处理**:对搜索结果进行排序、分页,并映射回ORM实体。 四、实际应用 在实际项目...

    基于Spring的Hibernate Search全文检索功能示例

    5. **查询API**:Hibernate Search提供了一套丰富的查询API,如`FullTextQuery`和`QueryBuilder`,可以创建布尔组合查询、模糊查询、短语查询等。例如,我们可以使用`keyword()`函数构建简单查询,或者用`match()`来...

    hibernate-search-4.2.0.jar及说明pdf

    3. **查询API**:详细阐述如何使用QueryBuilder和FullTextQuery接口来构建和执行全文查询。 4. **分词和分析**:讨论如何自定义分析流程,包括分词器、过滤器的选择和配置。 5. **持久化和缓存**:说明如何管理...

    hibernateSearch 搜索 索引列子源代码

    **hibernateSearch 搜索 索引列子源代码** Hibernate Search 是 Hibernate 的一个扩展模块,它将全文搜索引擎的功能集成到了 Java 应用中,允许开发者在数据库中进行复杂的文本搜索。本教程将深入探讨 Hibernate ...

    hibernate包

    14. ** CriteriaBuilder** 和 **QueryBuilder**:在Hibernate 4.0之后引入的新API,提供了更简洁、强大的构建查询的方法。 这个“hibernate包”可能包含以下组件: - Hibernate核心库(hibernate-core.jar) - ...

    hibernate-jar包

    这包括使用`FullTextQuery`、`BooleanQuery`和`QueryBuilder`等。你可以根据需要进行精确匹配、模糊搜索、范围查询、排序和分组等操作。 5. **实时索引**: 4.4.0 Alpha2版本继续支持实时索引,即当对象被持久化或...

    Hibernate-Search

    Hibernate Search提供了丰富的查询构建器API,包括QueryBuilder、BooleanJunction、MatchAllQueryBuilder等,方便构建复杂查询条件。同时,也可以使用Lucene的原生API进行更底层的控制。 六、性能优化 1. 分布式...

    hibernate-search-4.5.2.Final-dist.tar.gz

    《Hibernate Search 4.5.2.Final:企业级全文搜索引擎集成详解》 Hibernate Search是Hibernate ORM的一个扩展,它提供了一种在Java应用程序中实现全文搜索功能的方式。这个压缩包"hibernate-search-4.5.2.Final-...

    hibernate-search-4.5.2.Final-dist.zip

    《深入理解Hibernate Search 4.5.2.Final:企业级全文检索的利器》 Hibernate Search是Hibernate ORM框架的一个扩展,它将强大的全文搜索引擎Lucene集成到Java应用程序中,为数据库中的数据提供高效的全文检索能力...

    hibernate-search-3.1.1.GA-dist

    开发者可以通过`QueryBuilder`构建复杂的查询条件,以满足用户多样化的搜索需求。同时,实时索引更新也是Hibernate Search的一大亮点,当数据库中的数据发生变化时,索引会自动更新,确保搜索结果的实时性。 在性能...

    23、Doctrine QueryBuilder对象介绍1

    DQL是专门为Doctrine设计的一种查询语言,类似于Hibernate的HQL和Java Persistence API(JPA)的JPQL。与SQL不同,DQL处理的对象是实体(Entities),而不是表。在DQL中,我们可以用Model类的全名代替表名,并使用...

    Hibernate Search指南

    1. **QueryBuilder**:通过 `FullTextEntityManager` 的 `createQueryBuilder()` 方法创建 QueryBuilder 对象,用于构建复杂的全文查询。 2. **匹配条件**:使用 `match()`、`like()` 或 `keyword()` 方法指定查询...

Global site tag (gtag.js) - Google Analytics