From 58cd2e4a160ff6507c766c26bcff982e6db0f2fb Mon Sep 17 00:00:00 2001
From: aoshiguchen <1052045476@qq.com>
Date: Mon, 27 Jun 2022 22:29:24 +0800
Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9Ejdbctemplate=E5=B0=81?=
=?UTF-8?q?=E8=A3=85=E5=8F=8A=E6=B5=8B=E8=AF=95=E4=BB=A3=E7=A0=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
neutrino-core/pom.xml | 12 +
.../fun/asgc/neutrino/core/base/Convert.java | 82 ++++
.../fun/asgc/neutrino/core/base/Orderly.java | 46 ++
.../neutrino/core/db/annotation/Column.java | 37 ++
.../asgc/neutrino/core/db/annotation/Id.java | 32 ++
.../core/db/annotation/NotColumn.java | 39 ++
.../core/db/annotation/PrimaryKey.java | 32 ++
.../neutrino/core/db/annotation/Table.java | 37 ++
.../neutrino/core/db/dialect/SqlDialect.java | 111 +++++
.../neutrino/core/db/template/DbCache.java | 212 +++++++++
.../db/template/DefaultColumnNameConvert.java | 89 ++++
.../db/template/DefaultTableNameConvert.java | 88 ++++
.../core/db/template/JdbcCallback.java | 36 ++
.../core/db/template/JdbcOperations.java | 242 +++++++++++
.../core/db/template/JdbcTemplate.java | 404 ++++++++++++++++++
.../PreparedStatementJdbcCallback.java | 98 +++++
.../core/db/template/SqlAndParams.java | 100 +++++
.../asgc/neutrino/core/type/TypeMatchers.java | 22 +-
.../asgc/neutrino/core/util/ReflectUtil.java | 40 ++
.../fun/asgc/neutrino/core/util/TypeUtil.java | 13 +-
.../core/db/template/JdbcTemplateTest.java | 171 ++++++++
21 files changed, 1935 insertions(+), 8 deletions(-)
create mode 100644 neutrino-core/src/main/java/fun/asgc/neutrino/core/base/Convert.java
create mode 100644 neutrino-core/src/main/java/fun/asgc/neutrino/core/base/Orderly.java
create mode 100644 neutrino-core/src/main/java/fun/asgc/neutrino/core/db/annotation/Column.java
create mode 100644 neutrino-core/src/main/java/fun/asgc/neutrino/core/db/annotation/Id.java
create mode 100644 neutrino-core/src/main/java/fun/asgc/neutrino/core/db/annotation/NotColumn.java
create mode 100644 neutrino-core/src/main/java/fun/asgc/neutrino/core/db/annotation/PrimaryKey.java
create mode 100644 neutrino-core/src/main/java/fun/asgc/neutrino/core/db/annotation/Table.java
create mode 100644 neutrino-core/src/main/java/fun/asgc/neutrino/core/db/dialect/SqlDialect.java
create mode 100644 neutrino-core/src/main/java/fun/asgc/neutrino/core/db/template/DbCache.java
create mode 100644 neutrino-core/src/main/java/fun/asgc/neutrino/core/db/template/DefaultColumnNameConvert.java
create mode 100644 neutrino-core/src/main/java/fun/asgc/neutrino/core/db/template/DefaultTableNameConvert.java
create mode 100644 neutrino-core/src/main/java/fun/asgc/neutrino/core/db/template/JdbcCallback.java
create mode 100644 neutrino-core/src/main/java/fun/asgc/neutrino/core/db/template/JdbcOperations.java
create mode 100644 neutrino-core/src/main/java/fun/asgc/neutrino/core/db/template/JdbcTemplate.java
create mode 100644 neutrino-core/src/main/java/fun/asgc/neutrino/core/db/template/PreparedStatementJdbcCallback.java
create mode 100644 neutrino-core/src/main/java/fun/asgc/neutrino/core/db/template/SqlAndParams.java
create mode 100644 neutrino-core/src/test/java/fun/asgc/neutrino/core/db/template/JdbcTemplateTest.java
diff --git a/neutrino-core/pom.xml b/neutrino-core/pom.xml
index b73b8371..d903271c 100644
--- a/neutrino-core/pom.xml
+++ b/neutrino-core/pom.xml
@@ -21,6 +21,18 @@
org.yaml
snakeyaml
+
+ com.alibaba
+ druid
+ 1.1.24
+ test
+
+
+ mysql
+ mysql-connector-java
+ 8.0.29
+ test
+
diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/base/Convert.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/base/Convert.java
new file mode 100644
index 00000000..5c70ce36
--- /dev/null
+++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/base/Convert.java
@@ -0,0 +1,82 @@
+/**
+ * Copyright (c) 2022 aoshiguchen
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package fun.asgc.neutrino.core.base;
+
+import com.google.common.collect.Lists;
+import fun.asgc.neutrino.core.util.CollectionUtil;
+
+import java.util.List;
+
+/**
+ * 转换器
+ * @author: aoshiguchen
+ * @date: 2022/6/27
+ */
+public interface Convert {
+
+ /**
+ * 从目标内容转换为原内容
+ * @param target
+ * @return
+ */
+ S from(T target);
+
+ /**
+ * 从原内容转换为目标内容
+ * @param source
+ * @return
+ */
+ T to(S source);
+
+ /**
+ * 从目标内容转换为原内容
+ * @param targetList
+ * @return
+ */
+ default List from(List targetList) {
+ List list = Lists.newArrayList();
+ if (CollectionUtil.isEmpty(targetList)) {
+ return list;
+ }
+ for (T target : targetList) {
+ list.add(from(target));
+ }
+ return list;
+ }
+
+ /**
+ * 从原内容转换为目标内容
+ * @param sourceList
+ * @return
+ */
+ default List to(List sourceList) {
+ List list = Lists.newArrayList();
+ if (CollectionUtil.isEmpty(sourceList)) {
+ return list;
+ }
+ for (S source : sourceList) {
+ list.add(to(source));
+ }
+ return list;
+ }
+}
diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/base/Orderly.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/base/Orderly.java
new file mode 100644
index 00000000..e0de553e
--- /dev/null
+++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/base/Orderly.java
@@ -0,0 +1,46 @@
+/**
+ * Copyright (c) 2022 aoshiguchen
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package fun.asgc.neutrino.core.base;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+/**
+ * @author: aoshiguchen
+ * @date: 2022/6/27
+ */
+@Accessors(chain = true)
+@AllArgsConstructor
+@NoArgsConstructor
+@Data
+public class Orderly implements Comparable {
+ private T data;
+ private int order;
+
+ @Override
+ public int compareTo(Orderly o) {
+ return getOrder() - o.getOrder();
+ }
+}
diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/annotation/Column.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/annotation/Column.java
new file mode 100644
index 00000000..41a27ee5
--- /dev/null
+++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/annotation/Column.java
@@ -0,0 +1,37 @@
+/**
+ * Copyright (c) 2022 aoshiguchen
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package fun.asgc.neutrino.core.db.annotation;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ *
+ * @author: aoshiguchen
+ * @date: 2022/6/27
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface Column {
+ String value();
+}
diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/annotation/Id.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/annotation/Id.java
new file mode 100644
index 00000000..dcb04770
--- /dev/null
+++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/annotation/Id.java
@@ -0,0 +1,32 @@
+/**
+ * Copyright (c) 2022 aoshiguchen
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package fun.asgc.neutrino.core.db.annotation;
+
+/**
+ * Id
+ * 在持久化模型中标注单一主键
+ * @author: aoshiguchen
+ * @date: 2022/6/27
+ */
+public @interface Id {
+
+}
diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/annotation/NotColumn.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/annotation/NotColumn.java
new file mode 100644
index 00000000..a80c2593
--- /dev/null
+++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/annotation/NotColumn.java
@@ -0,0 +1,39 @@
+/**
+ * Copyright (c) 2022 aoshiguchen
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package fun.asgc.neutrino.core.db.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ *
+ * 在持久化模型中标注不需要持久化的字段
+ * @author: aoshiguchen
+ * @date: 2022/6/27
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface NotColumn {
+
+}
diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/annotation/PrimaryKey.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/annotation/PrimaryKey.java
new file mode 100644
index 00000000..55e0de10
--- /dev/null
+++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/annotation/PrimaryKey.java
@@ -0,0 +1,32 @@
+/**
+ * Copyright (c) 2022 aoshiguchen
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package fun.asgc.neutrino.core.db.annotation;
+
+/**
+ * PrimaryKey
+ * 在持久化模型中标注主键(可标注一个或多个)
+ * @author: aoshiguchen
+ * @date: 2022/6/27
+ */
+public @interface PrimaryKey {
+
+}
diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/annotation/Table.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/annotation/Table.java
new file mode 100644
index 00000000..18420878
--- /dev/null
+++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/annotation/Table.java
@@ -0,0 +1,37 @@
+/**
+ * Copyright (c) 2022 aoshiguchen
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package fun.asgc.neutrino.core.db.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * @author: aoshiguchen
+ * @date: 2022/6/27
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface Table {
+ String value();
+}
diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/dialect/SqlDialect.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/dialect/SqlDialect.java
new file mode 100644
index 00000000..3a790149
--- /dev/null
+++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/dialect/SqlDialect.java
@@ -0,0 +1,111 @@
+/**
+ * Copyright (c) 2022 aoshiguchen
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package fun.asgc.neutrino.core.db.dialect;
+
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * sql方言,用于屏蔽各种不同的数据库的sql差异
+ * @author: aoshiguchen
+ * @date: 2022/6/27
+ */
+public interface SqlDialect {
+ /**
+ * 获取记录数
+ * @return
+ */
+ String getRecordCount();
+
+ /**
+ * 查询所有数据
+ * @return
+ */
+ String findAll();
+
+ /**
+ * 根据id查询单条数据
+ * @param id
+ * @return
+ */
+ String findById(String id);
+
+ /**
+ * 查询
+ * @param filterField
+ * @param params
+ * @return
+ */
+ String find(Set filterField, Map params);
+
+ /**
+ * 根据id删除
+ * @param id
+ * @return
+ */
+ String deleteById(String id);
+
+ /**
+ * 删除
+ * @param filterField
+ * @param params
+ * @return
+ */
+ String delete(Set filterField,Map params);
+
+ /**
+ * 删除所有数据
+ * @return
+ */
+ String deleteAll();
+
+ /**
+ * 更新
+ * @param filterField
+ * @param params
+ * @return
+ */
+ String update(Set filterField,Map params);
+
+ /**
+ * 新增
+ * @param filterField
+ * @param params
+ * @return
+ */
+ String create(Set filterField,Map params);
+
+ /**
+ * 分页查询
+ * @return
+ */
+ String findPage();
+
+ /**
+ * 分页查询
+ * @param filterField
+ * @param params
+ * @return
+ */
+ String findPage(Set filterField,Map params);
+
+}
diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/template/DbCache.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/template/DbCache.java
new file mode 100644
index 00000000..0ca63138
--- /dev/null
+++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/template/DbCache.java
@@ -0,0 +1,212 @@
+/**
+ * Copyright (c) 2022 aoshiguchen
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package fun.asgc.neutrino.core.db.template;
+
+import com.google.common.collect.Lists;
+import fun.asgc.neutrino.core.cache.Cache;
+import fun.asgc.neutrino.core.cache.MemoryCache;
+import fun.asgc.neutrino.core.cache.MemoryCacheGroup;
+import fun.asgc.neutrino.core.db.annotation.Column;
+import fun.asgc.neutrino.core.db.annotation.NotColumn;
+import fun.asgc.neutrino.core.db.annotation.Table;
+import fun.asgc.neutrino.core.util.*;
+
+import java.lang.reflect.Field;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * 数据库相关缓存
+ * @author: aoshiguchen
+ * @date: 2022/6/27
+ */
+public class DbCache {
+ /**
+ * 名称映射缓存组
+ */
+ private static final MemoryCacheGroup nameMappingCache = new MemoryCacheGroup<>();
+ private static final String GROUP_COLUMN_NAME_TO = "GROUP_COLUMN_NAME_TO";
+ private static final String GROUP_COLUMN_NAME_FROM = "GROUP_COLUMN_NAME_FROM";
+ private static final String GROUP_TABLE_NAME_TO = "GROUP_TABLE_NAME_TO";
+ private static final String GROUP_TABLE_NAME_FROM = "GROUP_TABLE_NAME_FROM";
+ private static final Cache, Cache> fieldToColumnCache = new MemoryCache<>();
+ private static final Object fieldToColumnCacheLock = new Object();
+
+ /**
+ * 转换为列名
+ * @param s
+ * @return
+ */
+ public static String toColumnName(String s) {
+ return LockUtil.doubleCheckProcess(
+ () -> !nameMappingCache.containsKey(GROUP_COLUMN_NAME_TO, s),
+ GROUP_COLUMN_NAME_TO,
+ () -> nameMappingCache.set(GROUP_COLUMN_NAME_TO, s, DefaultColumnNameConvert.getInstance().to(s)),
+ () -> nameMappingCache.get(GROUP_COLUMN_NAME_TO, s)
+ );
+ }
+
+ /**
+ * 转换为字段名
+ * @param s
+ * @return
+ */
+ public static String fromColumnName(String s) {
+ return LockUtil.doubleCheckProcess(
+ () -> !nameMappingCache.containsKey(GROUP_COLUMN_NAME_FROM, s),
+ GROUP_COLUMN_NAME_FROM,
+ () -> nameMappingCache.set(GROUP_COLUMN_NAME_FROM, s, DefaultColumnNameConvert.getInstance().from(s)),
+ () -> nameMappingCache.get(GROUP_COLUMN_NAME_FROM, s)
+ );
+ }
+
+ /**
+ * 转换为表名
+ * @param s
+ * @return
+ */
+ public static String toTableName(String s) {
+ return LockUtil.doubleCheckProcess(
+ () -> !nameMappingCache.containsKey(GROUP_TABLE_NAME_TO, s),
+ GROUP_TABLE_NAME_TO,
+ () -> nameMappingCache.set(GROUP_TABLE_NAME_TO, s, DefaultTableNameConvert.getInstance().to(s)),
+ () -> nameMappingCache.get(GROUP_TABLE_NAME_TO, s)
+ );
+ }
+
+ /**
+ * 转换为表名
+ * @param clazz
+ * @return
+ */
+ public static String toTableName(Class> clazz) {
+ Table table = clazz.getAnnotation(Table.class);
+ if (null != table && StringUtil.notEmpty(table.value())) {
+ return table.value();
+ }
+ return toTableName(TypeUtil.getSimpleName(clazz));
+ }
+
+ /**
+ * 转换为实体名
+ * @param s
+ * @return
+ */
+ public static String fromTableName(String s) {
+ return LockUtil.doubleCheckProcess(
+ () -> !nameMappingCache.containsKey(GROUP_TABLE_NAME_FROM, s),
+ GROUP_TABLE_NAME_FROM,
+ () -> nameMappingCache.set(GROUP_TABLE_NAME_FROM, s, DefaultTableNameConvert.getInstance().from(s)),
+ () -> nameMappingCache.get(GROUP_TABLE_NAME_FROM, s)
+ );
+ }
+
+ /**
+ * 根据类+列名获取字段
+ * @param clazz
+ * @param column
+ * @return
+ */
+ public static List getField(Class> clazz, String column) {
+ return LockUtil.doubleCheckProcess(
+ () -> !fieldToColumnCache.containsKey(clazz),
+ fieldToColumnCacheLock,
+ () -> initFieldCache(clazz),
+ () -> {
+ List list = Lists.newArrayList();
+ Cache cache = fieldToColumnCache.get(clazz);
+ if (null == cache || cache.isEmpty()) {
+ return list;
+ }
+ for (Field field : cache.keySet()) {
+ if (cache.get(field).equals(column)) {
+ list.add(field);
+ }
+ }
+
+ return list;
+ }
+ );
+ }
+
+ /**
+ * 根据类名获取列名列表
+ * @param clazz
+ * @return
+ */
+ public static List getFieldList(Class> clazz) {
+ return LockUtil.doubleCheckProcess(
+ () -> !fieldToColumnCache.containsKey(clazz),
+ fieldToColumnCacheLock,
+ () -> initFieldCache(clazz),
+ () -> {
+ List list = Lists.newArrayList();
+ Cache cache = fieldToColumnCache.get(clazz);
+ if (null == cache || cache.isEmpty()) {
+ return list;
+ }
+ list.addAll(cache.keySet());
+ return list;
+ }
+ );
+ }
+
+ public static String getColumnNameByField(Field field) {
+ return LockUtil.doubleCheckProcess(
+ () -> !fieldToColumnCache.containsKey(field.getDeclaringClass()),
+ fieldToColumnCacheLock,
+ () -> initFieldCache(field.getDeclaringClass()),
+ () -> {
+ if (!fieldToColumnCache.containsKey(field.getDeclaringClass()) || !fieldToColumnCache.get(field.getDeclaringClass()).containsKey(field)) {
+ return null;
+ }
+ return fieldToColumnCache.get(field.getDeclaringClass()).get(field);
+ }
+ );
+ }
+
+ /**
+ * 初始化字段缓存
+ * @param clazz
+ */
+ private static void initFieldCache(Class> clazz) {
+ Set fieldSet = ReflectUtil.getDeclaredFields(clazz);
+ if (CollectionUtil.isEmpty(fieldSet)) {
+ return;
+ }
+ Cache cache = new MemoryCache<>();
+ fieldSet.forEach(field -> {
+ if (field.isAnnotationPresent(NotColumn.class)) {
+ return;
+ }
+ Column column = field.getAnnotation(Column.class);
+ if (null != column && StringUtil.notEmpty(column.value())) {
+ cache.set(field, column.value());
+ } else {
+ cache.set(field, toColumnName(field.getName()));
+ }
+
+ });
+
+ fieldToColumnCache.set(clazz, cache);
+ }
+}
diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/template/DefaultColumnNameConvert.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/template/DefaultColumnNameConvert.java
new file mode 100644
index 00000000..4a7cb70f
--- /dev/null
+++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/template/DefaultColumnNameConvert.java
@@ -0,0 +1,89 @@
+/**
+ * Copyright (c) 2022 aoshiguchen
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package fun.asgc.neutrino.core.db.template;
+
+import fun.asgc.neutrino.core.base.Convert;
+import fun.asgc.neutrino.core.util.StringUtil;
+
+/**
+ * 默认的列名转换器转换器
+ * 代码 -> DB
+ * @author: aoshiguchen
+ * @date: 2022/6/27
+ */
+public class DefaultColumnNameConvert implements Convert {
+ private static final DefaultColumnNameConvert instance = new DefaultColumnNameConvert();
+ private static final char SEPARATOR = '_';
+
+ private DefaultColumnNameConvert() {
+
+ }
+
+ public static DefaultColumnNameConvert getInstance() {
+ return instance;
+ }
+
+ @Override
+ public String from(String target) {
+ if (StringUtil.isEmpty(target)) {
+ return "";
+ }
+ boolean flag = false;
+ StringBuilder sb = new StringBuilder(target.length());
+ for (char c : target.toCharArray()) {
+ if (SEPARATOR == c) {
+ flag = true;
+ } else {
+ if (flag) {
+ sb.append(Character.toUpperCase(c));
+ flag = false;
+ } else {
+ sb.append(c);
+ }
+ }
+ }
+ return sb.toString();
+ }
+
+ @Override
+ public String to(String source) {
+ if (StringUtil.isEmpty(source)) {
+ return "";
+ }
+ boolean flag = true;
+ StringBuilder sb = new StringBuilder(source.length());
+ for (char c : source.toCharArray()) {
+ if (flag) {
+ sb.append(Character.toLowerCase(c));
+ flag = false;
+ } else {
+ if (Character.isUpperCase(c)) {
+ sb.append(SEPARATOR);
+ sb.append(Character.toLowerCase(c));
+ } else {
+ sb.append(c);
+ }
+ }
+ }
+ return sb.toString();
+ }
+}
diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/template/DefaultTableNameConvert.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/template/DefaultTableNameConvert.java
new file mode 100644
index 00000000..026592dd
--- /dev/null
+++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/template/DefaultTableNameConvert.java
@@ -0,0 +1,88 @@
+/**
+ * Copyright (c) 2022 aoshiguchen
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package fun.asgc.neutrino.core.db.template;
+
+import fun.asgc.neutrino.core.base.Convert;
+import fun.asgc.neutrino.core.util.StringUtil;
+
+/**
+ *
+ * @author: aoshiguchen
+ * @date: 2022/6/27
+ */
+public class DefaultTableNameConvert implements Convert {
+ private static final DefaultTableNameConvert instance = new DefaultTableNameConvert();
+ private static final char SEPARATOR = '_';
+
+ private DefaultTableNameConvert() {
+
+ }
+
+ public static DefaultTableNameConvert getInstance() {
+ return instance;
+ }
+
+ @Override
+ public String from(String target) {
+ if (StringUtil.isEmpty(target)) {
+ return "";
+ }
+ boolean flag = true;
+ StringBuilder sb = new StringBuilder(target.length());
+ for (char c : target.toCharArray()) {
+ if (SEPARATOR == c) {
+ flag = true;
+ } else {
+ if (flag) {
+ sb.append(Character.toUpperCase(c));
+ flag = false;
+ } else {
+ sb.append(c);
+ }
+ }
+ }
+ return sb.toString();
+ }
+
+ @Override
+ public String to(String source) {
+ if (StringUtil.isEmpty(source)) {
+ return "";
+ }
+ boolean flag = true;
+ StringBuilder sb = new StringBuilder(source.length());
+ for (char c : source.toCharArray()) {
+ if (flag) {
+ sb.append(Character.toLowerCase(c));
+ flag = false;
+ } else {
+ if (Character.isUpperCase(c)) {
+ sb.append(SEPARATOR);
+ sb.append(Character.toLowerCase(c));
+ } else {
+ sb.append(c);
+ }
+ }
+ }
+ return sb.toString();
+ }
+}
diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/template/JdbcCallback.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/template/JdbcCallback.java
new file mode 100644
index 00000000..1cf60465
--- /dev/null
+++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/template/JdbcCallback.java
@@ -0,0 +1,36 @@
+/**
+ * Copyright (c) 2022 aoshiguchen
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package fun.asgc.neutrino.core.db.template;
+
+/**
+ * @author: aoshiguchen
+ * @date: 2022/6/27
+ */
+public interface JdbcCallback {
+
+ /**
+ * 执行
+ * @return
+ */
+ T execute();
+
+}
diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/template/JdbcOperations.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/template/JdbcOperations.java
new file mode 100644
index 00000000..ea3495ab
--- /dev/null
+++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/template/JdbcOperations.java
@@ -0,0 +1,242 @@
+/**
+ * Copyright (c) 2022 aoshiguchen
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package fun.asgc.neutrino.core.db.template;
+
+import fun.asgc.neutrino.core.util.ReflectUtil;
+import fun.asgc.neutrino.core.util.TypeUtil;
+
+import java.lang.reflect.Field;
+import java.sql.*;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ *
+ * @author: aoshiguchen
+ * @date: 2022/6/27
+ */
+public class JdbcOperations {
+ private static final JdbcOperations instance = new JdbcOperations();
+
+ private JdbcOperations() {
+
+ }
+
+ public static JdbcOperations getInstance() {
+ return instance;
+ }
+
+ /**
+ * 通用执行方法
+ * @param callback
+ * @param
+ * @return
+ */
+ public T execute(JdbcCallback callback) {
+ T res = null;
+ try {
+ res = callback.execute();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ return res;
+ }
+
+ /**
+ * 执行更新操作
+ * @param conn
+ * @param sql
+ * @param params
+ * @return
+ */
+ public int executeUpdate(final Connection conn , final String sql, final Object[] params) {
+ return this.execute(new PreparedStatementJdbcCallback(){
+ @Override
+ public Integer execute(PreparedStatement ps) {
+ int res = -1;
+ try{
+ res = ps.executeUpdate();
+ }catch(SQLException e){
+ e.printStackTrace();
+ }
+ return res;
+ }
+ @Override
+ public Object[] getParams() {
+ return params;
+ }
+ @Override
+ public String getSql() {
+ return sql;
+ }
+ @Override
+ public Connection getConnection(){
+ return conn;
+ }
+ });
+ }
+
+ /**
+ * 执行单条查询操作
+ * @param conn
+ * @param clazz
+ * @param sql
+ * @param params
+ * @param
+ * @return
+ */
+ public T executeQuery(final Connection conn,final Class clazz,final String sql,final Object[] params) {
+ return this.execute(new PreparedStatementJdbcCallback() {
+
+ @Override
+ public T execute(PreparedStatement ps) {
+ T obj = null;
+
+ try{
+ ResultSet resultSet = ps.executeQuery();
+ if(resultSet.next()){
+ if(TypeUtil.isNormalBasicType(clazz)){
+ Object value = resultSet.getObject(1);
+ obj = TypeUtil.conversion(value, clazz);
+ }else if(TypeUtil.isMap(clazz)){
+ Map map = new HashMap();
+ obj = (T)map;
+
+ ResultSetMetaData rsmd = resultSet.getMetaData();
+ int columnCount = rsmd.getColumnCount();
+ for(int i = 1;i <= columnCount;i++){
+ String name = rsmd.getColumnName(i);
+ Object value = resultSet.getObject(i);
+ map.put(DbCache.fromColumnName(name), value);
+ }
+ }else{
+ obj = clazz.newInstance();
+ ResultSetMetaData rsmd = resultSet.getMetaData();
+ int columnCount = rsmd.getColumnCount();
+ for(int i = 1;i <= columnCount;i++){
+ String name = rsmd.getColumnName(i);
+ Object value = resultSet.getObject(i);
+ List fieldList = DbCache.getField(clazz, name);
+ ReflectUtil.setFieldValue(fieldList, obj, value);
+ }
+ }
+ }
+ }catch(Exception e){
+ throw new RuntimeException(e);
+ }
+ return obj;
+ }
+ @Override
+ public Connection getConnection() {
+ return conn;
+ }
+ @Override
+ public Object[] getParams() {
+ return params;
+ }
+ @Override
+ public String getSql() {
+ return sql;
+ }
+ });
+ }
+
+ /**
+ * 执行多条查询操作
+ * @param conn
+ * @param clazz
+ * @param sql
+ * @param params
+ * @param
+ * @return
+ */
+ public List executeQueryForList(final Connection conn, final Class clazz, final String sql, final Object[] params) {
+ return this.execute(new PreparedStatementJdbcCallback>() {
+ @Override
+ public List execute(PreparedStatement ps) {
+ List res = new ArrayList();
+ try{
+ ResultSet resultSet = ps.executeQuery();
+ ResultSetMetaData rsmd = resultSet.getMetaData();
+ int columnCount = rsmd.getColumnCount();
+
+ while(resultSet.next()){
+ T obj = null;
+
+ if(TypeUtil.isNormalBasicType(clazz)){
+ Object value = resultSet.getObject(1);
+ obj = TypeUtil.conversion(value, clazz);
+ }else if(TypeUtil.isMap(clazz)){
+ Map map = new HashMap();
+ obj = (T)map;
+
+ for(int i = 1;i <= columnCount;i++){
+ String name = rsmd.getColumnName(i);
+ Object value = resultSet.getObject(i);
+ map.put(DbCache.fromColumnName(name), value);
+ }
+ }else{
+ System.out.println(clazz);
+ obj = clazz.newInstance();
+
+ for(int i = 1;i <= columnCount;i++){
+ String name = rsmd.getColumnName(i);
+ Object value = resultSet.getObject(i);
+ List fieldList = DbCache.getField(clazz, name);
+ ReflectUtil.setFieldValue(fieldList, obj, value);
+ }
+ }
+
+ res.add(obj);
+ }
+
+ }catch(Exception e){
+ e.printStackTrace();
+ }
+
+ return res;
+ }
+
+ @Override
+ public Connection getConnection() {
+
+ return conn;
+ }
+
+ @Override
+ public Object[] getParams() {
+
+ return params;
+ }
+
+ @Override
+ public String getSql() {
+
+ return sql;
+ }
+
+ });
+ }
+}
diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/template/JdbcTemplate.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/template/JdbcTemplate.java
new file mode 100644
index 00000000..88560d3f
--- /dev/null
+++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/template/JdbcTemplate.java
@@ -0,0 +1,404 @@
+/**
+ * Copyright (c) 2022 aoshiguchen
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package fun.asgc.neutrino.core.db.template;
+
+import javax.sql.DataSource;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ *
+ * @author: aoshiguchen
+ * @date: 2022/6/27
+ */
+public class JdbcTemplate {
+
+ /**
+ * 数据源
+ */
+ private DataSource dataSource;
+ /**
+ * jdbc操作
+ */
+ private JdbcOperations jdbcOperations;
+
+ public JdbcTemplate(DataSource dataSource) {
+ this.dataSource = dataSource;
+ this.jdbcOperations = JdbcOperations.getInstance();
+ }
+
+ public int update(String sql, Object ...params){
+ int res = -1;
+ Connection conn = null;
+
+ try {
+ conn = dataSource.getConnection();
+ res = jdbcOperations.executeUpdate(conn,sql, params);
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+
+ return res;
+ }
+
+ public int updateByMap(String sql, Map params){
+ SqlAndParams sqlAndParams = new SqlAndParams(sql, params);
+ return update(sqlAndParams.getSql(),sqlAndParams.getParamArray());
+ }
+
+ public int updateByModel(String sql, Object model){
+ SqlAndParams sqlAndParams = new SqlAndParams(sql, model);
+ return update(sqlAndParams.getSql(),sqlAndParams.getParamArray());
+ }
+
+ public T query(Class clazz, String sql, Object ...params){
+ T res = null;
+ Connection conn = null;
+
+ try {
+ conn = dataSource.getConnection();
+ res = jdbcOperations.executeQuery(conn,clazz,sql, params);
+ } catch (SQLException e) {
+ new RuntimeException(e);
+ }
+
+ return res;
+ }
+
+ public T queryByMap(Class clazz, String sql, Map params){
+ SqlAndParams sqlAndParams = new SqlAndParams(sql, params);
+ return query(clazz,sqlAndParams.getSql(), sqlAndParams.getParamArray());
+ }
+
+ public T queryByModel(Class clazz, String sql, Object model){
+ SqlAndParams sqlAndParams = new SqlAndParams(sql, model);
+ return query(clazz, sqlAndParams.getSql(), sqlAndParams.getParamArray());
+ }
+
+ public byte queryForByteByMap(String sql, Map params){
+ SqlAndParams sqlAndParams = new SqlAndParams(sql, params);
+ return queryForByte(sqlAndParams.getSql(), sqlAndParams.getParamArray());
+ }
+
+ public byte queryForByteByModel(String sql, Object model){
+ SqlAndParams sqlAndParams = new SqlAndParams(sql, model);
+ return queryForByte(sqlAndParams.getSql(), sqlAndParams.getParamArray());
+ }
+
+ public byte queryForByte(String sql, Object ...params){
+ return query(byte.class, sql, params);
+ }
+
+ public short queryForShortByMap(String sql, Map params){
+ SqlAndParams sqlAndParams = new SqlAndParams(sql, params);
+ return queryForShort(sqlAndParams.getSql(), sqlAndParams.getParamArray());
+ }
+
+ public short queryForShortByModel(String sql, Object model){
+ SqlAndParams sqlAndParams = new SqlAndParams(sql, model);
+ return queryForShort(sqlAndParams.getSql(), sqlAndParams.getParamArray());
+ }
+
+ public short queryForShort(String sql, Object ...params){
+ return query(short.class, sql, params);
+ }
+
+ public int queryForIntByMap(String sql, Map params){
+ SqlAndParams sqlAndParams = new SqlAndParams(sql, params);
+ return queryForInt(sqlAndParams.getSql(), sqlAndParams.getParamArray());
+ }
+
+ public int queryForIntByModel(String sql, Object model){
+ SqlAndParams sqlAndParams = new SqlAndParams(sql, model);
+ return queryForInt(sqlAndParams.getSql(), sqlAndParams.getParamArray());
+ }
+
+ public int queryForInt(String sql, Object ...params){
+ return query(int.class, sql, params);
+ }
+
+ public Long queryForLongByMap(String sql, Map params){
+ SqlAndParams sqlAndParams = new SqlAndParams(sql, params);
+ return queryForLong(sqlAndParams.getSql(), sqlAndParams.getParamArray());
+ }
+
+ public Long queryForLongByModel(String sql, Object model){
+ SqlAndParams sqlAndParams = new SqlAndParams(sql, model);
+ return queryForLong(sqlAndParams.getSql(), sqlAndParams.getParamArray());
+ }
+
+ public Long queryForLong(String sql,Object ...params){
+ return query(long.class, sql, params);
+ }
+
+ public float queryForFloatByMap(String sql, Map params){
+ SqlAndParams sqlAndParams = new SqlAndParams(sql, params);
+ return queryForFloat(sqlAndParams.getSql(), sqlAndParams.getParamArray());
+ }
+
+ public float queryForFloatByModel(String sql, Object model){
+ SqlAndParams sqlAndParams = new SqlAndParams(sql, model);
+ return queryForFloat(sqlAndParams.getSql(), sqlAndParams.getParamArray());
+ }
+
+ public float queryForFloat(String sql,Object ...params){
+ return query(float.class, sql, params);
+ }
+
+ public double queryForDoubleByMap(String sql, Map params){
+ SqlAndParams sqlAndParams = new SqlAndParams(sql, params);
+ return queryForDouble(sqlAndParams.getSql(), sqlAndParams.getParamArray());
+ }
+
+ public double queryForDoubleByModel(String sql, Object model){
+ SqlAndParams sqlAndParams = new SqlAndParams(sql, model);
+ return queryForDouble(sqlAndParams.getSql(), sqlAndParams.getParamArray());
+ }
+
+ public double queryForDouble(String sql, Object ...params){
+ return query(double.class, sql, params);
+ }
+
+ public char queryForCharByMap(String sql, Map params){
+ SqlAndParams sqlAndParams = new SqlAndParams(sql, params);
+ return queryForChar(sqlAndParams.getSql(), sqlAndParams.getParamArray());
+ }
+
+ public char queryForCharByModel(String sql, Object model){
+ SqlAndParams sqlAndParams = new SqlAndParams(sql, model);
+ return queryForChar(sqlAndParams.getSql(), sqlAndParams.getParamArray());
+ }
+
+ public char queryForChar(String sql, Object ...params){
+ return query(char.class, sql, params);
+ }
+
+ public boolean queryForBooleanByMap(String sql, Map params){
+ SqlAndParams sqlAndParams = new SqlAndParams(sql, params);
+ return queryForBoolean(sqlAndParams.getSql(), sqlAndParams.getParamArray());
+ }
+
+ public boolean queryForBooleanByModel(String sql, Object model){
+ SqlAndParams sqlAndParams = new SqlAndParams(sql, model);
+ return queryForBoolean(sqlAndParams.getSql(), sqlAndParams.getParamArray());
+ }
+
+ public boolean queryForBoolean(String sql, Object ...params){
+ return query(boolean.class, sql, params);
+ }
+
+ public String queryForStringByMap(String sql, Map params){
+ SqlAndParams sqlAndParams = new SqlAndParams(sql, params);
+ return queryForString(sqlAndParams.getSql(), sqlAndParams.getParamArray());
+ }
+
+ public String queryForStringByModel(String sql, Object model){
+ SqlAndParams sqlAndParams = new SqlAndParams(sql, model);
+ return queryForString(sql, sqlAndParams.getParamArray());
+ }
+
+ public String queryForString(String sql, Object ...params){
+ return query(String.class, sql, params);
+ }
+
+ public Map queryForMapByMap(String sql, Map params){
+ SqlAndParams sqlAndParams = new SqlAndParams(sql, params);
+ return queryForMap(sql, sqlAndParams.getParamArray());
+ }
+
+ public Map queryForMapByModel(String sql, Object model){
+ SqlAndParams sqlAndParams = new SqlAndParams(sql, model);
+ return queryForMap(sql, sqlAndParams.getParamArray());
+ }
+
+ public Map queryForMap(String sql, Object ...params){
+ return (Map)query(HashMap.class, sql, params);
+ }
+
+ public List queryForList(Class clazz, String sql, Object ...params){
+ List res = null;
+ Connection conn = null;
+
+ try {
+ conn = dataSource.getConnection();
+ res = jdbcOperations.executeQueryForList(conn, clazz, sql, params);
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+
+ return res;
+ }
+
+ public List queryForListByMap(Class clazz, String sql, Map params){
+ SqlAndParams sqlAndParams = new SqlAndParams(sql, params);
+ return queryForList(clazz, sqlAndParams.getSql(), sqlAndParams.getParamArray());
+ }
+
+ public List queryForListByModel(Class clazz, String sql, Object model){
+ SqlAndParams sqlAndParams = new SqlAndParams(sql, model);
+ return queryForList(clazz, sqlAndParams.getSql(), sqlAndParams.getParamArray());
+ }
+
+ public List queryForListByteByMap(String sql, Map params){
+ SqlAndParams sqlAndParams = new SqlAndParams(sql, params);
+ return queryForListByte(sqlAndParams.getSql(), sqlAndParams.getParamArray());
+ }
+
+ public List queryForListByteByModel(String sql, Object model){
+ SqlAndParams sqlAndParams = new SqlAndParams(sql, model);
+ return queryForListByte(sqlAndParams.getSql(), sqlAndParams.getParamArray());
+ }
+
+ public List queryForListByte(String sql,Object ...params){
+ return queryForList(byte.class, sql,params);
+ }
+
+ public List queryForListShortByMap(String sql, Map params){
+ SqlAndParams sqlAndParams = new SqlAndParams(sql, params);
+ return queryForListShort(sqlAndParams.getSql(), sqlAndParams.getParamArray());
+ }
+
+ public List queryForListShortByModel(String sql, Object model){
+ SqlAndParams sqlAndParams = new SqlAndParams(sql, model);
+ return queryForListShort(sqlAndParams.getSql(), sqlAndParams.getParamArray());
+ }
+
+ public List queryForListShort(String sql, Object ...params){
+ return queryForList(short.class, sql, params);
+ }
+
+ public List queryForListIntByMap(String sql, Map params){
+ SqlAndParams sqlAndParams = new SqlAndParams(sql, params);
+ return queryForListInt(sqlAndParams.getSql(), sqlAndParams.getParamArray());
+ }
+
+ public List queryForListIntByModel(String sql, Object model){
+ SqlAndParams sqlAndParams = new SqlAndParams(sql, model);
+ return queryForListInt(sqlAndParams.getSql(), sqlAndParams.getParamArray());
+ }
+
+ public List queryForListInt(String sql, Object ...params){
+ return queryForList(int.class, sql, params);
+ }
+
+ public List queryForListLongByMap(String sql, Map params){
+ SqlAndParams sqlAndParams = new SqlAndParams(sql, params);
+ return queryForListLong(sqlAndParams.getSql(), sqlAndParams.getParamArray());
+ }
+
+ public List queryForListLongByModel(String sql, Object model){
+ SqlAndParams sqlAndParams = new SqlAndParams(sql, model);
+ return queryForListLong(sqlAndParams.getSql(), sqlAndParams.getParamArray());
+ }
+
+ public List queryForListLong(String sql,Object ...params){
+ return queryForList(long.class, sql, params);
+ }
+
+ public List queryForListFloatByMap(String sql, Map params){
+ SqlAndParams sqlAndParams = new SqlAndParams(sql, params);
+ return queryForListFloat(sqlAndParams.getSql(), sqlAndParams.getParamArray());
+ }
+
+ public List queryForListFloatByModel(String sql, Object model){
+ SqlAndParams sqlAndParams = new SqlAndParams(sql, model);
+ return queryForListFloat(sqlAndParams.getSql(), sqlAndParams.getParamArray());
+ }
+
+ public List queryForListFloat(String sql, Object ...params){
+ return queryForList(float.class, sql, params);
+ }
+
+ public List queryForListDoubleByMap(String sql ,Map params){
+ SqlAndParams sqlAndParams = new SqlAndParams(sql, params);
+ return queryForListDouble(sqlAndParams.getSql(), sqlAndParams.getParamArray());
+ }
+
+ public List queryForListDoubleByModel(String sql, Object model){
+ SqlAndParams sqlAndParams = new SqlAndParams(sql, model);
+ return queryForListDouble(sqlAndParams.getSql(), sqlAndParams.getParamArray());
+ }
+
+ public List queryForListDouble(String sql, Object ...params){
+ return queryForList(double.class, sql, params);
+ }
+
+ public List queryForListCharByMap(String sql, Map params){
+ SqlAndParams sqlAndParams = new SqlAndParams(sql, params);
+ return queryForListChar(sqlAndParams.getSql(), sqlAndParams.getParamArray());
+ }
+
+ public List queryForListCharByModel(String sql, Object model){
+ SqlAndParams sqlAndParams = new SqlAndParams(sql, model);
+ return queryForListChar(sqlAndParams.getSql(), sqlAndParams.getParamArray());
+ }
+
+ public List queryForListChar(String sql, Object ...params){
+ return queryForList(char.class, sql, params);
+ }
+
+ public List queryForListBooleanByMap(String sql, Map params){
+ SqlAndParams sqlAndParams = new SqlAndParams(sql, params);
+ return queryForListBoolean(sqlAndParams.getSql(), sqlAndParams.getParamArray());
+ }
+
+ public List queryForListBooleanByModel(String sql, Object model){
+ SqlAndParams sqlAndParams = new SqlAndParams(sql, model);
+ return queryForListBoolean(sqlAndParams.getSql(), sqlAndParams.getParamArray());
+ }
+
+ public List queryForListBoolean(String sql, Object ...params){
+ return queryForList(boolean.class, sql, params);
+ }
+
+ public List queryForListStringByMap(String sql, Map params){
+ SqlAndParams sqlAndParams = new SqlAndParams(sql, params);
+ return queryForListString(sqlAndParams.getSql(), sqlAndParams.getParamArray());
+ }
+
+ public List queryForListStringByModel(String sql, Object model){
+ SqlAndParams sqlAndParams = new SqlAndParams(sql, model);
+ return queryForListString(sqlAndParams.getSql(), sqlAndParams.getParamArray());
+ }
+
+ public List queryForListString(String sql, Object ...params){
+ return queryForList(String.class, sql, params);
+ }
+
+ public List