!118 optimize SqlProvider

Merge pull request !118 from 王帅/main
This commit is contained in:
Michael Yang 2023-07-09 02:51:36 +00:00 committed by Gitee
commit e0dea23822
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
4 changed files with 183 additions and 162 deletions

View File

@ -16,6 +16,7 @@
package com.mybatisflex.core.exception;
import java.util.Collection;
import java.util.Map;
/**
@ -32,26 +33,52 @@ public final class FlexAssert {
/**
* 断言对象不为空如果为空抛出异常并指明哪个对象为空
*
* @param obj 对象
* @param msg 错误消息
* @param obj 对象
* @param message 错误消息
* @throws MybatisFlexException 如果对象为空抛出此异常
*/
public static void notNull(Object obj, String msg) {
public static void notNull(Object obj, String message) {
if (obj == null) {
throw FlexExceptions.wrap(msg);
throw FlexExceptions.wrap(message);
}
}
/**
* 断言 Map 集合不为 {@code null} 或者空集合如果为空则抛出异常并指明为什么不允许为空集合
*
* @param map Map 集合
* @param msg 错误消息
* @param map Map 集合
* @param message 错误消息
* @throws MybatisFlexException 如果集合为空抛出此异常
*/
public static void notEmpty(Map<?, ?> map, String msg) {
public static void notEmpty(Map<?, ?> map, String message) {
if (map == null || map.isEmpty()) {
throw FlexExceptions.wrap(msg);
throw FlexExceptions.wrap(message);
}
}
/**
* 断言集合不为 {@code null} 或者空集合如果为空则抛出异常并指明为什么不允许为空集合
*
* @param collection 集合
* @param message 错误消息
* @throws MybatisFlexException 如果集合为空抛出此异常
*/
public static void notEmpty(Collection<?> collection, String message) {
if (collection == null || collection.isEmpty()) {
throw FlexExceptions.wrap(message);
}
}
/**
* 断言数组不为 {@code null} 或者空数组如果为空则抛出异常并指明为什么不允许为空数组
*
* @param array 数组
* @param message 错误消息
* @throws MybatisFlexException 如果数组为空抛出此异常
*/
public static <T> void notEmpty(T[] array, String message) {
if (array == null || array.length == 0) {
throw FlexExceptions.wrap(message);
}
}

View File

@ -17,6 +17,7 @@ package com.mybatisflex.core.provider;
import com.mybatisflex.core.FlexConsts;
import com.mybatisflex.core.dialect.DialectFactory;
import com.mybatisflex.core.exception.FlexAssert;
import com.mybatisflex.core.exception.FlexExceptions;
import com.mybatisflex.core.query.CPI;
import com.mybatisflex.core.query.QueryTable;
@ -31,6 +32,7 @@ import org.apache.ibatis.builder.annotation.ProviderContext;
import java.io.Serializable;
import java.util.*;
@SuppressWarnings({"rawtypes", "DuplicatedCode"})
public class EntitySqlProvider {
/**
@ -40,20 +42,18 @@ public class EntitySqlProvider {
private EntitySqlProvider() {
}
/**
* insert sql 构建
* insert SQL 构建
*
* @param params
* @param context
* @return sql
* @param params 方法参数
* @param context 上下文对象
* @return SQL 语句
* @see com.mybatisflex.core.BaseMapper#insert(Object)
*/
public static String insert(Map params, ProviderContext context) {
Object entity = ProviderUtil.getEntity(params);
if (entity == null) {
throw FlexExceptions.wrap("entity can not be null.");
}
FlexAssert.notNull(entity, "entity can not be null.");
boolean ignoreNulls = ProviderUtil.isIgnoreNulls(params);
@ -78,11 +78,18 @@ public class EntitySqlProvider {
}
/**
* insertWithPk SQL 构建
*
* @param params 方法参数
* @param context 上下文对象
* @return SQL 语句
* @see com.mybatisflex.core.BaseMapper#insertWithPk(Object, boolean)
*/
public static String insertWithPk(Map params, ProviderContext context) {
Object entity = ProviderUtil.getEntity(params);
if (entity == null) {
throw FlexExceptions.wrap("entity can not be null.");
}
FlexAssert.notNull(entity, "entity can not be null.");
boolean ignoreNulls = ProviderUtil.isIgnoreNulls(params);
@ -108,19 +115,18 @@ public class EntitySqlProvider {
/**
* insertBatch sql 构建
* insertBatch SQL 构建
*
* @param params
* @param context
* @return sql
* @param params 方法参数
* @param context 上下文对象
* @return SQL 语句
* @see com.mybatisflex.core.BaseMapper#insertBatch(List)
* @see com.mybatisflex.core.FlexConsts#METHOD_INSERT_BATCH
*/
public static String insertBatch(Map params, ProviderContext context) {
List<Object> entities = ProviderUtil.getEntities(params);
if (CollectionUtil.isEmpty(entities)) {
throw FlexExceptions.wrap("entities can not be null or empty.");
}
FlexAssert.notEmpty(entities, "entities can not be null or empty.");
TableInfo tableInfo = ProviderUtil.getTableInfo(context);
for (Object entity : entities) {
@ -145,18 +151,17 @@ public class EntitySqlProvider {
/**
* deleteById sql 构建
* deleteById SQL 构建
*
* @param params
* @param context
* @return sql
* @param params 方法参数
* @param context 上下文对象
* @return SQL 语句
* @see com.mybatisflex.core.BaseMapper#deleteById(Serializable)
*/
public static String deleteById(Map params, ProviderContext context) {
Object[] primaryValues = ProviderUtil.getPrimaryValues(params);
if (ArrayUtil.isEmpty(primaryValues)) {
throw FlexExceptions.wrap("primaryValues can not be null or empty.");
}
FlexAssert.notEmpty(primaryValues, "primaryValues can not be null or empty.");
TableInfo tableInfo = ProviderUtil.getTableInfo(context);
@ -168,18 +173,17 @@ public class EntitySqlProvider {
/**
* deleteBatchByIds sql 构建
* deleteBatchByIds SQL 构建
*
* @param params
* @param context
* @return sql
* @param params 方法参数
* @param context 上下文对象
* @return SQL 语句
* @see com.mybatisflex.core.BaseMapper#deleteBatchByIds(Collection)
*/
public static String deleteBatchByIds(Map params, ProviderContext context) {
Object[] primaryValues = ProviderUtil.getPrimaryValues(params);
if (ArrayUtil.isEmpty(primaryValues)) {
throw FlexExceptions.wrap("primaryValues can not be null or empty.");
}
FlexAssert.notEmpty(primaryValues, "primaryValues can not be null or empty.");
TableInfo tableInfo = ProviderUtil.getTableInfo(context);
@ -191,11 +195,11 @@ public class EntitySqlProvider {
/**
* deleteByQuery sql 构建
* deleteByQuery SQL 构建
*
* @param params
* @param context
* @return sql
* @param params 方法参数
* @param context 上下文对象
* @return SQL 语句
* @see com.mybatisflex.core.BaseMapper#deleteByQuery(QueryWrapper)
*/
public static String deleteByQuery(Map params, ProviderContext context) {
@ -213,18 +217,17 @@ public class EntitySqlProvider {
/**
* update sql 构建
* update SQL 构建
*
* @param params
* @param context
* @return sql
* @param params 方法参数
* @param context 上下文对象
* @return SQL 语句
* @see com.mybatisflex.core.BaseMapper#update(Object, boolean)
*/
public static String update(Map params, ProviderContext context) {
Object entity = ProviderUtil.getEntity(params);
if (entity == null) {
throw FlexExceptions.wrap("entity can not be null");
}
FlexAssert.notNull(entity, "entity can not be null");
boolean ignoreNulls = ProviderUtil.isIgnoreNulls(params);
@ -246,18 +249,18 @@ public class EntitySqlProvider {
/**
* updateByQuery sql 构建
* updateByQuery SQL 构建
*
* @param params
* @param context
* @return sql
* @param params 方法参数
* @param context 上下文对象
* @return SQL 语句
* @see com.mybatisflex.core.BaseMapper#updateByQuery(Object, boolean, QueryWrapper)
*/
public static String updateByQuery(Map params, ProviderContext context) {
Object entity = ProviderUtil.getEntity(params);
if (entity == null) {
throw FlexExceptions.wrap("entity can not be null");
}
FlexAssert.notNull(entity, "entity can not be null");
boolean ignoreNulls = ProviderUtil.isIgnoreNulls(params);
QueryWrapper queryWrapper = ProviderUtil.getQueryWrapper(params);
@ -280,11 +283,11 @@ public class EntitySqlProvider {
}
/**
* updateNumberByQuery sql 构建
* updateNumberByQuery SQL 构建
*
* @param params
* @param context
* @return sql
* @param params 方法参数
* @param context 上下文对象
* @return SQL 语句
* @see com.mybatisflex.core.BaseMapper#updateNumberAddByQuery(String, Number, QueryWrapper)
*/
public static String updateNumberAddByQuery(Map params, ProviderContext context) {
@ -310,18 +313,17 @@ public class EntitySqlProvider {
/**
* selectOneById sql 构建
* selectOneById SQL 构建
*
* @param params
* @param context
* @return sql
* @param params 方法参数
* @param context 上下文对象
* @return SQL 语句
* @see com.mybatisflex.core.BaseMapper#selectOneById(Serializable)
*/
public static String selectOneById(Map params, ProviderContext context) {
Object[] primaryValues = ProviderUtil.getPrimaryValues(params);
if (ArrayUtil.isEmpty(primaryValues)) {
throw FlexExceptions.wrap("primaryValues can not be null or empty.");
}
FlexAssert.notEmpty(primaryValues, "primaryValues can not be null or empty.");
TableInfo tableInfo = ProviderUtil.getTableInfo(context);
@ -334,18 +336,17 @@ public class EntitySqlProvider {
/**
* selectListByIds sql 构建
* selectListByIds SQL 构建
*
* @param params
* @param context
* @return sql
* @param params 方法参数
* @param context 上下文对象
* @return SQL 语句
* @see com.mybatisflex.core.BaseMapper#selectListByIds(Collection)
*/
public static String selectListByIds(Map params, ProviderContext context) {
Object[] primaryValues = ProviderUtil.getPrimaryValues(params);
if (ArrayUtil.isEmpty(primaryValues)) {
throw FlexExceptions.wrap("primaryValues can not be null or empty.");
}
FlexAssert.notEmpty(primaryValues, "primaryValues can not be null or empty.");
TableInfo tableInfo = ProviderUtil.getTableInfo(context);
@ -357,11 +358,11 @@ public class EntitySqlProvider {
/**
* selectListByQuery sql 构建
* selectListByQuery SQL 构建
*
* @param params
* @param context
* @return sql
* @param params 方法参数
* @param context 上下文对象
* @return SQL 语句
* @see com.mybatisflex.core.BaseMapper#selectListByQuery(QueryWrapper)
*/
public static String selectListByQuery(Map params, ProviderContext context) {
@ -380,11 +381,11 @@ public class EntitySqlProvider {
/**
* selectCountByQuery sql 构建
* selectCountByQuery SQL 构建
*
* @param params
* @param context
* @return sql
* @param params 方法参数
* @param context 上下文对象
* @return SQL 语句
* @see com.mybatisflex.core.BaseMapper#selectObjectByQuery(QueryWrapper)
*/
public static String selectObjectByQuery(Map params, ProviderContext context) {

View File

@ -1,22 +1,23 @@
/**
* 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.
/*
* 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.core.provider;
import com.mybatisflex.core.FlexConsts;
import com.mybatisflex.core.dialect.DialectFactory;
import com.mybatisflex.core.exception.FlexAssert;
import com.mybatisflex.core.exception.FlexExceptions;
import com.mybatisflex.core.query.CPI;
import com.mybatisflex.core.query.QueryWrapper;
@ -26,13 +27,12 @@ import com.mybatisflex.core.row.RowMapper;
import com.mybatisflex.core.table.TableInfo;
import com.mybatisflex.core.table.TableInfoFactory;
import com.mybatisflex.core.util.ArrayUtil;
import com.mybatisflex.core.util.CollectionUtil;
import java.util.*;
@SuppressWarnings({"rawtypes", "DuplicatedCode"})
public class RowSqlProvider {
public static final String METHOD_RAW_SQL = "providerRawSql";
/**
@ -45,8 +45,8 @@ public class RowSqlProvider {
/**
* 执行原生 sql 的方法
*
* @param params
* @return sql
* @param params 方法参数
* @return SQL 语句
* @see RowMapper#insertBySql(String, Object...)
* @see RowMapper#deleteBySql(String, Object...)
* @see RowMapper#updateBySql(String, Object...)
@ -56,10 +56,10 @@ public class RowSqlProvider {
}
/**
* insert sql 构建
* insert SQL 构建
*
* @param params
* @return sql
* @param params 方法参数
* @return SQL 语句
* @see RowMapper#insert(String, String, Row)
*/
public static String insert(Map params) {
@ -71,26 +71,25 @@ public class RowSqlProvider {
}
/**
* insertBatch sql 构建
* insertBatch SQL 构建
*
* @param params
* @return sql
* @param params 方法参数
* @return SQL 语句
* @see RowMapper#insertBatchWithFirstRowColumns(String, String, List)
*/
public static String insertBatchWithFirstRowColumns(Map params) {
List<Row> rows = ProviderUtil.getRows(params);
FlexAssert.notEmpty(rows, "rows can not be null or empty.");
String tableName = ProviderUtil.getTableName(params);
String schema = ProviderUtil.getSchemaName(params);
List<Row> rows = ProviderUtil.getRows(params);
if (rows == null || rows.isEmpty()) {
throw FlexExceptions.wrap("rows can not be null or empty.");
}
// 让所有 row 的列顺序和值的数量与第条数据保持一致
// 这个必须 new 一个 LinkedHashSet因为 keepModifyAttrs 会清除 row 所有的 modifyAttrs
Set<String> modifyAttrs = new LinkedHashSet<>(RowCPI.getModifyAttrs(rows.get(0)));
rows.forEach(row -> row.keep(modifyAttrs));
Object[] values = new Object[]{};
for (Row row : rows) {
values = ArrayUtil.concat(values, RowCPI.obtainModifyValues(row));
@ -102,32 +101,31 @@ public class RowSqlProvider {
}
/**
* deleteById sql 构建
* deleteById SQL 构建
*
* @param params
* @return sql
* @param params 方法参数
* @return SQL 语句
* @see RowMapper#deleteById(String, String, String, Object)
*/
public static String deleteById(Map params) {
Object[] primaryValues = ProviderUtil.getPrimaryValues(params);
FlexAssert.notEmpty(primaryValues, "primaryValue can not be null or empty.");
String schema = ProviderUtil.getSchemaName(params);
String tableName = ProviderUtil.getTableName(params);
String[] primaryKeys = ProviderUtil.getPrimaryKeys(params);
Object[] primaryValues = ProviderUtil.getPrimaryValues(params);
if (primaryValues.length == 0) {
throw FlexExceptions.wrap("primaryValue can not be null");
} else {
ProviderUtil.setSqlArgs(params, primaryValues);
}
ProviderUtil.setSqlArgs(params, primaryValues);
return DialectFactory.getDialect().forDeleteById(schema, tableName, primaryKeys);
}
/**
* deleteBatchByIds sql 构建
* deleteBatchByIds SQL 构建
*
* @param params
* @return sql
* @param params 方法参数
* @return SQL 语句
* @see RowMapper#deleteBatchByIds(String, String, String, Collection)
*/
public static String deleteBatchByIds(Map params) {
@ -140,12 +138,11 @@ public class RowSqlProvider {
return DialectFactory.getDialect().forDeleteBatchByIds(schema, tableName, primaryKeys, primaryValues);
}
/**
* deleteByQuery sql 构建
* deleteByQuery SQL 构建
*
* @param params
* @return sql
* @param params 方法参数
* @return SQL 语句
* @see RowMapper#deleteByQuery(String, String, QueryWrapper)
*/
public static String deleteByQuery(Map params) {
@ -164,10 +161,10 @@ public class RowSqlProvider {
}
/**
* updateById sql 构建
* updateById SQL 构建
*
* @param params
* @return sql
* @param params 方法参数
* @return SQL 语句
* @see RowMapper#updateById(String, String, Row)
*/
public static String updateById(Map params) {
@ -178,12 +175,11 @@ public class RowSqlProvider {
return DialectFactory.getDialect().forUpdateById(schema, tableName, row);
}
/**
* updateByQuery sql 构建
* updateByQuery SQL 构建
*
* @param params
* @return sql
* @param params 方法参数
* @return SQL 语句
* @see RowMapper#updateByQuery(String, String, Row, QueryWrapper)
*/
public static String updateByQuery(Map params) {
@ -205,22 +201,21 @@ public class RowSqlProvider {
return sql;
}
/**
* updateBatchById sql 构建
* updateBatchById SQL 构建
* mysql 等链接配置需要开启 allowMultiQueries=true
*
* @param params
* @return sql
* @param params 方法参数
* @return SQL 语句
* @see RowMapper#updateBatchById(String, String, List)
*/
public static String updateBatchById(Map params) {
List<Row> rows = ProviderUtil.getRows(params);
FlexAssert.notEmpty(rows, "rows can not be null or empty.");
String schema = ProviderUtil.getSchemaName(params);
String tableName = ProviderUtil.getTableName(params);
List<Row> rows = ProviderUtil.getRows(params);
if (CollectionUtil.isEmpty(rows)) {
throw FlexExceptions.wrap("rows can not be null or empty.");
}
Object[] values = FlexConsts.EMPTY_ARRAY;
for (Row row : rows) {
@ -231,17 +226,16 @@ public class RowSqlProvider {
}
/**
* updateEntity sql 构建
* updateEntity SQL 构建
*
* @param params
* @return sql
* @param params 方法参数
* @return SQL 语句
* @see RowMapper#updateEntity(Object entities)
*/
public static String updateEntity(Map params) {
Object entity = ProviderUtil.getEntity(params);
if (entity == null) {
throw FlexExceptions.wrap("entity can not be null");
}
FlexAssert.notNull(entity, "entity can not be null");
// Mapper 是通用 Mapper 无法通过 ProviderContext 获取直接使用 TableInfoFactory
TableInfo tableInfo = TableInfoFactory.ofEntityClass(entity.getClass());
@ -263,12 +257,11 @@ public class RowSqlProvider {
/**
* 执行类似 update table set field=field+1 where ... 的场景
*
* @param params
* @return sql
* @param params 方法参数
* @return SQL 语句
* @see RowMapper#updateNumberAddByQuery(String, String, String, Number, QueryWrapper)
*/
public static String updateNumberAddByQuery(Map params) {
QueryWrapper queryWrapper = ProviderUtil.getQueryWrapper(params);
String schema = ProviderUtil.getSchemaName(params);
String tableName = ProviderUtil.getTableName(params);
@ -284,12 +277,11 @@ public class RowSqlProvider {
return sql;
}
/**
* selectOneById sql 构建
* selectOneById SQL 构建
*
* @param params
* @return sql
* @param params 方法参数
* @return SQL 语句
* @see RowMapper#selectOneById(String, String, String, Object)
*/
public static String selectOneById(Map params) {
@ -303,12 +295,11 @@ public class RowSqlProvider {
return DialectFactory.getDialect().forSelectOneById(schema, tableName, primaryKeys, primaryValues);
}
/**
* selectListByQuery sql 构建
* selectListByQuery SQL 构建
*
* @param params
* @return sql
* @param params 方法参数
* @return SQL 语句
* @see RowMapper#selectListByQuery(String, String, QueryWrapper)
*/
public static String selectListByQuery(Map params) {
@ -327,5 +318,4 @@ public class RowSqlProvider {
return sql;
}
}

View File

@ -60,6 +60,7 @@ public interface RowMapper {
* @param args 参数
* @return 执行影响的行数
* @see Db#insertBySql(String, Object...)
* @see RowSqlProvider#providerRawSql(Map)
*/
@InsertProvider(value = RowSqlProvider.class, method = RowSqlProvider.METHOD_RAW_SQL)
int insertBySql(@Param(FlexConsts.SQL) String sql, @Param(FlexConsts.SQL_ARGS) Object... args);
@ -87,6 +88,7 @@ public interface RowMapper {
* @param sql delete sql 语句
* @param args 参数
* @return 执行影响的行数
* @see RowSqlProvider#providerRawSql(Map)
*/
@DeleteProvider(value = RowSqlProvider.class, method = RowSqlProvider.METHOD_RAW_SQL)
int deleteBySql(@Param(FlexConsts.SQL) String sql, @Param(FlexConsts.SQL_ARGS) Object... args);
@ -152,6 +154,7 @@ public interface RowMapper {
* @param sql sql 语句
* @param args 参数内容
* @return 执行影响的行数
* @see RowSqlProvider#providerRawSql(Map)
*/
@UpdateProvider(value = RowSqlProvider.class, method = RowSqlProvider.METHOD_RAW_SQL)
int updateBySql(@Param(FlexConsts.SQL) String sql, @Param(FlexConsts.SQL_ARGS) Object... args);