新增单表API操作拦截器

This commit is contained in:
mxd
2021-10-14 22:17:53 +08:00
parent d267443ed6
commit aec4809452
6 changed files with 353 additions and 57 deletions

View File

@@ -100,6 +100,11 @@ public class MagicAPIAutoConfiguration implements WebMvcConfigurer, WebSocketCon
*/
private final ObjectProvider<List<SQLInterceptor>> sqlInterceptorsProvider;
/**
* 单表API拦截器
*/
private final ObjectProvider<List<NamedTableInterceptor>> namedTableInterceptorsProvider;
/**
* 自定义的类型扩展
*/
@@ -164,6 +169,7 @@ public class MagicAPIAutoConfiguration implements WebMvcConfigurer, WebSocketCon
ObjectProvider<List<MagicFunction>> magicFunctionsProvider,
ObjectProvider<MagicNotifyService> magicNotifyServiceProvider,
ObjectProvider<AuthorizationInterceptor> authorizationInterceptorProvider,
ObjectProvider<List<NamedTableInterceptor>> namedTableInterceptorsProvider,
Environment environment,
ApplicationContext applicationContext
) {
@@ -177,6 +183,7 @@ public class MagicAPIAutoConfiguration implements WebMvcConfigurer, WebSocketCon
this.magicFunctionsProvider = magicFunctionsProvider;
this.magicNotifyServiceProvider = magicNotifyServiceProvider;
this.authorizationInterceptorProvider = authorizationInterceptorProvider;
this.namedTableInterceptorsProvider = namedTableInterceptorsProvider;
this.environment = environment;
this.applicationContext = applicationContext;
}
@@ -414,6 +421,7 @@ public class MagicAPIAutoConfiguration implements WebMvcConfigurer, WebSocketCon
sqlInterceptors.add(new DefaultSqlInterceptor());
}
sqlModule.setSqlInterceptors(sqlInterceptors);
sqlModule.setNamedTableInterceptors(namedTableInterceptorsProvider.getIfAvailable(Collections::emptyList));
ColumnMapperAdapter columnMapperAdapter = new ColumnMapperAdapter();
this.columnMapperProvidersProvider.getIfAvailable(Collections::emptyList).stream().filter(mapperProvider -> !"default".equals(mapperProvider.name())).forEach(columnMapperAdapter::add);
columnMapperAdapter.setDefault(properties.getSqlColumnCase());

View File

@@ -0,0 +1,17 @@
package org.ssssssss.magicapi.interceptor;
import org.ssssssss.magicapi.model.SqlMode;
import org.ssssssss.magicapi.modules.table.NamedTable;
/**
* 单表模块拦截器
*
* @since 1.5.3
*/
public interface NamedTableInterceptor {
/**
* 执行之前
*/
void preHandle(SqlMode sqlMode, NamedTable namedTable);
}

View File

