mymapper 完善,但是没有测试
parent
9399401fb7
commit
5e3c18b8bb
|
@ -2200,7 +2200,20 @@ public class Util extends weaver.general.Util {
|
||||||
appender.setName("ayh_cus");
|
appender.setName("ayh_cus");
|
||||||
appender.setEncoding("UTF-8");
|
appender.setEncoding("UTF-8");
|
||||||
appender.setDatePattern("'_'yyyyMMdd'.log'");
|
appender.setDatePattern("'_'yyyyMMdd'.log'");
|
||||||
appender.setFile(weaver.general.GCONST.getLogPath() + "cus" + File.separator + "util_cus" + File.separator + "cus.log");
|
String logPath = GCONST.getLogPath();
|
||||||
|
try {
|
||||||
|
Map<String, Object> map = getProperties2Map("logPathConfig", "cus");
|
||||||
|
if (map != null) {
|
||||||
|
if (map.containsKey("logPath")) {
|
||||||
|
logPath = "".equals(null2String(map.get("logPath"))) ? logPath : null2String(map.get("logPath"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception ignore) {
|
||||||
|
}
|
||||||
|
if (!logPath.endsWith(File.separator)) {
|
||||||
|
logPath = logPath + File.separator;
|
||||||
|
}
|
||||||
|
appender.setFile(logPath + "cus" + File.separator + "util_cus" + File.separator + "cus.log");
|
||||||
appender.setThreshold(Priority.DEBUG);
|
appender.setThreshold(Priority.DEBUG);
|
||||||
appender.setLayout(new PatternLayout("[%-5p] [%d{yyyy-MM-dd HH:mm:ss,SSS}] [%F.%M:%L] ==> %m %x %n"));
|
appender.setLayout(new PatternLayout("[%-5p] [%d{yyyy-MM-dd HH:mm:ss,SSS}] [%F.%M:%L] ==> %m %x %n"));
|
||||||
appender.setAppend(true);
|
appender.setAppend(true);
|
||||||
|
@ -2258,7 +2271,21 @@ public class Util extends weaver.general.Util {
|
||||||
appender.setName("cus_" + name);
|
appender.setName("cus_" + name);
|
||||||
appender.setEncoding("UTF-8");
|
appender.setEncoding("UTF-8");
|
||||||
appender.setDatePattern("'_'yyyyMMdd'.log'");
|
appender.setDatePattern("'_'yyyyMMdd'.log'");
|
||||||
appender.setFile(weaver.general.GCONST.getLogPath() + "cus" + File.separator + name + File.separator + "cus.log");
|
String logPath = GCONST.getLogPath();
|
||||||
|
try {
|
||||||
|
Map<String, Object> map = getProperties2Map("logPathConfig", "cus");
|
||||||
|
if (map != null) {
|
||||||
|
if (map.containsKey("logPath")) {
|
||||||
|
logPath = "".equals(null2String(map.get("logPath"))) ? logPath : null2String(map.get("logPath"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception ignore) {
|
||||||
|
|
||||||
|
}
|
||||||
|
if (!logPath.endsWith(File.separator)) {
|
||||||
|
logPath = logPath + File.separator;
|
||||||
|
}
|
||||||
|
appender.setFile(logPath + "cus" + File.separator + name + File.separator + "cus.log");
|
||||||
appender.setThreshold(Priority.DEBUG);
|
appender.setThreshold(Priority.DEBUG);
|
||||||
appender.setLayout(new PatternLayout("[%-5p] [%d{yyyy-MM-dd HH:mm:ss,SSS}] [%r] [%F.%M:%L] ==> \n %m %x %n"));
|
appender.setLayout(new PatternLayout("[%-5p] [%d{yyyy-MM-dd HH:mm:ss,SSS}] [%r] [%F.%M:%L] ==> \n %m %x %n"));
|
||||||
appender.setAppend(true);
|
appender.setAppend(true);
|
||||||
|
@ -3294,6 +3321,45 @@ public class Util extends weaver.general.Util {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String logStr(String logStr, String... args) {
|
||||||
|
try {
|
||||||
|
if (Strings.isNullOrEmpty(logStr)) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
if (args == null || args.length == 0) {
|
||||||
|
return logStr;
|
||||||
|
}
|
||||||
|
String pattern = "\\{}";
|
||||||
|
Pattern compile = Pattern.compile(pattern);
|
||||||
|
Matcher matcher = compile.matcher(logStr);
|
||||||
|
int n = 0;
|
||||||
|
while (matcher.find()) {
|
||||||
|
if (n + 1 > args.length) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
logStr = logStr.replaceFirst(pattern, "{" + n++ + "}");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Object arg = args[args.length - 1];
|
||||||
|
if (arg instanceof Throwable) {
|
||||||
|
for (int i = 0; i < args.length - 1; i++) {
|
||||||
|
pattern = "\\{" + i + "}";
|
||||||
|
logStr = logStr.replaceFirst(pattern, Matcher.quoteReplacement(String.valueOf(args[i])));
|
||||||
|
}
|
||||||
|
return logStr + "\n" + getErrString((Throwable) arg);
|
||||||
|
}
|
||||||
|
} catch (Exception ignore) {
|
||||||
|
}
|
||||||
|
for (int i = 0; i < args.length; i++) {
|
||||||
|
pattern = "\\{" + i + "}";
|
||||||
|
logStr = logStr.replaceFirst(pattern, Matcher.quoteReplacement(String.valueOf(args[i])));
|
||||||
|
}
|
||||||
|
return logStr;
|
||||||
|
} catch (Exception e) {
|
||||||
|
return logStr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <h2>测试流程工具类</h2>
|
* <h2>测试流程工具类</h2>
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
package aiyh.utils.annotation.recordset;
|
||||||
|
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <h1>结果集映射</h1>
|
||||||
|
*
|
||||||
|
* <p>create: 2023/3/16 10:07</p>
|
||||||
|
*
|
||||||
|
* @author youHong.ai
|
||||||
|
*/
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.ANNOTATION_TYPE)
|
||||||
|
@Documented
|
||||||
|
public @interface ResultMap {
|
||||||
|
|
||||||
|
/** 原型 */
|
||||||
|
String property() default "";
|
||||||
|
|
||||||
|
/** 数据库字段 */
|
||||||
|
String column();
|
||||||
|
|
||||||
|
/** 原型类型 */
|
||||||
|
Class<?> javaType() default String.class;
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package aiyh.utils.annotation.recordset;
|
||||||
|
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <h1>结果集映射</h1>
|
||||||
|
*
|
||||||
|
* <p>create: 2023/3/16 10:07</p>
|
||||||
|
*
|
||||||
|
* @author youHong.ai
|
||||||
|
*/
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.METHOD)
|
||||||
|
@Documented
|
||||||
|
public @interface ResultMappings {
|
||||||
|
|
||||||
|
ResultMap[] value();
|
||||||
|
}
|
|
@ -26,6 +26,11 @@ public class CustomerException extends RuntimeException {
|
||||||
this.msg = msg;
|
this.msg = msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CustomerException(String msg, String... obj) {
|
||||||
|
super(Util.logStr(msg, obj));
|
||||||
|
this.msg = Util.logStr(msg, obj);
|
||||||
|
}
|
||||||
|
|
||||||
public CustomerException(String msg, Integer code) {
|
public CustomerException(String msg, Integer code) {
|
||||||
super(msg);
|
super(msg);
|
||||||
this.code = code;
|
this.code = code;
|
||||||
|
@ -33,7 +38,7 @@ public class CustomerException extends RuntimeException {
|
||||||
}
|
}
|
||||||
|
|
||||||
public CustomerException(String msg, Integer code, Throwable throwable) {
|
public CustomerException(String msg, Integer code, Throwable throwable) {
|
||||||
super(msg);
|
super(msg, throwable);
|
||||||
this.code = code;
|
this.code = code;
|
||||||
this.msg = msg;
|
this.msg = msg;
|
||||||
}
|
}
|
||||||
|
|
|
@ -553,15 +553,14 @@ public class ResultMapper {
|
||||||
Class<?> propertyType = propertyDescriptor.getPropertyType();
|
Class<?> propertyType = propertyDescriptor.getPropertyType();
|
||||||
Object value = null;
|
Object value = null;
|
||||||
String fieldName = propertyDescriptor.getName();
|
String fieldName = propertyDescriptor.getName();
|
||||||
|
|
||||||
Field declaredField = o.getClass().getDeclaredField(fieldName);
|
|
||||||
if (Strings.isNullOrEmpty(fieldName)) {
|
if (Strings.isNullOrEmpty(fieldName)) {
|
||||||
fieldName = propertyDescriptor.getDisplayName();
|
fieldName = propertyDescriptor.getDisplayName();
|
||||||
}
|
}
|
||||||
|
Field declaredField = o.getClass().getDeclaredField(fieldName);
|
||||||
|
|
||||||
if (method.isAnnotationPresent(Associations.class)) {
|
if (method.isAnnotationPresent(Associations.class)) {
|
||||||
Association association = searchAssociation(method, fieldName, false);
|
Association association = searchAssociation(method, fieldName, false);
|
||||||
if (association != null) {
|
if (association != null) {
|
||||||
if (association.property().equals(fieldName)) {
|
|
||||||
Object cassociationValue = association(rs, association, method);
|
Object cassociationValue = association(rs, association, method);
|
||||||
if (cassociationValue == null) {
|
if (cassociationValue == null) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -580,11 +579,9 @@ public class ResultMapper {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (method.isAnnotationPresent(CollectionMappings.class)) {
|
if (method.isAnnotationPresent(CollectionMappings.class)) {
|
||||||
CollectionMapping collectionMapping = searchCollection(method, fieldName, false);
|
CollectionMapping collectionMapping = searchCollection(method, fieldName, false);
|
||||||
if (collectionMapping != null) {
|
if (collectionMapping != null) {
|
||||||
if (fieldName.equals(collectionMapping.property()) && !"".equals(collectionMapping.property())) {
|
|
||||||
Object collection = collection(rs, collectionMapping, method);
|
Object collection = collection(rs, collectionMapping, method);
|
||||||
try {
|
try {
|
||||||
propertyDescriptor.getWriteMethod().invoke(o, collection);
|
propertyDescriptor.getWriteMethod().invoke(o, collection);
|
||||||
|
@ -597,7 +594,6 @@ public class ResultMapper {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
TypeHandler typeHandler = ResultMapper.typeHandler.get(propertyType);
|
TypeHandler typeHandler = ResultMapper.typeHandler.get(propertyType);
|
||||||
if (enable) {
|
if (enable) {
|
||||||
value = typeHandler == null ? null : typeHandler.getValue(rs, Util.toUnderlineCase(fieldName), declaredField);
|
value = typeHandler == null ? null : typeHandler.getValue(rs, Util.toUnderlineCase(fieldName), declaredField);
|
||||||
|
@ -651,6 +647,7 @@ public class ResultMapper {
|
||||||
Association[] mappings = annotation.value();
|
Association[] mappings = annotation.value();
|
||||||
Association mapping = null;
|
Association mapping = null;
|
||||||
for (Association item : mappings) {
|
for (Association item : mappings) {
|
||||||
|
Util.getLogger().info("column: " + item.column() + " ===property: " + item.property() + " ====fieldName: " + filedName);
|
||||||
String property = isMap ? item.column() : item.property();
|
String property = isMap ? item.column() : item.property();
|
||||||
if (isMap ? filedName.equalsIgnoreCase(property) : filedName.equals(property)) {
|
if (isMap ? filedName.equalsIgnoreCase(property) : filedName.equals(property)) {
|
||||||
mapping = item;
|
mapping = item;
|
||||||
|
@ -663,6 +660,7 @@ public class ResultMapper {
|
||||||
Id id = annotation.id();
|
Id id = annotation.id();
|
||||||
String column = annotation.column();
|
String column = annotation.column();
|
||||||
String columnValue = rs.getString(column);
|
String columnValue = rs.getString(column);
|
||||||
|
Util.getLogger().info(Arrays.toString(rs.getColumnName()));
|
||||||
if (Objects.isNull(columnValue) || "".equals(columnValue)) {
|
if (Objects.isNull(columnValue) || "".equals(columnValue)) {
|
||||||
columnValue = rs.getString(column.toUpperCase());
|
columnValue = rs.getString(column.toUpperCase());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package weaver.youhong.ai.yihong.formmode.stagediagram;
|
package weaver.youhong.ai.yihong.formmode.stagediagram;
|
||||||
|
|
||||||
import aiyh.utils.Util;
|
import aiyh.utils.Util;
|
||||||
import com.alibaba.fastjson.JSON;
|
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
import weaver.formmode.customjavacode.AbstractModeExpandJavaCodeNew;
|
import weaver.formmode.customjavacode.AbstractModeExpandJavaCodeNew;
|
||||||
import weaver.youhong.ai.yihong.formmode.stagediagram.service.ModeExpandSaveService;
|
import weaver.youhong.ai.yihong.formmode.stagediagram.service.ModeExpandSaveService;
|
||||||
|
@ -26,7 +25,6 @@ public class ModeExpandQuanJinSaveAction extends AbstractModeExpandJavaCodeNew {
|
||||||
Map<String, String> result = new HashMap<>(8);
|
Map<String, String> result = new HashMap<>(8);
|
||||||
ModeExpandSaveService service = new ModeExpandSaveService();
|
ModeExpandSaveService service = new ModeExpandSaveService();
|
||||||
try {
|
try {
|
||||||
log.info("自定义接口保存动作参数: " + JSON.toJSONString(param));
|
|
||||||
service.updateStageDiagramView(param,
|
service.updateStageDiagramView(param,
|
||||||
"STAGE_DIAGRAM_AMOUNT_TABLE_QJ", "STAGE_DIAGRAM_PROJECT_ID_FIELD_QJ",
|
"STAGE_DIAGRAM_AMOUNT_TABLE_QJ", "STAGE_DIAGRAM_PROJECT_ID_FIELD_QJ",
|
||||||
"STAGE_DIAGRAM_AMOUNT_FIELD_QJ", "MAPPING_CONFIG_MARK_QJ");
|
"STAGE_DIAGRAM_AMOUNT_FIELD_QJ", "MAPPING_CONFIG_MARK_QJ");
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package weaver.youhong.ai.yihong.formmode.stagediagram;
|
package weaver.youhong.ai.yihong.formmode.stagediagram;
|
||||||
|
|
||||||
import aiyh.utils.Util;
|
import aiyh.utils.Util;
|
||||||
import com.alibaba.fastjson.JSON;
|
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
import weaver.formmode.customjavacode.AbstractModeExpandJavaCodeNew;
|
import weaver.formmode.customjavacode.AbstractModeExpandJavaCodeNew;
|
||||||
import weaver.youhong.ai.yihong.formmode.stagediagram.service.ModeExpandSaveService;
|
import weaver.youhong.ai.yihong.formmode.stagediagram.service.ModeExpandSaveService;
|
||||||
|
@ -26,7 +25,6 @@ public class ModeExpandSaveAction extends AbstractModeExpandJavaCodeNew {
|
||||||
Map<String, String> result = new HashMap<>(8);
|
Map<String, String> result = new HashMap<>(8);
|
||||||
ModeExpandSaveService service = new ModeExpandSaveService();
|
ModeExpandSaveService service = new ModeExpandSaveService();
|
||||||
try {
|
try {
|
||||||
log.info("自定义接口保存动作参数: " + JSON.toJSONString(param));
|
|
||||||
service.updateStageDiagramView(param,
|
service.updateStageDiagramView(param,
|
||||||
"STAGE_DIAGRAM_AMOUNT_TABLE", "STAGE_DIAGRAM_PROJECT_ID_FIELD",
|
"STAGE_DIAGRAM_AMOUNT_TABLE", "STAGE_DIAGRAM_PROJECT_ID_FIELD",
|
||||||
"STAGE_DIAGRAM_AMOUNT_FIELD", "MAPPING_CONFIG_MARK");
|
"STAGE_DIAGRAM_AMOUNT_FIELD", "MAPPING_CONFIG_MARK");
|
||||||
|
|
|
@ -2,7 +2,7 @@ package weaver.youhong.ai.yihong.formmode.stagediagram.service;
|
||||||
|
|
||||||
import aiyh.utils.Util;
|
import aiyh.utils.Util;
|
||||||
import aiyh.utils.tool.cn.hutool.core.lang.Assert;
|
import aiyh.utils.tool.cn.hutool.core.lang.Assert;
|
||||||
import com.alibaba.fastjson.JSON;
|
import aiyh.utils.tool.cn.hutool.core.util.StrUtil;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import weaver.soa.workflow.request.Property;
|
import weaver.soa.workflow.request.Property;
|
||||||
|
@ -41,17 +41,14 @@ public class ModeExpandSaveService {
|
||||||
RequestInfo requestInfo = (RequestInfo) param.get("RequestInfo");
|
RequestInfo requestInfo = (RequestInfo) param.get("RequestInfo");
|
||||||
Map<String, String> mainTableValue = getMainTableValue(requestInfo);
|
Map<String, String> mainTableValue = getMainTableValue(requestInfo);
|
||||||
String projectId = mainTableValue.get(stageDiagramProjectFieldName);
|
String projectId = mainTableValue.get(stageDiagramProjectFieldName);
|
||||||
log.info("主表数据:" + JSON.toJSONString(mainTableValue));
|
|
||||||
// 获取当前模块id
|
// 获取当前模块id
|
||||||
/* ******************* 查询台账中对应的project是否存在, 台账中不存在则插入,存在则更新 ******************* */
|
/* ******************* 查询台账中对应的project是否存在, 台账中不存在则插入,存在则更新 ******************* */
|
||||||
StageNodeInfo nodeInfo = mapper.selectStageNodeInfoByProjectId(projectId);
|
StageNodeInfo nodeInfo = mapper.selectStageNodeInfoByProjectId(projectId);
|
||||||
log.info("查询到的nodeInFo数据:" + JSON.toJSONString(nodeInfo));
|
|
||||||
if (Objects.isNull(nodeInfo)) {
|
if (Objects.isNull(nodeInfo)) {
|
||||||
// 不存在项目信息在台账中插入项目信息到台账信息中
|
// 不存在项目信息在台账中插入项目信息到台账信息中
|
||||||
Integer dataId = Util.getModeDataId("uf_stage_node_info", 1);
|
Integer dataId = Util.getModeDataId("uf_stage_node_info", 1);
|
||||||
// 查询配置表信息
|
// 查询配置表信息
|
||||||
String nodeName = (String) currentNodeConfig.get("nodeName");
|
String nodeName = (String) currentNodeConfig.get("nodeName");
|
||||||
log.info("节点名称: " + nodeName);
|
|
||||||
String amount = mapper.selectAmountByProjectId(projectId,
|
String amount = mapper.selectAmountByProjectId(projectId,
|
||||||
Util.getCusConfigValueNullOrEmpty(projectIdField, ""),
|
Util.getCusConfigValueNullOrEmpty(projectIdField, ""),
|
||||||
Util.getCusConfigValueNullOrEmpty(amountTable, ""),
|
Util.getCusConfigValueNullOrEmpty(amountTable, ""),
|
||||||
|
@ -76,6 +73,9 @@ public class ModeExpandSaveService {
|
||||||
}
|
}
|
||||||
/* ******************* 更新其他字段 ******************* */
|
/* ******************* 更新其他字段 ******************* */
|
||||||
String onlyMark = Util.getCusConfigValue(mappingConfigMark);
|
String onlyMark = Util.getCusConfigValue(mappingConfigMark);
|
||||||
|
if (StrUtil.isBlank(onlyMark)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
StageUpdateFieldConfig stageUpdateFieldConfig = mapper.selectConfigUpdate(onlyMark);
|
StageUpdateFieldConfig stageUpdateFieldConfig = mapper.selectConfigUpdate(onlyMark);
|
||||||
if (stageUpdateFieldConfig == null) {
|
if (stageUpdateFieldConfig == null) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
cus.logPath=/applog/tongweb/ecology_log/
|
|
@ -0,0 +1,54 @@
|
||||||
|
package youhong.ai.mymapper;
|
||||||
|
|
||||||
|
|
||||||
|
import aiyh.utils.annotation.recordset.SqlMapper;
|
||||||
|
import aiyh.utils.excention.BindingException;
|
||||||
|
import youhong.ai.mymapper.proxy.MyMapperProxy;
|
||||||
|
|
||||||
|
import java.lang.reflect.Proxy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <h1>myMapper工具类</h1>
|
||||||
|
*
|
||||||
|
* <p>create: 2023/3/15 14:04</p>
|
||||||
|
*
|
||||||
|
* @author youHong.ai
|
||||||
|
*/
|
||||||
|
public class MyMapper {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <h2>获取代理对象</h2>
|
||||||
|
*
|
||||||
|
* @param tClass 需要代理的对象的class
|
||||||
|
* @param autoCommit 是否自动提交,true -自动提交 false - 不自动提交开启事务
|
||||||
|
* @param <T> 范型
|
||||||
|
* @return 代理对象
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static <T> T getMapper(Class<T> tClass, boolean autoCommit) {
|
||||||
|
if (tClass == null) {
|
||||||
|
throw new BindingException("class is null!");
|
||||||
|
}
|
||||||
|
if (tClass.getAnnotation(SqlMapper.class) == null) {
|
||||||
|
throw new BindingException("can not find SqlMapper annotation!");
|
||||||
|
}
|
||||||
|
return (T) Proxy.newProxyInstance(
|
||||||
|
tClass.getClassLoader(),
|
||||||
|
new Class[]{tClass},
|
||||||
|
new MyMapperProxy(autoCommit)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <h2>获取代理对象</h2>
|
||||||
|
*
|
||||||
|
* @param tClass 需要代理的对象的class
|
||||||
|
* @param <T> 范型
|
||||||
|
* @return 代理对象
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static <T> T getMapper(Class<T> tClass) {
|
||||||
|
return getMapper(tClass, true);
|
||||||
|
}
|
||||||
|
}
|
|
@ -112,4 +112,11 @@ public class ParseSqlTest extends BaseTest {
|
||||||
SqlDefinition parse = parseSqlUtil.parse(sql, param);
|
SqlDefinition parse = parseSqlUtil.parse(sql, param);
|
||||||
System.out.println(JSON.toJSONString(parse));
|
System.out.println(JSON.toJSONString(parse));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testArrayClass() {
|
||||||
|
String[] strs = new String[0];
|
||||||
|
System.out.println(strs.getClass().getComponentType());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,4 +46,14 @@ public class CommandConsTant {
|
||||||
public static final String WHEN = "when";
|
public static final String WHEN = "when";
|
||||||
public static final String OTHERWISE = "otherwise";
|
public static final String OTHERWISE = "otherwise";
|
||||||
public static final String BIND = "bind";
|
public static final String BIND = "bind";
|
||||||
|
|
||||||
|
public static final String SELECT_SQL = "select";
|
||||||
|
|
||||||
|
public static final String UPDATE_SQL = "update";
|
||||||
|
|
||||||
|
public static final String DELETE_SQL = "delete";
|
||||||
|
|
||||||
|
public static final String INSERT_SQL = "insert";
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,4 +19,5 @@ import java.util.List;
|
||||||
public class SqlDefinition {
|
public class SqlDefinition {
|
||||||
private String sql;
|
private String sql;
|
||||||
private List<Object> args;
|
private List<Object> args;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,226 @@
|
||||||
|
package youhong.ai.mymapper.proxy;
|
||||||
|
|
||||||
|
import aiyh.utils.Util;
|
||||||
|
import aiyh.utils.annotation.recordset.*;
|
||||||
|
import aiyh.utils.excention.CustomerException;
|
||||||
|
import aiyh.utils.tool.cn.hutool.core.util.StrUtil;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import weaver.conn.RecordSet;
|
||||||
|
import weaver.conn.RecordSetTrans;
|
||||||
|
import weaver.conn.constant.DBConstant;
|
||||||
|
import youhong.ai.mymapper.command.constant.CommandConsTant;
|
||||||
|
import youhong.ai.mymapper.command.entity.SqlDefinition;
|
||||||
|
import youhong.ai.mymapper.proxy.entity.SqlAndExecuteType;
|
||||||
|
import youhong.ai.mymapper.proxy.entity.SqlDbTypeMapping;
|
||||||
|
import youhong.ai.mymapper.util.ParseSqlUtil;
|
||||||
|
|
||||||
|
import java.lang.annotation.Annotation;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.lang.reflect.Parameter;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <h1>代理执行</h1>
|
||||||
|
*
|
||||||
|
* <p>create: 2023/3/15 14:34</p>
|
||||||
|
*
|
||||||
|
* @author youHong.ai
|
||||||
|
*/
|
||||||
|
public class MapperProxyExecute {
|
||||||
|
|
||||||
|
private final Logger logger = Util.getLogger();
|
||||||
|
private final List<Class<? extends Annotation>> SELECT_LIST = Arrays.asList(Select.class, SelectOracle.class);
|
||||||
|
private final List<Class<? extends Annotation>> UPDATE_LIST = Arrays.asList(Update.class, UpdateOracle.class);
|
||||||
|
private final List<Class<? extends Annotation>> DELETE_LIST = Arrays.asList(Delete.class, DeleteOracle.class);
|
||||||
|
private final List<Class<? extends Annotation>> INSERT_LIST = Arrays.asList(Insert.class, InsertOracle.class);
|
||||||
|
|
||||||
|
private static final Map<String, SqlDbTypeMapping> INSERT_MAP = new HashMap<>();
|
||||||
|
private static final Map<String, SqlDbTypeMapping> SELECT_MAP = new HashMap<>();
|
||||||
|
private static final Map<String, SqlDbTypeMapping> DELETE_MAP = new HashMap<>();
|
||||||
|
private static final Map<String, SqlDbTypeMapping> UPDATE_MAP = new HashMap<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
INSERT_MAP.put(DBConstant.DB_TYPE_ORACLE,
|
||||||
|
SqlDbTypeMapping.builder()
|
||||||
|
.getSql(method -> method.getAnnotation(InsertOracle.class).value())
|
||||||
|
.isCustomer(method -> method.getAnnotation(InsertOracle.class).custom())
|
||||||
|
.build());
|
||||||
|
SELECT_MAP.put(DBConstant.DB_TYPE_ORACLE,
|
||||||
|
SqlDbTypeMapping.builder()
|
||||||
|
.getSql(method -> method.getAnnotation(SelectOracle.class).value())
|
||||||
|
.isCustomer(method -> method.getAnnotation(SelectOracle.class).custom())
|
||||||
|
.build());
|
||||||
|
DELETE_MAP.put(DBConstant.DB_TYPE_ORACLE,
|
||||||
|
SqlDbTypeMapping.builder()
|
||||||
|
.getSql(method -> method.getAnnotation(DeleteOracle.class).value())
|
||||||
|
.isCustomer(method -> method.getAnnotation(DeleteOracle.class).custom())
|
||||||
|
.build());
|
||||||
|
UPDATE_MAP.put(DBConstant.DB_TYPE_ORACLE,
|
||||||
|
SqlDbTypeMapping.builder()
|
||||||
|
.getSql(method -> method.getAnnotation(UpdateOracle.class).value())
|
||||||
|
.isCustomer(method -> method.getAnnotation(UpdateOracle.class).custom())
|
||||||
|
.build());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object execute(RecordSet rs, Method method, Object[] args) {
|
||||||
|
SqlAndExecuteType sqlAndExecuteType = null;
|
||||||
|
try {
|
||||||
|
sqlAndExecuteType = getSqlStr(rs.getDBType(), method, args);
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
logger.error(Util.getErrString(e));
|
||||||
|
throw new CustomerException("该方法没有正确添加注解!请检查是否正确添加注解!@Select、@Update、@Insert、@Delete、@BatchUpdate、@BatchInsert、@BatchDelete");
|
||||||
|
}
|
||||||
|
if (sqlAndExecuteType == null || StrUtil.isBlank(sqlAndExecuteType.getSql())) {
|
||||||
|
throw new CustomerException("can not find sql string and sql annotation in method: " +
|
||||||
|
method.getDeclaringClass().getName() + "." + method.getName());
|
||||||
|
}
|
||||||
|
Map<String, Object> sqlParam = getSqlParam(method, args);
|
||||||
|
ParseSqlUtil parseSqlUtil = new ParseSqlUtil();
|
||||||
|
SqlDefinition parse = parseSqlUtil.parse(sqlAndExecuteType.getSql(), sqlParam);
|
||||||
|
sqlAndExecuteType.setMethod(method);
|
||||||
|
sqlAndExecuteType.setArgs(parse.getArgs());
|
||||||
|
sqlAndExecuteType.setSql(parse.getSql());
|
||||||
|
sqlAndExecuteType.setRecordSet(rs);
|
||||||
|
return SqlExecutor.execute(sqlAndExecuteType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object execute(RecordSetTrans rs, Method method, Object[] args) {
|
||||||
|
SqlAndExecuteType sql = getSqlStr(rs.getDBType(), method, args);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private SqlAndExecuteType getSqlStr(String dbType, Method method, Object[] args) {
|
||||||
|
Annotation[] annotations = method.getAnnotations();
|
||||||
|
for (Annotation annotation : annotations) {
|
||||||
|
if (SELECT_LIST.contains(annotation.getClass())) {
|
||||||
|
// select 处理
|
||||||
|
return selectSql(dbType, method, args);
|
||||||
|
}
|
||||||
|
if (UPDATE_LIST.contains(annotation.getClass())) {
|
||||||
|
// update 处理
|
||||||
|
return updateSql(dbType, method, args);
|
||||||
|
}
|
||||||
|
if (DELETE_LIST.contains(annotation.getClass())) {
|
||||||
|
// delete 处理
|
||||||
|
return deleteSql(dbType, method, args);
|
||||||
|
}
|
||||||
|
if (INSERT_LIST.contains(annotation.getClass())) {
|
||||||
|
// insert 处理
|
||||||
|
return insertSql(dbType, method, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private SqlAndExecuteType insertSql(String dbType, Method method, Object[] args) {
|
||||||
|
SqlDbTypeMapping mapping = new SqlDbTypeMapping();
|
||||||
|
mapping.setIsCustomerDefaultSql(funMethod -> funMethod.getAnnotation(Insert.class).custom());
|
||||||
|
mapping.setGetDefaultSql(funMethod -> funMethod.getAnnotation(Insert.class).value());
|
||||||
|
mapping.setMappingMap(INSERT_MAP);
|
||||||
|
String sql = getSql(dbType, method, args, mapping);
|
||||||
|
SqlAndExecuteType sqlAndExecuteType = new SqlAndExecuteType();
|
||||||
|
sqlAndExecuteType.setSql(sql);
|
||||||
|
sqlAndExecuteType.setType(CommandConsTant.INSERT_SQL);
|
||||||
|
return sqlAndExecuteType;
|
||||||
|
}
|
||||||
|
|
||||||
|
private SqlAndExecuteType deleteSql(String dbType, Method method, Object[] args) {
|
||||||
|
SqlDbTypeMapping mapping = new SqlDbTypeMapping();
|
||||||
|
mapping.setIsCustomerDefaultSql(funMethod -> funMethod.getAnnotation(Delete.class).custom());
|
||||||
|
mapping.setGetDefaultSql(funMethod -> funMethod.getAnnotation(Delete.class).value());
|
||||||
|
mapping.setMappingMap(DELETE_MAP);
|
||||||
|
String sql = getSql(dbType, method, args, mapping);
|
||||||
|
SqlAndExecuteType sqlAndExecuteType = new SqlAndExecuteType();
|
||||||
|
sqlAndExecuteType.setSql(sql);
|
||||||
|
sqlAndExecuteType.setType(CommandConsTant.DELETE_SQL);
|
||||||
|
return sqlAndExecuteType;
|
||||||
|
}
|
||||||
|
|
||||||
|
private SqlAndExecuteType updateSql(String dbType, Method method, Object[] args) {
|
||||||
|
SqlDbTypeMapping mapping = new SqlDbTypeMapping();
|
||||||
|
mapping.setIsCustomerDefaultSql(funMethod -> funMethod.getAnnotation(Update.class).custom());
|
||||||
|
mapping.setGetDefaultSql(funMethod -> funMethod.getAnnotation(Update.class).value());
|
||||||
|
mapping.setMappingMap(UPDATE_MAP);
|
||||||
|
String sql = getSql(dbType, method, args, mapping);
|
||||||
|
SqlAndExecuteType sqlAndExecuteType = new SqlAndExecuteType();
|
||||||
|
sqlAndExecuteType.setSql(sql);
|
||||||
|
sqlAndExecuteType.setType(CommandConsTant.UPDATE_SQL);
|
||||||
|
return sqlAndExecuteType;
|
||||||
|
}
|
||||||
|
|
||||||
|
private SqlAndExecuteType selectSql(String dbType, Method method, Object[] args) {
|
||||||
|
SqlDbTypeMapping mapping = new SqlDbTypeMapping();
|
||||||
|
mapping.setIsCustomerDefaultSql(funMethod -> funMethod.getAnnotation(Select.class).custom());
|
||||||
|
mapping.setGetDefaultSql(funMethod -> funMethod.getAnnotation(Select.class).value());
|
||||||
|
mapping.setMappingMap(SELECT_MAP);
|
||||||
|
String sql = getSql(dbType, method, args, mapping);
|
||||||
|
SqlAndExecuteType sqlAndExecuteType = new SqlAndExecuteType();
|
||||||
|
sqlAndExecuteType.setSql(sql);
|
||||||
|
sqlAndExecuteType.setType(CommandConsTant.SELECT_SQL);
|
||||||
|
return sqlAndExecuteType;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private String getSql(String dbType,
|
||||||
|
Method method,
|
||||||
|
Object[] args,
|
||||||
|
SqlDbTypeMapping mapping) {
|
||||||
|
Function<Method, String> getDefaultSql = mapping.getGetDefaultSql();
|
||||||
|
Function<Method, Boolean> isCustomerDefaultSql = mapping.getIsCustomerDefaultSql();
|
||||||
|
Map<String, SqlDbTypeMapping> mappingMap = mapping.getMappingMap();
|
||||||
|
if (!mappingMap.containsKey(dbType)) {
|
||||||
|
if (isCustomerDefaultSql.apply(method)) {
|
||||||
|
return getSqlByParam(method, args);
|
||||||
|
}
|
||||||
|
return getDefaultSql.apply(method);
|
||||||
|
}
|
||||||
|
SqlDbTypeMapping sqlDbTypeMapping = mappingMap.get(dbType);
|
||||||
|
Function<Method, Boolean> isCustomer = sqlDbTypeMapping.getIsCustomer();
|
||||||
|
if (isCustomer.apply(method)) {
|
||||||
|
return getSqlByParam(method, args);
|
||||||
|
}
|
||||||
|
return sqlDbTypeMapping.getGetSql().apply(method);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private String getSqlByParam(Method method, Object[] args) {
|
||||||
|
Parameter[] parameters = method.getParameters();
|
||||||
|
for (int i = 0; i < parameters.length; i++) {
|
||||||
|
Parameter parameter = parameters[i];
|
||||||
|
if (parameter.isAnnotationPresent(SqlString.class)) {
|
||||||
|
Object sqlObj = args[i];
|
||||||
|
if (sqlObj instanceof String) {
|
||||||
|
return String.valueOf(sqlObj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new CustomerException("can not find sql string and sql annotation in method: " +
|
||||||
|
method.getDeclaringClass().getName() + "." + method.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Map<String, Object> getSqlParam(Method method, Object[] args) {
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
Parameter[] parameters = method.getParameters();
|
||||||
|
for (int i = 0; i < parameters.length; i++) {
|
||||||
|
Parameter parameter = parameters[i];
|
||||||
|
if (parameter.isAnnotationPresent(SqlString.class)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (parameter.isAnnotationPresent(ParamMapper.class)) {
|
||||||
|
ParamMapper annotation = parameter.getAnnotation(ParamMapper.class);
|
||||||
|
String name = annotation.value();
|
||||||
|
map.put(name, args[i]);
|
||||||
|
}
|
||||||
|
map.put("var" + i, args[i]);
|
||||||
|
map.put("param" + i, args[i]);
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,87 @@
|
||||||
|
package youhong.ai.mymapper.proxy;
|
||||||
|
|
||||||
|
import aiyh.utils.Util;
|
||||||
|
import aiyh.utils.recordset.RsThreadLocalManager;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import weaver.conn.RecordSet;
|
||||||
|
import weaver.conn.RecordSetTrans;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationHandler;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <h1>代理类</h1>
|
||||||
|
*
|
||||||
|
* <p>create: 2023/3/15 14:01</p>
|
||||||
|
*
|
||||||
|
* @author youHong.ai
|
||||||
|
*/
|
||||||
|
public class MyMapperProxy implements InvocationHandler {
|
||||||
|
|
||||||
|
public static final String SQL_LOG = "sql_log";
|
||||||
|
private final RsThreadLocalManager rsManager = new RsThreadLocalManager();
|
||||||
|
|
||||||
|
private final MapperProxyExecute mapperProxyExecute = new MapperProxyExecute();
|
||||||
|
private Logger logger = null;
|
||||||
|
|
||||||
|
private final boolean autoCommit;
|
||||||
|
|
||||||
|
public MyMapperProxy(boolean autoCommit) {
|
||||||
|
this.autoCommit = autoCommit;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object invoke(Object proxy, Method method, Object[] args) {
|
||||||
|
if (logger == null) {
|
||||||
|
logger = Util.getLogger(SQL_LOG);
|
||||||
|
|
||||||
|
}
|
||||||
|
if (this.autoCommit) {
|
||||||
|
return invokeRs(proxy, method, args, null);
|
||||||
|
}
|
||||||
|
return invokeTrans(proxy, method, args, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <h2>事务的代理对象</h2>
|
||||||
|
*
|
||||||
|
* @param proxy 代理对象
|
||||||
|
* @param method 执行方法
|
||||||
|
* @param args 方法参数
|
||||||
|
* @return 执行结果
|
||||||
|
*/
|
||||||
|
public Object invokeTrans(Object proxy, Method method, Object[] args, String name) {
|
||||||
|
String mapperKey = "myMapper:" + method.getDeclaringClass().getName();
|
||||||
|
if (!"".equals(name) && null != name) {
|
||||||
|
mapperKey += "." + name;
|
||||||
|
}
|
||||||
|
RecordSet rs = rsManager.getRs(mapperKey);
|
||||||
|
if (rs == null) {
|
||||||
|
rsManager.setRecordSet(mapperKey);
|
||||||
|
rs = rsManager.getRs(mapperKey);
|
||||||
|
}
|
||||||
|
return mapperProxyExecute.execute(rs, method, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <h2>代理对象</h2>
|
||||||
|
*
|
||||||
|
* @param proxy 代理对象
|
||||||
|
* @param method 执行方法
|
||||||
|
* @param args 方法参数
|
||||||
|
* @return 执行结果
|
||||||
|
*/
|
||||||
|
public Object invokeRs(Object proxy, Method method, Object[] args, String name) {
|
||||||
|
String mapperKey = "myMapper:" + method.getDeclaringClass().getName();
|
||||||
|
if (!"".equals(name) && null != name) {
|
||||||
|
mapperKey += "." + name;
|
||||||
|
}
|
||||||
|
RecordSetTrans rs = rsManager.getTrans(mapperKey);
|
||||||
|
if (rs == null) {
|
||||||
|
rsManager.setRecordSetTrans(mapperKey);
|
||||||
|
rs = rsManager.getTrans(mapperKey);
|
||||||
|
}
|
||||||
|
return mapperProxyExecute.execute(rs, method, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,99 @@
|
||||||
|
package youhong.ai.mymapper.proxy;
|
||||||
|
|
||||||
|
import aiyh.utils.annotation.MethodRuleNo;
|
||||||
|
import aiyh.utils.excention.CustomerException;
|
||||||
|
import aiyh.utils.tool.cn.hutool.core.collection.CollectionUtil;
|
||||||
|
import weaver.conn.RecordSet;
|
||||||
|
import youhong.ai.mymapper.command.constant.CommandConsTant;
|
||||||
|
import youhong.ai.mymapper.proxy.entity.SqlAndExecuteType;
|
||||||
|
import youhong.ai.mymapper.util.ResultMapperUtil;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <h1>sql执行器</h1>
|
||||||
|
*
|
||||||
|
* <p>create: 2023/3/15 17:33</p>
|
||||||
|
*
|
||||||
|
* @author youHong.ai
|
||||||
|
*/
|
||||||
|
public class SqlExecutor {
|
||||||
|
|
||||||
|
|
||||||
|
private static final Map<String, Function<SqlAndExecuteType, Object>> EXECUTE_MAP = new HashMap<>();
|
||||||
|
|
||||||
|
|
||||||
|
/* ******************* 初始化参数 ******************* */ static {
|
||||||
|
Class<SqlExecutor> valueRuleMethodClass = SqlExecutor.class;
|
||||||
|
Method[] methods = valueRuleMethodClass.getDeclaredMethods();
|
||||||
|
SqlExecutor factory = new SqlExecutor();
|
||||||
|
for (Method method : methods) {
|
||||||
|
method.setAccessible(true);
|
||||||
|
if (method.isAnnotationPresent(MethodRuleNo.class)) {
|
||||||
|
MethodRuleNo annotation = method.getAnnotation(MethodRuleNo.class);
|
||||||
|
String value = annotation.name();
|
||||||
|
EXECUTE_MAP.put(value, sqlDefinition -> {
|
||||||
|
try {
|
||||||
|
return method.invoke(factory, sqlDefinition);
|
||||||
|
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object execute(SqlAndExecuteType sqlDefinition) {
|
||||||
|
String executeType = sqlDefinition.getExecuteType();
|
||||||
|
if (!EXECUTE_MAP.containsKey(executeType)) {
|
||||||
|
throw new CustomerException("Unsupported sql execution type!" + executeType);
|
||||||
|
}
|
||||||
|
Function<SqlAndExecuteType, Object> fun = EXECUTE_MAP.get(executeType);
|
||||||
|
return fun.apply(sqlDefinition);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@MethodRuleNo(name = CommandConsTant.SELECT_SQL, desc = "查询sql执行方法")
|
||||||
|
private Object executeSelect(SqlAndExecuteType sqlDefinition) {
|
||||||
|
ResultMapperUtil resultMapperUtil = new ResultMapperUtil();
|
||||||
|
if (!sqlDefinition.isTrans()) {
|
||||||
|
RecordSet recordSet = sqlDefinition.getRecordSet();
|
||||||
|
List<Object> args = sqlDefinition.getArgs();
|
||||||
|
if (CollectionUtil.isEmpty(args)) {
|
||||||
|
recordSet.executeQuery(sqlDefinition.getSql());
|
||||||
|
} else {
|
||||||
|
recordSet.executeQuery(sqlDefinition.getSql(), args);
|
||||||
|
}
|
||||||
|
return resultMapperUtil.parseResult(sqlDefinition.getMethod(), recordSet);
|
||||||
|
} else {
|
||||||
|
// 事务查询
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@MethodRuleNo(name = CommandConsTant.INSERT_SQL, desc = "新增sql执行方法")
|
||||||
|
private Object executeInsert(SqlAndExecuteType sqlDefinition) {
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@MethodRuleNo(name = CommandConsTant.UPDATE_SQL, desc = "更新sql执行方法")
|
||||||
|
private Object executeUpdate(SqlAndExecuteType sqlDefinition) {
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@MethodRuleNo(name = CommandConsTant.DELETE_SQL, desc = "删除sql执行方法")
|
||||||
|
private Object executeDelete(SqlAndExecuteType sqlDefinition) {
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package youhong.ai.mymapper.proxy.entity;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import lombok.ToString;
|
||||||
|
import weaver.conn.RecordSet;
|
||||||
|
import weaver.conn.RecordSetTrans;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <h1>sql字符串和执行类型</h1>
|
||||||
|
*
|
||||||
|
* <p>create: 2023/3/15 16:48</p>
|
||||||
|
*
|
||||||
|
* @author youHong.ai
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@ToString
|
||||||
|
public class SqlAndExecuteType {
|
||||||
|
|
||||||
|
private String sql;
|
||||||
|
|
||||||
|
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
private List<Object> args;
|
||||||
|
|
||||||
|
private String executeType;
|
||||||
|
|
||||||
|
private Method method;
|
||||||
|
|
||||||
|
private RecordSet recordSet;
|
||||||
|
|
||||||
|
private RecordSetTrans recordSetTrans;
|
||||||
|
|
||||||
|
private boolean trans;
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package youhong.ai.mymapper.proxy.entity;
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <h1>sql类型映射</h1>
|
||||||
|
*
|
||||||
|
* <p>create: 2023/3/15 15:33</p>
|
||||||
|
*
|
||||||
|
* @author youHong.ai
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@ToString
|
||||||
|
@Builder
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class SqlDbTypeMapping {
|
||||||
|
|
||||||
|
|
||||||
|
private Function<Method, String> getDefaultSql;
|
||||||
|
private Function<Method, Boolean> isCustomerDefaultSql;
|
||||||
|
private Function<Method, Boolean> isCustomer;
|
||||||
|
private Function<Method, String> getSql;
|
||||||
|
|
||||||
|
private Map<String, SqlDbTypeMapping> mappingMap;
|
||||||
|
}
|
|
@ -0,0 +1,93 @@
|
||||||
|
package youhong.ai.mymapper.util;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <h1>构造者模式</h1>
|
||||||
|
*
|
||||||
|
* <p>create: 2022-11-26 16:46</p>
|
||||||
|
*
|
||||||
|
* @author youHong.ai
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class Builder<T> {
|
||||||
|
|
||||||
|
private Supplier<T> constructor;
|
||||||
|
|
||||||
|
private T target;
|
||||||
|
|
||||||
|
private final List<Consumer<T>> propertiesInjects = new ArrayList<>();
|
||||||
|
|
||||||
|
private Builder(Supplier<T> constructor) {
|
||||||
|
this.constructor = constructor;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Builder(T instance) {
|
||||||
|
this.target = instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <h2>获取建造者对象</h2>
|
||||||
|
*
|
||||||
|
* @param constructor 传入需要创造的对象的构造方法
|
||||||
|
* @param <T> 需要创造的对象的范型
|
||||||
|
* @return 建造者对象
|
||||||
|
*/
|
||||||
|
public static <T> Builder<T> builder(Supplier<T> constructor) {
|
||||||
|
return new Builder<T>(constructor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Builder<T> startSet(T instance) {
|
||||||
|
return new Builder<T>(instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <h2>设置值方法</h2>
|
||||||
|
*
|
||||||
|
* @param setFun 对象字段的set方法
|
||||||
|
* @param value 需要设置的值
|
||||||
|
* @param <V> 值的范型
|
||||||
|
* @return 当前建造者对象本省
|
||||||
|
*/
|
||||||
|
public <V> Builder<T> with(PropertiesInject<T, V> setFun, V value) {
|
||||||
|
Consumer<T> c = instance -> setFun.accept(instance, value);
|
||||||
|
propertiesInjects.add(c);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <h2>创建出目标对象</h2>
|
||||||
|
*
|
||||||
|
* @return 目标对象
|
||||||
|
*/
|
||||||
|
public T build() {
|
||||||
|
T instance;
|
||||||
|
if (this.target == null) {
|
||||||
|
instance = this.constructor.get();
|
||||||
|
} else {
|
||||||
|
instance = target;
|
||||||
|
}
|
||||||
|
this.propertiesInjects.forEach(inject -> inject.accept(instance));
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void endSet() {
|
||||||
|
T instance;
|
||||||
|
if (this.target == null) {
|
||||||
|
instance = this.constructor.get();
|
||||||
|
} else {
|
||||||
|
instance = target;
|
||||||
|
}
|
||||||
|
this.propertiesInjects.forEach(inject -> inject.accept(instance));
|
||||||
|
}
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface PropertiesInject<T, V> {
|
||||||
|
void accept(T setFun, V value);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,639 @@
|
||||||
|
package youhong.ai.mymapper.util;
|
||||||
|
|
||||||
|
import aiyh.utils.Util;
|
||||||
|
import aiyh.utils.annotation.recordset.*;
|
||||||
|
import aiyh.utils.excention.CustomerException;
|
||||||
|
import aiyh.utils.tool.cn.hutool.core.util.ArrayUtil;
|
||||||
|
import aiyh.utils.tool.cn.hutool.core.util.StrUtil;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import weaver.conn.RecordSet;
|
||||||
|
import weaver.conn.constant.DBConstant;
|
||||||
|
import youhong.ai.mymapper.proxy.MyMapperProxy;
|
||||||
|
|
||||||
|
import java.beans.BeanInfo;
|
||||||
|
import java.beans.IntrospectionException;
|
||||||
|
import java.beans.Introspector;
|
||||||
|
import java.beans.PropertyDescriptor;
|
||||||
|
import java.lang.reflect.*;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <h1>结果集映射</h1>
|
||||||
|
*
|
||||||
|
* <p>create: 2023/3/15 18:15</p>
|
||||||
|
*
|
||||||
|
* @author youHong.ai
|
||||||
|
*/
|
||||||
|
public class ResultMapperUtil {
|
||||||
|
public Object parseResult(Method method, RecordSet recordSet) {
|
||||||
|
Class<?> returnType = method.getReturnType();
|
||||||
|
if (void.class.equals(returnType)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (returnType.isArray()) {
|
||||||
|
return getArray(recordSet, method);
|
||||||
|
}
|
||||||
|
if (returnType.isPrimitive()) {
|
||||||
|
if (recordSet.next()) {
|
||||||
|
return getPrimitive(recordSet, method);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (Map.class.isAssignableFrom(returnType)) {
|
||||||
|
return getMap(recordSet, method, method.getGenericReturnType());
|
||||||
|
}
|
||||||
|
if (List.class.isAssignableFrom(returnType)) {
|
||||||
|
return getList(recordSet, method);
|
||||||
|
}
|
||||||
|
if (recordSet.next()) {
|
||||||
|
return getBean(recordSet, method);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object getPrimitive(RecordSet recordSet, Method method) {
|
||||||
|
Object value = null;
|
||||||
|
if (method.isAnnotationPresent(ResultMappings.class)) {
|
||||||
|
ResultMappings annotation = method.getAnnotation(ResultMappings.class);
|
||||||
|
ResultMap[] resultMaps = annotation.value();
|
||||||
|
if (ArrayUtil.isEmpty(resultMaps)) {
|
||||||
|
throw new CustomerException("ResultMappings must have a value of ResultMap!");
|
||||||
|
}
|
||||||
|
if (resultMaps.length > 1) {
|
||||||
|
throw new CustomerException("Multiple ResultMaps exist. A single method has only one return value");
|
||||||
|
}
|
||||||
|
ResultMap resultMap = resultMaps[0];
|
||||||
|
String column = resultMap.column();
|
||||||
|
value = recordSet.getString(column);
|
||||||
|
if (Objects.isNull(value)) {
|
||||||
|
value = recordSet.getString(column.toUpperCase());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (value == null) {
|
||||||
|
value = recordSet.getString(1);
|
||||||
|
}
|
||||||
|
return primitiveParseValue(method.getReturnType(), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object getArray(RecordSet recordSet, Method method) {
|
||||||
|
Class<?> returnType = method.getReturnType();
|
||||||
|
Class<?> componentType = returnType.getComponentType();
|
||||||
|
if (componentType.isArray()) {
|
||||||
|
throw new CustomerException("can not definition conversion rule of " + returnType);
|
||||||
|
}
|
||||||
|
List<Object> result = new ArrayList<>();
|
||||||
|
if (componentType.isPrimitive()) {
|
||||||
|
while (recordSet.next()) {
|
||||||
|
result.add(getPrimitive(recordSet, method));
|
||||||
|
}
|
||||||
|
} else if (Map.class.isAssignableFrom(componentType)) {
|
||||||
|
while (recordSet.next()) {
|
||||||
|
result.add(getMap(recordSet, method, method.getGenericReturnType()));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
while (recordSet.next()) {
|
||||||
|
result.add(getBean(recordSet, method));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (result.size() > 0) {
|
||||||
|
Object array = Array.newInstance(componentType, result.size());
|
||||||
|
for (int i = 0; i < result.size(); i++) {
|
||||||
|
Array.set(array, i, result.get(i));
|
||||||
|
}
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object getMap(RecordSet recordSet, Method method, Type genericReturnType) {
|
||||||
|
Class<?> keyClass = null;
|
||||||
|
Class<?> valueClass = null;
|
||||||
|
if (genericReturnType instanceof ParameterizedType) {
|
||||||
|
ParameterizedType genericType = (ParameterizedType) genericReturnType;
|
||||||
|
Type[] types = genericType.getActualTypeArguments();
|
||||||
|
for (int i = 0; i < types.length; i++) {
|
||||||
|
if (i == 0) {
|
||||||
|
keyClass = (Class<?>) types[i];
|
||||||
|
}
|
||||||
|
if (i == 2) {
|
||||||
|
valueClass = (Class<?>) types[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ResultMap[] resultMaps = null;
|
||||||
|
if (method.isAnnotationPresent(ResultMappings.class)) {
|
||||||
|
ResultMappings annotation = method.getAnnotation(ResultMappings.class);
|
||||||
|
resultMaps = annotation.value();
|
||||||
|
if (ArrayUtil.isEmpty(resultMaps)) {
|
||||||
|
throw new CustomerException("ResultMappings must have a value of ResultMap!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
if (keyClass == null && valueClass == null) {
|
||||||
|
if (resultMaps == null) {
|
||||||
|
getMapForRs(recordSet, result, method);
|
||||||
|
} else {
|
||||||
|
getMapForResultMaps(recordSet, resultMaps, result, method);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if (!String.class.equals(keyClass)) {
|
||||||
|
throw new CustomerException("result map key must be String! actually be " + keyClass);
|
||||||
|
}
|
||||||
|
if (resultMaps == null) {
|
||||||
|
getMapForRs(recordSet, result, method);
|
||||||
|
} else {
|
||||||
|
getMapForResultMaps(recordSet, resultMaps, result, method);
|
||||||
|
}
|
||||||
|
for (Map.Entry<String, Object> entry : result.entrySet()) {
|
||||||
|
entry.setValue(primitiveParseValue(valueClass, entry.getValue()));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void getMapForResultMaps(RecordSet recordSet, ResultMap[] resultMaps,
|
||||||
|
Map<String, Object> result, Method method) {
|
||||||
|
for (ResultMap resultMap : resultMaps) {
|
||||||
|
String property = resultMap.property();
|
||||||
|
Class<?> aClass = resultMap.javaType();
|
||||||
|
String column = resultMap.column();
|
||||||
|
String value = recordSet.getString(column);
|
||||||
|
if (Objects.isNull(value)) {
|
||||||
|
value = recordSet.getString(column.toUpperCase());
|
||||||
|
}
|
||||||
|
AssociationAndCollectionResult association = getAssociation(method, column, recordSet);
|
||||||
|
if (association.isParse()) {
|
||||||
|
Object parseValue = association.getValue();
|
||||||
|
result.put(property, parseValue);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
AssociationAndCollectionResult collection = getCollection(method, column, recordSet);
|
||||||
|
if (collection.isParse()) {
|
||||||
|
Object parseValue = collection.getValue();
|
||||||
|
result.put(property, parseValue);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
result.put(property, primitiveParseValue(aClass, value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void getMapForRs(RecordSet recordSet, Map<String, Object> result, Method method) {
|
||||||
|
String[] columnName = recordSet.getColumnName();
|
||||||
|
if (columnName == null || columnName.length == 0) {
|
||||||
|
throw new CustomerException("can not read columnName array for recordSet");
|
||||||
|
}
|
||||||
|
for (String column : columnName) {
|
||||||
|
String value = recordSet.getString(column);
|
||||||
|
if (Objects.isNull(value)) {
|
||||||
|
value = recordSet.getString(column.toUpperCase());
|
||||||
|
}
|
||||||
|
AssociationAndCollectionResult association = getAssociation(method, column, recordSet);
|
||||||
|
if (association.isParse()) {
|
||||||
|
Object parseValue = association.getValue();
|
||||||
|
result.put(column, parseValue);
|
||||||
|
result.put(column.toUpperCase(), parseValue);
|
||||||
|
result.put(column.toLowerCase(), parseValue);
|
||||||
|
result.put(Util.toCamelCase(column), parseValue);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
AssociationAndCollectionResult collection = getCollection(method, column, recordSet);
|
||||||
|
if (collection.isParse()) {
|
||||||
|
Object parseValue = collection.getValue();
|
||||||
|
result.put(column, parseValue);
|
||||||
|
result.put(column.toUpperCase(), parseValue);
|
||||||
|
result.put(column.toLowerCase(), parseValue);
|
||||||
|
result.put(Util.toCamelCase(column), parseValue);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
result.put(column, value);
|
||||||
|
result.put(column.toUpperCase(), value);
|
||||||
|
result.put(column.toLowerCase(), value);
|
||||||
|
result.put(Util.toCamelCase(column), value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Object getList(RecordSet recordSet, Method method) {
|
||||||
|
List<Object> result = new ArrayList<>();
|
||||||
|
Type genericReturnType = method.getGenericReturnType();
|
||||||
|
if (genericReturnType instanceof ParameterizedType) {
|
||||||
|
ParameterizedType parameterizedType = (ParameterizedType) genericReturnType;
|
||||||
|
Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
|
||||||
|
if (actualTypeArguments.length >= 1) {
|
||||||
|
Type actualTypeArgument = actualTypeArguments[0];
|
||||||
|
if (actualTypeArgument instanceof ParameterizedType) {
|
||||||
|
Type rawType = ((ParameterizedType) actualTypeArgument).getRawType();
|
||||||
|
Class<?> aClass = null;
|
||||||
|
try {
|
||||||
|
aClass = Class.forName(rawType.getTypeName());
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
throw new CustomerException("can not get generic type!", e);
|
||||||
|
}
|
||||||
|
if (aClass.isArray() || List.class.isAssignableFrom(aClass)) {
|
||||||
|
throw new CustomerException("Unsupported type!List<{}>", aClass.getName());
|
||||||
|
}
|
||||||
|
if (aClass.isPrimitive()) {
|
||||||
|
// 普通类型
|
||||||
|
while (recordSet.next()) {
|
||||||
|
Object primitive = getPrimitive(recordSet, method);
|
||||||
|
result.add(primitive);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if (Map.class.isAssignableFrom(aClass)) {
|
||||||
|
// map处理
|
||||||
|
while (recordSet.next()) {
|
||||||
|
Object map = getMap(recordSet, method, rawType);
|
||||||
|
result.add(map);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
// java bean 类型
|
||||||
|
while (recordSet.next()) {
|
||||||
|
Object bean = getBean(recordSet, method);
|
||||||
|
result.add(bean);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new CustomerException("can not get generic type!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new CustomerException("Return value of position type, unable to obtain method return generic type.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object getBean(RecordSet recordSet, Method method) {
|
||||||
|
Class<?> returnType = method.getReturnType();
|
||||||
|
BeanInfo beanInfo = null;
|
||||||
|
try {
|
||||||
|
beanInfo = Introspector.getBeanInfo(returnType, Object.class);
|
||||||
|
} catch (IntrospectionException e) {
|
||||||
|
throw new CustomerException(e);
|
||||||
|
}
|
||||||
|
Constructor<?> constructor = null;
|
||||||
|
try {
|
||||||
|
constructor = returnType.getConstructor();
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
throw new CustomerException("can not get no argument constructor on " + returnType);
|
||||||
|
}
|
||||||
|
Object obj = null;
|
||||||
|
try {
|
||||||
|
obj = constructor.newInstance();
|
||||||
|
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||||
|
throw new CustomerException("can not initialization bean of " + returnType);
|
||||||
|
}
|
||||||
|
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
|
||||||
|
for (PropertyDescriptor item : propertyDescriptors) {
|
||||||
|
String name = item.getName();
|
||||||
|
if (StrUtil.isBlank(name)) {
|
||||||
|
name = item.getDisplayName();
|
||||||
|
}
|
||||||
|
Method writeMethod = item.getWriteMethod();
|
||||||
|
Class<?> propertyType = item.getPropertyType();
|
||||||
|
AssociationAndCollectionResult association = getAssociation(method, name, recordSet);
|
||||||
|
if (association.isParse()) {
|
||||||
|
Object value = association.getValue();
|
||||||
|
if (value != null) {
|
||||||
|
try {
|
||||||
|
writeMethod.invoke(obj, value);
|
||||||
|
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||||
|
throw new CustomerException("invoke writeMethod fail ! {}.{}, target arg type:{}, value arg type: {}",
|
||||||
|
returnType.getName(), writeMethod.getName(), propertyType.getName(), value.getClass().getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
AssociationAndCollectionResult collection = getCollection(method, name, recordSet);
|
||||||
|
if (collection.isParse()) {
|
||||||
|
Object value = collection.getValue();
|
||||||
|
try {
|
||||||
|
writeMethod.invoke(obj, value);
|
||||||
|
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||||
|
throw new CustomerException("invoke writeMethod fail ! {}.{}, target arg type:{}, value arg type: {}",
|
||||||
|
returnType.getName(), writeMethod.getName(), propertyType.getName(), value.getClass().getName());
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Field declaredField = null;
|
||||||
|
try {
|
||||||
|
declaredField = returnType.getDeclaredField(name);
|
||||||
|
} catch (NoSuchFieldException e) {
|
||||||
|
throw new CustomerException("no such field {} in {}", name, returnType.getName());
|
||||||
|
}
|
||||||
|
String columnName = name;
|
||||||
|
Object value;
|
||||||
|
if (declaredField.isAnnotationPresent(SqlDbFieldAnn.class)) {
|
||||||
|
columnName = declaredField.getAnnotation(SqlDbFieldAnn.class).value();
|
||||||
|
}
|
||||||
|
boolean caseConversion = true;
|
||||||
|
|
||||||
|
if (DBConstant.DB_TYPE_ORACLE.equals(recordSet.getDBType())) {
|
||||||
|
caseConversion = false;
|
||||||
|
if (declaredField.isAnnotationPresent(SqlOracleDbFieldAnn.class)) {
|
||||||
|
columnName = declaredField.getAnnotation(SqlOracleDbFieldAnn.class).value();
|
||||||
|
}
|
||||||
|
value = recordSet.getString(columnName);
|
||||||
|
if (value != null) {
|
||||||
|
Object parseValue = primitiveParseValue(propertyType, value);
|
||||||
|
try {
|
||||||
|
writeMethod.invoke(obj, parseValue);
|
||||||
|
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||||
|
throw new CustomerException("invoke writeMethod fail ! {}.{}, target arg type:{}, value arg type: {}",
|
||||||
|
returnType.getName(), writeMethod.getName(), propertyType.getName(),
|
||||||
|
parseValue == null ? "" :
|
||||||
|
parseValue.getClass().getName());
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (method.isAnnotationPresent(CaseConversion.class)) {
|
||||||
|
caseConversion = method.getAnnotation(CaseConversion.class).value();
|
||||||
|
}
|
||||||
|
if (caseConversion) {
|
||||||
|
value = recordSet.getString(Util.toUnderlineCase(columnName));
|
||||||
|
Object parseValue = primitiveParseValue(propertyType, value);
|
||||||
|
try {
|
||||||
|
writeMethod.invoke(obj, parseValue);
|
||||||
|
continue;
|
||||||
|
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||||
|
throw new CustomerException("invoke writeMethod fail ! {}.{}, target arg type:{}, value arg type: {}",
|
||||||
|
returnType.getName(), writeMethod.getName(), propertyType.getName(),
|
||||||
|
parseValue == null ? "" :
|
||||||
|
parseValue.getClass().getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
value = recordSet.getString(columnName);
|
||||||
|
if (value != null) {
|
||||||
|
Object parseValue = primitiveParseValue(propertyType, value);
|
||||||
|
try {
|
||||||
|
writeMethod.invoke(obj, parseValue);
|
||||||
|
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||||
|
throw new CustomerException("invoke writeMethod fail ! {}.{}, target arg type:{}, value arg type: {}",
|
||||||
|
returnType.getName(), writeMethod.getName(), propertyType.getName(),
|
||||||
|
parseValue == null ? "" : parseValue.getClass().getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private AssociationAndCollectionResult getAssociation(Method method, String column, RecordSet recordSet) {
|
||||||
|
AssociationAndCollectionResult result = new AssociationAndCollectionResult();
|
||||||
|
if (method.isAnnotationPresent(Associations.class)) {
|
||||||
|
Associations associations = method.getAnnotation(Associations.class);
|
||||||
|
Association[] associationArray = associations.value();
|
||||||
|
for (Association item : associationArray) {
|
||||||
|
if (column.equalsIgnoreCase(item.property())) {
|
||||||
|
getAssociationAndCollectionResult(method, item.column(), recordSet, result, item, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private AssociationAndCollectionResult getCollection(Method method, String column,
|
||||||
|
RecordSet recordSet) {
|
||||||
|
AssociationAndCollectionResult result = new AssociationAndCollectionResult();
|
||||||
|
if (method.isAnnotationPresent(CollectionMappings.class)) {
|
||||||
|
CollectionMappings collectionMappings = method.getAnnotation(CollectionMappings.class);
|
||||||
|
CollectionMapping[] mappingArray = collectionMappings.value();
|
||||||
|
for (CollectionMapping item : mappingArray) {
|
||||||
|
if (column.equalsIgnoreCase(item.property())) {
|
||||||
|
getAssociationAndCollectionResult(method, item.column(), recordSet, result, null, item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private void getAssociationAndCollectionResult(Method method, String column,
|
||||||
|
RecordSet recordSet,
|
||||||
|
AssociationAndCollectionResult result,
|
||||||
|
Association association,
|
||||||
|
CollectionMapping collectionMapping) {
|
||||||
|
String select;
|
||||||
|
Id id;
|
||||||
|
String property;
|
||||||
|
if (association != null) {
|
||||||
|
select = association.select();
|
||||||
|
id = association.id();
|
||||||
|
property = association.property();
|
||||||
|
} else {
|
||||||
|
select = collectionMapping.select();
|
||||||
|
id = collectionMapping.id();
|
||||||
|
property = collectionMapping.property();
|
||||||
|
}
|
||||||
|
String value = recordSet.getString(column);
|
||||||
|
MyMapperProxy myMapperProxy = new MyMapperProxy(true);
|
||||||
|
if (StrUtil.isBlank(value)) {
|
||||||
|
value = recordSet.getString(column.toUpperCase());
|
||||||
|
}
|
||||||
|
Object parseValue = primitiveParseValue(id.value(), value);
|
||||||
|
if (id.methodId() == -1) {
|
||||||
|
// 自定义查询方法路径
|
||||||
|
customerSqlPathParseResult(method, result, collectionMapping, select, id, property, myMapperProxy, parseValue);
|
||||||
|
} else {
|
||||||
|
currentClassMethodParseResult(method, result, collectionMapping, id, property, myMapperProxy, parseValue);
|
||||||
|
if (!result.isParse()) {
|
||||||
|
if (collectionMapping == null) {
|
||||||
|
throw new CustomerException(Util.logStr("can not find AssociationMethod annotation in in class [{}] value of [{}]", method.getDeclaringClass(), id.methodId()));
|
||||||
|
} else {
|
||||||
|
throw new CustomerException(Util.logStr("can not find CollectionMethod annotation in in class [{}] value of [{}]", method.getDeclaringClass(), id.methodId()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void currentClassMethodParseResult(Method method,
|
||||||
|
AssociationAndCollectionResult result,
|
||||||
|
CollectionMapping collectionMapping,
|
||||||
|
Id id, String property,
|
||||||
|
MyMapperProxy myMapperProxy,
|
||||||
|
Object parseValue) {
|
||||||
|
Method[] methods = method.getDeclaringClass().getMethods();
|
||||||
|
for (Method innerMethod : methods) {
|
||||||
|
if (innerMethod.isAnnotationPresent(AssociationMethod.class) || innerMethod.isAnnotationPresent(CollectionMethod.class)) {
|
||||||
|
int methodId = -1;
|
||||||
|
if (collectionMapping == null) {
|
||||||
|
AssociationMethod methodAnnotation = innerMethod.getAnnotation(AssociationMethod.class);
|
||||||
|
methodId = methodAnnotation.value();
|
||||||
|
} else {
|
||||||
|
CollectionMethod methodAnnotation = innerMethod.getAnnotation(CollectionMethod.class);
|
||||||
|
methodId = methodAnnotation.value();
|
||||||
|
}
|
||||||
|
if (methodId != id.methodId()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Class<?> returnType = innerMethod.getReturnType();
|
||||||
|
if (collectionMapping == null) {
|
||||||
|
if (List.class.isAssignableFrom(returnType)) {
|
||||||
|
throw new CustomerException("can not set result, Associations annotation not support result of list! Do you want to use @CollectionMappings!");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!List.class.isAssignableFrom(returnType)) {
|
||||||
|
throw new CustomerException("can not set result, CollectionMappings annotation only support result of list! Do you want to use @Associations!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Object o = myMapperProxy.invokeRs(null, innerMethod, new Object[]{parseValue}, method.getName());
|
||||||
|
result.setParse(true);
|
||||||
|
result.setValue(o);
|
||||||
|
result.setProperty(property);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void customerSqlPathParseResult(Method method,
|
||||||
|
AssociationAndCollectionResult result,
|
||||||
|
CollectionMapping collectionMapping,
|
||||||
|
String select,
|
||||||
|
Id id, String property,
|
||||||
|
MyMapperProxy myMapperProxy,
|
||||||
|
Object parseValue) {
|
||||||
|
int i = select.lastIndexOf(".");
|
||||||
|
String selectClass = select.substring(0, i);
|
||||||
|
Class<?> aClass = null;
|
||||||
|
try {
|
||||||
|
aClass = Class.forName(selectClass);
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
throw new CustomerException("can not find class of " + selectClass);
|
||||||
|
}
|
||||||
|
Method associationMethod = null;
|
||||||
|
try {
|
||||||
|
associationMethod = aClass.getMethod(select.substring(i + 1), id.value());
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
throw new CustomerException("can not find method of " + select);
|
||||||
|
}
|
||||||
|
Class<?> returnType = associationMethod.getReturnType();
|
||||||
|
if (collectionMapping == null) {
|
||||||
|
if (List.class.isAssignableFrom(returnType)) {
|
||||||
|
throw new CustomerException("can not set result, Associations annotation not support result of list! Do you want to use @CollectionMappings!");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!List.class.isAssignableFrom(returnType)) {
|
||||||
|
throw new CustomerException("can not set result, CollectionMappings annotation only support result of list! Do you want to use @Associations!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Object o = myMapperProxy.invokeRs(null, associationMethod, new Object[]{parseValue}, method.getName());
|
||||||
|
result.setParse(true);
|
||||||
|
result.setValue(o);
|
||||||
|
result.setProperty(property);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Object primitiveParseValue(Class<?> aclass, Object obj) {
|
||||||
|
if (Number.class.isAssignableFrom(aclass)) {
|
||||||
|
return parseNumber(aclass, obj);
|
||||||
|
}
|
||||||
|
if (CharSequence.class.isAssignableFrom(aclass)) {
|
||||||
|
return parseCharSequence(aclass, obj);
|
||||||
|
}
|
||||||
|
if (Character.class.isAssignableFrom(aclass) || char.class.isAssignableFrom(aclass)) {
|
||||||
|
return obj == null ? null : String.valueOf(obj).charAt(0);
|
||||||
|
}
|
||||||
|
throw new CustomerException("can not definition conversion rule of " + aclass);
|
||||||
|
}
|
||||||
|
|
||||||
|
private CharSequence parseCharSequence(Class<?> aclass, Object obj) {
|
||||||
|
if (String.class.isAssignableFrom(aclass)) {
|
||||||
|
return obj == null ? null : String.valueOf(obj);
|
||||||
|
}
|
||||||
|
throw new CustomerException("can not definition conversion rule of " + aclass);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <h2>数字类型转换</h2>
|
||||||
|
*
|
||||||
|
* @param aclass 类型
|
||||||
|
* @param obj 待转换值
|
||||||
|
* @return 转换结果
|
||||||
|
*/
|
||||||
|
public static Number parseNumber(Class<?> aclass, Object obj) {
|
||||||
|
String value = Util.null2String(obj);
|
||||||
|
if ("".equals(value)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (int.class.isAssignableFrom(aclass) || Integer.class.isAssignableFrom(aclass)) {
|
||||||
|
return Integer.parseInt(value);
|
||||||
|
}
|
||||||
|
if (double.class.isAssignableFrom(aclass) || Double.class.isAssignableFrom(aclass)) {
|
||||||
|
return Double.parseDouble(value);
|
||||||
|
}
|
||||||
|
if (float.class.isAssignableFrom(aclass) || Float.class.isAssignableFrom(aclass)) {
|
||||||
|
return Float.parseFloat(value);
|
||||||
|
}
|
||||||
|
if (long.class.isAssignableFrom(aclass) || Long.class.isAssignableFrom(aclass)) {
|
||||||
|
return Long.parseLong(value);
|
||||||
|
}
|
||||||
|
if (byte.class.isAssignableFrom(aclass) || Byte.class.isAssignableFrom(aclass)) {
|
||||||
|
return Byte.parseByte(value);
|
||||||
|
}
|
||||||
|
if (short.class.isAssignableFrom(aclass) || Short.class.isAssignableFrom(aclass)) {
|
||||||
|
return Short.parseShort(value);
|
||||||
|
}
|
||||||
|
throw new CustomerException("can not definition conversion rule of " + aclass);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <h2>获取范型类型</h2>
|
||||||
|
*
|
||||||
|
* @param type 类型
|
||||||
|
* @return 范型
|
||||||
|
*/
|
||||||
|
public Class<?> getRawType(Type type) {
|
||||||
|
if (type instanceof Class) {
|
||||||
|
return (Class) type;
|
||||||
|
} else if (type instanceof ParameterizedType) {
|
||||||
|
ParameterizedType parameterizedType = (ParameterizedType) type;
|
||||||
|
Type rawType = parameterizedType.getRawType();
|
||||||
|
return (Class) rawType;
|
||||||
|
} else if (type instanceof GenericArrayType) {
|
||||||
|
Type componentType = ((GenericArrayType) type).getGenericComponentType();
|
||||||
|
return Array.newInstance(getRawType(componentType), 0).getClass();
|
||||||
|
} else if (type instanceof TypeVariable) {
|
||||||
|
return Object.class;
|
||||||
|
} else if (type instanceof WildcardType) {
|
||||||
|
return getRawType(((WildcardType) type).getUpperBounds()[0]);
|
||||||
|
} else {
|
||||||
|
String className = type == null ? "null" : type.getClass().getName();
|
||||||
|
throw new IllegalArgumentException("Expected a Class, ParameterizedType, or GenericArrayType, but <" + type + "> is of type " + className);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class AssociationAndCollectionResult {
|
||||||
|
private boolean isParse;
|
||||||
|
|
||||||
|
private Object value;
|
||||||
|
|
||||||
|
private String property;
|
||||||
|
|
||||||
|
public String getProperty() {
|
||||||
|
return property;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProperty(String property) {
|
||||||
|
this.property = property;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isParse() {
|
||||||
|
return isParse;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setParse(boolean parse) {
|
||||||
|
isParse = parse;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(Object value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
package youhong.ai.taibao;
|
package youhong.ai.taibao;
|
||||||
|
|
||||||
|
import aiyh.utils.Util;
|
||||||
import basetest.BaseTest;
|
import basetest.BaseTest;
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONArray;
|
||||||
|
@ -9,16 +10,18 @@ import com.cloudstore.dev.api.util.Util_DataCache;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import weaver.conn.RecordSet;
|
import weaver.conn.RecordSet;
|
||||||
import weaver.general.BaseBean;
|
import weaver.general.BaseBean;
|
||||||
import weaver.general.Util;
|
import weaver.general.GCONST;
|
||||||
import weaver.hrm.User;
|
import weaver.hrm.User;
|
||||||
import weaver.workflow.request.todo.OfsSettingObject;
|
import weaver.workflow.request.todo.OfsSettingObject;
|
||||||
import weaver.workflow.request.todo.RequestUtil;
|
import weaver.workflow.request.todo.RequestUtil;
|
||||||
import weaver.workflow.webservices.WorkflowBaseInfo;
|
import weaver.workflow.webservices.WorkflowBaseInfo;
|
||||||
import weaver.workflow.webservices.WorkflowRequestInfo;
|
import weaver.workflow.webservices.WorkflowRequestInfo;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <h1>测试</h1>
|
* <h1>测试</h1>
|
||||||
|
@ -32,6 +35,21 @@ public class TestTaiBao extends BaseTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test() {
|
public void test() {
|
||||||
|
String logPath = GCONST.getLogPath();
|
||||||
|
try {
|
||||||
|
Map<String, Object> map = Util.getProperties2Map("logPathConfig", "cus");
|
||||||
|
if (map != null) {
|
||||||
|
if (map.containsKey("logPath")) {
|
||||||
|
logPath = "".equals(Util.null2String(map.get("logPath"))) ? logPath : Util.null2String(map.get("logPath"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception ignore) {
|
||||||
|
|
||||||
|
}
|
||||||
|
if (!logPath.endsWith(File.separator)) {
|
||||||
|
logPath = logPath + File.separator;
|
||||||
|
}
|
||||||
|
System.out.println(logPath);
|
||||||
FunctionListService functionListService = new FunctionListService();
|
FunctionListService functionListService = new FunctionListService();
|
||||||
System.out.println(JSON.toJSONString(functionListService.getFunctionList(new User(90))));
|
System.out.println(JSON.toJSONString(functionListService.getFunctionList(new User(90))));
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
package youhong.ai.utiltest;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.ParameterizedType;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
||||||
|
public class GenericTest {
|
||||||
|
|
||||||
|
private final List<Map<String, Integer>> map = new ArrayList<>();
|
||||||
|
|
||||||
|
public static void main(String[] args) throws SecurityException, NoSuchFieldException {
|
||||||
|
// 获取Class实例
|
||||||
|
Class<GenericTest> class1 = GenericTest.class;
|
||||||
|
// 根据属性名取得该属性对应的Field对象
|
||||||
|
Field mapField = class1.getDeclaredField("map");
|
||||||
|
// 示范第一个方法:直接通过getType()取出Field的类型,只对普通类型的Field有效
|
||||||
|
Class<?> class2 = mapField.getType();
|
||||||
|
// 输出查看
|
||||||
|
System.out.println("属性名为map的属性类型为:" + class2);
|
||||||
|
|
||||||
|
// 示范第二种方法:
|
||||||
|
Type mapMainType = mapField.getGenericType();
|
||||||
|
// 为了确保安全转换,使用instanceof
|
||||||
|
if (mapMainType instanceof ParameterizedType) {
|
||||||
|
// 执行强制类型转换
|
||||||
|
ParameterizedType parameterizedType = (ParameterizedType) mapMainType;
|
||||||
|
// 获取基本类型信息,即Map
|
||||||
|
Type basicType = parameterizedType.getRawType();
|
||||||
|
System.out.println("基本类型为:" + basicType);
|
||||||
|
// 获取泛型类型的泛型参数
|
||||||
|
Type[] types = parameterizedType.getActualTypeArguments();
|
||||||
|
for (int i = 0; i < types.length; i++) {
|
||||||
|
Type type = types[i];
|
||||||
|
if (type instanceof ParameterizedType) {
|
||||||
|
ParameterizedType parameterizedTypeInner = (ParameterizedType) type;
|
||||||
|
System.out.println(parameterizedTypeInner.getRawType());
|
||||||
|
Type[] actualTypeArguments = parameterizedTypeInner.getActualTypeArguments();
|
||||||
|
for (Type actualTypeArgument : actualTypeArguments) {
|
||||||
|
Class<?> clazz = (Class<?>) actualTypeArgument;
|
||||||
|
System.out.println(clazz.getSimpleName());
|
||||||
|
System.out.println("泛型类型是:" + actualTypeArgument.getTypeName());
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Class<?> clazz = (Class<?>) type;
|
||||||
|
System.out.println(clazz.getSimpleName());
|
||||||
|
System.out.println("第" + (i + 1) + "个泛型类型是:" + types[i].getTypeName());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
System.out.println("获取泛型类型出错!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue