diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/constant/FuncName.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/constant/FuncName.java index 2b2c63ba..ded85859 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/constant/FuncName.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/constant/FuncName.java @@ -144,6 +144,9 @@ public class FuncName { public static final String WEEKOFYEAR = "WEEKOFYEAR"; public static final String YEAR = "YEAR"; public static final String GROUP_CONCAT = "GROUP_CONCAT"; + public static final String STRING_AGG = "STRING_AGG"; + public static final String LISTAGG = "LISTAGG"; + private FuncName() { } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/dialect/DbType.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/dialect/DbType.java index 61f5a262..9c880f05 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/dialect/DbType.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/dialect/DbType.java @@ -17,6 +17,7 @@ package com.mybatisflex.core.dialect; import com.mybatisflex.core.util.StringUtil; import java.util.Arrays; +import java.util.List; public enum DbType { @@ -208,4 +209,44 @@ public enum DbType { .findFirst() .orElse(null); } + + /** + * 获取所有数据库类型 + * + * @return 包含所有数据库类型的列表 + */ + public static List all() { + return Arrays.asList(DbType.values()); + } + + /** + * 判断当前数据库语法是否与MySQL属于同一类型 + */ + public boolean mysqlSameType() { + return this == MYSQL || this == MARIADB || this == GBASE || this == OSCAR || this == XUGU || this == CLICK_HOUSE || this == OCEAN_BASE || this == CUBRID || this == SUNDB || this == GOLDENDB || this == YASDB; + } + + /** + * 判断当前数据库语法是否与Oracle属于同一类型 + */ + public boolean oracleSameType() { + return this == ORACLE || this == DM; + } + + /** + * 判断当前数据库语法是否与PostgreSQL属于同一类型 + */ + public boolean postgresqlSameType() { + return this == POSTGRE_SQL || this == H2 || this == LEALONE || this == SQLITE || this == HSQL || this == KINGBASE_ES || this == PHOENIX || this == SAP_HANA || this == IMPALA || this == HIGH_GO || this == VERTICA || this == REDSHIFT || this == GAUSS || this == OPENGAUSS || this == TDENGINE || this == UXDB || this == GBASE_8S_PG || this == GBASE_8C || this == VASTBASE || this == DUCKDB; + } + + /** + * 是否为已兼容的数据库类型 + * 允许的数据库类型包括MySQL系列、Oracle系列和PostgreSQL系列 + * + * @return 如果是允许的数据库类型返回true,否则返回false + */ + public boolean isSupportDb() { + return mysqlSameType() || oracleSameType() || postgresqlSameType(); + } } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/dialect/DbTypeUtil.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/dialect/DbTypeUtil.java index 1ceafbae..6bb58b3a 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/dialect/DbTypeUtil.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/dialect/DbTypeUtil.java @@ -16,6 +16,7 @@ package com.mybatisflex.core.dialect; +import com.mybatisflex.core.FlexGlobalConfig; import com.mybatisflex.core.exception.FlexExceptions; import com.mybatisflex.core.exception.locale.LocalizedFormats; import com.mybatisflex.core.util.StringUtil; @@ -37,6 +38,20 @@ public class DbTypeUtil { private DbTypeUtil() { } + /** + * 获取当前数据库类型 + *

首先从全局配置中获取数据库类型,如果全局配置中未设置,则尝试从方言工厂中获取线程局部变量设置的数据库类型 + * + * @return 当前数据库类型,可能为null + */ + public static DbType getCurrentDbType() { + DbType dbType = FlexGlobalConfig.getDefaultConfig().getDbType(); + if (dbType == null) { + dbType = DialectFactory.getHintDbType(); + } + return dbType; + } + /** * 获取当前配置的 DbType */ diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/CastQueryColumn.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/CastQueryColumn.java new file mode 100644 index 00000000..6c477b59 --- /dev/null +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/CastQueryColumn.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2022-2024, Mybatis-Flex (fuhai999@gmail.com). + *

+ * 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 + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * 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.core.query; + +import com.mybatisflex.core.FlexConsts; +import com.mybatisflex.core.dialect.IDialect; + +import java.util.List; + +/** + * CAST函数查询列 + */ +public class CastQueryColumn extends QueryColumn implements HasParamsColumn { + + private QueryColumn column; + private final String dataType; + + public CastQueryColumn(QueryColumn column, String dataType) { + this.column = column; + this.dataType = dataType; + } + + public CastQueryColumn(String column, String dataType) { + this.column = new QueryColumn(column); + this.dataType = dataType; + } + + @Override + protected String toConditionSql(List queryTables, IDialect dialect) { + return " CAST(" + column.toConditionSql(queryTables, dialect) + " AS " + dataType + ") "; + } + + @Override + protected String toSelectSql(List queryTables, IDialect dialect) { + return " CAST(" + column.toSelectSql(queryTables, dialect) + " AS " + dataType + ") " + WrapperUtil.buildColumnAlias(alias, dialect); + } + + @Override + public CastQueryColumn clone() { + CastQueryColumn clone = (CastQueryColumn) super.clone(); + clone.column = column.clone(); + return clone; + } + + @Override + public String toString() { + return "CastQueryColumn{" + + "column=" + column + + ", dataType='" + dataType + '\'' + + ", alias='" + alias + '\'' + + '}'; + } + + @Override + public Object[] getParamValues() { + if (column instanceof HasParamsColumn) { + return ((HasParamsColumn) column).getParamValues(); + } + return FlexConsts.EMPTY_ARRAY; + } +} diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/QueryColumn.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/QueryColumn.java index 3ac6f5a6..624d3878 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/QueryColumn.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/QueryColumn.java @@ -955,6 +955,10 @@ public class QueryColumn implements CloneSupport, Conditional QueryColumn stringAgg(LambdaGetter columnX, String separator) { + return new FunctionQueryColumn(STRING_AGG, LambdaUtil.getQueryColumn(columnX), string(separator)); + } + + /** + * LISTAGG 聚合函数 + */ + public static QueryColumn listAgg(QueryColumn column, String separator) { + return new FunctionQueryColumn(LISTAGG, column, string(separator)); + } + + public static QueryColumn listAgg(String column, String separator) { + return new FunctionQueryColumn(STRING_AGG, column, separator); + } + + public static QueryColumn listAgg(LambdaGetter column, String separator) { + return new FunctionQueryColumn(STRING_AGG, LambdaUtil.getQueryColumn(column), string(separator)); + } + + /** + * CAST函数查询列 + */ + public static QueryColumn cast(QueryColumn column, String dataType) { + return new CastQueryColumn(column, dataType); + } + + public static QueryColumn cast(String column, String dataType) { + return new CastQueryColumn(column, dataType); + } + + public static QueryColumn cast(LambdaGetter column, String dataType) { + return new CastQueryColumn(LambdaUtil.getQueryColumn(column), dataType); + } + /** * date 函数 * @return