@@ -1,5 +1,7 @@
package org.ssssssss.magicapi.model;
import org.ssssssss.script.annotation.UnableCall;
import java.util.HashMap;
import java.util.Map;
@@ -13,18 +15,31 @@ public class Attributes<T> {
protected Map<String, T> properties = new HashMap<>();
/**
* 设置属性
* @param key key
* @param value value
*/
@UnableCall
public void setAttribute(String key, T value) {
properties.put(key, value);
}
/**
* 获取属性
* @param key key
*/
@UnableCall
public Object getAttribute(String key) {
return properties.get(key);
}
@UnableCall
public Map<String, T> getProperties() {
return properties;
}
@UnableCall
public void setProperties(Map<String, T> properties) {
this.properties = properties;
}

View File

@@ -0,0 +1,36 @@
package org.ssssssss.magicapi.model;
/**
* 单表API操作
*/
public enum SqlMode {
/**
* 执行插入动作
*/
INSERT,
/**
* 执行修改动作
*/
UPDATE,
/**
* 执行删除动作
*/
DELETE,
/**
* 执行查询操作
*/
SELECT,
/**
* 执行查询单个操作
*/
SELECT_ONE,
/**
* 执行分页查询动作
*/
PAGE,
/**
* 执行count查询操作
*/
COUNT
}

View File

@@ -15,6 +15,7 @@ import org.ssssssss.magicapi.config.MagicDynamicDataSource.DataSourceNode;
import org.ssssssss.magicapi.config.MagicModule;
import org.ssssssss.magicapi.context.RequestContext;
import org.ssssssss.magicapi.dialect.Dialect;
import org.ssssssss.magicapi.interceptor.NamedTableInterceptor;
import org.ssssssss.magicapi.interceptor.SQLInterceptor;
import org.ssssssss.magicapi.model.Page;
import org.ssssssss.magicapi.model.RequestEntity;
@@ -76,6 +77,7 @@ public class SQLModule extends HashMap<String, SQLModule> implements MagicModule
private SqlCache sqlCache;
private String cacheName;
private List<SQLInterceptor> sqlInterceptors;
private List<NamedTableInterceptor> namedTableInterceptors;
private long ttl;
private String logicDeleteColumn;
private String logicDeleteValue;
@@ -127,6 +129,11 @@ public class SQLModule extends HashMap<String, SQLModule> implements MagicModule
this.sqlInterceptors = sqlInterceptors;
}
@UnableCall
public void setNamedTableInterceptors(List<NamedTableInterceptor> namedTableInterceptors) {
this.namedTableInterceptors = namedTableInterceptors;
}
@UnableCall
public void setDataSourceNode(DataSourceNode dataSourceNode) {
this.dataSourceNode = dataSourceNode;
@@ -194,6 +201,7 @@ public class SQLModule extends HashMap<String, SQLModule> implements MagicModule
sqlModule.setSqlInterceptors(this.sqlInterceptors);
sqlModule.setLogicDeleteValue(this.logicDeleteValue);
sqlModule.setLogicDeleteColumn(this.logicDeleteColumn);
sqlModule.setNamedTableInterceptors(this.namedTableInterceptors);
return sqlModule;
}

View File

