Hibernate結合JPA編寫通用泛型多條件查詢

項目中使用Hibernate和JPA對數據庫對象進行實例化,可是生成的方法不支持多條件查詢。而若是針對每個數據庫對象進行多條件查詢編碼,則會變得很麻煩,並且一旦之後發生表結構發生變化,這些方法可能還須要進行從新編碼。因此考慮編寫一個方法能夠對數據庫對象進行多條件查詢,並返回泛型對象,這樣就能夠方便使用。具體實現思路以下:java

第一步:編寫數據庫查詢參數對象,此部分包含兩個,一個是查詢實體名稱(QueryCondition.java),一個是數據庫查詢條件對象(QueryParameter.java)。web

數據庫查詢條件對象(QueryParameter.java)包含三個參數,分別爲參數名、參數值、查詢條件表達式sql

複製代碼

package com.imstudio.jpa;
public class QueryParameter {
	
	public enum QueryOperateType {
		Equal, CharIn
	}

	public String ParameterName;
	public Object ParameterValue;
	public QueryOperateType ParameterType;

	public QueryParameter() {

	}

	public QueryParameter(String parameterName, Object parameterValue,
			QueryOperateType parameterType) {
		this.ParameterName = parameterName;
		this.ParameterValue = parameterValue;
		this.ParameterType = parameterType;
	}

	public String getParameterName() {
		return ParameterName;
	}

	public QueryOperateType getParameterType() {
		return ParameterType;
	}

	public Object getParameterValue() {
		return ParameterValue;
	}

	public void setParameterName(String parameterName) {
		ParameterName = parameterName;
	}

	public void setParameterType(QueryOperateType parameterType) {
		this.ParameterType = parameterType;
	}

	public void setParameterValue(Object parameterValue) {
		ParameterValue = parameterValue;
	}

}

複製代碼

查詢對象實體(QueryCondition.java)包含查詢實體名稱以及查詢參數對象數據庫

複製代碼

package com.imstudio.jpa;
import java.util.ArrayList;
import java.util.List;

public class QueryCondition {
	public String ModelName;
	public List<QueryParameter> Parameters = new ArrayList<QueryParameter>();

	public QueryCondition() {

	}

	public QueryCondition(String modelName) {
		this.ModelName = modelName;
	}

	public QueryCondition(String modelName, List<QueryParameter> parameters) {
		this.ModelName = modelName;
		this.Parameters = parameters;
	}

	public void add(QueryParameter queryParameter) {
		this.Parameters.add(queryParameter);
	}

	public String getModelName() {
		return ModelName;
	}

	public List<QueryParameter> getParameters() {
		return Parameters;
	}

	public void setModelName(String modelName) {
		ModelName = modelName;
	}

	public void setParameters(List<QueryParameter> parameters) {
		Parameters = parameters;
	}
}

複製代碼

在完成上述兩個實體對象以後就能夠具體查詢方法的編寫了,在查詢中使用到一個變量querySymbols,下述編碼是從配置文件web.xml中獲取,這裏主要是爲了在使用不一樣數據庫的時候查詢關鍵字標示符的修改。同時爲了增長查詢方法的通用性,查詢返回數據這裏定義爲泛型。apache

複製代碼

package com.imstudio.jpa;import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import org.apache.struts2.ServletActionContext;
import com.imstudio.jpa.QueryParameter.QueryOperateType;

public class QueryDataAction {    
    public String errorCode;
    public QueryDataAction() {
    
    }    
    
    public QueryDataAction(String errorCode) {
            this.errorCode = errorCode;
    } 
       
    public String getErrorCode() {
            return errorCode;
    };

    @SuppressWarnings("unchecked")    
    public <T> List<T> queryByPropertys(QueryCondition queryCondition) {
        String querySymbols = ServletActionContext.getServletContext()
                .getInitParameter("QuerySymbols");
        StringBuffer sqlBuffer = new StringBuffer();
        sqlBuffer.append("select model \n");
        sqlBuffer.append("from " + queryCondition.ModelName + " as model \n");        
        boolean first = true;        
        for (int pi = 0; pi < queryCondition.Parameters.size(); pi++) {
             if (queryCondition.Parameters.get(pi).getParameterName() != null) {                                if (first) {
                    sqlBuffer.append("where ");
                    first = false;
                } else {
                    sqlBuffer.append("and ");
                }                
                if (queryCondition.Parameters.get(pi).getParameterType() == QueryOperateType.Equal) {
                    sqlBuffer.append("model."
                            + queryCondition.Parameters.get(pi)
                                    .getParameterName()                            + " = "
                            + querySymbols                            + queryCondition.Parameters.get(pi)
                                    .getParameterName() + " \n");
                } else if (queryCondition.Parameters.get(pi).getParameterType() == QueryOperateType.CharIn) {
                    sqlBuffer.append("InStr(model."
                            + queryCondition.Parameters.get(pi)
                                    .getParameterName()                            + " , "
                            + querySymbols                            + queryCondition.Parameters.get(pi)
                                    .getParameterName() + " ) > 0 \n");
                }
            }
        }
        List<T> list = new ArrayList<T>();        
        try {
            EntityManagerHelper.log(sqlBuffer.toString(), Level.INFO, null);
            EntityManager emEntityManager = EntityManagerHelper
                    .getEntityManager();
            Query queryObject = emEntityManager.createQuery(sqlBuffer
                    .toString());            
                    for (int li = 0; li < queryCondition.Parameters.size(); li++) {
                queryObject.setParameter(queryCondition.Parameters.get(li)
                        .getParameterName(), queryCondition.Parameters.get(li)
                        .getParameterValue());
            }
            list = queryObject.getResultList();
            emEntityManager.close();

        } catch (RuntimeException re) {
            errorCode += "CM000006";
            EntityManagerHelper.log("queryByPropertys error", Level.SEVERE, re);
            throw re;
        }        return list;
    }    
    
    public void setErrorCode(String errorCode) {
            this.errorCode = errorCode;
    }

}

複製代碼

相關文章
相關標籤/搜索