Commit 143d37ee authored by trumansdo's avatar trumansdo
Browse files

更换至beetlsql3最新版本

parent 398a4c6b
package entity;
import lombok.Data;
import org.beetl.sql.core.annotatoin.AutoID;
import org.beetl.sql.annotation.entity.AutoID;
@Data
public class CmsBlog {
@AutoID
private Long id;
private String title;
private String content;
private Long createUserId;
private FunctionTypeEnum type;
private Long createTime;
}
......@@ -3,14 +3,14 @@ package entity;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
import com.ibeetl.admin.core.util.enums.DictTypeEnum;
import org.beetl.sql.core.annotatoin.EnumMapping;
import org.beetl.sql.annotation.entity.EnumValue;
@EnumMapping("value")
public enum FunctionTypeEnum implements DictTypeEnum<FunctionTypeEnum> {
FN0("FN0", "导航访问", "function_type"),
FN1("FN1", "功能访问", "function_type"),
FN2("FN2", "菜单访问", "function_type");
@EnumValue
private String value;
private String name;
......
......@@ -53,8 +53,8 @@
</dependency>
<dependency>
<groupId>com.ibeetl</groupId>
<artifactId>beetl-framework-starter</artifactId>
<version>1.2.20.RELEASE</version>
<artifactId>sql-springboot-starter</artifactId>
<version>3.12.0-RELEASE</version>
</dependency>
<!-- Log4j2 异步支持 -->
<dependency>
......
......@@ -5,8 +5,6 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import com.ibeetl.admin.core.util.enums.CoreDictType;
/**
* 描述: 用来标注词典字段
*
......
......@@ -3,12 +3,9 @@ package com.ibeetl.admin.core.conf;
import java.io.UnsupportedEncodingException;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cache.Cache;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCache;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
......
......@@ -183,9 +183,15 @@ public class CustomErrorController extends AbstractErrorController {
}
/**
* 提取errorAttributes 中的错误信息,包括:<br> timestamp:时间<br> status:http响应码<br> error:响应码的原因<br>
* exception:异常类名<br> errors:controller可能的校验错误对象集合<br> message:controller的错误信息<br> trace:
* 异常的堆栈信息<br> path:请求路径<br>
* 提取errorAttributes 中的错误信息,包括:<br>
* timestamp:时间<br>
* status:http响应码<br>
* error:响应码的原因<br>
* exception:异常类名<br>
* errors:controller可能的校验错误对象集合<br>
* message:controller的错误信息<br>
* trace: 异常的堆栈信息<br>
* path:请求路径<br>
*/
protected Map<String, Object> wrapErrorInfo(HttpServletRequest request) {
......
package com.ibeetl.admin.core.conf;
import com.zaxxer.hikari.HikariDataSource;
import javax.sql.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import com.zaxxer.hikari.HikariDataSource;
@Configuration
public class DataSourceConfig {
@Bean(name = "baseDataSource")
......
package com.ibeetl.admin.core.conf;
import com.ibeetl.admin.core.file.FileService;
import com.ibeetl.admin.core.file.LocalFileService;
import java.io.File;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
......@@ -10,9 +11,6 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import com.ibeetl.admin.core.file.FileService;
import com.ibeetl.admin.core.file.LocalFileService;
@Configuration
@ConditionalOnMissingBean(FileService.class)
public class FileSystemConfig {
......
package com.ibeetl.admin.core.conf;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import com.ibeetl.admin.core.conf.PasswordConfig.PasswordEncryptService;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.ibeetl.admin.core.conf.PasswordConfig.PasswordEncryptService;
/**
* 描述: 密码工具,系统默认采用明文存储,可以自动装配一个加密的
*
......
package com.ibeetl.admin.core.conf;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ibeetl.admin.core.annotation.Function;
import com.ibeetl.admin.core.entity.CoreAudit;
import com.ibeetl.admin.core.entity.CoreFunction;
import com.ibeetl.admin.core.entity.CoreUser;
import com.ibeetl.admin.core.service.CoreAuditService;
import com.ibeetl.admin.core.service.CorePlatformService;
import com.ibeetl.admin.core.util.FunctionLocal;
import com.ibeetl.admin.core.util.RequestContextThreadLocal;
import com.ibeetl.admin.core.util.PlatformException;
import java.lang.reflect.Method;
import java.util.Date;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
......@@ -13,17 +22,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ibeetl.admin.core.annotation.Function;
import com.ibeetl.admin.core.entity.CoreAudit;
import com.ibeetl.admin.core.entity.CoreFunction;
import com.ibeetl.admin.core.entity.CoreUser;
import com.ibeetl.admin.core.service.CoreAuditService;
import com.ibeetl.admin.core.service.CorePlatformService;
import com.ibeetl.admin.core.util.FunctionLocal;
import com.ibeetl.admin.core.util.HttpRequestLocal;
import com.ibeetl.admin.core.util.PlatformException;
/**
* 在springboot-plus中,有两种权限:功能点(或者说一个个controller方法)和数据权限。
* 菜单实际上也是绑定在了功能点中
......@@ -34,7 +32,6 @@ import com.ibeetl.admin.core.util.PlatformException;
public class RbacAnnotationConfig {
@Autowired CorePlatformService platformService;
@Autowired CoreAuditService sysAuditService;
@Autowired HttpRequestLocal httpRequestLocal;
@Autowired Environment env;
......@@ -114,7 +111,7 @@ public class RbacAnnotationConfig {
audit.setUserName(user.getName());
audit.setMessage(msg);
audit.setIp(httpRequestLocal.getRequestIP());
audit.setIp(RequestContextThreadLocal.getRequestIp());
sysAuditService.save(audit);
}
......@@ -122,7 +119,7 @@ public class RbacAnnotationConfig {
if (functionCode.startsWith("audit.")) {
return true;
}
String uri = httpRequestLocal.getRequestURI();
String uri = RequestContextThreadLocal.getRequestUri();
if (uri != null && uri.endsWith("/index/condition.json")) {
return true;
......
package com.ibeetl.admin.core.conf;
import com.ibeetl.admin.core.rbac.DataAccessFactory;
import com.ibeetl.admin.core.rbac.da.DefaultDataAccessFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.ibeetl.admin.core.rbac.DataAccessFactory;
import com.ibeetl.admin.core.rbac.da.DefaultDataAccessFactory;
/** 数据权限,可以自动装配 */
@Configuration
public class RbacDataAccessConfig {
......
......@@ -3,7 +3,6 @@ package com.ibeetl.admin.core.conf;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import org.apache.commons.digester3.RegexRules;
import org.hibernate.validator.HibernateValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.error.DefaultErrorAttributes;
......
......@@ -14,8 +14,6 @@ import com.ibeetl.admin.core.conf.springmvc.interceptor.HttpRequestInterceptor;
import com.ibeetl.admin.core.conf.springmvc.interceptor.SessionInterceptor;
import com.ibeetl.admin.core.conf.springmvc.resolve.RequestBodyPlusProcessor;
import com.ibeetl.admin.core.service.CoreUserService;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
......@@ -29,7 +27,6 @@ import org.springframework.format.FormatterRegistry;
import org.springframework.format.datetime.DateFormatter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
......@@ -59,12 +56,6 @@ public class SpringWebMvcConfigurer implements WebMvcConfigurer, InitializingBea
@Autowired
private CoreUserService userService;
@Autowired
private BeetlGroupUtilConfiguration beetlGroupUtilConfiguration;
@Autowired
private GroupTemplate groupTemplate;
@Autowired
private RequestMappingHandlerAdapter adapter;
......@@ -139,14 +130,6 @@ public class SpringWebMvcConfigurer implements WebMvcConfigurer, InitializingBea
@Override
public void afterPropertiesSet() {
this.mvcTestPath = env.getProperty("mvc.test.path");
Map<String, Object> var = new HashMap<>(5);
String appName = env.getProperty("app.name");
if (appName == null) {
var.put("appName", DEFAULT_APP_NAME);
}
var.put("jsVer", System.currentTimeMillis());
groupTemplate.setSharedVars(var);
/*自定义参数解析器配置,自定义应该优先级最高*/
List<HandlerMethodArgumentResolver> argumentResolvers = CollUtil.newArrayList();
argumentResolvers.add(new RequestBodyPlusProcessor(adapter.getMessageConverters()));
......
package com.ibeetl.admin.core.conf.beetl;
import cn.hutool.core.util.CharsetUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ibeetl.admin.core.conf.JacksonConfig;
import com.ibeetl.admin.core.conf.beetl.handler.DateTypeHandler;
......@@ -8,7 +7,6 @@ import com.ibeetl.admin.core.conf.beetl.handler.DictTypeHandler;
import com.ibeetl.admin.core.conf.beetl.handler.ZonedDateTimeTypeHandler;
import com.ibeetl.admin.core.conf.beetl.processor.JsonBeanProcessor;
import com.ibeetl.admin.core.entity.DictType;
import com.ibeetl.admin.core.rbac.DataAccess;
import com.ibeetl.admin.core.rbac.DataAccessFactory;
import com.ibeetl.admin.core.service.CorePlatformService;
import com.ibeetl.admin.core.util.beetl.DictQueryFunction;
......@@ -20,29 +18,23 @@ import com.ibeetl.admin.core.util.beetl.OrgFunction;
import com.ibeetl.admin.core.util.beetl.RoleFunction;
import com.ibeetl.admin.core.util.beetl.SearchCondtionFunction;
import com.ibeetl.admin.core.util.beetl.SysFunctionTreeFunction;
import com.ibeetl.admin.core.util.beetl.UUIDFunction;
import com.ibeetl.admin.core.util.beetl.XXSDefenderFormat;
import com.ibeetl.admin.core.web.query.QueryParser;
import com.ibeetl.starter.BeetlSqlMutipleSourceCustomize;
import com.ibeetl.starter.BeetlTemplateCustomize;
import com.ibeetl.starter.ObjectMapperJsonUtil;
import java.io.UnsupportedEncodingException;
import java.sql.JDBCType;
import java.time.ZonedDateTime;
import java.util.Date;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.beetl.core.Context;
import org.beetl.core.Function;
import org.beetl.core.GroupTemplate;
import org.beetl.ext.simulate.JsonUtil;
import org.beetl.ext.simulate.WebSimulate;
import org.beetl.sql.core.Interceptor;
import org.beetl.sql.core.InterceptorContext;
import org.beetl.sql.core.SqlId;
import org.beetl.sql.core.engine.SQLParameter;
import org.beetl.sql.core.engine.SQLPlaceholderST;
import org.beetl.sql.core.mapping.type.JavaSqlTypeHandler;
import org.beetl.sql.ext.DebugInterceptor;
import org.beetl.sql.starter.SQLManagerCustomize;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -55,54 +47,58 @@ import org.springframework.core.env.Environment;
@Configuration
@AutoConfigureAfter(JacksonConfig.class)
public class BeetlConf {
@Autowired Environment env;
@Autowired CorePlatformService platFormService;
@Autowired OrgFunction orgFunction;
@Autowired
Environment env;
@Autowired SysFunctionTreeFunction sysFunctionTreeFunction;
@Autowired
CorePlatformService platFormService;
@Autowired DictQueryFunction dictDownQueryFunction;
@Autowired
OrgFunction orgFunction;
@Autowired RoleFunction roleFunction;
@Autowired FileFunction fileFunction;
@Autowired
SysFunctionTreeFunction sysFunctionTreeFunction;
@Autowired SearchCondtionFunction searchCondtionFunction;
@Autowired
DictQueryFunction dictDownQueryFunction;
@Autowired DataAccessFactory dataAccessFactory;
@Autowired
RoleFunction roleFunction;
@Autowired ApplicationContext applicationContext;
@Autowired
FileFunction fileFunction;
@Autowired FunFunction funFunction;
@Autowired
SearchCondtionFunction searchCondtionFunction;
@Autowired FunAccessUrlFunction funAccessUrlFunction;
@Autowired
DataAccessFactory dataAccessFactory;
@Autowired MenuFunction menuFunction;
@Autowired
ApplicationContext applicationContext;
@Bean
public WebSimulate getWebSimulate(GroupTemplate gt, ObjectMapper objectMapper) {
return new WebSimulate(gt, new ObjectMapperJsonUtil(objectMapper)) {
@Override
protected String getRenderPath(HttpServletRequest request) {
String defaultRenderPath = request.getServletPath();
return defaultRenderPath.replace(".do", ".html");
}
};
}
@Autowired
FunFunction funFunction;
@Autowired
FunAccessUrlFunction funAccessUrlFunction;
@Autowired
MenuFunction menuFunction;
/**
* 对BeetlSql 的多数据源中每个数据源单独自定义配置
*
* @return
*/
@Bean
public BeetlSqlMutipleSourceCustomize beetlSqlMutipleSourceCustomize() {
public SQLManagerCustomize beetlSqlMutipleSourceCustomize() {
SQLPlaceholderST.textFunList.add("mapping");
return (dataSource, manager) -> {
/*bean转换处理器*/
JsonBeanProcessor jsonBeanProcessor = new JsonBeanProcessor(manager);
manager.setDefaultBeanProcessors(jsonBeanProcessor);
// JsonBeanProcessor jsonBeanProcessor = new JsonBeanProcessor();
// manager.setDefaultBeanProcessors(jsonBeanProcessor);
/*类型处理器*/
Map<Class, JavaSqlTypeHandler> typeHandlerMap =
manager.getDefaultBeanProcessors().getHandlers();
......@@ -113,89 +109,19 @@ public class BeetlConf {
typeHandlerMap.put(DictType.class, new DictTypeHandler());
/*拦截器*/
manager.setInters(
new Interceptor[] {new StarterDebugInterceptor(), new TypeHandlerInterceptor()});
};
}
/**
* Beetl模板引擎的自定义配置
*
* @return
*/
@Bean
public BeetlTemplateCustomize beetlTemplateCustomize() {
return groupTemplate -> {
groupTemplate.registerFunctionPackage("platform", platFormService);
groupTemplate.registerFunctionPackage("queryCondtion", new QueryParser());
groupTemplate.registerFunction("core.orgName", orgFunction);
groupTemplate.registerFunction("core.functionName", funFunction);
groupTemplate.registerFunction("core.funAccessUrl", funAccessUrlFunction);
groupTemplate.registerFunction("core.menuName", menuFunction);
groupTemplate.registerFunction("core.searchCondtion", searchCondtionFunction);
groupTemplate.registerFunction("core.roles", roleFunction);
groupTemplate.registerFunction("core.file", fileFunction);
groupTemplate.registerFormat("xss", new XXSDefenderFormat());
groupTemplate.registerFunction("uuid", new UUIDFunction());
groupTemplate.registerFunctionPackage("dict", dictDownQueryFunction);
// 模板页面判断是否有按钮权限,比如canAccess
groupTemplate.registerFunction(
"canAccess",
(paras, ctx) -> {
Long userId = platFormService.getCurrentUser().getId();
Long orgId = platFormService.getCurrentOrgId();
String functionCode = (String) paras[0];
return platFormService.canAcessFunction(userId, orgId, functionCode);
});
groupTemplate.registerFunction(
"env",
new Function() {
@Override
public String call(Object[] paras, Context ctx) {
String key = (String) paras[0];
String value = env.getProperty(key);
if (value != null) {
return getStr(value);
}
if (paras.length == 2) {
return (String) paras[1];
}
return null;
}
protected String getStr(String str) {
try {
return new String(str.getBytes(CharsetUtil.ISO_8859_1), CharsetUtil.UTF_8);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
});
groupTemplate.registerFunction(
"dataAccessList",
new Function() {
@Override
public List<DataAccess> call(Object[] paras, Context ctx) {
return dataAccessFactory.all();
}
});
new Interceptor[]{new StarterDebugInterceptor(), new TypeHandlerInterceptor()});
};
}
static class StarterDebugInterceptor extends DebugInterceptor {
private Logger logger = LoggerFactory.getLogger("beetlsql");
/**
* 将内置生成的SQL排除打印
*
* @param sqlId
* @return
*/
@Override
protected boolean isSimple(String sqlId) {
protected boolean isSimple(SqlId sqlId) {
// if (sqlId.indexOf("_gen_") != -1) {
// return true;
// } else {
......@@ -203,7 +129,9 @@ public class BeetlConf {
// }
return super.isSimple(sqlId);
}
}
}
/**
......@@ -216,7 +144,8 @@ class TypeHandlerInterceptor implements Interceptor {
@Override
public void before(InterceptorContext ctx) {
List<SQLParameter> paras = ctx.getParas();
List<SQLParameter> paras = ctx.getExecuteContext().sqlResult.jdbcPara;
for (SQLParameter para : paras) {
if (para.value instanceof Date) {
para.value = ((Date) para.value).getTime();
......@@ -226,8 +155,13 @@ class TypeHandlerInterceptor implements Interceptor {
}
@Override
public void after(InterceptorContext ctx) {}
public void after(InterceptorContext ctx) {
}
@Override
public void exception(InterceptorContext ctx, Exception ex) {}
public void exception(InterceptorContext ctx, Exception ex) {
}
}
......@@ -8,11 +8,13 @@ import java.sql.Types;
import java.time.Instant;
import java.util.Date;
import org.beetl.sql.core.mapping.type.JavaSqlTypeHandler;
import org.beetl.sql.core.mapping.type.TypeParameter;
import org.beetl.sql.core.mapping.type.ReadTypeParameter;
public class DateTypeHandler extends JavaSqlTypeHandler {
@Override
public Object getValue(TypeParameter typePara) throws SQLException {
public Object getValue(ReadTypeParameter typePara) throws SQLException {
if (ObjectUtil.isNull(typePara.getRs().getObject(typePara.getIndex()))) {
return null;
}
......@@ -27,4 +29,5 @@ public class DateTypeHandler extends JavaSqlTypeHandler {
return null;
}
}
}
\ No newline at end of file
......@@ -4,7 +4,7 @@ import cn.hutool.core.util.ObjectUtil;
import com.ibeetl.admin.core.entity.DictType;
import java.sql.SQLException;
import org.beetl.sql.core.mapping.type.JavaSqlTypeHandler;
import org.beetl.sql.core.mapping.type.TypeParameter;
import org.beetl.sql.core.mapping.type.ReadTypeParameter;
/**
* 字典字段的映射处理器
......@@ -12,7 +12,7 @@ import org.beetl.sql.core.mapping.type.TypeParameter;
public class DictTypeHandler extends JavaSqlTypeHandler {
@Override
public Object getValue(TypeParameter typePara) throws SQLException {
public Object getValue(ReadTypeParameter typePara) throws SQLException {
if (ObjectUtil.isNull(typePara.getRs().getObject(typePara.getIndex()))) {
return null;
......
......@@ -14,15 +14,20 @@ import org.beetl.core.GroupTemplate;
import org.beetl.core.resource.StringTemplateResourceLoader;
import org.beetl.sql.core.SQLManager;
import org.beetl.sql.core.SQLResult;
import org.beetl.sql.core.SqlId;
import org.beetl.sql.core.engine.template.BeetlTemplateContext;
import org.beetl.sql.core.engine.template.BeetlTemplateEngine;
public class MappingFunction implements Function {
private static final StringWriter STRING_WRITER = new StringWriter();
private static final StringTemplateResourceLoader STRING_TEMPLATE_RESOURCE_LOADER =
new StringTemplateResourceLoader();
@Override
public Object call(Object[] paras, Context ctx) {
String currentSqlId = ctx.getGlobal("_id").toString();
Object cache = CacheUtil.get(currentSqlId);
if (ObjectUtil.isNotNull(cache)) {
......@@ -44,17 +49,19 @@ public class MappingFunction implements Function {
SQLResult result;
if (sqlSegmentId.indexOf(".") == -1) {
/*同一个md文件的sql段*/
result = sm.getSQLResult(file + "." + sqlSegmentId, inputParas, ctx);
result = sm
.getSQLResult(SqlId.of(file, sqlSegmentId), inputParas, new BeetlTemplateContext(ctx));
} else {
/*另一个md文件的sql段*/
result = sm.getSQLResult(sqlSegmentId, inputParas, ctx);
result = sm.getSQLResult(SqlId.of(sqlSegmentId), inputParas, new BeetlTemplateContext(ctx));
}
// 追加参数
list.addAll(result.jdbcPara);
ctx.set("_paras", list);
GroupTemplate groupTemplate = sm.getBeetl().getGroupTemplate();
GroupTemplate groupTemplate = ((BeetlTemplateEngine) sm.getSqlTemplateEngine()).getBeetl()
.getGroupTemplate();
Map rsMap =
groupTemplate.runScript(
result.jdbcSql, inputParas, STRING_WRITER, STRING_TEMPLATE_RESOURCE_LOADER);
......@@ -69,9 +76,11 @@ public class MappingFunction implements Function {
}
private String getParentId(Context ctx) {
String id = (String) ctx.getGlobal("_id");
int index = id.lastIndexOf(".");
String file = id.substring(0, index);
return file;
}
}
......@@ -9,11 +9,13 @@ import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import org.beetl.sql.core.mapping.type.JavaSqlTypeHandler;
import org.beetl.sql.core.mapping.type.TypeParameter;
import org.beetl.sql.core.mapping.type.ReadTypeParameter;
public class ZonedDateTimeTypeHandler extends JavaSqlTypeHandler {
@Override
public Object getValue(TypeParameter typePara) throws SQLException {
public Object getValue(ReadTypeParameter typePara) throws SQLException {
if (ObjectUtil.isNull(typePara.getRs().getObject(typePara.getIndex()))) {
return null;
}
......@@ -30,4 +32,5 @@ public class ZonedDateTimeTypeHandler extends JavaSqlTypeHandler {
return null;
}
}
}
......@@ -24,26 +24,20 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.Set;
import org.beetl.sql.core.SQLManager;
import org.beetl.sql.core.db.DBStyle;
import org.beetl.sql.core.kit.BeanKit;
import org.beetl.sql.clazz.kit.BeanKit;
import org.beetl.sql.core.ExecuteContext;
import org.beetl.sql.core.db.DBType;
import org.beetl.sql.core.mapping.BeanProcessor;
import org.beetl.sql.core.mapping.type.JavaSqlTypeHandler;
import org.beetl.sql.core.mapping.type.TypeParameter;
import org.beetl.sql.core.mapping.type.ReadTypeParameter;
public class JsonBeanProcessor extends BeanProcessor {
public JsonBeanProcessor(SQLManager sm) {
super(sm);
}
/**
* 网格化输出结果集
*
* @param resultSet
* @throws SQLException
*/
public void printfResultSet(ResultSet resultSet) throws SQLException {
Map<String, List<Object>> map = MapUtil.<String, List<Object>>builder().build();
ResultSetMetaData metaData = resultSet.getMetaData();
int count = metaData.getColumnCount();
......@@ -75,21 +69,19 @@ public class JsonBeanProcessor extends BeanProcessor {
System.out.println();
}
}
/**
* 将ResultSet映射为一个POJO对象
*
* @param rs
* @param type
* @return
* @throws SQLException
*/
@Override
public <T> T toBean(String sqlId, ResultSet rs, Class<T> type) throws SQLException {
public <T> T toBean(ExecuteContext ctx, ResultSet rs, Class<T> type) throws SQLException {
String sqlId = ctx.sqlId.toString();
List<T> results = new ArrayList<T>();
PropertyDescriptor[] props = this.propertyDescriptors(type);
ResultSetMetaData rsmd = rs.getMetaData();
int[] columnToProperty = this.mapColumnsToProperties(type, rsmd, props);
int[] columnToProperty = this.mapColumnsToProperties(ctx, type, rsmd, props);
GridMapping mapping = null;
if (StrUtil.isNotBlank(sqlId)) {
......@@ -98,14 +90,14 @@ public class JsonBeanProcessor extends BeanProcessor {
if (mapping == null) {
/*无映射的情况下使用beetlsql默认自带的映射*/
do {
T bean = super.createBean(sqlId, rs, type, props, columnToProperty);
T bean = super.createBean(ctx, rs, type, props, columnToProperty);
results.add(bean);
} while (rs.next());
} else {
/*复杂结果集映射,取消TailBean的便利性*/
rs.absolute(0);
mapping.getVirtualCell().getNestedCells().clear();
fillMappingNestedCells(sqlId, rs, mapping);
fillMappingNestedCells(ctx, rs, mapping);
results = parserMappingNestedCells(mapping);
}
return CollUtil.isNotEmpty(results) ? CollUtil.getFirst(results) : null;
......@@ -113,37 +105,32 @@ public class JsonBeanProcessor extends BeanProcessor {
/**
* 将ResultSet映射为一个List&lt;POJO&gt;集合
*
* @param sqlId
* @param rs
* @param type
* @param <T>
* @return
* @throws SQLException
*/
@Override
public <T> List<T> toBeanList(String sqlId, ResultSet rs, Class<T> type) throws SQLException {
public <T> List<T> toBeanList(ExecuteContext ctx, ResultSet rs, Class<T> type)
throws SQLException {
if (!rs.next()) {
return new ArrayList<T>(0);
}
String sqlId = ctx.sqlId.toString();
List<T> results = new ArrayList<T>();
PropertyDescriptor[] props = this.propertyDescriptors(type);
ResultSetMetaData rsmd = rs.getMetaData();
int[] columnToProperty = this.mapColumnsToProperties(type, rsmd, props);
int[] columnToProperty = this.mapColumnsToProperties(ctx, type, rsmd, props);
GridMapping mapping = (GridMapping) CacheUtil.get(sqlId);
if (null == mapping) {
/*无映射的情况下使用beetlsql默认自带的映射*/
do {
T bean = super.createBean(sqlId, rs, type, props, columnToProperty);
T bean = super.createBean(ctx, rs, type, props, columnToProperty);
results.add(bean);
} while (rs.next());
} else {
/*复杂结果集映射,取消TailBean的便利性*/
rs.absolute(0);
mapping.getVirtualCell().getNestedCells().clear();
fillMappingNestedCells(sqlId, rs, mapping);
fillMappingNestedCells(ctx, rs, mapping);
results = parserMappingNestedCells(mapping);
}
return results;
......@@ -152,19 +139,17 @@ public class JsonBeanProcessor extends BeanProcessor {
/**
* 循环转换整个网格映射为最终的映射类型
*
* @param mapping 预先处理好的网格映射
* @return
* @param mapping
* 预先处理好的网格映射
*/
public List parserMappingNestedCells(GridMapping mapping) throws SQLException {
List results = parserRealContainerCell(mapping.getVirtualCell());
return results;
}
/**
* 递归转换整个网格
*
* @param virtualCell
* @return
*/
public List parserRealContainerCell(GridCell virtualCell) throws SQLException {
/*判断是单个对象还是集合*/
......@@ -203,6 +188,7 @@ public class JsonBeanProcessor extends BeanProcessor {
}
private Object createObjectFromResultSetMap(GridCell contentCell) throws SQLException {
Object bean;
Map<String, Object> valueMap = contentCell.getBeanMap();
GridHeader relationGridHeader = contentCell.getRelationGridHeader();
......@@ -233,35 +219,37 @@ public class JsonBeanProcessor extends BeanProcessor {
}
return bean;
}
/**
* 填充整个网格映射mapping数据结构:通过网格头映射生成一个个网格单元。<br>
* 并没有对大数据量结果集做处理。而且递归有深度限制,列数映射过多可能会出现递归堆栈溢出,不过应该极少出现。
*
* @param resultSet
* @param mapping
* @throws SQLException
*/
protected void fillMappingNestedCells(String sqlId, ResultSet resultSet, GridMapping mapping)
protected void fillMappingNestedCells(ExecuteContext ctx, ResultSet resultSet,
GridMapping mapping)
throws SQLException {
if (!resultSet.next()) return;
if (!resultSet.next()) {
return;
}
GridHeader header = mapping.getHeader();
processJdbcColumn(header, resultSet);
processJdbcColumn(ctx, header, resultSet);
/*必须给一个虚假容器,为了实现递归*/
do {
fillNestedGridCell(sqlId, resultSet, header, mapping.getVirtualCell());
fillNestedGridCell(ctx, resultSet, header, mapping.getVirtualCell());
} while (resultSet.next());
}
/** 填充网格映射中的单元格映射结构。 */
protected void fillNestedGridCell(
String sqlId, ResultSet resultSet, GridHeader header, GridCell virtualCell) {
ExecuteContext ctx, ResultSet resultSet, GridHeader header, GridCell virtualCell) {
/*通过当前header获取对应的结果集列*/
Map<String, Object> beanMap = extractMapFromRs(sqlId, resultSet, header);
Map<String, Object> beanMap = extractMapFromRs(ctx, resultSet, header);
GridCell realContainerCell = virtualCell.findOrCreateNestedCell(header, beanMap);
List<GridHeader> nestedHeaders = header.getNestedHeaders();
for (GridHeader nestedHeader : nestedHeaders) {
/*在 realContainerCell 中找到对应header的虚拟cell*/
GridCell nestedVirtualCell = realContainerCell.findVirtualCell(nestedHeader);
fillNestedGridCell(sqlId, resultSet, nestedHeader, nestedVirtualCell);
fillNestedGridCell(ctx, resultSet, nestedHeader, nestedVirtualCell);
}
}
......@@ -269,13 +257,16 @@ public class JsonBeanProcessor extends BeanProcessor {
* Method processJdbcColumn ...<br>
* 根据当前sql语句的resultset 处理gridheader中的fieldToColumnMap。
*
* @param header of type GridHeader
* @param resultSet of type ResultSet
* @param header
* of type GridHeader
* @param resultSet
* of type ResultSet
*/
private void processJdbcColumn(GridHeader header, ResultSet resultSet) {
private void processJdbcColumn(ExecuteContext ctx, GridHeader header, ResultSet resultSet) {
List<GridHeader> nestedHeaders = header.getNestedHeaders();
for (GridHeader nestedHeader : nestedHeaders) {
processJdbcColumn(nestedHeader, resultSet);
processJdbcColumn(ctx, nestedHeader, resultSet);
}
try {
ResultSetMetaData metaData = resultSet.getMetaData();
......@@ -294,8 +285,9 @@ public class JsonBeanProcessor extends BeanProcessor {
dbColumnProperty.setHasEffective(false);
continue;
}
int dbType = ctx.sqlManager.getDbStyle().getDBType();
boolean isSpecialDbRn =
(super.dbType == DBStyle.DB_ORACLE || super.dbType == DBStyle.DB_SQLSERVER)
(dbType == DBType.DB_ORACLE || dbType == DBType.DB_SQLSERVER)
&& columnLabel.equalsIgnoreCase("beetl_rn");
if (isSpecialDbRn) {
dbColumnProperty.setHasEffective(false);
......@@ -314,13 +306,10 @@ public class JsonBeanProcessor extends BeanProcessor {
/**
* 遍历网格头,由网格头的信息从结果集中读取值。<br>
*
* @param resultSet
* @param header
* @return
*/
private Map<String, Object> extractMapFromRs(
String sqlId, ResultSet resultSet, GridHeader header) {
ExecuteContext ctx, ResultSet resultSet, GridHeader header) {
Map<String, Object> tempBeanMap = MapUtil.newHashMap();
/*处理每个头部映射的bean类型与结果集的列的类型转换*/
Map<JavaFieldProperty, DBColumnProperty> fieldToColumnMap = header.getFieldToColumnMap();
......@@ -344,14 +333,14 @@ public class JsonBeanProcessor extends BeanProcessor {
handler = super.getDefaultHandler();
}
TypeParameter typeParameter =
new TypeParameter(
sqlId,
super.dbName,
ReadTypeParameter typeParameter =
new ReadTypeParameter(
ctx.sqlId,
ctx.sqlManager.getDbStyle().getName(),
fieldType,
resultSet,
resultSet.getMetaData(),
dbColumnProperty.getColumnIndex());
dbColumnProperty.getColumnIndex(), ctx);
tempBeanMap.put(javaFieldProperty.getKey(), handler.getValue(typeParameter));
} catch (SQLException e) {
......@@ -364,10 +353,6 @@ public class JsonBeanProcessor extends BeanProcessor {
/**
* 根据class取得属性描述PropertyDescriptor
*
* @param c
* @return
* @throws SQLException
*/
private PropertyDescriptor[] propertyDescriptors(Class<?> c) throws SQLException {
......@@ -377,4 +362,5 @@ public class JsonBeanProcessor extends BeanProcessor {
throw new SQLException("Bean introspection failed: " + e.getMessage());
}
}
}
......@@ -7,7 +7,6 @@ import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.Set;
/**
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment