新增jdbctemplate封装及测试代码

This commit is contained in:
aoshiguchen
2022-06-27 22:29:24 +08:00
parent 5daebb4aee
commit 58cd2e4a16
21 changed files with 1935 additions and 8 deletions
+12
View File
@@ -21,6 +21,18 @@
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.24</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.29</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
@@ -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<S,T> {
/**
* 从目标内容转换为原内容
* @param target
* @return
*/
S from(T target);
/**
* 从原内容转换为目标内容
* @param source
* @return
*/
T to(S source);
/**
* 从目标内容转换为原内容
* @param targetList
* @return
*/
default List<S> from(List<T> targetList) {
List<S> list = Lists.newArrayList();
if (CollectionUtil.isEmpty(targetList)) {
return list;
}
for (T target : targetList) {
list.add(from(target));
}
return list;
}
/**
* 从原内容转换为目标内容
* @param sourceList
* @return
*/
default List<T> to(List<S> sourceList) {
List<T> list = Lists.newArrayList();
if (CollectionUtil.isEmpty(sourceList)) {
return list;
}
for (S source : sourceList) {
list.add(to(source));
}
return list;
}
}
@@ -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<T> implements Comparable<Orderly> {
private T data;
private int order;
@Override
public int compareTo(Orderly o) {
return getOrder() - o.getOrder();
}
}
@@ -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();
}
@@ -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 {
}
@@ -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 {
}
@@ -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 {
}
@@ -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();
}
@@ -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<String> filterField, Map<String,Object> params);
/**
* 根据id删除
* @param id
* @return
*/
String deleteById(String id);
/**
* 删除
* @param filterField
* @param params
* @return
*/
String delete(Set<String> filterField,Map<String,Object> params);
/**
* 删除所有数据
* @return
*/
String deleteAll();
/**
* 更新
* @param filterField
* @param params
* @return
*/
String update(Set<String> filterField,Map<String,Object> params);
/**
* 新增
* @param filterField
* @param params
* @return
*/
String create(Set<String> filterField,Map<String,Object> params);
/**
* 分页查询
* @return
*/
String findPage();
/**
* 分页查询
* @param filterField
* @param params
* @return
*/
String findPage(Set<String> filterField,Map<String,Object> params);
}
@@ -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<String, String> 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<Class<?>, Cache<Field, String>> 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<Field> getField(Class<?> clazz, String column) {
return LockUtil.doubleCheckProcess(
() -> !fieldToColumnCache.containsKey(clazz),
fieldToColumnCacheLock,
() -> initFieldCache(clazz),
() -> {
List<Field> list = Lists.newArrayList();
Cache<Field, String> 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<Field> getFieldList(Class<?> clazz) {
return LockUtil.doubleCheckProcess(
() -> !fieldToColumnCache.containsKey(clazz),
fieldToColumnCacheLock,
() -> initFieldCache(clazz),
() -> {
List<Field> list = Lists.newArrayList();
Cache<Field, String> 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<Field> fieldSet = ReflectUtil.getDeclaredFields(clazz);
if (CollectionUtil.isEmpty(fieldSet)) {
return;
}
Cache<Field, String> 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);
}
}
@@ -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<String, String> {
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();
}
}
@@ -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<String, String> {
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();
}
}
@@ -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<T> {
/**
* 执行
* @return
*/
T execute();
}
@@ -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 <T>
* @return
*/
public <T> T execute(JdbcCallback<T> 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<Integer>(){
@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 <T>
* @return
*/
public <T> T executeQuery(final Connection conn,final Class<T> clazz,final String sql,final Object[] params) {
return this.execute(new PreparedStatementJdbcCallback<T>() {
@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<String,Object> map = new HashMap<String,Object>();
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<Field> 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 <T>
* @return
*/
public <T> List<T> executeQueryForList(final Connection conn, final Class<T> clazz, final String sql, final Object[] params) {
return this.execute(new PreparedStatementJdbcCallback<List<T>>() {
@Override
public List<T> execute(PreparedStatement ps) {
List<T> res = new ArrayList<T>();
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<String,Object> map = new HashMap<String,Object>();
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<Field> 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;
}
});
}
}
@@ -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<String,Object> 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> T query(Class<T> 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> T queryByMap(Class<T> clazz, String sql, Map<String,Object> params){
SqlAndParams sqlAndParams = new SqlAndParams(sql, params);
return query(clazz,sqlAndParams.getSql(), sqlAndParams.getParamArray());
}
public <T> T queryByModel(Class<T> clazz, String sql, Object model){
SqlAndParams sqlAndParams = new SqlAndParams(sql, model);
return query(clazz, sqlAndParams.getSql(), sqlAndParams.getParamArray());
}
public byte queryForByteByMap(String sql, Map<String,Object> 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<String,Object> 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<String,Object> 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<String,Object> 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<String,Object> 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<String,Object> 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<String,Object> 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<String,Object> 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<String,Object> 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<String,Object> queryForMapByMap(String sql, Map<String,Object> params){
SqlAndParams sqlAndParams = new SqlAndParams(sql, params);
return queryForMap(sql, sqlAndParams.getParamArray());
}
public Map<String,Object> queryForMapByModel(String sql, Object model){
SqlAndParams sqlAndParams = new SqlAndParams(sql, model);
return queryForMap(sql, sqlAndParams.getParamArray());
}
public Map<String,Object> queryForMap(String sql, Object ...params){
return (Map<String,Object>)query(HashMap.class, sql, params);
}
public <T> List<T> queryForList(Class<T> clazz, String sql, Object ...params){
List<T> 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 <T> List<T> queryForListByMap(Class<T> clazz, String sql, Map<String,Object> params){
SqlAndParams sqlAndParams = new SqlAndParams(sql, params);
return queryForList(clazz, sqlAndParams.getSql(), sqlAndParams.getParamArray());
}
public <T> List<T> queryForListByModel(Class<T> clazz, String sql, Object model){
SqlAndParams sqlAndParams = new SqlAndParams(sql, model);
return queryForList(clazz, sqlAndParams.getSql(), sqlAndParams.getParamArray());
}
public List<Byte> queryForListByteByMap(String sql, Map<String,Object> params){
SqlAndParams sqlAndParams = new SqlAndParams(sql, params);
return queryForListByte(sqlAndParams.getSql(), sqlAndParams.getParamArray());
}
public List<Byte> queryForListByteByModel(String sql, Object model){
SqlAndParams sqlAndParams = new SqlAndParams(sql, model);
return queryForListByte(sqlAndParams.getSql(), sqlAndParams.getParamArray());
}
public List<Byte> queryForListByte(String sql,Object ...params){
return queryForList(byte.class, sql,params);
}
public List<Short> queryForListShortByMap(String sql, Map<String, Object> params){
SqlAndParams sqlAndParams = new SqlAndParams(sql, params);
return queryForListShort(sqlAndParams.getSql(), sqlAndParams.getParamArray());
}
public List<Short> queryForListShortByModel(String sql, Object model){
SqlAndParams sqlAndParams = new SqlAndParams(sql, model);
return queryForListShort(sqlAndParams.getSql(), sqlAndParams.getParamArray());
}
public List<Short> queryForListShort(String sql, Object ...params){
return queryForList(short.class, sql, params);
}
public List<Integer> queryForListIntByMap(String sql, Map<String,Object> params){
SqlAndParams sqlAndParams = new SqlAndParams(sql, params);
return queryForListInt(sqlAndParams.getSql(), sqlAndParams.getParamArray());
}
public List<Integer> queryForListIntByModel(String sql, Object model){
SqlAndParams sqlAndParams = new SqlAndParams(sql, model);
return queryForListInt(sqlAndParams.getSql(), sqlAndParams.getParamArray());
}
public List<Integer> queryForListInt(String sql, Object ...params){
return queryForList(int.class, sql, params);
}
public List<Long> queryForListLongByMap(String sql, Map<String,Object> params){
SqlAndParams sqlAndParams = new SqlAndParams(sql, params);
return queryForListLong(sqlAndParams.getSql(), sqlAndParams.getParamArray());
}
public List<Long> queryForListLongByModel(String sql, Object model){
SqlAndParams sqlAndParams = new SqlAndParams(sql, model);
return queryForListLong(sqlAndParams.getSql(), sqlAndParams.getParamArray());
}
public List<Long> queryForListLong(String sql,Object ...params){
return queryForList(long.class, sql, params);
}
public List<Float> queryForListFloatByMap(String sql, Map<String,Object> params){
SqlAndParams sqlAndParams = new SqlAndParams(sql, params);
return queryForListFloat(sqlAndParams.getSql(), sqlAndParams.getParamArray());
}
public List<Float> queryForListFloatByModel(String sql, Object model){
SqlAndParams sqlAndParams = new SqlAndParams(sql, model);
return queryForListFloat(sqlAndParams.getSql(), sqlAndParams.getParamArray());
}
public List<Float> queryForListFloat(String sql, Object ...params){
return queryForList(float.class, sql, params);
}
public List<Double> queryForListDoubleByMap(String sql ,Map<String,Object> params){
SqlAndParams sqlAndParams = new SqlAndParams(sql, params);
return queryForListDouble(sqlAndParams.getSql(), sqlAndParams.getParamArray());
}
public List<Double> queryForListDoubleByModel(String sql, Object model){
SqlAndParams sqlAndParams = new SqlAndParams(sql, model);
return queryForListDouble(sqlAndParams.getSql(), sqlAndParams.getParamArray());
}
public List<Double> queryForListDouble(String sql, Object ...params){
return queryForList(double.class, sql, params);
}
public List<Character> queryForListCharByMap(String sql, Map<String,Object> params){
SqlAndParams sqlAndParams = new SqlAndParams(sql, params);
return queryForListChar(sqlAndParams.getSql(), sqlAndParams.getParamArray());
}
public List<Character> queryForListCharByModel(String sql, Object model){
SqlAndParams sqlAndParams = new SqlAndParams(sql, model);
return queryForListChar(sqlAndParams.getSql(), sqlAndParams.getParamArray());
}
public List<Character> queryForListChar(String sql, Object ...params){
return queryForList(char.class, sql, params);
}
public List<Boolean> queryForListBooleanByMap(String sql, Map<String,Object> params){
SqlAndParams sqlAndParams = new SqlAndParams(sql, params);
return queryForListBoolean(sqlAndParams.getSql(), sqlAndParams.getParamArray());
}
public List<Boolean> queryForListBooleanByModel(String sql, Object model){
SqlAndParams sqlAndParams = new SqlAndParams(sql, model);
return queryForListBoolean(sqlAndParams.getSql(), sqlAndParams.getParamArray());
}
public List<Boolean> queryForListBoolean(String sql, Object ...params){
return queryForList(boolean.class, sql, params);
}
public List<String> queryForListStringByMap(String sql, Map<String,Object> params){
SqlAndParams sqlAndParams = new SqlAndParams(sql, params);
return queryForListString(sqlAndParams.getSql(), sqlAndParams.getParamArray());
}
public List<String> queryForListStringByModel(String sql, Object model){
SqlAndParams sqlAndParams = new SqlAndParams(sql, model);
return queryForListString(sqlAndParams.getSql(), sqlAndParams.getParamArray());
}
public List<String> queryForListString(String sql, Object ...params){
return queryForList(String.class, sql, params);
}
public List<Map> queryForListMap(String sql, Object ...params){
return queryForList(Map.class, sql, params);
}
public List<Map> queryForListMapByMap(String sql, Map<String,Object> params){
SqlAndParams sqlAndParams = new SqlAndParams(sql, params);
return queryForListMap(sqlAndParams.getSql(), sqlAndParams.getParamArray());
}
public List<Map> queryForListMapByModel(String sql, Object model){
SqlAndParams sqlAndParams = new SqlAndParams(sql, model);
return queryForListMap(sqlAndParams.getSql(), sqlAndParams.getParamArray());
}
}
@@ -0,0 +1,98 @@
/**
* 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 lombok.extern.slf4j.Slf4j;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
/**
*
* @author: aoshiguchen
* @date: 2022/6/27
*/
@Slf4j
public abstract class PreparedStatementJdbcCallback<T> implements JdbcCallback<T> {
@Override
public T execute() {
PreparedStatement pstm = null;
Object[] params = this.getParams();
Connection conn = getConnection();
T res = null;
try {
log.debug("sql:" + this.getSql());
StringBuffer sb = new StringBuffer();
for(Object o : params){
sb.append(o.toString()).append(",");
}
if(sb.length() > 0 && sb.charAt(sb.length() - 1) == ','){
sb.deleteCharAt(sb.length() - 1);
}
log.debug("params:" + sb.toString());
pstm = conn.prepareStatement(this.getSql());
for(int i = 0;i < params.length;i++){
pstm.setObject(i + 1, params[i]);
}
res = this.execute(pstm);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return res;
}
/**
* 获取参数
* @return
*/
abstract Object[] getParams();
/**
* 获取sql语句
* @return
*/
abstract String getSql();
/**
* 执行
* @param ps
* @return
*/
abstract T execute(PreparedStatement ps);
/**
* 获取数据库连接
* @return
*/
abstract Connection getConnection();
}
@@ -0,0 +1,100 @@
/**
* 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.Orderly;
import fun.asgc.neutrino.core.util.ReflectUtil;
import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;
/**
* sql语句+sql参数的封装,用于支持以下3种用法
* 1、jdbcTemplate.query(User.class,"select * from user where id = ?",1);
* 2、dbcTemplate.query(User.class,"select * from user where id = :id", new HashMap<String,Object>(){
* {
* this.put("id","1");
* }
* });
* 3、dbcTemplate.query(User.class,"select * from user where id = :id", new User().setId("1"));
* @author: aoshiguchen
* @date: 2022/6/27
*/
public class SqlAndParams {
private String sql;
private Object[] paramArray;
private Map<String,Object> paramMap;
private Object paramObject;
public SqlAndParams(String sql, Object[] paramArray) {
this.sql = sql;
this.paramArray = paramArray;
}
public SqlAndParams(String sql,Map<String,Object> paramMap) {
this.sql = sql;
this.paramMap = paramMap;
this.initParams();
}
public SqlAndParams(String sql,Object paramObject) {
this.sql = sql;
this.paramObject = paramObject;
this.initParamMap();
this.initParams();
}
private void initParamMap(){
if (null == paramObject) {
return;
}
if (null == paramMap) {
paramMap = new HashMap<>();
}
for(Field field : ReflectUtil.getDeclaredFields(paramObject.getClass())){
paramMap.put(field.getName(), ReflectUtil.getFieldValue(field, paramObject));
}
}
private void initParams() {
List<Orderly> orderlyList = new ArrayList<>();
for(String key : paramMap.keySet()){
int index = sql.indexOf(":" + key);
if(-1 != index){
orderlyList.add(new Orderly(paramMap.get(key), index));
sql = sql.replaceFirst(":" + key, "?");
}
}
this.paramArray = orderlyList.stream().sorted().map(Orderly::getData).collect(Collectors.toList()).toArray();
}
public Object[] getParamArray(){
return paramArray;
}
public String getSql(){
return sql;
}
}
@@ -16,10 +16,10 @@ import fun.asgc.neutrino.core.util.Assert;
import fun.asgc.neutrino.core.util.StringUtil;
import fun.asgc.neutrino.core.util.TypeUtil;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -108,6 +108,9 @@ public class TypeMatchers {
if (value == type || TypeUtil.getWrapType(value.getClass()) == type) {
return value;
}
if (TypeUtil.isInteger(clazz) && TypeUtil.isLong(targetClass)) {
return Long.valueOf(String.valueOf(value));
}
if (TypeUtil.isBoolean(value.getClass())) {
return ((boolean)value) ? 1 : 0;
}
@@ -240,7 +243,7 @@ public class TypeMatchers {
return matchInfo;
}
});
// 日期1
// 日期
extensionMatcherList.add(new TypeMatcher() {
@Override
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
@@ -254,11 +257,18 @@ public class TypeMatchers {
return new java.sql.Date((long)value);
}
}));
} else if (LocalDateTime.class.isAssignableFrom(clazz) && TypeUtil.isDate(targetClass)) {
matchInfo.setTypeDistance(TypeMatchLevel.EXTENSION.getDistanceMin() + 201);
matchInfo.setTypeConverter(((value, targetType) -> {
ZoneId zone = ZoneId.systemDefault();
Instant instant = ((LocalDateTime)value).atZone(zone).toInstant();
return Date.from(instant);
}));
}
return matchInfo;
}
});
// 日期2
// 日期
extensionMatcherList.add(new TypeMatcher() {
@Override
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
@@ -283,6 +283,26 @@ public class ReflectUtil {
}
}
/**
* 设置字段的值
* @param fieldList
* @param obj
* @param value
* @return
*/
public static boolean setFieldValue(List<Field> fieldList, Object obj, Object value) {
if (CollectionUtil.isEmpty(fieldList)) {
return false;
}
boolean result = true;
for (Field field : fieldList) {
if (!setFieldValue(field, obj, value)) {
result = false;
}
}
return result;
}
/**
* 设置字段的值
* 先尝试通过set方法设置,若设置失败则通过字段直接设置
@@ -302,6 +322,26 @@ public class ReflectUtil {
}
}
/**
* 获取字段的值
* @param field
* @param obj
* @return
*/
public static Object getFieldValue(Field field, Object obj) {
Assert.notNull(field, "field不能为空");
Assert.notNull(obj, "对象不能为空");
try {
if (!field.isAccessible()) {
field.setAccessible(true);
}
return field.get(obj);
} catch (Exception e) {
// ignore
}
return null;
}
/**
* 通过字段设置值
* @param field
@@ -414,6 +414,15 @@ public class TypeUtil {
return clazz == char.class || clazz == Character.class;
}
/**
* 是否是map类型
* @param clazz
* @return
*/
public static boolean isMap(Class<?> clazz) {
return Map.class.isAssignableFrom(clazz);
}
/**
* 获取包装类型
* @param clazz
@@ -532,7 +541,7 @@ public class TypeUtil {
* @param targetType
* @return
*/
public static Object conversion(Object value, Class<?> targetType) {
return defaultTypeMatchers.conversion(value, targetType);
public static <T> T conversion(Object value, Class<T> targetType) {
return (T)defaultTypeMatchers.conversion(value, targetType);
}
}
@@ -0,0 +1,171 @@
/**
* 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.alibaba.druid.pool.DruidDataSource;
import fun.asgc.neutrino.core.db.annotation.Id;
import lombok.Data;
import lombok.experimental.Accessors;
import org.junit.Test;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
*
* @author: aoshiguchen
* @date: 2022/6/27
*/
public class JdbcTemplateTest {
private JdbcTemplate jdbcTemplate;
{
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl("jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=utf8");
dataSource.setUsername("root");
dataSource.setPassword("YWasgc@10520");
jdbcTemplate = new JdbcTemplate(dataSource);
}
@Test
public void 新增数据1() {
jdbcTemplate.update("insert into user(`id`,`name`,`age`,`email`,`sex`,`create_time`) values(?,?,?,?,?,?)", 1, "张三", 21, "[email protected]", "", new Date());
}
@Test
public void 数据新增2() {
Map<String, Object> params = new HashMap<>();
params.put("id", 2);
params.put("name", "李四");
params.put("age", 22);
params.put("email", "[email protected]");
params.put("sex", "");
params.put("createTime", new Date());
jdbcTemplate.updateByMap("insert into user(`id`,`name`,`age`,`email`,`sex`,`create_time`) values(:id,:name,:age,:email,:sex,:createTime)", params);
}
@Test
public void 数据新增3() {
User user = new User();
user.setId(3L);
user.setName("王五");
user.setAge(23);
user.setEmail("[email protected]");
user.setSex("");
user.setCreateTime(new Date());
jdbcTemplate.updateByModel("insert into user(`id`,`name`,`age`,`email`,`sex`,`create_time`) values(:id,:name,:age,:email,:sex,:createTime)", user);
}
@Test
public void 更新数据1() {
jdbcTemplate.update("update user set age = ? ,update_time = ? where id = ?", 31, new Date(), 1);
}
@Test
public void 更新数据2() {
Map<String, Object> params = new HashMap<>();
params.put("id", 2);
params.put("updateTime", new Date());
params.put("age", 32);
jdbcTemplate.updateByMap("update user set age = :age ,update_time = :updateTime where id = :id", params);
}
@Test
public void 更新数据3() {
User user = new User();
user.setId(3L);
user.setAge(33);
user.setUpdateTime(new Date());
jdbcTemplate.updateByModel("update user set age = :age ,update_time = :updateTime where id = :id", user);
}
@Test
public void 删除数据1() {
jdbcTemplate.update("delete from user where id = ?", 1L);
}
@Test
public void 删除数据2() {
Map<String, Object> params = new HashMap<>();
params.put("id", 2);
jdbcTemplate.updateByMap("delete from user where id = :id", params);
}
@Test
public void 删除数据3() {
User user = new User();
user.setId(3L);
jdbcTemplate.updateByModel("delete from user where id = :id", user);
}
@Test
public void 查询单个行记录1() {
Map<String, Object> map = jdbcTemplate.queryForMap("select * from user where id = ?", 1);
System.out.println(map);
}
@Test
public void 查询单个行记录2() {
User user = jdbcTemplate.query(User.class, "select * from user where id = 1");
System.out.println(user);
}
@Test
public void 查询单个字段记录1() {
String name = jdbcTemplate.queryForString("select name from user where id = ?", 1);
System.out.println(name);
}
@Test
public void 查询多个行记录1() {
List<Map> list = jdbcTemplate.queryForListMap("select * from user");
System.out.println(list);
}
@Test
public void 查询多个行记录2() {
List<User> list = jdbcTemplate.queryForList(User.class, "select * from user");
System.out.println(list);
}
@Test
public void 查询多个字段记录1() {
List<Integer> list = jdbcTemplate.queryForListInt("select age from user");
System.out.println(list);
}
@Accessors(chain = true)
@Data
public static class User {
@Id
private Long id;
private String name;
private Integer age;
private String email;
private String sex;
private Date createTime;
private Date updateTime;
}
}