@@ -1,11 +1,17 @@
package org.ssssssss.magicapi.modules.table;
import org.apache.commons.lang3.StringUtils;
import org.ssssssss.magicapi.context.RequestContext;
import org.ssssssss.magicapi.exception.MagicAPIException;
import org.ssssssss.magicapi.interceptor.NamedTableInterceptor;
import org.ssssssss.magicapi.model.Attributes;
import org.ssssssss.magicapi.model.Page;
import org.ssssssss.magicapi.model.RequestEntity;
import org.ssssssss.magicapi.model.SqlMode;
import org.ssssssss.magicapi.modules.BoundSql;
import org.ssssssss.magicapi.modules.SQLModule;
import org.ssssssss.script.annotation.Comment;
import org.ssssssss.script.annotation.UnableCall;
import java.io.Serializable;
import java.util.*;
@@ -18,7 +24,7 @@ import java.util.stream.Collectors;
*
* @author mxd
*/
public class NamedTable {
public class NamedTable extends Attributes<Object> {
String tableName;
@@ -48,6 +54,8 @@ public class NamedTable {
boolean withBlank = false;
List<NamedTableInterceptor> namedTableInterceptors;
Where where = new Where(this);
public NamedTable(String tableName, SQLModule sqlModule, Function<String, String> rowMapColumnMapper) {
@@ -92,7 +100,8 @@ public class NamedTable {
namedTable.defaultPrimaryValue = this.defaultPrimaryValue;
namedTable.useLogic = this.useLogic;
namedTable.withBlank = this.withBlank;
namedTable.where = new Where(namedTable);
namedTable.where = this.where == null ? null : this.where.clone();
namedTable.namedTableInterceptors = this.namedTableInterceptors;
return namedTable;
}
@@ -211,20 +220,6 @@ public class NamedTable {
return this;
}
private Collection<Map.Entry<String, Object>> filterNotBlanks() {
if (this.withBlank) {
return this.columns.entrySet()
.stream()
.filter(it -> !excludeColumns.contains(it.getKey()))
.collect(Collectors.toList());
}
return this.columns.entrySet()
.stream()
.filter(it -> StringUtils.isNotBlank(Objects.toString(it.getValue(), "")))
.filter(it -> !excludeColumns.contains(it.getKey()))
.collect(Collectors.toList());
}
@Comment("执行插入,返回主键")
public Object insert() {
return insert(null);
@@ -242,6 +237,7 @@ public class NamedTable {
this.columns.put(this.primary, this.defaultPrimaryValue);
}
}
preHandle(SqlMode.INSERT);
Collection<Map.Entry<String, Object>> entries = filterNotBlanks();
if (entries.isEmpty()) {
throw new MagicAPIException("参数不能为空");
@@ -259,6 +255,7 @@ public class NamedTable {
@Comment("执行delete语句")
public int delete() {
preHandle(SqlMode.DELETE);
if (useLogic) {
Map<String, Object> dataMap = new HashMap<>();
dataMap.put(logicDeleteColumn, logicDeleteValue);
@@ -321,62 +318,25 @@ public class NamedTable {
@Comment("执行`select`查询")
public List<Map<String, Object>> select() {
preHandle(SqlMode.SELECT);
return sqlModule.select(buildSelect());
}
@Comment("执行`selectOne`查询")
public Map<String, Object> selectOne() {
preHandle(SqlMode.SELECT_ONE);
return sqlModule.selectOne(buildSelect());
}
private BoundSql buildSelect() {
StringBuilder builder = new StringBuilder();
builder.append("select ");
List<String> fields = this.fields.stream()
.filter(it -> !excludeColumns.contains(it))
.collect(Collectors.toList());
if (fields.isEmpty()) {
builder.append("*");
} else {
builder.append(StringUtils.join(fields, ","));
}
builder.append(" from ").append(tableName);
List<Object> params = buildWhere(builder);
if (!orders.isEmpty()) {
builder.append(" order by ");
builder.append(String.join(",", orders));
}
if (!groups.isEmpty()) {
builder.append(" group by ");
builder.append(String.join(",", groups));
}
BoundSql boundSql = new BoundSql(builder.toString(), params, sqlModule);
boundSql.setExcludeColumns(excludeColumns);
return boundSql;
}
private List<Object> buildWhere(StringBuilder builder) {
List<Object> params = new ArrayList<>();
if (!where.isEmpty()) {
where.and();
where.ne(useLogic, logicDeleteColumn, logicDeleteValue);
builder.append(where.getSql());
params.addAll(where.getParams());
} else if (useLogic) {
where.ne(logicDeleteColumn, logicDeleteValue);
builder.append(where.getSql());
params.addAll(where.getParams());
}
return params;
}
@Comment("执行分页查询")
public Object page() {
preHandle(SqlMode.PAGE);
return sqlModule.page(buildSelect());
}
@Comment("执行分页查询,分页条件手动传入")
public Object page(@Comment("限制条数") long limit, @Comment("跳过条数") long offset) {
preHandle(SqlMode.PAGE);
return sqlModule.page(buildSelect(), new Page(limit, offset));
}
@@ -395,6 +355,7 @@ public class NamedTable {
primaryValue = this.columns.remove(this.primary);
}
this.withBlank = isUpdateBlank;
preHandle(SqlMode.UPDATE);
List<Map.Entry<String, Object>> entries = new ArrayList<>(filterNotBlanks());
if (entries.isEmpty()) {
throw new MagicAPIException("要修改的列不能为空");
@@ -431,6 +392,7 @@ public class NamedTable {
@Comment("查询条数")
public int count() {
preHandle(SqlMode.COUNT);
StringBuilder builder = new StringBuilder();
builder.append("select count(1) from ").append(tableName);
List<Object> params = buildWhere(builder);
@@ -442,4 +404,254 @@ public class NamedTable {
return count() > 0;
}
private Collection<Map.Entry<String, Object>> filterNotBlanks() {
if (this.withBlank) {
return this.columns.entrySet()
.stream()
.filter(it -> !excludeColumns.contains(it.getKey()))
.collect(Collectors.toList());
}
return this.columns.entrySet()
.stream()
.filter(it -> StringUtils.isNotBlank(Objects.toString(it.getValue(), "")))
.filter(it -> !excludeColumns.contains(it.getKey()))
.collect(Collectors.toList());
}
private void preHandle(SqlMode sqlMode){
if(this.namedTableInterceptors != null){
this.namedTableInterceptors.forEach(interceptor -> interceptor.preHandle(sqlMode, this));
}
}
private BoundSql buildSelect() {
StringBuilder builder = new StringBuilder();
builder.append("select ");
List<String> fields = this.fields.stream()
.filter(it -> !excludeColumns.contains(it))
.collect(Collectors.toList());
if (fields.isEmpty()) {
builder.append("*");
} else {
builder.append(StringUtils.join(fields, ","));
}
builder.append(" from ").append(tableName);
List<Object> params = buildWhere(builder);
if (!orders.isEmpty()) {
builder.append(" order by ");
builder.append(String.join(",", orders));
}
if (!groups.isEmpty()) {
builder.append(" group by ");
builder.append(String.join(",", groups));
}
BoundSql boundSql = new BoundSql(builder.toString(), params, sqlModule);
boundSql.setExcludeColumns(excludeColumns);
return boundSql;
}
private List<Object> buildWhere(StringBuilder builder) {
List<Object> params = new ArrayList<>();
if (!where.isEmpty()) {
where.and();
where.ne(useLogic, logicDeleteColumn, logicDeleteValue);
builder.append(where.getSql());
params.addAll(where.getParams());
} else if (useLogic) {
where.ne(logicDeleteColumn, logicDeleteValue);
builder.append(where.getSql());
params.addAll(where.getParams());
}
return params;
}
/**
* 获取查询的表名
* @return 表名
*/
@UnableCall
public String getTableName() {
return tableName;
}
/**
* 获取SQL模块
*
*/
@UnableCall
public SQLModule getSqlModule() {
return sqlModule;
}
/**
* 获取主键列
*/
@UnableCall
public String getPrimary() {
return primary;
}
/**
* 获取逻辑删除列
*/
@UnableCall
public String getLogicDeleteColumn() {
return logicDeleteColumn;
}
/**
* 获取逻辑删除值
*/
@UnableCall
public Object getLogicDeleteValue() {
return logicDeleteValue;
}
/**
* 获取设置的columns
*/
@UnableCall
public Map<String, Object> getColumns() {
return columns;
}
/**
* 获取设置的fields
*/
@UnableCall
public List<String> getFields() {
return fields;
}
/**
* 获取设置的group
*/
@UnableCall
public List<String> getGroups() {
return groups;
}
/**
* 获取设置的order
*/
@UnableCall
public List<String> getOrders() {
return orders;
}
/**
* 获取设置的排除的列
*/
@UnableCall
public Set<String> getExcludeColumns() {
return excludeColumns;
}
/**
* 主键默认值
* @return
*/
@UnableCall
public Object getDefaultPrimaryValue() {
return defaultPrimaryValue;
}
/**
* 是否设逻辑了逻辑删除
*/
@UnableCall
public boolean isUseLogic() {
return useLogic;
}
/**
* 获取是否不过滤空参数
*/
@UnableCall
public boolean isWithBlank() {
return withBlank;
}
/**
* 获取where
*/
@UnableCall
public Where getWhere() {
return where;
}
/**
* 设置表名
* @param tableName 表名
*/
@UnableCall
public void setTableName(String tableName) {
this.tableName = tableName;
}
/**
* 设置columns
*/
@UnableCall
public void setColumns(Map<String, Object> columns) {
this.columns = columns;
}
/**
* 设置 fields
*/
@UnableCall
public void setFields(List<String> fields) {
this.fields = fields;
}
/**
* 设置 group
*/
@UnableCall
public void setGroups(List<String> groups) {
this.groups = groups;
}
/**
* 设置 order
*/
@UnableCall
public void setOrders(List<String> orders) {
this.orders = orders;
}
/**
* 设置排除的列
*/
@UnableCall
public void setExcludeColumns(Set<String> excludeColumns) {
this.excludeColumns = excludeColumns;
}
/**
* 设置是否使用逻辑删除
*/
@UnableCall
public void setUseLogic(boolean useLogic) {
this.useLogic = useLogic;
}
/**
* 设置是否不过滤空参数
*/
@UnableCall
public void setWithBlank(boolean withBlank) {
this.withBlank = withBlank;
}
/**
* 获取RequestEntity
*/
@UnableCall
public RequestEntity getRequestEntity() {
return RequestContext.getRequestEntity();
}
}