import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
* QueryRule,主要功能用于构造查询条件
*
* @author Tom
*/
public final class QueryRule implements Serializable
{
private static final long serialVersionUID = 1L;
public static final int ASC_ORDER = 101;
public static final int DESC_ORDER = 102;
public static final int LIKE = 1;
public static final int IN = 2;
public static final int NOTIN = 3;
public static final int BETWEEN = 4;
public static final int EQ = 5;
public static final int NOTEQ = 6;
public static final int GT = 7;
public static final int GE = 8;
public static final int LT = 9;
public static final int LE = 10;
public static final int ISNULL = 11;
public static final int ISNOTNULL = 12;
public static final int ISEMPTY = 13;
public static final int ISNOTEMPTY = 14;
public static final int AND = 201;
public static final int OR = 202;
private List ruleList = new ArrayList();
private List queryRuleList = new ArrayList();
private String propertyName;
private QueryRule() {}private QueryRule(String propertyName) {
this.propertyName = propertyName;
}public static QueryRule getInstance() {
return new QueryRule();
}/**
* 添加升序规则
* @param propertyName
* @return
*/
public QueryRule addAscOrder(String propertyName) {
this.ruleList.add(new Rule(ASC_ORDER, propertyName));
return this;
}/**
* 添加降序规则
* @param propertyName
* @return
*/
public QueryRule addDescOrder(String propertyName) {
this.ruleList.add(new Rule(DESC_ORDER, propertyName));
return this;
}public QueryRule andIsNull(String propertyName) {
this.ruleList.add(new Rule(ISNULL, propertyName).setAndOr(AND));
return this;
}public QueryRule andIsNotNull(String propertyName) {
this.ruleList.add(new Rule(ISNOTNULL, propertyName).setAndOr(AND));
return this;
}public QueryRule andIsEmpty(String propertyName) {
this.ruleList.add(new Rule(ISEMPTY, propertyName).setAndOr(AND));
return this;
}public QueryRule andIsNotEmpty(String propertyName) {
this.ruleList.add(new Rule(ISNOTEMPTY, propertyName).setAndOr(AND));
return this;
}public QueryRule andLike(String propertyName, Object value) {
this.ruleList.add(new Rule(LIKE, propertyName, new Object[] { value }).setAndOr(AND));
return this;
}public QueryRule andEqual(String propertyName, Object value) {
this.ruleList.add(new Rule(EQ, propertyName, new Object[] { value }).setAndOr(AND));
return this;
}public QueryRule andBetween(String propertyName, Object... values) {
this.ruleList.add(new Rule(BETWEEN, propertyName, values).setAndOr(AND));
return this;
}public QueryRule andIn(String propertyName, List
然后创建QueryRuleSqlBuilder类。
package com.tom.vip.pattern.builder.sql;
/**
* 根据QueryRule自动构建SQL语句
* @author Tom
*
*/
public class QueryRuleSqlBuilder {
private int CURR_INDEX = 0;
//记录参数所在的位置
private List properties;
//保存列名列表
private List values;
//保存参数值列表
private List orders;
//保存排序规则列表private String whereSql = "";
private String orderSql = "";
private Object [] valueArr = new Object[]{};
private Map valueMap = new HashMap();
/**
* 获得查询条件
* @return
*/
private String getWhereSql(){
return this.whereSql;
}/**
* 获得排序条件
* @return
*/
private String getOrderSql(){
return this.orderSql;
}/**
* 获得参数值列表
* @return
*/
public Object [] getValues(){
return this.valueArr;
}/**
* 获得参数列表
* @return
*/
private Map getValueMap(){
return this.valueMap;
}/**
* 创建SQL构造器
* @param queryRule
*/
public QueryRuleSqlBuilder(QueryRule queryRule) {
CURR_INDEX = 0;
properties = new ArrayList();
values = new ArrayList();
orders = new ArrayList();
for (QueryRule.Rule rule : queryRule.getRuleList()) {
switch (rule.getType()) {
case QueryRule.BETWEEN:
processBetween(rule);
break;
case QueryRule.EQ:
processEqual(rule);
break;
case QueryRule.LIKE:
processLike(rule);
break;
case QueryRule.NOTEQ:
processNotEqual(rule);
break;
case QueryRule.GT:
processGreaterThen(rule);
break;
case QueryRule.GE:
processGreaterEqual(rule);
break;
case QueryRule.LT:
processLessThen(rule);
break;
case QueryRule.LE:
processLessEqual(rule);
break;
case QueryRule.IN:
processIN(rule);
break;
case QueryRule.NOTIN:
processNotIN(rule);
break;
case QueryRule.ISNULL:
processIsNull(rule);
break;
case QueryRule.ISNOTNULL:
processIsNotNull(rule);
break;
case QueryRule.ISEMPTY:
processIsEmpty(rule);
break;
case QueryRule.ISNOTEMPTY:
processIsNotEmpty(rule);
break;
case QueryRule.ASC_ORDER:
processOrder(rule);
break;
case QueryRule.DESC_ORDER:
processOrder(rule);
break;
default:
throw new IllegalArgumentException("type"+rule.getType()+"not supported.");
}
}
//拼装where语句
appendWhereSql();
//拼装排序语句
appendOrderSql();
//拼装参数值
appendValues();
}/**
* 去掉order
*
* @param sql
* @return
*/
private String removeOrders(String sql) {
Pattern p = Pattern.compile("order\\s*by[\\w|\\W|\\s|\\S]*", Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(sql);
StringBuffer sb = new StringBuffer();
while (m.find()) {
m.appendReplacement(sb, "");
}
m.appendTail(sb);
return sb.toString();
}/**
* 去掉select
*
* @param sql
* @return
*/
private String removeSelect(String sql) {
if(sql.toLowerCase().matches("from\\s+")){
int beginPos = sql.toLowerCase().indexOf("from");
return sql.substring(beginPos);
}else{
return sql;
}
}/**
* 处理like
* @param rule
*/
privatevoid processLike(QueryRule.Rule rule) {
if (ArrayUtils.isEmpty(rule.getValues())) {
return;
}
Object obj = rule.getValues()[0];
if (obj != null) {
String value = https://www.it610.com/article/obj.toString();
if (!StringUtils.isEmpty(value)) {
value = value.replace('*', '%');
obj = value;
}
}
add(rule.getAndOr(),rule.getPropertyName(),"like","%"+rule.getValues()[0]+"%");
}/**
* 处理between
* @param rule
*/
privatevoid processBetween(QueryRule.Rule rule) {
if ((ArrayUtils.isEmpty(rule.getValues()))
|| (rule.getValues().length < 2)) {
return;
}
add(rule.getAndOr(),rule.getPropertyName(),"","between",rule.getValues()[0],"and");
add(0,"","","",rule.getValues()[1],"");
}//此处省略部分代码/**
* 加入SQL查询规则队列
* @param andOr and或者or
* @param key 列名
* @param split 列名与值之间的间隔
* @param value 值
*/
privatevoid add(int andOr,String key,String split ,Object value){
add(andOr,key,split,"",value,"");
}/**
* 加入SQL查询规则队列
* @param andOr and或者or
* @param key 列名
* @param split 列名与值之间的间隔
* @param prefix 值前缀
* @param value 值
* @param suffix 值后缀
*/
privatevoid add(int andOr,String key,String split ,String prefix,Object value,Stringsuffix){
String andOrStr = (0 == andOr ? "" :(QueryRule.AND == andOr ? " and " : " or "));
properties.add(CURR_INDEX,
andOrStr + key + " " + split + prefix + (null != value ? " ? " : " ") + suffix);
if(null != value){
values.add(CURR_INDEX,value);
CURR_INDEX ++;
}
}/**
* 拼装where语句
*/
private void appendWhereSql(){
StringBuffer whereSql = new StringBuffer();
for (String p : properties) {
whereSql.append(p);
}
this.whereSql = removeSelect(removeOrders(whereSql.toString()));
}/**
* 拼装排序语句
*/
private void appendOrderSql(){
StringBuffer orderSql = new StringBuffer();
for (int i = 0 ;
i < orders.size();
i ++) {
if(i > 0 && i < orders.size()){
orderSql.append(",");
}
orderSql.append(orders.get(i).toString());
}
this.orderSql = removeSelect(removeOrders(orderSql.toString()));
}/**
* 拼装参数值
*/
private void appendValues(){
Object [] val = new Object[values.size()];
for (int i = 0;
i < values.size();
i ++) {
val[i] = values.get(i);
valueMap.put(i, values.get(i));
}
this.valueArr = val;
}public String builder(String tableName){
String ws = removeFirstAnd(this.getWhereSql());
String whereSql = ("".equals(ws) ? ws : (" where " + ws));
String sql = "select * from " + tableName + whereSql;
Object [] values = this.getValues();
String orderSql = this.getOrderSql();
orderSql = (StringUtils.isEmpty(orderSql) ? " " : (" order by " + orderSql));
sql += orderSql;
return sql;
}private String removeFirstAnd(String sql){
if(StringUtils.isEmpty(sql)){return sql;
}
return sql.trim().toLowerCase().replaceAll("^\\s*and", "") + " ";
}}
接着创建Order类。
/**
* SQL排序组件
* @author Tom
*/
public class Order {
private boolean ascending;
//升序还是降序
private String propertyName;
//哪个字段升序,哪个字段降序public String toString() {
return propertyName + ' ' + (ascending ? "asc" : "desc");
}/**
* Constructor for Order.
*/
protected Order(String propertyName, boolean ascending) {
this.propertyName = propertyName;
this.ascending = ascending;
}/**
* Ascending order
*
* @param propertyName
* @return Order
*/
public static Order asc(String propertyName) {
return new Order(propertyName, true);
}/**
* Descending order
*
* @param propertyName
* @return Order
*/
public static Order desc(String propertyName) {
return new Order(propertyName, false);
}}