項目中為了使項目的資料庫操作從dao層轉移到service層,隻好寫一個通用的sql語句拼接類和相應的mapper類和mapper的xml檔案,自定義的SelectBuilder.java的代碼如下:
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import com.util.StringHelper;
/**
* SelectBuilder:SQL條件拼接類,該類隻做sql語句的拼接
* @author LMH 修改
* @notice 注意:為了用好該類,必須熟悉掌握sql語句完整文法
* @SQLGrammar SELECT語句的完整文法為:
*SELECT[ALL|DISTINCT|DISTINCTROW|TOP] <br/>
*{*|talbe.*|[table.]field1[AS alias1][,[table.]field2[AS alias2][,…]]} <br/>
*FROM tableexpression[,…][IN externaldatabase] <br/>
*[WHERE…] <br/>
*[GROUP BY…] <br/>
*[HAVING…] <br/>
*[ORDER BY…] <br/>
*[WITH OWNERACCESS OPTION] <br/>
*說明: <br/>
*用中括号([])括起來的部分表示是可選的,用大括号({})括起來的部分是表示必須從中選擇其中的一個。 <br/>
*
*/
public class SelectBuilder
{
private static final String AND = ") \nAND (";
private static final String OR = ") \nOR (";
List<String> select = new ArrayList<String>();
List<String> from = new ArrayList<String>();
List<String> join = new ArrayList<String>();
List<String> innerJoin = new ArrayList<String>();
List<String> outerJoin = new ArrayList<String>();
List<String> leftOuterJoin = new ArrayList<String>();
List<String> rightOuterJoin = new ArrayList<String>();
List<Criterion> where = new ArrayList<Criterion>();
List<Criterion> having = new ArrayList<Criterion>();
List<String> groupBy = new ArrayList<String>();
List<String> orderBy = new ArrayList<String>();
List<String> lastList = new ArrayList<String>();
boolean distinct;
/**
* 設定SQL語句中從select到from的部分
* @param conditons 查詢的内容,可以寫字段,聚合函數等
* @example 參數例子:" table1.id as id,table2.mc as mc ",
* @notice 注意:如果要查詢的字段名有相同的,必須用as **的方式進行區分,不然會不能正确set進hashmap裡
*
*/
public void SELECT(String conditons)
{
select.add(conditons);
}
/**
* 設定SQL語句中從select distinct到from的部分,可以寫字段,聚合函數等
* @param columns 查詢的字段清單
* @example 參數例子:" table1.id as id,table2.mc as mc ",
* @notice 注意:如果要查詢的字段名有相同的,必須用as **的方式進行區分,不然會不能正确set進hashmap裡
*
*/
public void SELECT_DISTINCT(String columns)
{
distinct = true;
SELECT(columns);
}
/**
* 設定SQL語句中從from到where的部分
* @param table: 表名清單,可以是要查詢的表名清單,或者直接加上join連接配接
* @example 參數例子:" table1 " 或者" table1,table2 "
*/
public void FROM(String table)
{
from.add(table);
}
/**
* 設定JOIN連接配接條件 <br/>
* 切記用了join相關的連結,則form裡隻能有一個表,而且,join函數之後,後面不得再加from函數
* @param join:JOIN連接配接條件,由3部分組成:表名 别名 + on +連接配接條件
* @example join參數例子:" bmd_mss b on b.bmd_h=loc.x_h "
*/
public void JOIN(String join)
{
this.join.add(join);
}
/**
* 設定INNER_JOIN連接配接條件 <br/>
* 切記用了join相關的連結,則form裡隻能有一個表,而且,join函數之後,後面不得再加from函數
* @param join:INNER_JOIN連接配接條件,由3部分組成:表名 别名 + on +連接配接條件
* @example join參數例子:" bmd_mss b on b.bmd_h=loc.x_h "
*/
public void INNER_JOIN(String join)
{
innerJoin.add(join);
}
/**
* 設定LEFT_OUTER_JOIN連接配接條件
* 用了join相關的連結,則form裡隻能有一個表,而且,join之後,後面不得再加form函數
* @param join:LEFT_OUTER_JOIN連接配接條件,由3部分組成:表名 别名 + on +連接配接條件
* @example join參數例子:" bmd_mss b on b.bmd_h=loc.x_h "
*/
public void LEFT_OUTER_JOIN(String join)
{
leftOuterJoin.add(join);
}
/**
* 設定RIGHT_OUTER_JOIN連接配接條件
* 用了join相關的連結,則form裡隻能有一個表,而且,join之後,後面不得再加form函數
* @param join:RIGHT_OUTER_JOIN連接配接條件,由3部分組成:表名 别名 + on +連接配接條件
* @example join參數例子:" bmd_mss b on b.bmd_h=loc.x_h "
*/
public void RIGHT_OUTER_JOIN(String join)
{
rightOuterJoin.add(join);
}
/**
* 設定OUTER_JOIN連接配接條件
* 用了join相關的連結,則form裡隻能有一個表,而且,join之後,後面不得再加form函數
* @param join:OUTER_JOIN連接配接條件,由3部分組成:表名 别名 + on +連接配接條件
* @example join參數例子:" bmd_mss b on b.bmd_h=loc.x_h "
*/
public void OUTER_JOIN(String join)
{
outerJoin.add(join);
}
//為了适應動态參數而重寫的where方法(沒有參數的情況)
/**
*設定where子語句(一個參數的情況)
* @param conditions: 連接配接條件,沒有傳動态參數的查詢條件部分<br/>
* 一個靜态查詢條件必須包含4部分内容:連接配接規則 字段列 運算符 值 <br/>
* 連接配接規則: (and 或者 or)<br/>
* 字段名: (field1)<br/>
* 運算符: 必須以下運算符中的一個( > 或者 >= 或者 < 或者 <= 或者 <br/>
* = 或者 <> 或者!= 或者 like 或者 not like 或者 in 或者 not in <br/>
* 或者 between 或者 not between ) <br/>
* 值 : 注意:如果元素符是in,則值部分必須寫成 (value1,value2...)的形式。<br/>
* 如果元素符是between,則值部分必須為 value1 and value2 的形式,value1為min,value2為max。<br/>
* 如果元素符是like,則值部分可以在值的左右兩邊加上%或者_的通配符。<br/>
* %:表示比對任意個字元;_:表示比對一個字元。<br/>
* @example conditions參數例子:" and table1.id=table2.id or table1.mc=table2.mc and table1.id like '%1%' "
*/
public void WHERE(String conditions)
{
if(StringHelper.isNotBlank(conditions))
where.add( new Criterion(conditions));
}
//為了适應動态參數而重寫的where方法,(單個參數或者in的情況)
/**
* 設定where子語句(兩個參數的情況)支援單個參數或者in的情況
* @param conditions: 連接配接條件,沒有傳動态參數的查詢條件部分,必須包含3部分内容:<br/>
* 連接配接規則:(and 或者 or)+ 字段列:(field1)+ 運算符 <br/>
* 運算符:必須以下運算符中的一個( > 或者 >= 或者 < 或者 <= 或者 = 或者 <br/>
* <> 或者!= 或者 like 或者 not like 或者 in 或者not in ) <br/>
* @param value: 參數值,Object對象,支援任何類型<br/>
* 注意:如果conditions的運算符是in, 則value部分可以傳遞一個list的對象,<br/>
* list對象至少要包含一個Object類型的元素;如果conditions的運算符是like<br/>
* 部分,則value部分可以在"value1"值的左右兩邊加上%或者_的通配符。<br/>
* %:表示比對任意個字元;_:表示比對一個字元<br/>
* @example conditions參數例子:" and table1.id= " 或者" and table1.id like "
*/
public void WHERE(String conditions,Object value)
{
if(value!=null) //如果非空
{
if (value instanceof List<?>) //如果為list
{
if(!((List)value).isEmpty() ) //如果list非空
where.add( new Criterion(conditions,value));
}
else //如果為其他直接添加
where.add( new Criterion(conditions,value));
}
}
//為了适應動态參數而重寫的where方法(單個參數或者in的情況),有close關閉符号的情況
/**
* 設定where子語句(三個參數的情況)支援單個參數或者in的情況,有close關閉符号的情況
* @param conditions: 連接配接條件,沒有傳動态參數的查詢條件部分,必須包含3部分内容:<br/>
* 連接配接規則:(and 或者 or)+ 字段列:(field1)+ 運算符 <br/>
* 運算符:必須以下運算符中的一個( > 或者 >= 或者 < 或者 <= 或者 <br/>
* = 或者 <> 或者!= 或者 like 或者 not like 或者 in 或者 not in ) <br/>
* @param value: 參數值,Object對象,支援任何類型<br/>
* 注意:如果conditions的運算符是in, 則value部分可以傳遞一個list的對象,list對象至少要包含一個Object類型的元素<br/>
* 如果conditions的運算符是like部分,則value部分可以在"value1"值的左右兩邊加上%或者_的通配符<br/>
* %:表示比對任意個字元;_:表示比對一個字元<br/>
* @example conditions參數例子:" and table1.id= " 或者" and table1.id like "
* @param close: 關閉符号,隻有在處理or條件的時候才會用到,其他時候設定null或者""
*/
public void WHERE(String conditions,Object value,String close)
{
if(value!=null) //如果非空
{
if (value instanceof List<?>) //如果為list
{
if(!((List)value).isEmpty() ) //如果list非空
where.add( new Criterion(conditions,value,close));
}
else //如果為其他直接添加
where.add( new Criterion(conditions,value,close));
}
}
//為了适應動态參數而重寫的where方法(between的情況),有close關閉符号的情況
/**
* 設定where子語句(四個參數的情況)支援between的情況,有close關閉符号的情況
* @param conditions: 連接配接條件,沒有傳動态參數的查詢條件部分,必須包含3部分内容:<br/>
* 連接配接規則:(and 或者 or)+ 字段列:(field1)+ 運算符 <br/>
* 運算符:必須以下運算符中的一個( between 或者 not between )<br/>
* @param value: 參數值,Object對象,between的參數值左部分,支援任何類型<br/>
* @param secondValue 參數值,Object對象,between的參數值右部分,支援任何類型<br/>
* @example conditions參數例子:" and table1.id= " 或者" and table1.id like "
* @param close: 關閉符号,隻有在處理or條件的時候才會用到,其他時候設定null或者""
*/
public void WHERE(String conditions,Object value,Object secondValue,String close)
{
if(value!=null&&secondValue!=null)
where.add( new Criterion(conditions,value,secondValue,close));
}
/**
* 設定分組字段清單
* 切記GROUP_BY裡面的字段select裡面的字段必須有,不然會觸發sql文法錯誤異常
* @param columns: 分組字段
* @example columns參數例子:"table1.id,table2.mc "
*/
public void GROUP_BY(String columns)
{
groupBy.add(columns);
}
//為了适應動态參數而重寫的having方法(沒有參數的情況)
/**
*
* 設定having子語句(一個參數的情況)<br/>
* 切記having裡面的字段group by裡面必須有,不然會觸發sql文法錯誤異常<br/>
* @param conditions: 連接配接條件,沒有傳動态參數的查詢條件部分<br/>
* 一個靜态查詢條件必須包含4部分内容:連接配接規則 字段列 運算符 值 <br/>
* 連接配接規則: (and 或者 or)<br/>
* 字段名: (field1)<br/>
* 運算符: 必須以下運算符中的一個( > 或者 >= 或者 < 或者 <= 或者 <br/>
* = 或者 <> 或者!= 或者 like 或者 not like 或者 in 或者 not in <br/>
* 或者 between 或者 not between ) <br/>
* 值: 注意:如果元素符是in,則值部分必須寫成 (value1,value2...)的形式。<br/>
* 如果元素符是between,則值部分必須為 value1 and value2 的形式,value1為min,value2為max。<br/>
* 如果元素符是like,則值部分可以在值的左右兩邊加上%或者_的通配符。<br/>
* %:表示比對任意個字元;_:表示比對一個字元。<br/>
* @example conditions參數例子:" and table1.id=table2.id or table1.mc=table2.mc and table1.id like '%1%' "
*/
public void HAVING(String conditions)
{
if(StringHelper.isNotBlank(conditions))
having.add( new Criterion(conditions));
}
//為了适應動态參數而重寫的having方法(單個參數或者in的情況)
/**
* 設定having子語句(兩個參數的情況)支援單個參數或者in的情況<br/>
* 切記having裡面的字段group by裡面必須有,不然會觸發sql文法錯誤異常<br/>
* @param conditions: 連接配接條件,沒有傳動态參數的查詢條件部分,必須包含3部分内容:<br/>
* 連接配接規則:(and 或者 or)+ 字段列:(field1)+ 運算符 <br/>
* 運算符:必須以下運算符中的一個( > 或者 >= 或者 < 或者 <= 或者 = 或者 <br/>
* <> 或者!= 或者 like 或者 not like 或者 in 或者not in ) <br/>
* @param value: 參數值,Object對象,支援任何類型<br/>
* 注意:如果conditions的運算符是in, 則value部分可以傳遞一個list的對象,<br/>
* list對象至少要包含一個Object類型的元素;如果conditions的運算符是like<br/>
* 部分,則value部分可以在"value1"值的左右兩邊加上%或者_的通配符。<br/>
* %:表示比對任意個字元;_:表示比對一個字元<br/>
* @example conditions參數例子:" and table1.id= " 或者" and table1.id like "
*/
public void HAVING(String conditions,Object value)
{
if(value!=null) //如果非空
{
if (value instanceof List<?>) //如果為list
{
if(!((List)value).isEmpty() ) //如果list非空
having.add( new Criterion(conditions,value));
}
else //如果為其他直接添加
having.add( new Criterion(conditions,value));
}
}
//為了适應動态參數而重寫的having方法(單個參數或者in的情況),有close關閉符号的情況
/**
* 設定having子語句(三個參數的情況)支援單個參數或者in的情況,有close關閉符号的情況 <br/>
* 切記having裡面的字段group by裡面必須有,不然會觸發sql文法錯誤異常<br/>
* @param conditions: 連接配接條件,沒有傳動态參數的查詢條件部分,必須包含3部分内容:<br/>
* 連接配接規則:(and 或者 or)+ 字段列:(field1)+ 運算符 <br/>
* 運算符:必須以下運算符中的一個( > 或者 >= 或者 < 或者 <= 或者 <br/>
* = 或者 <> 或者!= 或者 like 或者 not like 或者 in 或者 not in ) <br/>
* @param value: 參數值,Object對象,支援任何類型<br/>
* 注意:如果conditions的運算符是in, 則value部分必須傳遞一個list的對象,<br/>
* list對象至少要包含一個Object類型的元素;<br/>
* 如果conditions的運算符是like部分,則value部分可以在"value1"值的左右兩邊加上%或者_的通配符<br/>
* %:表示比對任意個字元;_:表示比對一個字元<br/>
* @example conditions參數例子:" and table1.id= " 或者" and table1.id like "
* @param close: 關閉符号,隻有在處理or條件的時候才會用到,其他時候設定null或者""
*/
public void HAVING(String conditions,Object value,String close)
{
if(value!=null) //如果非空
{
if (value instanceof List<?>) //如果為list
{
if(!((List)value).isEmpty() ) //如果list非空
having.add( new Criterion(conditions,value,close));
}
else //如果為其他直接添加
having.add( new Criterion(conditions,value,close));
}
}
//為了适應動态參數而重寫的having方法(between的情況),有close關閉符号的情況
/**
* 設定having子語句(四個參數的情況)支援between的情況,有close關閉符号的情況<br/>
* 切記having裡面的字段group by裡面必須有,不然會觸發sql文法錯誤異常<br/>
* @param conditions: 連接配接條件,沒有傳動态參數的查詢條件部分,必須包含3部分内容:<br/>
* 連接配接規則:(and 或者 or)+ 字段列:(field1)+ 運算符 <br/>
* 運算符:必須以下運算符中的一個( between 或者 not between )<br/>
* @param value: 參數值,Object對象,between的參數值左部分,支援任何類型<br/>
* @param secondValue: 參數值,Object對象,between的參數值右部分,支援任何類型<br/>
* @example conditions參數例子:" and table1.id= " 或者" and table1.id like "
* @param close: 關閉符号,隻有在處理or條件的時候才會用到,其他時候設定null或者""
*/
public void HAVING(String conditions,Object value,Object secondValue,String close)
{
if(value!=null&&secondValue!=null)
having.add( new Criterion(conditions,value,secondValue,close));
}
/**
* 設定排序子語句
* 切記ORDER_BY裡面的字段select裡面的字段必須有,不然會觸發sql文法錯誤異常
* @param conditions: 排序條件
* @example conditions參數例子:"table1.id decs"
*/
public void ORDER_BY(String conditions)
{
orderBy.add(conditions);
}
private StringBuilder selectClause( String keyword,
List<String> parts, String open, String close, String conjunction)
{
StringBuilder builder=new StringBuilder();
if (!parts.isEmpty())
{
if (builder.length() > 0)
builder.append("\n");
builder.append(keyword);
builder.append(" ");
builder.append(open);
String last = "________";
for (int i = 0, n = parts.size(); i < n; i++)
{
String part = parts.get(i);
if (i > 0 && !part.equals(AND) && !part.equals(OR) && !last.equals(AND)
&& !last.equals(OR))
{
builder.append(conjunction);
}
builder.append(part);
last = part;
}
builder.append(close);
}
return builder;
}
private void whereClause()
{
if(where.size()>0)
{
System.out.print(" WHERE 1=1 ");
for(Criterion cri:where)
{
if(cri.isNoValue())
System.out.print(cri.getCondition());
if(cri.isSingleValue())
System.out.print(cri.getCondition()+" '"+cri.getValue()+"'");
if(cri.isBetweenValue())
System.out.print(cri.getCondition()+" '"+cri.getValue()+"' and '"+cri.getSecondValue()+"'");
if(cri.isListValue())
{
StringBuilder strb= new StringBuilder();
strb.append(cri.getCondition());
strb.append(" (");
List list=(List)cri.getValue();
for(int i=0;i<list.size();i++)
{
Object o=list.get(i);
strb.append("'"+o+"'");
if(i<list.size()-1)
strb.append(",");
}
strb.append(")");
System.out.print(strb);
}
//處理關閉符号的代碼
if(cri.close==null||cri.close.equals(""))
System.out.println();
else
System.out.println(cri.close);
}
}
}
private void havingClause()
{
if(having.size()>0)
{
System.out.print(" HAVING 1=1 ");
for(Criterion cri:having)
{
if(cri.isNoValue())
System.out.print(cri.getCondition());
if(cri.isSingleValue())
System.out.print(cri.getCondition()+" '"+cri.getValue()+"'");
if(cri.isBetweenValue())
System.out.print(cri.getCondition()+" '"+cri.getValue()+"' and '"+cri.getSecondValue()+"'");
if(cri.isListValue())
{
StringBuilder strb= new StringBuilder();
strb.append(cri.getCondition());
strb.append(" (");
List list=(List)cri.getValue();
for(int i=0;i<list.size();i++)
{
Object o=list.get(i);
strb.append("'"+o+"'");
if(i<list.size()-1)
strb.append(",");
}
strb.append(")");
System.out.print(strb);
}
//處理關閉符号的代碼
if(cri.close==null||cri.close.equals(""))
System.out.println();
else
System.out.println(cri.close);
}
}
}
/**
* 列印由各部分組合起來的SQL語句
*/
public void printSQL()
{
if(!select.isEmpty())
System.out.println(selectClause( "SELECT", this.select, "", "", ", "));
if(!from.isEmpty())
System.out.println(selectClause( "FROM", this.from, "", "", ", "));
if(!innerJoin.isEmpty())
System.out.println(selectClause("INNER JOIN", this.innerJoin, "", "", "\nINNER JOIN "));
if(!outerJoin.isEmpty())
System.out.println(selectClause("OUTER JOIN", this.outerJoin, "", "", "\nOUTER JOIN "));
if(!leftOuterJoin.isEmpty())
System.out.println(selectClause(" LEFT OUTER JOIN", this.leftOuterJoin, "", "", "\nLEFT OUTER JOIN "));
if(!rightOuterJoin.isEmpty())
System.out.println(selectClause(" RIGHT OUTER JOIN", this.rightOuterJoin, "", "", "\nRIGHT OUTER JOIN "));
whereClause();
if(!groupBy.isEmpty())
System.out.println(selectClause(" GROUP BY", this.groupBy, "", "", ", "));
havingClause();
if(!orderBy.isEmpty())
System.out.println(selectClause(" ORDER BY", this.orderBy, "", "", ", "));
}
/**
* Criterion :where或者having的子語句條件類
* @author LMH 修改
*
*/
public class Criterion {
private String condition;
private Object value;
private Object secondValue;
private boolean noValue;
private boolean singleValue;
private boolean betweenValue;
private boolean listValue;
private String close; //為了解決or要有括号括起來而添加的屬性
private String typeHandler;
public String getCondition() {
return condition;
}
public Object getValue() {
return value;
}
public Object getSecondValue() {
return secondValue;
}
public boolean isNoValue() {
return noValue;
}
public boolean isSingleValue() {
return singleValue;
}
public boolean isBetweenValue() {
return betweenValue;
}
public boolean isListValue() {
return listValue;
}
public String getTypeHandler() {
return typeHandler;
}
public String getClose() {
return close;
}
public void setClose(String close) {
this.close = close;
}
protected Criterion(String condition) {
super();
this.condition = condition;
this.typeHandler = null;
this.noValue = true;
}
protected Criterion(String condition, Object value) {
this.condition = condition;
this.value = value;
if (value instanceof List<?>) {
this.listValue = true;
} else {
this.singleValue = true;
}
}
protected Criterion(String condition, Object value,String close) {
this.condition = condition;
this.value = value;
this.close=close;
if (value instanceof List<?>) {
this.listValue = true;
} else {
this.singleValue = true;
}
}
protected Criterion(String condition, Object value, Object secondValue, String close) {
super();
this.condition = condition;
this.value = value;
this.secondValue = secondValue;
this.close = close;
this.betweenValue = true;
}
}
public static void main(String[] args) throws IOException {
SelectBuilder sql=new SelectBuilder();
sql.SELECT("l.mc,l.id");
System.out.println(sql.selectClause( "SELECT", sql.select, "", "", ", "));
sql.FROM("bmd l,user u");
System.out.println(sql.selectClause( "FROM", sql.from, "", "", ", "));
sql.INNER_JOIN("DEPARTMENT D on D.ID = P.DEPARTMENT_ID");
System.out.println(sql.selectClause("INNER JOIN", sql.innerJoin, "", "", "\nINNER JOIN "));
sql.WHERE(" l.id=u.id");
List l=new ArrayList();
l.add("1");
l.add("2");
sql.WHERE("or( l.id in",l);
sql.WHERE("and l.id between",1,2,")");
sql.whereClause();
sql.GROUP_BY("l.id,u.id");
System.out.println(sql.selectClause( "GROUP BY", sql.groupBy, "", "", ", "));
sql.HAVING(" l.id=u.id");
List l2=new ArrayList();
l2.add("1");
l2.add("2");
sql.HAVING("or( l.id in",l2);
sql.HAVING("and l.id between","1","2",")");
sql.havingClause();
}
/**********get方法*******/
public List<String> getSelect() {
return select;
}
public List<String> getFrom() {
return from;
}
public List<String> getJoin() {
return join;
}
public List<String> getInnerJoin() {
return innerJoin;
}
public List<String> getOuterJoin() {
return outerJoin;
}
public List<String> getLeftOuterJoin() {
return leftOuterJoin;
}
public List<String> getRightOuterJoin() {
return rightOuterJoin;
}
public List<Criterion> getWhere() {
return where;
}
public List<Criterion> getHaving() {
return having;
}
public List<String> getGroupBy() {
return groupBy;
}
public List<String> getOrderBy() {
return orderBy;
}
public boolean isDistinct() {
return distinct;
}
}
SqlMapper.xml的映射檔案如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.dao.SqlMapper">
<!-- 方法一:支援單表或者多表的通用查詢方法 By 梁敏鴻 2012年2月24日 -->
<select id="selectBySql" resultType="map" parameterType="com.common.SelectBuilder">
<!-- 1.SQL語句的基本部分 -->
<if test="distinct">
<if test="!select.empty">
SELECT DISTINCT
</if>
<foreach collection="select" item="select_content" open=" " separator="," close=" " >
${select_content}
</foreach>
</if>
<if test="!distinct">
<if test="!select.empty">
SELECT
</if>
<foreach collection="select" item="select_content" open=" " separator="," close=" " >
${select_content}
</foreach>
</if>
<if test="!from.empty">
FROM
<foreach collection="from" item="from_content" open=" " separator="," close=" " >
${from_content}
</foreach>
</if>
<!-- 2.join 查詢部分-->
<if test="!join.empty">
JOIN
<foreach collection="join" item="join_content" open=" " separator="\n JOIN" close=" " >
${join_content}
</foreach>
</if>
<if test="!innerJoin.empty">
INNER JOIN
<foreach collection="innerJoin" item="innerJoin_content" open=" " separator="\n INNER JOIN" close=" " >
${innerJoin_content}
</foreach>
</if>
<if test="!outerJoin.empty">
OUTER JOIN
<foreach collection="outerJoin" item="outerJoin_content" open=" " separator="\n OUTER JOIN" close=" " >
${outerJoin_content}
</foreach>
</if>
<if test="!leftOuterJoin.empty">
LEFT OUTER JOIN
<foreach collection="leftOuterJoin" item="leftOuterJoin_content" open=" " separator="\n LEFT OUTER JOIN" close=" " >
${leftOuterJoin_content}
</foreach>
</if>
<if test="!rightOuterJoin.empty">
RIGHT OUTER JOIN
<foreach collection="rightOuterJoin" item="rightOuterJoin_content" open=" " separator="\n RIGHT OUTER JOIN" close=" " >
${rightOuterJoin_content}
</foreach>
</if>
<!-- 3.SQL語句WHERE部分 -->
<if test="!where.empty">
where 1=1
<foreach collection="where" item="where_Criterion" open=" " separator=" " close=" " >
<choose >
<when test="where_Criterion.noValue" >
${where_Criterion.condition}
</when>
<when test="where_Criterion.singleValue" >
${where_Criterion.condition} #{where_Criterion.value}
</when>
<when test="where_Criterion.betweenValue" >
${where_Criterion.condition} #{where_Criterion.value} and #{where_Criterion.secondValue}
</when>
<when test="where_Criterion.listValue" >
${where_Criterion.condition}
<foreach collection="where_Criterion.value" item="listItem" open="(" close=")" separator="," >
#{listItem}
</foreach>
</when>
</choose>
<!-- 加上close關閉符号,為了處理or的括号包含的情況 -->
<if test="where_Criterion.close!=null and where_Criterion.close!=''">
${where_Criterion.close}
</if>
</foreach>
</if>
<!-- 4.SQL語句GROUP BY部分 -->
<if test="!groupBy.empty">
GROUP BY
<foreach collection="groupBy" item="groupBy_content" open=" " separator="," close=" " >
${groupBy_content}
</foreach>
</if>
<!-- 5.SQL語句HAVING部分 -->
<if test="!having.empty">
HAVING 1=1
<foreach collection="having" item="having_Criterion" open=" " separator=" " close=" " >
<choose >
<when test="having_Criterion.noValue" >
${having_Criterion.condition}
</when>
<when test="having_Criterion.singleValue" >
${having_Criterion.condition} #{having_Criterion.value}
</when>
<when test="having_Criterion.betweenValue" >
${having_Criterion.condition} #{having_Criterion.value} and #{having_Criterion.secondValue}
</when>
<when test="having_Criterion.listValue" >
${having_Criterion.condition}
<foreach collection="having_Criterion.value" item="listItem" open="(" close=")" separator="," >
#{listItem}
</foreach>
</when>
</choose>
<!-- 加上close關閉符号,為了處理or的括号包含的情況 -->
<if test="having_Criterion.close!=null and having_Criterion.close!=''">
${having_Criterion.close}
</if>
</foreach>
</if>
<!-- 6.SQL語句ORDER BY部分 -->
<if test="!orderBy.empty">
ORDER BY
<foreach collection="orderBy" item="orderBy_content" open=" " separator="," close=" " >
${orderBy_content}
</foreach>
</if>
</select>
<!-- 方法二:支援單表或者多表的通用統計方法 By lmh 2012年2月24日 -->
<select id="countBySql" resultType="int" parameterType="com.common.SelectBuilder">
<if test="distinct">
<if test="!select.empty">
SELECT DISTINCT
</if>
COUNT(*)
</if>
<if test="!distinct">
<if test="!select.empty">
SELECT
</if>
COUNT(*)
</if>
<if test="!from.empty">
FROM
<foreach collection="from" item="from_content" open=" " separator="," close=" " >
${from_content}
</foreach>
</if>
<if test="!join.empty">
JOIN
<foreach collection="join" item="join_content" open=" " separator="\n JOIN" close=" " >
${join_content}
</foreach>
</if>
<if test="!innerJoin.empty">
INNER JOIN
<foreach collection="innerJoin" item="innerJoin_content" open=" " separator="\n INNER JOIN" close=" " >
${innerJoin_content}
</foreach>
</if>
<if test="!outerJoin.empty">
OUTER JOIN
<foreach collection="outerJoin" item="outerJoin_content" open=" " separator="\n OUTER JOIN" close=" " >
${outerJoin_content}
</foreach>
</if>
<if test="!leftOuterJoin.empty">
LEFT OUTER JOIN
<foreach collection="leftOuterJoin" item="leftOuterJoin_content" open=" " separator="\n LEFT OUTER JOIN" close=" " >
${leftOuterJoin_content}
</foreach>
</if>
<if test="!rightOuterJoin.empty">
RIGHT OUTER JOIN
<foreach collection="rightOuterJoin" item="rightOuterJoin_content" open=" " separator="\n RIGHT OUTER JOIN" close=" " >
${rightOuterJoin_content}
</foreach>
</if>
<if test="!where.empty">
where 1=1
<foreach collection="where" item="where_Criterion" open=" " separator=" " close=" " >
<choose >
<when test="where_Criterion.noValue" >
${where_Criterion.condition}
</when>
<when test="where_Criterion.singleValue" >
${where_Criterion.condition} #{where_Criterion.value}
</when>
<when test="where_Criterion.betweenValue" >
${where_Criterion.condition} #{where_Criterion.value} and #{where_Criterion.secondValue}
</when>
<when test="where_Criterion.listValue" >
${where_Criterion.condition}
<foreach collection="where_Criterion.value" item="listItem" open="(" close=")" separator="," >
#{listItem}
</foreach>
</when>
</choose>
<if test="where_Criterion.close!=null and where_Criterion.close!=''">
${where_Criterion.close}
</if>
</foreach>
</if>
<if test="!groupBy.empty">
GROUP BY
<foreach collection="groupBy" item="groupBy_content" open=" " separator="," close=" " >
${groupBy_content}
</foreach>
</if>
<if test="!having.empty">
HAVING 1=1
<foreach collection="having" item="having_Criterion" open=" " separator=" " close=" " >
<choose >
<when test="having_Criterion.noValue" >
${having_Criterion.condition}
</when>
<when test="having_Criterion.singleValue" >
${having_Criterion.condition} #{having_Criterion.value}
</when>
<when test="having_Criterion.betweenValue" >
${having_Criterion.condition} #{having_Criterion.value} and #{having_Criterion.secondValue}
</when>
<when test="having_Criterion.listValue" >
${having_Criterion.condition}
<foreach collection="having_Criterion.value" item="listItem" open="(" close=")" separator="," >
#{listItem}
</foreach>
</when>
</choose>
<if test="having_Criterion.close!=null and having_Criterion.close!=''">
${having_Criterion.close}
</if>
</foreach>
</if>
<if test="!orderBy.empty">
ORDER BY
<foreach collection="orderBy" item="orderBy_content" open=" " separator="," close=" " >
${orderBy_content}
</foreach>
</if>
</select>
</mapper>
望大家指出設計的不足和程式存在的漏洞和錯誤。