add logic delete support

This commit is contained in:
开源海哥 2023-03-02 16:32:13 +08:00
parent ca180e18a4
commit 0afe2e5401
4 changed files with 168 additions and 21 deletions

View File

@ -15,6 +15,7 @@
*/ */
package com.mybatisflex.core; package com.mybatisflex.core;
import com.mybatisflex.core.exception.FlexExceptions;
import com.mybatisflex.core.paginate.Page; import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.provider.EntitySqlProvider; import com.mybatisflex.core.provider.EntitySqlProvider;
import com.mybatisflex.core.querywrapper.QueryColumn; import com.mybatisflex.core.querywrapper.QueryColumn;
@ -82,6 +83,9 @@ public interface BaseMapper<T> {
* @return 返回影响的行数 * @return 返回影响的行数
*/ */
default int deleteByMap(Map<String, Object> whereConditions) { default int deleteByMap(Map<String, Object> whereConditions) {
if (whereConditions == null || whereConditions.isEmpty()) {
throw FlexExceptions.wrap("deleteByMap is not allow empty map.");
}
return deleteByQuery(QueryWrapper.create().where(whereConditions)); return deleteByQuery(QueryWrapper.create().where(whereConditions));
} }
@ -109,7 +113,7 @@ public interface BaseMapper<T> {
/** /**
* 根据主键来更新数据到数据库 * 根据主键来更新数据到数据库
* *
* @param entity 数据内容 * @param entity 数据内容
* @param ignoreNulls 是否忽略空内容字段 * @param ignoreNulls 是否忽略空内容字段
* @return 返回影响的行数 * @return 返回影响的行数
* @see com.mybatisflex.core.provider.EntitySqlProvider#update(Map, ProviderContext) * @see com.mybatisflex.core.provider.EntitySqlProvider#update(Map, ProviderContext)
@ -145,9 +149,9 @@ public interface BaseMapper<T> {
/** /**
* 根据 query 构建的条件来更新数据 * 根据 query 构建的条件来更新数据
* *
* @param entity 数据内容 * @param entity 数据内容
* @param ignoreNulls 是否忽略空值 * @param ignoreNulls 是否忽略空值
* @param queryWrapper query 条件 * @param queryWrapper query 条件
* @return * @return
* @see com.mybatisflex.core.provider.EntitySqlProvider#updateByQuery(Map, ProviderContext) * @see com.mybatisflex.core.provider.EntitySqlProvider#updateByQuery(Map, ProviderContext)
*/ */

View File

@ -402,12 +402,109 @@ public class CommonsDialectImpl implements IDialect {
@Override @Override
public String forDeleteEntityById(TableInfo tableInfo) { public String forDeleteEntityById(TableInfo tableInfo) {
return forDeleteById(tableInfo.getTableName(), tableInfo.getPrimaryKeys()); String logicDeleteColumn = tableInfo.getLogicDeleteColumn();
//正常删除
if (StringUtil.isBlank(logicDeleteColumn)) {
return forDeleteById(tableInfo.getTableName(), tableInfo.getPrimaryKeys());
}
//逻辑删除
StringBuilder sql = new StringBuilder();
String[] primaryKeys = tableInfo.getPrimaryKeys();
sql.append("UPDATE ").append(wrap(tableInfo.getTableName())).append(" SET ");
sql.append(wrap(logicDeleteColumn)).append(" = 1");
sql.append(" WHERE ");
for (int i = 0; i < primaryKeys.length; i++) {
if (i > 0) {
sql.append(" AND ");
}
sql.append(wrap(primaryKeys[i])).append(" = ?");
}
sql.append(" AND ").append(wrap(logicDeleteColumn)).append(" = 0 ");
return sql.toString();
} }
@Override @Override
public String forDeleteEntityBatchById(TableInfo tableInfo, Object[] primaryValues) { public String forDeleteEntityBatchByIds(TableInfo tableInfo, Object[] primaryValues) {
return forDeleteBatchByIds(tableInfo.getTableName(), tableInfo.getPrimaryKeys(), primaryValues); String logicDeleteColumn = tableInfo.getLogicDeleteColumn();
//正常删除
if (StringUtil.isBlank(logicDeleteColumn)) {
return forDeleteBatchByIds(tableInfo.getTableName(), tableInfo.getPrimaryKeys(), primaryValues);
}
StringBuilder sql = new StringBuilder();
sql.append("UPDATE");
sql.append(wrap(tableInfo.getTableName()));
sql.append("SET ").append(wrap(logicDeleteColumn)).append(" = 1");
sql.append(" WHERE ");
String[] primaryKeys = tableInfo.getPrimaryKeys();
//多主键的场景
if (primaryKeys.length > 1) {
for (int i = 0; i < primaryValues.length / primaryKeys.length; i++) {
if (i > 0) {
sql.append(" OR ");
}
sql.append("(");
for (int j = 0; j < primaryKeys.length; j++) {
if (j > 0) {
sql.append(" AND ");
}
sql.append(wrap(primaryKeys[j])).append(" = ?");
}
sql.append(")");
}
}
// 单主键
else {
for (int i = 0; i < primaryValues.length; i++) {
if (i > 0) {
sql.append(" OR ");
}
sql.append(wrap(primaryKeys[0])).append(" = ?");
}
}
return sql.toString();
}
@Override
public String forDeleteEntityBatchByQuery(TableInfo tableInfo, QueryWrapper queryWrapper) {
String logicDeleteColumn = tableInfo.getLogicDeleteColumn();
//正常删除
if (StringUtil.isBlank(logicDeleteColumn)) {
return forDeleteByQuery(queryWrapper);
}
//逻辑删除
List<QueryTable> queryTables = CPI.getQueryTables(queryWrapper);
List<QueryTable> joinTables = CPI.getJoinTables(queryWrapper);
List<QueryTable> allTables = CollectionUtil.merge(queryTables, joinTables);
//ignore selectColumns
StringBuilder sqlBuilder = new StringBuilder("UPDATE ");
sqlBuilder.append(wrap(tableInfo.getTableName()));
sqlBuilder.append(" SET ").append(wrap(logicDeleteColumn)).append(" = 1 ");
buildJoinSql(sqlBuilder, queryWrapper, allTables);
buildWhereSql(sqlBuilder, queryWrapper, allTables);
buildGroupBySql(sqlBuilder, queryWrapper, allTables);
buildHavingSql(sqlBuilder, queryWrapper, allTables);
//ignore orderBy and limit
//buildOrderBySql(sqlBuilder, queryWrapper);
//buildLimitSql(sqlBuilder, queryWrapper);
return sqlBuilder.toString();
} }
@ -419,22 +516,20 @@ public class CommonsDialectImpl implements IDialect {
String[] primaryKeys = tableInfo.getPrimaryKeys(); String[] primaryKeys = tableInfo.getPrimaryKeys();
sql.append("UPDATE ").append(wrap(tableInfo.getTableName())).append(" SET "); sql.append("UPDATE ").append(wrap(tableInfo.getTableName())).append(" SET ");
int index = 0;
StringJoiner stringJoiner = new StringJoiner(", ");
for (String modifyAttr : modifyAttrs) { for (String modifyAttr : modifyAttrs) {
if (index > 0) { stringJoiner.add(wrap(modifyAttr) + " = ?");
sql.append(", ");
}
sql.append(wrap(modifyAttr)).append(" = ? ");
index++;
} }
Map<String, String> onUpdateColumns = tableInfo.getOnUpdateColumns(); Map<String, String> onUpdateColumns = tableInfo.getOnUpdateColumns();
if (onUpdateColumns != null && !onUpdateColumns.isEmpty()) { if (onUpdateColumns != null && !onUpdateColumns.isEmpty()) {
StringJoiner stringJoiner = new StringJoiner(", ");
onUpdateColumns.forEach((column, value) -> stringJoiner.add(wrap(column) + " = " + value)); onUpdateColumns.forEach((column, value) -> stringJoiner.add(wrap(column) + " = " + value));
sql.append(", ").append(stringJoiner);
} }
sql.append(stringJoiner);
sql.append(" WHERE "); sql.append(" WHERE ");
for (int i = 0; i < primaryKeys.length; i++) { for (int i = 0; i < primaryKeys.length; i++) {
if (i > 0) { if (i > 0) {
@ -443,6 +538,11 @@ public class CommonsDialectImpl implements IDialect {
sql.append(wrap(primaryKeys[i])).append(" = ?"); sql.append(wrap(primaryKeys[i])).append(" = ?");
} }
String logicDeleteColumn = tableInfo.getLogicDeleteColumn();
if (StringUtil.isNotBlank(logicDeleteColumn)) {
sql.append(" AND ").append(wrap(logicDeleteColumn)).append(" = 0 ");
}
return sql.toString(); return sql.toString();
} }
@ -487,6 +587,13 @@ public class CommonsDialectImpl implements IDialect {
} }
sql.append(wrap(pKeys[i])).append(" = ?"); sql.append(wrap(pKeys[i])).append(" = ?");
} }
//逻辑删除的情况下需要添加逻辑删除的条件
String logicDeleteColumn = tableInfo.getLogicDeleteColumn();
if (StringUtil.isNotBlank(logicDeleteColumn)) {
sql.append(" AND ").append(wrap(logicDeleteColumn)).append(" = 0 ");
}
return sql.toString(); return sql.toString();
} }
@ -498,6 +605,11 @@ public class CommonsDialectImpl implements IDialect {
sql.append(" WHERE "); sql.append(" WHERE ");
String[] primaryKeys = tableInfo.getPrimaryKeys(); String[] primaryKeys = tableInfo.getPrimaryKeys();
String logicDeleteColumn = tableInfo.getLogicDeleteColumn();
if (StringUtil.isNotBlank(logicDeleteColumn)) {
sql.append(wrap(logicDeleteColumn)).append(" = 0 AND (");
}
//多主键的场景 //多主键的场景
if (primaryKeys.length > 1) { if (primaryKeys.length > 1) {
for (int i = 0; i < primaryValues.length / primaryKeys.length; i++) { for (int i = 0; i < primaryValues.length / primaryKeys.length; i++) {
@ -523,6 +635,11 @@ public class CommonsDialectImpl implements IDialect {
sql.append(wrap(primaryKeys[0])).append(" = ?"); sql.append(wrap(primaryKeys[0])).append(" = ?");
} }
} }
if (StringUtil.isNotBlank(logicDeleteColumn)) {
sql.append(wrap(logicDeleteColumn)).append(" )");
}
return sql.toString(); return sql.toString();
} }

View File

@ -65,7 +65,9 @@ public interface IDialect {
String forDeleteEntityById(TableInfo tableInfo); String forDeleteEntityById(TableInfo tableInfo);
String forDeleteEntityBatchById(TableInfo tableInfo, Object[] primaryValues); String forDeleteEntityBatchByIds(TableInfo tableInfo, Object[] primaryValues);
String forDeleteEntityBatchByQuery(TableInfo tableInfo, QueryWrapper queryWrapper);
String forUpdateEntity(TableInfo tableInfo, Object entity, boolean ignoreNulls); String forUpdateEntity(TableInfo tableInfo, Object entity, boolean ignoreNulls);

View File

@ -17,11 +17,14 @@ package com.mybatisflex.core.provider;
import com.mybatisflex.core.dialect.DialectFactory; import com.mybatisflex.core.dialect.DialectFactory;
import com.mybatisflex.core.exception.FlexExceptions; import com.mybatisflex.core.exception.FlexExceptions;
import com.mybatisflex.core.querywrapper.QueryColumn;
import com.mybatisflex.core.querywrapper.QueryCondition;
import com.mybatisflex.core.querywrapper.QueryWrapper; import com.mybatisflex.core.querywrapper.QueryWrapper;
import com.mybatisflex.core.querywrapper.CPI; import com.mybatisflex.core.querywrapper.CPI;
import com.mybatisflex.core.table.TableInfo; import com.mybatisflex.core.table.TableInfo;
import com.mybatisflex.core.util.ArrayUtil; import com.mybatisflex.core.util.ArrayUtil;
import com.mybatisflex.core.util.CollectionUtil; import com.mybatisflex.core.util.CollectionUtil;
import com.mybatisflex.core.util.StringUtil;
import org.apache.ibatis.builder.annotation.ProviderContext; import org.apache.ibatis.builder.annotation.ProviderContext;
import java.io.Serializable; import java.io.Serializable;
@ -127,7 +130,7 @@ public class EntitySqlProvider {
TableInfo tableInfo = ProviderUtil.getTableInfo(context); TableInfo tableInfo = ProviderUtil.getTableInfo(context);
ProviderUtil.setSqlArgs(params, primaryValues); ProviderUtil.setSqlArgs(params, primaryValues);
return DialectFactory.getDialect().forDeleteEntityBatchById(tableInfo, primaryValues); return DialectFactory.getDialect().forDeleteEntityBatchByIds(tableInfo, primaryValues);
} }
@ -149,7 +152,8 @@ public class EntitySqlProvider {
TableInfo tableInfo = ProviderUtil.getTableInfo(context); TableInfo tableInfo = ProviderUtil.getTableInfo(context);
queryWrapper.from(tableInfo.getTableName()); queryWrapper.from(tableInfo.getTableName());
return DialectFactory.getDialect().forDeleteByQuery(queryWrapper);
return DialectFactory.getDialect().forDeleteEntityBatchByQuery(tableInfo, queryWrapper);
} }
@ -194,8 +198,13 @@ public class EntitySqlProvider {
boolean ignoreNulls = ProviderUtil.isIgnoreNulls(params); boolean ignoreNulls = ProviderUtil.isIgnoreNulls(params);
QueryWrapper queryWrapper = ProviderUtil.getQueryWrapper(params); QueryWrapper queryWrapper = ProviderUtil.getQueryWrapper(params);
TableInfo tableInfo = ProviderUtil.getTableInfo(context); TableInfo tableInfo = ProviderUtil.getTableInfo(context);
String logicDeleteColumn = tableInfo.getLogicDeleteColumn();
if (StringUtil.isNotBlank(logicDeleteColumn)) {
queryWrapper.and(QueryCondition.create(new QueryColumn(tableInfo.getTableName(), logicDeleteColumn), 0));
}
Object[] values = tableInfo.obtainUpdateValues(entity, ignoreNulls, true); Object[] values = tableInfo.obtainUpdateValues(entity, ignoreNulls, true);
ProviderUtil.setSqlArgs(params, ArrayUtil.concat(values, CPI.getValueArray(queryWrapper))); ProviderUtil.setSqlArgs(params, ArrayUtil.concat(values, CPI.getValueArray(queryWrapper)));
@ -259,11 +268,19 @@ public class EntitySqlProvider {
if (queryWrapper == null) { if (queryWrapper == null) {
throw FlexExceptions.wrap("queryWrapper can not be null."); throw FlexExceptions.wrap("queryWrapper can not be null.");
} }
TableInfo tableInfo = ProviderUtil.getTableInfo(context);
String logicDeleteColumn = tableInfo.getLogicDeleteColumn();
if (StringUtil.isNotBlank(logicDeleteColumn)) {
queryWrapper.and(QueryCondition.create(new QueryColumn(tableInfo.getTableName(), logicDeleteColumn), 0));
}
Object[] values = CPI.getValueArray(queryWrapper); Object[] values = CPI.getValueArray(queryWrapper);
ProviderUtil.setSqlArgs(params, values); ProviderUtil.setSqlArgs(params, values);
TableInfo tableInfo = ProviderUtil.getTableInfo(context);
queryWrapper.from(tableInfo.getTableName()); queryWrapper.from(tableInfo.getTableName());
return DialectFactory.getDialect().forSelectListByQuery(queryWrapper); return DialectFactory.getDialect().forSelectListByQuery(queryWrapper);
} }
@ -281,10 +298,17 @@ public class EntitySqlProvider {
throw FlexExceptions.wrap("queryWrapper can not be null."); throw FlexExceptions.wrap("queryWrapper can not be null.");
} }
TableInfo tableInfo = ProviderUtil.getTableInfo(context);
//逻辑删除
String logicDeleteColumn = tableInfo.getLogicDeleteColumn();
if (StringUtil.isNotBlank(logicDeleteColumn)) {
queryWrapper.and(QueryCondition.create(new QueryColumn(tableInfo.getTableName(), logicDeleteColumn), 0));
}
Object[] values = CPI.getValueArray(queryWrapper); Object[] values = CPI.getValueArray(queryWrapper);
ProviderUtil.setSqlArgs(params, values); ProviderUtil.setSqlArgs(params, values);
TableInfo tableInfo = ProviderUtil.getTableInfo(context);
queryWrapper.from(tableInfo.getTableName()); queryWrapper.from(tableInfo.getTableName());
return DialectFactory.getDialect().forSelectCountByQuery(queryWrapper); return DialectFactory.getDialect().forSelectCountByQuery(queryWrapper);
} }