在某些場景下需要我們在代碼中動态的建立SQL語句來查詢資料,正常的做法就是使用字元串的拼接來完成,但這樣的方式靈活度不高,如果SQL本身比較複雜,那麼其處理邏輯也會顯得比較混亂。下面簡單的介紹下使用開源的jsqlparser來以程式設計的方式建立動态SQL。
<dependency>
<groupId>com.github.jsqlparser</groupId>
<artifactId>jsqlparser</artifactId>
<version>4.2</version>
</dependency>
jsqlparser: https://github.com/JSQLParser/JSqlParser
1.建立普通的SELECT語句
PlainSelect plainSelect = new PlainSelect() ;
//設定查詢的列
plainSelect.addSelectItems(Arrays.asList(new SelectExpressionItem()
.withExpression(new Column("COLUMN_01") //設定列名
.withTable(new Table("TABLE01"))) //設定表名[可選]
.withAlias(new Alias("COLUMN_ALIAS")))); //設定列的别名[可選]
//設定查詢的表
plainSelect.setFromItem(new Table("TABLE01"));
最終生成的結果:
SELECT TABLE01.COLUMN_01 AS COLUMN_ALIAS FROM TABLE01
2.建立子查詢
PlainSelect plainSelect = new PlainSelect() ;
//設定查詢的列
plainSelect.addSelectItems(Arrays.asList(new SelectExpressionItem()
.withExpression(new Column("COLUMN_01") //設定列名
.withTable(new Table("TABLE01"))) //設定表名[可選]
.withAlias(new Alias("COLUMN_ALIAS")))); //設定列的别名[可選]
//子查詢
PlainSelect subSelect = new PlainSelect() ;
subSelect.addSelectItems(Arrays.asList(new SelectExpressionItem()
.withExpression(new Column("COLUMN_01"))));
subSelect.setFromItem(new Table("SUB_TABLE"));
//設定查詢的子表
plainSelect.setFromItem(new SubSelect()
.withSelectBody(subSelect)
.withAlias(new Alias("TABLE01")));
最終生成的結果:
SELECT
TABLE01.COLUMN_01 AS COLUMN_ALIAS
FROM
( SELECT COLUMN_01 FROM SUB_TABLE ) AS TABLE01
3.建立WHERE條件
PlainSelect plainSelect = new PlainSelect() ;
plainSelect.addSelectItems(Arrays.asList(new SelectExpressionItem()
.withExpression(new Column("COLUMN_01")
.withTable(new Table("TABLE01")))
.withAlias(new Alias("COLUMN_ALIAS"))));
//子查詢
PlainSelect subSelect = new PlainSelect() ;
subSelect.addSelectItems(Arrays.asList(new SelectExpressionItem()
.withExpression(new Column("COLUMN_01"))));
subSelect.setFromItem(new Table("SUB_TABLE"));
plainSelect.setFromItem(new SubSelect()
.withSelectBody(subSelect)
.withAlias(new Alias("TABLE01")));
//where條件
Column column = new Column().withColumnName("COLUMN_01")
.withTable(new Table("TABLE01"));
Expression expression1 = buildGreaterThanExpression(column,123) ;
Expression expression2 = buildInExpression(column,Arrays.asList("123","345")) ;
Expression whereExpression = buildAndExpression(Arrays.asList(expression1,expression2)) ;
plainSelect.setWhere(whereExpression);
SELECT
TABLE01.COLUMN_01 AS COLUMN_ALIAS
FROM
( SELECT COLUMN_01 FROM SUB_TABLE ) AS TABLE01
WHERE
TABLE01.COLUMN_01 > 123
AND TABLE01.COLUMN_01 IN ('123','345')
3.1建立AND表達式
public Expression buildAndExpression(List<Expression> expressionList){
Assert.notEmpty(expressionList,"建立AND辨別的是子表達式不能為空");
if(expressionList.size() == 1){
return expressionList.get(0) ;
}
AndExpression andExpression = new AndExpression() ;
andExpression.withLeftExpression(expressionList.get(0)).withRightExpression(expressionList.get(1)) ;
for(int i=2;i<expressionList.size();i++){
AndExpression itemExpression = new AndExpression() ;
itemExpression.withLeftExpression(andExpression).withRightExpression(expressionList.get(i));
andExpression = itemExpression ;
}
return andExpression ;
}
3.2 建立算數表達式
public Expression buildGreaterThanExpression(Column column,Object value){
/**
* GreaterThan: >
* GreaterThanEquals : >=
* MinorThan: <
* MinorThanEquals: <=
*/
GreaterThan greaterThan = new GreaterThan().withLeftExpression(column) ;
//greaterThan.withRightExpression(new StringValue(value.toString())) ;
greaterThan.withRightExpression(new DoubleValue(value.toString())) ;
return greaterThan ;
}
3.3 建立IN表達式
public Expression buildInExpression(Column column, List<String> values){
ExpressionList expressionList = new ExpressionList() ;
values.forEach(val -> {
expressionList.addExpressions(new StringValue(val);
});
InExpression inExpression = new InExpression()
.withLeftExpression(column)
.withRightExpression(new ValueListExpression()
.withExpressionList(expressionList)) ;
//inExpression.withNot(true); //設定成 NOT IN
return inExpression ;
}
3.4 建立Equals表達式
public Expression buildEqualsExpression(Column column, Object value){
//不等于:NotEqualsTo
EqualsTo equalsTo = new EqualsTo().withLeftExpression(column) ;
equalsTo.withRightExpression(new StringValue(value.toString()));
//equalsTo.withRightExpression(new DoubleValue(value.toString()));
return equalsTo ;
}
3.5 建立Between表達式
public Expression buildBetweenExpression(Column column, Object leftValue,Object rightValue){
Between between = new Between().withLeftExpression(column) ;
between.withLeftExpression(column) ;
between.withBetweenExpressionStart(new DoubleValue(leftValue.toString())) ;
between.withBetweenExpressionEnd(new DoubleValue(rightValue.toString())) ;
return between ;
}
3.6 建立Like表達式
public Expression buildLikeExpression(Column column, Object value){
LikeExpression likeExpression = new LikeExpression()
.withLeftExpression(column);
likeExpression.withRightExpression(new StringValue("%" + value.toString() + "%" )) ;
return likeExpression ;
}
4.建立分組、排序和分頁表達式
PlainSelect plainSelect = new PlainSelect() ;
plainSelect.addSelectItems(Arrays.asList(new SelectExpressionItem()
.withExpression(new Column("COLUMN_01")
.withTable(new Table("TABLE01")))
.withAlias(new Alias("COLUMN_ALIAS"))));
//子查詢
PlainSelect subSelect = new PlainSelect() ;
subSelect.addSelectItems(Arrays.asList(new SelectExpressionItem()
.withExpression(new Column("COLUMN_01"))));
subSelect.setFromItem(new Table("SUB_TABLE"));
plainSelect.setFromItem(new SubSelect()
.withSelectBody(subSelect)
.withAlias(new Alias("TABLE01")));
//where條件
Column column = new Column().withColumnName("COLUMN_01")
.withTable(new Table("TABLE01"));
Expression expression1 = buildGreaterThanExpression(column,123) ;
Expression expression2 = buildInExpression(column,Arrays.asList("123","345")) ;
Expression whereExpression = buildAndExpression(Arrays.asList(expression1,expression2)) ;
plainSelect.setWhere(whereExpression);
//添加分組語句
List<Column> groupByColumns = new ArrayList<>() ;
groupByColumns.add(new Column("COL_01")) ;
for(Column col : groupByColumns){
plainSelect.addGroupByColumnReference(col);
}
//添加排序語句
List<OrderByElement> orderByElements = new ArrayList<>() ;
OrderByElement orderByElement = new OrderByElement() ;
orderByElement.setExpression(new Column("COL_01"));
orderByElement.setAsc(false);
orderByElements.add(orderByElement) ;
plainSelect.setOrderByElements(orderByElements);
//添加分頁
int pageSize = 10 ;
int pageNum = 1 ;
plainSelect.setLimit(new Limit()
.withOffset(new LongValue((pageNum-1)*pageSize))
.withRowCount(new LongValue(pageSize)));
SELECT
TABLE01.COLUMN_01 AS COLUMN_ALIAS
FROM
( SELECT COLUMN_01 FROM SUB_TABLE ) AS TABLE01
WHERE
TABLE01.COLUMN_01 > 123 AND TABLE01.COLUMN_01 IN ( '123', '345' )
GROUP BY
COL_01
ORDER BY COL_01 DESC
LIMIT 0,10
5.建立join語句
//添加JOIN語句
EqualsTo equalsExpression = new EqualsTo() ;
equalsExpression.setLeftExpression(new Column(new Table("TABLE01"),"ID"));
equalsExpression.setRightExpression(new Column(new Table("TABLE02"),"ID"));
Join join = new Join(); // 建立Join對象
join.setInner(true); //設定為内關聯
join.withRightItem(new Table("TAB_02")) ;
join.setOnExpressions(Arrays.asList(equalsExpression));
plainSelect.addJoins(join) ;