!99 feat: 添加 SQL CONCAT 函数支持

Merge pull request !99 from 王帅/main
This commit is contained in:
Michael Yang 2023-06-29 03:43:10 +00:00 committed by Gitee
commit 638ff9e153
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
10 changed files with 129 additions and 32 deletions

View File

@ -96,7 +96,7 @@ public class ArithmeticQueryColumn extends QueryColumn {
sql.append(arithmeticInfos.get(i).toSql(queryTables, dialect, i));
}
if (StringUtil.isNotBlank(alias)) {
return WrapperUtil.withAlias(sql.toString(), dialect.wrap(alias), dialect);
return WrapperUtil.withAlias(sql.toString(), alias, dialect);
}
return sql.toString();
}

View File

@ -44,7 +44,7 @@ public class CaseQueryColumn extends QueryColumn implements HasParamsColumn {
String toSelectSql(List<QueryTable> queryTables, IDialect dialect) {
String sql = buildSql(queryTables, dialect);
if (StringUtil.isNotBlank(alias)) {
return WrapperUtil.withAlias(sql, dialect.wrap(alias), dialect);
return WrapperUtil.withAlias(sql, alias, dialect);
}
return sql;
}

View File

@ -37,7 +37,7 @@ public class CaseSearchQueryColumn extends QueryColumn implements HasParamsColum
String toSelectSql(List<QueryTable> queryTables, IDialect dialect) {
String sql = buildSql(queryTables, dialect);
if (StringUtil.isNotBlank(alias)) {
return WrapperUtil.withAlias(sql, dialect.wrap(alias), dialect);
return WrapperUtil.withAlias(sql, alias, dialect);
}
return sql;
}

View File

@ -18,11 +18,15 @@ package com.mybatisflex.core.query;
import com.mybatisflex.core.FlexConsts;
import com.mybatisflex.core.constant.SqlConsts;
import com.mybatisflex.core.dialect.IDialect;
import com.mybatisflex.core.util.ObjectUtil;
import com.mybatisflex.core.util.CollectionUtil;
import com.mybatisflex.core.util.SqlUtil;
import com.mybatisflex.core.util.StringUtil;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* 数据库 聚合函数例如 count(id) max(account.age) 等等
@ -30,19 +34,25 @@ import java.util.List;
public class FunctionQueryColumn extends QueryColumn implements HasParamsColumn {
protected String fnName;
protected QueryColumn column;
protected List<QueryColumn> columns;
public FunctionQueryColumn(String fnName, String column) {
public FunctionQueryColumn(String fnName) {
SqlUtil.keepColumnSafely(fnName);
SqlUtil.keepColumnSafely(column);
this.fnName = fnName;
this.column = new QueryColumn(column);
this.columns = new ArrayList<>();
}
public FunctionQueryColumn(String fnName, QueryColumn column) {
SqlUtil.keepColumnSafely(fnName);
this.fnName = fnName;
this.column = column;
public FunctionQueryColumn(String fnName, String... columns) {
this(fnName);
for (String column : columns) {
// SqlUtil.keepColumnSafely(column)
this.columns.add(new QueryColumn(column));
}
}
public FunctionQueryColumn(String fnName, QueryColumn... columns) {
this(fnName);
this.columns.addAll(Arrays.asList(columns));
}
public String getFnName() {
@ -53,41 +63,73 @@ public class FunctionQueryColumn extends QueryColumn implements HasParamsColumn
this.fnName = fnName;
}
public QueryColumn getColumn() {
return column;
public List<QueryColumn> getColumns() {
return columns;
}
public void setColumn(QueryColumn column) {
this.column = column;
public void setColumns(List<QueryColumn> columns) {
this.columns = columns;
}
@Override
public Object[] getParamValues() {
if (column instanceof HasParamsColumn) {
return ((HasParamsColumn) column).getParamValues();
if (CollectionUtil.isEmpty(columns)) {
return FlexConsts.EMPTY_ARRAY;
}
return FlexConsts.EMPTY_ARRAY;
List<Object> params = new ArrayList<>();
for (QueryColumn queryColumn : columns) {
if (queryColumn instanceof HasParamsColumn) {
Object[] paramValues = ((HasParamsColumn) queryColumn).getParamValues();
params.addAll(Arrays.asList(paramValues));
}
}
return params.toArray();
}
@Override
public String toSelectSql(List<QueryTable> queryTables, IDialect dialect) {
String sql = column.toSelectSql(queryTables, dialect);
if (StringUtil.isBlank(sql)) {
return SqlConsts.EMPTY;
}
String sql = getSql(queryTables, dialect);
if (StringUtil.isBlank(alias)) {
return fnName + WrapperUtil.withBracket(sql);
}
return fnName + WrapperUtil.withAlias(sql, dialect.wrap(alias), dialect);
return fnName + WrapperUtil.withAlias(sql, alias, dialect);
}
@Override
String toConditionSql(List<QueryTable> queryTables, IDialect dialect) {
String sql = column.toSelectSql(queryTables, dialect);
String sql = getSql(queryTables, dialect);
return fnName + WrapperUtil.withBracket(sql);
}
/**
* <p>获取函数括号里面的 SQL 内容
*
* <p>如果函数括号里面没有内容就返回空字符串这样构建出来就是函数名加括号
*
* <p>例如NOW() 函数的构建
* <pre>{@code
* FunctionQueryColumn c1 = new FunctionQueryColumn("NOW");
* FunctionQueryColumn c2 = new FunctionQueryColumn("NOW", new StringQueryColumn(""));
* }</pre>
*/
private String getSql(List<QueryTable> queryTables, IDialect dialect) {
if (CollectionUtil.isEmpty(columns)) {
return SqlConsts.EMPTY;
}
String sql = columns.stream()
.filter(Objects::nonNull)
.map(c -> c.toSelectSql(queryTables, dialect))
.collect(Collectors.joining(SqlConsts.DELIMITER));
if (StringUtil.isBlank(sql)) {
return SqlConsts.EMPTY;
}
return fnName + WrapperUtil.withBracket(sql);
return sql;
}
@Override
@ -101,7 +143,7 @@ public class FunctionQueryColumn extends QueryColumn implements HasParamsColumn
public String toString() {
return "FunctionQueryColumn{" +
"fnName='" + fnName + '\'' +
", column=" + column +
", columns=" + columns +
'}';
}
@ -109,7 +151,7 @@ public class FunctionQueryColumn extends QueryColumn implements HasParamsColumn
public FunctionQueryColumn clone() {
FunctionQueryColumn clone = (FunctionQueryColumn) super.clone();
// deep clone ...
clone.column = ObjectUtil.clone(this.column);
clone.columns = CollectionUtil.cloneArrayList(this.columns);
return clone;
}

View File

@ -18,6 +18,9 @@ package com.mybatisflex.core.query;
import com.mybatisflex.core.util.LambdaGetter;
import com.mybatisflex.core.util.LambdaUtil;
import java.util.Arrays;
import java.util.List;
import static com.mybatisflex.core.constant.SqlConsts.*;
public class QueryMethods {
@ -163,6 +166,15 @@ public class QueryMethods {
return new StringFunctionQueryColumn(CONVERT, params);
}
///CONCAT
public static FunctionQueryColumn concat(String str1, String str2, String... more) {
List<String> args = Arrays.asList(str1, str2);
args.addAll(Arrays.asList(more));
String[] columns = new String[args.size()];
args.toArray(columns);
return new FunctionQueryColumn("CONCAT", columns);
}
public static StringQueryColumn column(String column) {
return new StringQueryColumn(column);
}

View File

@ -45,7 +45,7 @@ public class SelectQueryColumn extends QueryColumn implements HasParamsColumn {
String toSelectSql(List<QueryTable> queryTables, IDialect dialect) {
String selectSql = dialect.forSelectByQuery(queryWrapper);
if (StringUtil.isNotBlank(selectSql) && StringUtil.isNotBlank(alias)) {
selectSql = WrapperUtil.withAlias(selectSql, dialect.wrap(alias), dialect);
selectSql = WrapperUtil.withAlias(selectSql, alias, dialect);
}
return selectSql;
}

View File

@ -49,7 +49,7 @@ public class SelectQueryTable extends QueryTable {
public String toSql(IDialect dialect) {
String sql = dialect.buildSelectSql(queryWrapper);
if (StringUtil.isNotBlank(alias)) {
return WrapperUtil.withAlias(sql, dialect.wrap(alias), dialect);
return WrapperUtil.withAlias(sql, alias, dialect);
} else {
return WrapperUtil.withBracket(sql);
}

View File

@ -65,7 +65,7 @@ public class StringFunctionQueryColumn extends QueryColumn {
if (StringUtil.isBlank(alias)) {
return fnName + WrapperUtil.withBracket(sql);
}
return fnName + WrapperUtil.withAlias(sql, dialect.wrap(alias), dialect);
return fnName + WrapperUtil.withAlias(sql, alias, dialect);
}
@Override

View File

@ -147,7 +147,7 @@ class WrapperUtil {
}
static String withAlias(String sql, String alias, IDialect dialect) {
return SqlConsts.BRACKET_LEFT + sql + SqlConsts.BRACKET_RIGHT + getAsKeyWord(dialect) + alias;
return SqlConsts.BRACKET_LEFT + sql + SqlConsts.BRACKET_RIGHT + getAsKeyWord(dialect) + dialect.wrap(alias);
}
static String buildAlias(String alias, IDialect dialect) {

View File

@ -0,0 +1,43 @@
/*
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mybatisflex.coretest;
import com.mybatisflex.core.query.FunctionQueryColumn;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.query.StringQueryColumn;
import org.junit.Test;
import static com.mybatisflex.coretest.table.AccountTableDef.ACCOUNT;
/**
* @author 王帅
* @since 2023-06-28
*/
public class FunctionSqlTest {
@Test
public void test() {
String sql = QueryWrapper.create()
.select(new FunctionQueryColumn("NOW").as("n1"))
.select(new FunctionQueryColumn("NOW", new StringQueryColumn("")).as("n2"))
.select(new FunctionQueryColumn("CONCAT", ACCOUNT.USER_NAME, ACCOUNT.AGE).as("c1"))
.from(ACCOUNT)
.toSQL();
System.out.println(sql);
}
}