From e603fd7ad23c50710d024d14c40ae52d5a27f533 Mon Sep 17 00:00:00 2001 From: IT-xiaoXiong <774495953@qq.com> Date: Tue, 21 Dec 2021 16:25:16 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B0=81=E8=A3=85RecordSet=E4=B8=BA=E4=BD=8E?= =?UTF-8?q?=E9=85=8D=E6=AE=8B=E8=A1=80=E6=B3=A8=E8=A7=A3=E7=89=88mybatis?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- html/index.js | 24 ++ src/main/java/aiyh/utils/Util.java | 28 +++ .../annotation/recordset/CaseConversion.java | 14 ++ .../utils/annotation/recordset/Delete.java | 16 ++ .../utils/annotation/recordset/Insert.java | 16 ++ .../annotation/recordset/ParamMapper.java | 15 ++ .../utils/annotation/recordset/Select.java | 18 ++ .../utils/annotation/recordset/SqlMapper.java | 15 ++ .../utils/annotation/recordset/SqlString.java | 13 + .../utils/annotation/recordset/Update.java | 16 ++ .../utils/excention/BindingException.java | 13 + .../excention/MethodNotFindException.java | 13 + .../utils/excention/ParseSqlException.java | 13 + .../excention/TypeNonsupportException.java | 13 + .../utils/recordset/BooleanTypeHandler.java | 21 ++ .../aiyh/utils/recordset/DataTypeHandler.java | 27 ++ .../utils/recordset/IntegerTypeHandler.java | 21 ++ .../aiyh/utils/recordset/RecordsetUtil.java | 125 ++++++++++ .../aiyh/utils/recordset/ResultMapper.java | 206 ++++++++++++++++ .../java/aiyh/utils/recordset/SqlHandler.java | 233 ++++++++++++++++++ .../utils/recordset/StringTypeHandler.java | 21 ++ .../aiyh/utils/recordset/TypeHandler.java | 13 + .../sqlResult/impl/PrepSqlResultImpl.java | 8 + src/test/java/baseTest/BaseTest.java | 2 +- src/test/java/entity/ImageInfo.java | 19 ++ src/test/java/utilTest/ITestMapper.java | 46 ++++ src/test/java/utilTest/UtilTest.java | 171 +++++++++++++ 27 files changed, 1139 insertions(+), 1 deletion(-) create mode 100644 html/index.js create mode 100644 src/main/java/aiyh/utils/annotation/recordset/CaseConversion.java create mode 100644 src/main/java/aiyh/utils/annotation/recordset/Delete.java create mode 100644 src/main/java/aiyh/utils/annotation/recordset/Insert.java create mode 100644 src/main/java/aiyh/utils/annotation/recordset/ParamMapper.java create mode 100644 src/main/java/aiyh/utils/annotation/recordset/Select.java create mode 100644 src/main/java/aiyh/utils/annotation/recordset/SqlMapper.java create mode 100644 src/main/java/aiyh/utils/annotation/recordset/SqlString.java create mode 100644 src/main/java/aiyh/utils/annotation/recordset/Update.java create mode 100644 src/main/java/aiyh/utils/excention/BindingException.java create mode 100644 src/main/java/aiyh/utils/excention/MethodNotFindException.java create mode 100644 src/main/java/aiyh/utils/excention/ParseSqlException.java create mode 100644 src/main/java/aiyh/utils/excention/TypeNonsupportException.java create mode 100644 src/main/java/aiyh/utils/recordset/BooleanTypeHandler.java create mode 100644 src/main/java/aiyh/utils/recordset/DataTypeHandler.java create mode 100644 src/main/java/aiyh/utils/recordset/IntegerTypeHandler.java create mode 100644 src/main/java/aiyh/utils/recordset/RecordsetUtil.java create mode 100644 src/main/java/aiyh/utils/recordset/ResultMapper.java create mode 100644 src/main/java/aiyh/utils/recordset/SqlHandler.java create mode 100644 src/main/java/aiyh/utils/recordset/StringTypeHandler.java create mode 100644 src/main/java/aiyh/utils/recordset/TypeHandler.java create mode 100644 src/test/java/entity/ImageInfo.java create mode 100644 src/test/java/utilTest/ITestMapper.java create mode 100644 src/test/java/utilTest/UtilTest.java diff --git a/html/index.js b/html/index.js new file mode 100644 index 0000000..9d0762d --- /dev/null +++ b/html/index.js @@ -0,0 +1,24 @@ + +function changeSingedType(detailTable,detailField,changeField,errValue,rightValue){ + let detailIndexStr = WfForm.getDetailAllRowIndexStr(detailTable) + let changeFieldId = WfForm.convertFieldNameToId(changeField) + if(detailIndexStr == null){ + return + } + let detailIndexArr = detailIndexStr.split(","); + let detailFieldId = WfForm.convertFieldNameToId(detailField, detailTable); + let n = 0; + detailIndexArr.forEach(item=>{ + console.log(item) + let fieldId = detailFieldId + "_" + item + let value = WfForm.getFieldValue(fieldId); + console.log(value) + if(value == null || value == ""){ + WfForm.changeFieldValue(changeFieldId, {value:errValue}); + } + n ++ + }) + if(n == detaiIndexArr.length){ + WfForm.changeFieldValue(changeFieldId, {value:rightValue}); + } +} \ No newline at end of file diff --git a/src/main/java/aiyh/utils/Util.java b/src/main/java/aiyh/utils/Util.java index 1136641..f94c200 100644 --- a/src/main/java/aiyh/utils/Util.java +++ b/src/main/java/aiyh/utils/Util.java @@ -614,6 +614,10 @@ public class Util extends weaver.general.Util { //处理字符串 for (int i = 0, l = charArray.length; i < l; i++) { if (charArray[i] >= 65 && charArray[i] <= 90) { + if(i==0){ + buffer.append(charArray[i] += 32); + continue; + } buffer.append("_").append(charArray[i] += 32); } else { buffer.append(charArray[i]); @@ -1749,4 +1753,28 @@ public class Util extends weaver.general.Util { } return obj; } + + /** + * 获取完整的错误信息 + * @param throwable 异常 + * @return 完整堆栈信息 + */ + public static String getErrString(Throwable throwable){ + StringWriter stringWriter = new StringWriter(); + throwable.printStackTrace(new PrintWriter(stringWriter,true)); + new Thread(() -> { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + }finally { + try { + stringWriter.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + }); + return stringWriter.getBuffer().toString(); + } } diff --git a/src/main/java/aiyh/utils/annotation/recordset/CaseConversion.java b/src/main/java/aiyh/utils/annotation/recordset/CaseConversion.java new file mode 100644 index 0000000..d10900a --- /dev/null +++ b/src/main/java/aiyh/utils/annotation/recordset/CaseConversion.java @@ -0,0 +1,14 @@ +package aiyh.utils.annotation.recordset; + +import java.lang.annotation.*; + +/** + * @author @author EBU7-dev1-ay + * create 2021/12/21 0021 15:25 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +@Documented +public @interface CaseConversion { + boolean value() default true; +} diff --git a/src/main/java/aiyh/utils/annotation/recordset/Delete.java b/src/main/java/aiyh/utils/annotation/recordset/Delete.java new file mode 100644 index 0000000..3101586 --- /dev/null +++ b/src/main/java/aiyh/utils/annotation/recordset/Delete.java @@ -0,0 +1,16 @@ +package aiyh.utils.annotation.recordset; + +import java.lang.annotation.*; + +/** + * @author @author EBU7-dev1-ay + * create 2021/12/19 0019 15:08 + */ + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +@Documented +public @interface Delete { + String value() default ""; + boolean custom() default false; +} diff --git a/src/main/java/aiyh/utils/annotation/recordset/Insert.java b/src/main/java/aiyh/utils/annotation/recordset/Insert.java new file mode 100644 index 0000000..b8fa244 --- /dev/null +++ b/src/main/java/aiyh/utils/annotation/recordset/Insert.java @@ -0,0 +1,16 @@ +package aiyh.utils.annotation.recordset; + +import java.lang.annotation.*; + +/** + * @author @author EBU7-dev1-ay + * create 2021/12/19 0019 15:08 + */ + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +@Documented +public @interface Insert { + String value() default "" ; + boolean custom() default false; +} diff --git a/src/main/java/aiyh/utils/annotation/recordset/ParamMapper.java b/src/main/java/aiyh/utils/annotation/recordset/ParamMapper.java new file mode 100644 index 0000000..75f3e80 --- /dev/null +++ b/src/main/java/aiyh/utils/annotation/recordset/ParamMapper.java @@ -0,0 +1,15 @@ +package aiyh.utils.annotation.recordset; + +import java.lang.annotation.*; + +/** + * @author @author EBU7-dev1-ay + * create 2021/12/19 0019 15:20 + */ + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.PARAMETER) +@Documented +public @interface ParamMapper { + String value(); +} diff --git a/src/main/java/aiyh/utils/annotation/recordset/Select.java b/src/main/java/aiyh/utils/annotation/recordset/Select.java new file mode 100644 index 0000000..25388c6 --- /dev/null +++ b/src/main/java/aiyh/utils/annotation/recordset/Select.java @@ -0,0 +1,18 @@ +package aiyh.utils.annotation.recordset; + +import java.lang.annotation.*; + +/** + * @author @author EBU7-dev1-ay + * create 2021/12/19 0019 15:08 + */ + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +@Documented +public @interface Select { +// sql + String value() default ""; +// sql是否是在参数中 + boolean custom() default false; +} diff --git a/src/main/java/aiyh/utils/annotation/recordset/SqlMapper.java b/src/main/java/aiyh/utils/annotation/recordset/SqlMapper.java new file mode 100644 index 0000000..e0360bc --- /dev/null +++ b/src/main/java/aiyh/utils/annotation/recordset/SqlMapper.java @@ -0,0 +1,15 @@ +package aiyh.utils.annotation.recordset; + +import java.lang.annotation.*; + +/** + * @author @author EBU7-dev1-ay + * create 2021/12/19 0019 15:01 + */ + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +@Documented +public @interface SqlMapper { + +} diff --git a/src/main/java/aiyh/utils/annotation/recordset/SqlString.java b/src/main/java/aiyh/utils/annotation/recordset/SqlString.java new file mode 100644 index 0000000..ad0de4e --- /dev/null +++ b/src/main/java/aiyh/utils/annotation/recordset/SqlString.java @@ -0,0 +1,13 @@ +package aiyh.utils.annotation.recordset; + +import java.lang.annotation.*; + +/** + * @author @author EBU7-dev1-ay + * create 2021/12/19 0019 15:31 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.PARAMETER) +@Documented +public @interface SqlString { +} diff --git a/src/main/java/aiyh/utils/annotation/recordset/Update.java b/src/main/java/aiyh/utils/annotation/recordset/Update.java new file mode 100644 index 0000000..8e44950 --- /dev/null +++ b/src/main/java/aiyh/utils/annotation/recordset/Update.java @@ -0,0 +1,16 @@ +package aiyh.utils.annotation.recordset; + +import java.lang.annotation.*; + +/** + * @author @author EBU7-dev1-ay + * create 2021/12/19 0019 15:08 + */ + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +@Documented +public @interface Update { + String value() default ""; + boolean custom() default false; +} diff --git a/src/main/java/aiyh/utils/excention/BindingException.java b/src/main/java/aiyh/utils/excention/BindingException.java new file mode 100644 index 0000000..9ac8c92 --- /dev/null +++ b/src/main/java/aiyh/utils/excention/BindingException.java @@ -0,0 +1,13 @@ +package aiyh.utils.excention; + +/** + * @author EBU7-dev1-ayh + * create 2021/12/19 0019 14:51 + */ + + +public class BindingException extends RuntimeException{ + public BindingException(String msg){ + super(msg); + } +} diff --git a/src/main/java/aiyh/utils/excention/MethodNotFindException.java b/src/main/java/aiyh/utils/excention/MethodNotFindException.java new file mode 100644 index 0000000..ddbf522 --- /dev/null +++ b/src/main/java/aiyh/utils/excention/MethodNotFindException.java @@ -0,0 +1,13 @@ +package aiyh.utils.excention; + +/** + * @author EBU7-dev1-ayh + * create 2021/12/19 0019 19:33 + */ + + +public class MethodNotFindException extends RuntimeException{ + public MethodNotFindException(String msg){ + super(msg); + } +} diff --git a/src/main/java/aiyh/utils/excention/ParseSqlException.java b/src/main/java/aiyh/utils/excention/ParseSqlException.java new file mode 100644 index 0000000..a8a955a --- /dev/null +++ b/src/main/java/aiyh/utils/excention/ParseSqlException.java @@ -0,0 +1,13 @@ +package aiyh.utils.excention; + +/** + * @author EBU7-dev1-ayh + * create 2021/12/21 0021 10:33 + */ + + +public class ParseSqlException extends RuntimeException{ + public ParseSqlException(String message) { + super(message); + } +} diff --git a/src/main/java/aiyh/utils/excention/TypeNonsupportException.java b/src/main/java/aiyh/utils/excention/TypeNonsupportException.java new file mode 100644 index 0000000..4059569 --- /dev/null +++ b/src/main/java/aiyh/utils/excention/TypeNonsupportException.java @@ -0,0 +1,13 @@ +package aiyh.utils.excention; + +/** + * @author EBU7-dev1-ayh + * create 2021/12/19 0019 19:24 + */ + + +public class TypeNonsupportException extends RuntimeException{ + public TypeNonsupportException(String msg){ + super(msg); + } +} diff --git a/src/main/java/aiyh/utils/recordset/BooleanTypeHandler.java b/src/main/java/aiyh/utils/recordset/BooleanTypeHandler.java new file mode 100644 index 0000000..d8e0863 --- /dev/null +++ b/src/main/java/aiyh/utils/recordset/BooleanTypeHandler.java @@ -0,0 +1,21 @@ +package aiyh.utils.recordset; + +import weaver.conn.RecordSet; + +/** + * @author EBU7-dev1-ayh + * create 2021/12/21 0021 13:34 + */ + + +public class BooleanTypeHandler implements TypeHandler{ + @Override + public Object getValue(RecordSet rs, String fieldName) { + return rs.getBoolean(fieldName); + } + + @Override + public Object getValue(RecordSet rs, int index) { + return rs.getBoolean(index); + } +} diff --git a/src/main/java/aiyh/utils/recordset/DataTypeHandler.java b/src/main/java/aiyh/utils/recordset/DataTypeHandler.java new file mode 100644 index 0000000..ed9fc25 --- /dev/null +++ b/src/main/java/aiyh/utils/recordset/DataTypeHandler.java @@ -0,0 +1,27 @@ +package aiyh.utils.recordset; + +import weaver.conn.RecordSet; + +import java.util.Date; + +/** + * @author EBU7-dev1-ayh + * create 2021/12/21 0021 13:35 + */ + + +public class DataTypeHandler implements TypeHandler{ + @Override + public Object getValue(RecordSet rs, String fieldName) { + String dataString = rs.getString(fieldName); + Date date = new Date(dataString); + return date; + } + + @Override + public Object getValue(RecordSet rs, int index) { + String dataString = rs.getString(index); + Date date = new Date(dataString); + return date; + } +} diff --git a/src/main/java/aiyh/utils/recordset/IntegerTypeHandler.java b/src/main/java/aiyh/utils/recordset/IntegerTypeHandler.java new file mode 100644 index 0000000..e2def61 --- /dev/null +++ b/src/main/java/aiyh/utils/recordset/IntegerTypeHandler.java @@ -0,0 +1,21 @@ +package aiyh.utils.recordset; + +import weaver.conn.RecordSet; + +/** + * @author EBU7-dev1-ayh + * create 2021/12/21 0021 13:10 + */ + + +public class IntegerTypeHandler implements TypeHandler{ + @Override + public Object getValue(RecordSet rs, String fieldName) { + return rs.getInt(fieldName); + } + + @Override + public Object getValue(RecordSet rs, int index) { + return rs.getInt(index); + } +} diff --git a/src/main/java/aiyh/utils/recordset/RecordsetUtil.java b/src/main/java/aiyh/utils/recordset/RecordsetUtil.java new file mode 100644 index 0000000..6f5a612 --- /dev/null +++ b/src/main/java/aiyh/utils/recordset/RecordsetUtil.java @@ -0,0 +1,125 @@ +package aiyh.utils.recordset; + +import aiyh.utils.annotation.recordset.*; +import aiyh.utils.excention.BindingException; +import aiyh.utils.sqlUtil.sqlResult.impl.PrepSqlResultImpl; +import aiyh.utils.zwl.common.ToolUtil; +import weaver.conn.RecordSet; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + +/** + * @author EBU7-dev1-ayh + * create 2021/12/19 0019 14:39 + */ + + +public class RecordsetUtil implements InvocationHandler { + + private final ToolUtil toolUtil = new ToolUtil(); + + public T getMapper(Class tClass) { + 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}, this); + } + + + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + + SqlHandler sqlHandler = new SqlHandler(); + toolUtil.writeDebuggerLog(String.format("%s===>Preparing to parse SQL", proxy.getClass().getName())); + RecordSet rs = new RecordSet(); + ResultMapper resultMapper = new ResultMapper(); + Select select = method.getAnnotation(Select.class); + if (select != null) { +// 查询 + String sql = select.value(); + boolean custom = select.custom(); + PrepSqlResultImpl handler = sqlHandler.handler(sql, custom, method, args); + if (handler.getArgs().isEmpty()) { + rs.executeQuery(handler.getSqlStr()); + } else { + rs.executeQuery(handler.getSqlStr(), handler.getArgs()); + } + return resultMapper.mapperResult(rs, method, method.getReturnType()); + } + Update update = method.getAnnotation(Update.class); + + if (update != null) { +// 查询 + String sql = update.value(); + boolean custom = update.custom(); + PrepSqlResultImpl handler = sqlHandler.handler(sql, custom, method, args); + Class returnType = method.getReturnType(); + boolean b; + if (handler.getArgs().isEmpty()) { + b = rs.executeUpdate(handler.getSqlStr()); + } else { + b = rs.executeUpdate(handler.getSqlStr(), handler.getArgs()); + } + if (returnType.equals(void.class)) { + return null; + } + if (returnType.equals(int.class) || returnType.equals(Integer.class)) { + if (b) { + return 1; + } else { + return 0; + } + } + if (returnType.equals(boolean.class) || returnType.equals(Boolean.class)) { + return b; + } + } + Insert insert = method.getAnnotation(Insert.class); + if (insert != null) { +// 查询 + String sql = insert.value(); + boolean custom = insert.custom(); + PrepSqlResultImpl handler = sqlHandler.handler(sql, custom, method, args); + Class returnType = method.getReturnType(); + boolean b; + if (handler.getArgs().isEmpty()) { + b = rs.executeUpdate(handler.getSqlStr()); + } else { + b = rs.executeUpdate(handler.getSqlStr(), handler.getArgs()); + } + if (returnType.equals(void.class)) { + return null; + } + if (returnType.equals(boolean.class) || returnType.equals(Boolean.class)) { + return b; + } + } + Delete delete = method.getAnnotation(Delete.class); + if (delete != null) { +// 查询 + String sql = delete.value(); + boolean custom = delete.custom(); + PrepSqlResultImpl handler = sqlHandler.handler(sql, custom, method, args); + Class returnType = method.getReturnType(); + boolean b; + if (handler.getArgs().isEmpty()) { + b = rs.executeUpdate(handler.getSqlStr()); + } else { + b = rs.executeUpdate(handler.getSqlStr(), handler.getArgs()); + } + if (returnType.equals(void.class)) { + return null; + } + if (returnType.equals(boolean.class) || returnType.equals(Boolean.class)) { + return b; + } + } + return null; + } + +} diff --git a/src/main/java/aiyh/utils/recordset/ResultMapper.java b/src/main/java/aiyh/utils/recordset/ResultMapper.java new file mode 100644 index 0000000..efe7c36 --- /dev/null +++ b/src/main/java/aiyh/utils/recordset/ResultMapper.java @@ -0,0 +1,206 @@ +package aiyh.utils.recordset; + +import aiyh.utils.Util; +import aiyh.utils.annotation.recordset.CaseConversion; +import aiyh.utils.excention.TypeNonsupportException; +import weaver.conn.RecordSet; + +import java.beans.BeanInfo; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.lang.reflect.*; +import java.util.*; + +/** + * @author EBU7-dev1-ayh + * create 2021/12/21 0021 11:03 + */ + + +public class ResultMapper { + + private static Map, TypeHandler> typeHandler = new HashMap<>(); + + static { + IntegerTypeHandler integerTypeHandler = new IntegerTypeHandler(); + typeHandler.put(String.class, new StringTypeHandler()); + typeHandler.put(Integer.class, integerTypeHandler); + typeHandler.put(int.class, integerTypeHandler); + typeHandler.put(byte.class, integerTypeHandler); + typeHandler.put(short.class, integerTypeHandler); + typeHandler.put(long.class, integerTypeHandler); + typeHandler.put(Long.class, integerTypeHandler); + typeHandler.put(Boolean.class, new BooleanTypeHandler()); + typeHandler.put(boolean.class, new BooleanTypeHandler()); + typeHandler.put(Date.class, new StringTypeHandler()); + } + + public T mapperResult(RecordSet rs, Method method, Class tClass) { + if (tClass.equals(void.class)) { + return null; + } + try { + if (tClass.equals(List.class)) { + tClass = (Class) ArrayList.class; + } + if (tClass.equals(Map.class)) { + tClass = (Class) HashMap.class; + } + if (ResultMapper.typeHandler.containsKey(tClass)) { + rs.next(); + return (T) ResultMapper.typeHandler.get(tClass).getValue(rs, 1); + } + T t = tClass.newInstance(); + if (t instanceof Collection) { +// 集合求出泛型 + //获取返回值的类型 + Type genericReturnType = method.getGenericReturnType(); + Type actualTypeArgument = ((ParameterizedType) genericReturnType).getActualTypeArguments()[0]; + Class rawType = this.getRawType(actualTypeArgument); + if (rawType.equals(Map.class)) { + rawType = HashMap.class; + } + while (rs.next()) { + Object o = rawType.newInstance(); + Object object = getObject(rs, o,method); + ((Collection) t).add(object); + } + return t; + } + if (t instanceof Map) { +// map + Type genericReturnType = method.getGenericReturnType(); + Type actualTypeArgument = ((ParameterizedType) genericReturnType).getActualTypeArguments()[0]; + Class rawType = this.getRawType(actualTypeArgument); + if (rawType.equals(List.class)) { + rawType = (Class) ArrayList.class; + } + if (rawType.equals(Map.class)) { + rawType = HashMap.class; + } + Object o = rawType.newInstance(); + if (o instanceof Map || o instanceof Collection) { + throw new TypeNonsupportException("An unsupported return type!"); + } + rs.next(); + return (T) getObject(rs, t,method); + } + + if (t.getClass().isArray()) { + throw new TypeNonsupportException("An unsupported return type!"); + } + return (T) getObject(rs, t,method); + + } catch (InstantiationException | IllegalAccessException e) { + e.printStackTrace(); + } + return null; + } + + public Object getObject(RecordSet rs, Object o,Method method) { + CaseConversion annotation = method.getAnnotation(CaseConversion.class); + boolean enable = annotation == null ? true : annotation.value(); + String[] columnName = rs.getColumnName(); + String[] columnTypeName = rs.getColumnTypeName(); + try { + for (int i = 0; i < columnName.length; i++) { + String columnType = columnTypeName[i]; + if (o instanceof Map) { + if ("int".equalsIgnoreCase(columnType) || + "long".equalsIgnoreCase(columnType) || + "number".equalsIgnoreCase(columnType) || + "MEDIUMINT".equalsIgnoreCase(columnType) || + "TINYINT".equalsIgnoreCase(columnType) || + "SMALLINT".equalsIgnoreCase(columnType) || + "BIGINT".equalsIgnoreCase(columnType) || + "INTEGER".equalsIgnoreCase(columnType)) { + if(enable){ + ((Map) o).put(Util.toCamelCase(columnName[i]), rs.getInt(i + 1)); + continue; + } + ((Map) o).put(columnName[i], rs.getInt(i + 1)); + continue; + } + if ("FLOAT".equalsIgnoreCase(columnType) || + "DOUBLE".equalsIgnoreCase(columnType) || + "DECIMAL".equalsIgnoreCase(columnType)) { + if(enable){ + ((Map) o).put(Util.toCamelCase(columnName[i]), rs.getFloat(i + 1)); + continue; + } + ((Map) o).put(columnName[i], rs.getFloat(i + 1)); + continue; + } + if(enable){ + ((Map) o).put(Util.toCamelCase(columnName[i]), rs.getString(i + 1)); + } + ((Map) o).put(columnName[i], rs.getString(i + 1)); + continue; + } + if (o instanceof Collection) { + throw new TypeNonsupportException("An unsupported return type!"); + } + if (o instanceof Number) { + if ("int".equalsIgnoreCase(columnType) || + "long".equalsIgnoreCase(columnType) || + "number".equalsIgnoreCase(columnType) || + "MEDIUMINT".equalsIgnoreCase(columnType) || + "TINYINT".equalsIgnoreCase(columnType) || + "SMALLINT".equalsIgnoreCase(columnType) || + "BIGINT".equalsIgnoreCase(columnType) || + "INTEGER".equalsIgnoreCase(columnType)) { + return rs.getInt(i + 1); + } + if ("FLOAT".equalsIgnoreCase(columnType) || + "DOUBLE".equalsIgnoreCase(columnType) || + "DECIMAL".equalsIgnoreCase(columnType)) { + return rs.getFloat(i + 1); + } + } + if (o instanceof String) { + return rs.getString(i + 1); + } + if (o instanceof Boolean) { + return rs.getBoolean(i + 1); + } + BeanInfo beanInfo = Introspector.getBeanInfo(o.getClass(), Object.class); + PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); + for (PropertyDescriptor propertyDescriptor : propertyDescriptors) { + Class propertyType = propertyDescriptor.getPropertyType(); + Object value = null; + if(enable){ + value = ResultMapper.typeHandler.get(propertyType).getValue(rs, Util.toUnderlineCase(propertyDescriptor.getName())); + }else { + value = ResultMapper.typeHandler.get(propertyType).getValue(rs, propertyDescriptor.getName()); + } + propertyDescriptor.getWriteMethod().invoke(o, value); + } + + } + + } catch (Exception e) { + e.printStackTrace(); + } + return o; + } + + 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); + } + } +} diff --git a/src/main/java/aiyh/utils/recordset/SqlHandler.java b/src/main/java/aiyh/utils/recordset/SqlHandler.java new file mode 100644 index 0000000..f8fce8b --- /dev/null +++ b/src/main/java/aiyh/utils/recordset/SqlHandler.java @@ -0,0 +1,233 @@ +package aiyh.utils.recordset; + +import aiyh.utils.annotation.recordset.ParamMapper; +import aiyh.utils.annotation.recordset.SqlString; +import aiyh.utils.excention.BindingException; +import aiyh.utils.excention.MethodNotFindException; +import aiyh.utils.excention.ParseSqlException; +import aiyh.utils.sqlUtil.sqlResult.impl.PrepSqlResultImpl; +import org.apache.commons.lang3.StringUtils; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * @author EBU7-dev1-ayh + * create 2021/12/19 0019 15:28 + */ + + +public class SqlHandler { + + List sqlArgs = new ArrayList<>(); + + public PrepSqlResultImpl handler(String sql, boolean custom, Method method, Object[] args) { + String findSql = findSql(sql, custom, method, args); + Map methodArgNameMap = buildMethodArgNameMap(method, args); +// 处理基本类型以及包装类 + String parse; + if (methodArgNameMap.size() == 0) { + return new PrepSqlResultImpl(sql, sqlArgs); + } + if (methodArgNameMap.size() == 1) { + if (!custom) { + Optional first = methodArgNameMap.values().stream().findFirst(); + parse = parse(findSql, first.get()); + } else { + return new PrepSqlResultImpl(sql, sqlArgs); + } + } else if (methodArgNameMap.size() == 2 && custom) { + int index = findArg(method); + parse = parse(findSql, args[index]); + } else { + parse = parse(findSql, methodArgNameMap); + + } + return new PrepSqlResultImpl(parse, sqlArgs); + } + + private int findArg(Method method) { + Parameter[] parameters = method.getParameters(); + for (int i = 0; i < parameters.length; i ++) { + Parameter parameter = parameters[i]; + SqlString annotation = parameter.getAnnotation(SqlString.class); + if(annotation == null){ + return i; + } + } + throw new BindingException("Wrong parameter annotation, cannot have two SQL string annotations!"); + } + + + private String findSql(String sql, boolean custom, Method method, Object[] args) { + String parsing = sql; + if (custom) { +// 自定义 + Parameter[] parameters = method.getParameters(); + try { + if (parameters.length == 0) { + throw new BindingException("cant not find sql parameter! this parameters is nothing!"); + } + } catch (NullPointerException e) { + throw new BindingException("cant not find sql parameter! this parameters is nothing!"); + } + for (int i = 0; i < parameters.length; i++) { + Parameter parameter = parameters[i]; + Object arg = args[i]; + Class type = parameter.getType(); + SqlString sqlAnnotation = parameter.getAnnotation(SqlString.class); + if (sqlAnnotation != null && type.equals(String.class)) { + try { + parsing = arg.toString(); + } catch (NullPointerException e) { + throw new BindingException("sql String param is null!"); + } + break; + } + } + } + return parsing; + } + + private Map buildMethodArgNameMap(Method method, Object[] args) { + Parameter[] parameters = method.getParameters(); + Map params = new HashMap<>(); +// 参数处理 + try { + for (int i = 0; i < parameters.length; i++) { + Parameter parameter = parameters[i]; + Object arg = args[i]; + String name = parameter.getName(); + Class type = parameter.getType(); + SqlString sqlAnnotation = parameter.getAnnotation(SqlString.class); + ParamMapper paramAnnotation = parameter.getAnnotation(ParamMapper.class); + if (sqlAnnotation != null && type.equals(String.class)) { + continue; + } + if (paramAnnotation != null) { + params.put(paramAnnotation.value(), arg); + continue; + } + params.put(name, arg); + } + } catch (NullPointerException e) { + throw new BindingException("cant not find sql parameter! this parameters is nothing!"); + } + return params; + } + + private String parse(String sql, Object arg) { + String parseSql = sql; + String pattern = "\\$\\{\\s*(?(?\\w+)(\\.?(?\\S+))*)\\s*}"; + Pattern compile = Pattern.compile(pattern); + Matcher matcher = compile.matcher(parseSql); + while (matcher.find()) { + String regx = matcher.group("regx"); + String field = matcher.group("field"); + String other = matcher.group("other"); + Object value = getValueByRegx(regx, field, other, arg, false); + parseSql = parseSql.replaceFirst(pattern, value.toString()); + } + pattern = "#\\{\\s*(?(?\\w+)(\\.?(?\\S+))*)\\s*}"; + compile = Pattern.compile(pattern); + matcher = compile.matcher(parseSql); + while (matcher.find()) { + String regx = matcher.group("regx"); + String field = matcher.group("field"); + String other = matcher.group("other"); + Object value = getValueByRegx(regx, field, other, arg, true); + parseSql = parseSql.replaceFirst(pattern, "?"); + sqlArgs.add(value); + } + return parseSql; + } + + private Object getValueByRegx(String regx, String field, String other, Object arg, boolean isEscape) { + if (!regx.contains(".")) { + return valueHandler(arg, field, isEscape); + } + String pattern = "(?\\w+)\\.*(?(\\S+)*)"; + Pattern compile = Pattern.compile(pattern); + Matcher matcher = compile.matcher(other); + Object o = valueHandler(arg, field, isEscape); + if (matcher.find()) { + String innerField = matcher.group("field"); + String innerOther = matcher.group("other"); + return getValueByRegx(other, innerField, innerOther, o, isEscape); + } +// return getValueByRegx(other,) + throw new BindingException("Unable to find value " + other); + } + + + private Object valueHandler(Object arg, String key, boolean isEscape) { + if (arg instanceof Number) { +// 处理数字类型 + return arg; + } + if (arg instanceof Boolean) { +// 处理布尔类型 + return arg; + } + if (arg instanceof Character || arg instanceof String) { +// 处理字符类型 + if (isEscape) { + return arg; + } else { + return "'" + arg + "'"; + } + } + if (arg.getClass().isArray()) { +// throw new TypeNonsupportException("A value is expected, but a set is received!"); + return StringUtils.join(Collections.singletonList(arg), ","); + } + // 判断参数类型 + if (arg instanceof Collection) { +// list +// throw new TypeNonsupportException("A value is expected, but a set is received!"); + return StringUtils.join((Collection)arg, ","); + } + if (arg instanceof Map) { +// map + if (!((Map) arg).containsKey(key)) { + throw new ParseSqlException("Failed to find {" + key + "} related field after parsing exception!"); + } + Object o = ((Map) arg).get(key); + if (o instanceof Character || o instanceof String) { +// 处理字符类型 + if (isEscape) { + return o; + } else { + return "'" + o + "'"; + } + } + return o; + } + String methodName = "get" + key.substring(0, 1).toUpperCase() + key.substring(1); +// 当做javaBean处理 + try { + + Method method = arg.getClass().getMethod(methodName); + Object invoke = method.invoke(arg); + if (invoke instanceof Character || invoke instanceof String) { +// 处理字符类型 + if (isEscape) { + return invoke; + } else { + return "'" + invoke + "'"; + } + } + return invoke; + } catch (NoSuchMethodException e) { +// e.printStackTrace(); + throw new MethodNotFindException(methodName + " is not find!"); + } catch (InvocationTargetException | IllegalAccessException e) { + e.printStackTrace(); + throw new RuntimeException(e.toString()); + } + } +} diff --git a/src/main/java/aiyh/utils/recordset/StringTypeHandler.java b/src/main/java/aiyh/utils/recordset/StringTypeHandler.java new file mode 100644 index 0000000..5a55e78 --- /dev/null +++ b/src/main/java/aiyh/utils/recordset/StringTypeHandler.java @@ -0,0 +1,21 @@ +package aiyh.utils.recordset; + +import weaver.conn.RecordSet; + +/** + * @author EBU7-dev1-ayh + * create 2021/12/21 0021 13:06 + */ + + +public class StringTypeHandler implements TypeHandler{ + @Override + public Object getValue(RecordSet rs, String fieldName) { + return rs.getString(fieldName); + } + + @Override + public Object getValue(RecordSet rs, int index) { + return rs.getString(index); + } +} diff --git a/src/main/java/aiyh/utils/recordset/TypeHandler.java b/src/main/java/aiyh/utils/recordset/TypeHandler.java new file mode 100644 index 0000000..716b700 --- /dev/null +++ b/src/main/java/aiyh/utils/recordset/TypeHandler.java @@ -0,0 +1,13 @@ +package aiyh.utils.recordset; + +import weaver.conn.RecordSet; + +/** + * @author @author EBU7-dev1-ay + * create 2021/12/21 0021 13:05 + */ + +public interface TypeHandler { + Object getValue(RecordSet rs,String fieldName); + Object getValue(RecordSet rs,int index); +} diff --git a/src/main/java/aiyh/utils/sqlUtil/sqlResult/impl/PrepSqlResultImpl.java b/src/main/java/aiyh/utils/sqlUtil/sqlResult/impl/PrepSqlResultImpl.java index d41b15b..4c6e478 100644 --- a/src/main/java/aiyh/utils/sqlUtil/sqlResult/impl/PrepSqlResultImpl.java +++ b/src/main/java/aiyh/utils/sqlUtil/sqlResult/impl/PrepSqlResultImpl.java @@ -27,4 +27,12 @@ public class PrepSqlResultImpl implements SqlResult { public List getArgs() { return args; } + + @Override + public String toString() { + return "PrepSqlResultImpl{" + + "sqlStr='" + sqlStr + '\'' + + ", args=" + args + + '}'; + } } diff --git a/src/test/java/baseTest/BaseTest.java b/src/test/java/baseTest/BaseTest.java index b4081d8..cc232bf 100644 --- a/src/test/java/baseTest/BaseTest.java +++ b/src/test/java/baseTest/BaseTest.java @@ -15,7 +15,7 @@ public class BaseTest { @Before public void before() { weaver.general.GCONST.setServerName("ecology"); - weaver.general.GCONST.setRootPath("H:\\ecology-weaver\\web\\"); + weaver.general.GCONST.setRootPath("H:\\ecology-9-dev\\src\\main\\resources"); } @Test diff --git a/src/test/java/entity/ImageInfo.java b/src/test/java/entity/ImageInfo.java new file mode 100644 index 0000000..de3846f --- /dev/null +++ b/src/test/java/entity/ImageInfo.java @@ -0,0 +1,19 @@ +package entity; + +import lombok.Data; + +/** + * @author EBU7-dev1-ayh + * create 2021/12/21 0021 15:12 + */ + +@Data +public class ImageInfo { + private Integer id; + private Integer docId; + private String operateDate; + private String operateTime; + private Integer imageFileId; + private String imageFileName; + +} diff --git a/src/test/java/utilTest/ITestMapper.java b/src/test/java/utilTest/ITestMapper.java new file mode 100644 index 0000000..0c25b91 --- /dev/null +++ b/src/test/java/utilTest/ITestMapper.java @@ -0,0 +1,46 @@ +package utilTest; + +import aiyh.utils.annotation.recordset.*; +import entity.ImageInfo; +import mybatisTest.entity.License; + +import java.util.List; +import java.util.Map; + +/** + * @author @author EBU7-dev1-ay + * create 2021/12/19 0019 17:24 + */ +@SqlMapper +public interface ITestMapper { + @Select("select * from laji where id = #{idparam} and " + + "name = #{name} or age > #{age} and loginid = #{map.loginid}") + Object selectOne(@ParamMapper("idparam") String id, String name, int age, + @ParamMapper("map") Map map); + + @Select(custom = true) + void selectOne(@SqlString String sql,String name); + + @Select("select * from lj where id = #{id} and name like #{nameLike} and age > #{age}") + Object selectOne(@ParamMapper("id") String id, + @ParamMapper("nameLike") String nameLike, + @ParamMapper("age") int age); + + @Select("select * from table where id = #{id} and name like #{nameLike} and age > ${age}" + + " and account = #{user.account} or userid = {user.uID}") + Object selectOne(Map map); + + @Select("select companyname company_name,license,expiredate expire_date,CVERSION c_version from license;") + License selectOne(); + + @Select("select imagefileid image_file_id,imagefilename image_file_name," + + "docid doc_id,id,operatedate operate_date,operatetime operate_time" + + " from docimagefile where docid in (${list})") + List> selectList(List list); + + + @Update("update hrmresource set email = #{email} where id > #{min} and id < #{max}") + void updateEmail(@ParamMapper("email") String email, + @ParamMapper("min") int min, + @ParamMapper("max") int max); +} diff --git a/src/test/java/utilTest/UtilTest.java b/src/test/java/utilTest/UtilTest.java new file mode 100644 index 0000000..63afd39 --- /dev/null +++ b/src/test/java/utilTest/UtilTest.java @@ -0,0 +1,171 @@ +package utilTest; + +import aiyh.utils.recordset.RecordsetUtil; +import entity.ImageInfo; +import mybatisTest.entity.License; +import org.apache.commons.lang3.StringUtils; +import org.junit.Before; +import org.junit.Test; +import weaver.hrm.User; + +import java.lang.reflect.*; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * @author EBU7-dev1-ayh + * create 2021/12/19 0019 14:41 + */ + + +public class UtilTest { + + @Before + public void before() { + weaver.general.GCONST.setServerName("ecology"); + weaver.general.GCONST.setRootPath("H:\\ecology-9-dev\\src\\main\\resources\\"); + } + + @Test + public void test() { + int i = 0; + testInstanceOfType(i); + Integer j = 10; + testInstanceOfType(j); + } + + public void testInstanceOfType(Object obj) { + System.out.println(obj.getClass().isPrimitive()); + System.out.println(obj instanceof Number); + } + + + @Test + public void testRecordsetUtil() { + RecordsetUtil recordsetUtil = new RecordsetUtil(); + ITestMapper mapper = recordsetUtil.getMapper(ITestMapper.class); +// User user = new User(); +// user.setUid(1002); +// user.setAccount("aiyh"); +// Map map = new HashMap() { +// { +// put("id", 10); +// put("nameLike", "%不知道%"); +// put("age", 20); +// put("user", user); +// } +// }; +// Object o = mapper.selectOne(map); +// o = mapper.selectOne(); +// o = mapper.selectOne("234", "%好的吧%", 30); +// System.out.println(o); +// License stringObjectMap = mapper.selectOne(); +// System.out.println(stringObjectMap); +// List> imageInfos = mapper.selectList(new ArrayList(){{ +// add(1); +// add(2); +// add(3); +// add(4); +// }}); +// System.out.println(imageInfos); + mapper.updateEmail("1234567@qq.com",20,40); + } + + + @Test + public void testTypeMethod() throws NoSuchMethodException, InstantiationException, IllegalAccessException { + Method getList = this.getClass().getMethod("getList"); + Class returnType = getList.getReturnType(); + + System.out.println(returnType.equals(void.class)); + //获取返回值的类型 + Type genericReturnType = getList.getGenericReturnType(); + //获取返回值的泛型参数 + Type actualTypeArgument = ((ParameterizedType) genericReturnType).getActualTypeArguments()[0]; + Class rawType = getRawType(actualTypeArgument); + if(rawType.equals(Map.class)){ + rawType = HashMap.class; + } + Object o = rawType.newInstance(); + System.out.println(rawType); + System.out.println( o); + // Class type = (Class) actualTypeArgument.getClass().newInstance(); +// System.out.println(type); + } + + public static 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); + } + } + + + public void getList() { + return; + } + + @Test + public void testType() { + Map map = new HashMap<>(); + map.put("hh", 1); + map.put("hl", false); + map.put("hList", new ArrayList()); + map.put("hMap", new HashMap()); + for (Map.Entry entry : map.entrySet()) { + System.out.println(entry.getKey() + "==========" + entry.getValue()); + System.out.println(entry.getValue() instanceof Number); + System.out.println(entry.getValue() instanceof Collection); + System.out.println(entry.getValue() instanceof Map); + } + } + + @Test + public void testRegx() { + String parse = "select * from laj where id = ${ id.public }"; + String pattern = "\\$\\{\\s*(?(?\\w+)(\\.?(?\\S+))*)\\s*}"; + Pattern compile = Pattern.compile(pattern); + Matcher matcher = compile.matcher(parse); + if (matcher.find()) { + System.out.println(matcher.group("regx")); + System.out.println(matcher.group("field")); + System.out.println(matcher.group("other")); + } + } + + @Test + public void testRegx1() { + ArrayList integers = new ArrayList() {{ + add(1); + add(2); + add(3); + add(4); + }}; + System.out.println(StringUtils.join(integers,",")); + String parse = "id.public.test.omg"; + String pattern = "(?\\w+)\\.*(?(\\S+)*)"; + Pattern compile = Pattern.compile(pattern); + Matcher matcher = compile.matcher(parse); + if (matcher.find()) { + System.out.println(matcher.group("field")); + System.out.println(matcher.group("other")); + } + } + + + +}