SqlMapper逻辑优化,sql解析逻辑分离到SqlParser。

This commit is contained in:
aoshiguchen
2022-08-03 20:56:32 +08:00
parent 47d39878f7
commit 1b42119085
3 changed files with 208 additions and 93 deletions
@@ -25,16 +25,10 @@ import fun.asgc.neutrino.core.annotation.Component;
import fun.asgc.neutrino.core.annotation.NonIntercept;
import fun.asgc.neutrino.core.aop.Invocation;
import fun.asgc.neutrino.core.aop.interceptor.Interceptor;
import fun.asgc.neutrino.core.cache.Cache;
import fun.asgc.neutrino.core.cache.MemoryCache;
import fun.asgc.neutrino.core.db.annotation.*;
import fun.asgc.neutrino.core.db.template.JdbcTemplate;
import fun.asgc.neutrino.core.util.*;
import lombok.Data;
import lombok.experimental.Accessors;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Map;
/**
@@ -45,28 +39,26 @@ import java.util.Map;
@NonIntercept
@Component
public class SqlMapperInterceptor implements Interceptor {
private static final Cache<Method, Params> paramsCache = new MemoryCache<>();
@Override
public void intercept(Invocation inv) throws Exception {
JdbcTemplate jdbcTemplate = BeanManager.getBean(JdbcTemplate.class);
Assert.notNull(jdbcTemplate, "JdbcTemplate未注入,调用失败!");
Params params = getParams(inv.getTargetMethod());
if (null == params) {
SqlParser sqlParser = SqlParser.getInstance(inv.getTargetMethod());
if (null == sqlParser) {
return;
}
String sql = params.getSql();
Class<?> resultType = params.getResultType();
String sql = sqlParser.getSql();
Class<?> resultType = sqlParser.getResultType();
Class<?> resultComponentType = sqlParser.getResultComponentType();
Object res = null;
if (params.isSelect()) {
if (params.isReturnCollection()) {
res = jdbcTemplate.queryForList(resultType, sql, inv.getArgs());
if (sqlParser.isSelect()) {
if (sqlParser.isReturnCollection()) {
res = jdbcTemplate.queryForList(resultComponentType, sql, inv.getArgs());
} else {
res = jdbcTemplate.query(resultType, sql, inv.getArgs());
}
} else if (params.isInsert() || params.isDelete() || params.isUpdate()) {
} else if (sqlParser.isInsert() || sqlParser.isDelete() || sqlParser.isUpdate()) {
int argsCount = ArrayUtil.isEmpty(inv.getArgs()) ? 0 : inv.getArgs().length;
if (argsCount == 1 && inv.getArgs()[0] instanceof Map) {
res = jdbcTemplate.updateByMap(sql, (Map)inv.getArgs()[0]);
@@ -78,80 +70,4 @@ public class SqlMapperInterceptor implements Interceptor {
}
inv.setReturnValue(TypeUtil.conversion(res, resultType));
}
/**
* 获取参数
* @param method
* @return
*/
private static Params getParams(Method method) throws Exception {
return LockUtil.doubleCheckProcess(
() -> !paramsCache.containsKey(method),
method,
() -> {
String sign = String.format("%s#%s", method.getDeclaringClass().getName(), method.getName());
Params params = null;
ResultType resultType = method.getAnnotation(ResultType.class);
Class<?> resultClass = (null == resultType) ? null : resultType.value();
if (method.isAnnotationPresent(Select.class)) {
// 查询
Select select = method.getAnnotation(Select.class);
String sql = select.value();
if (StringUtil.isEmpty(sql)) {
throw new RuntimeException(String.format("%s sql不能为空!", sign));
}
boolean isReturnCollection = Collection.class.isAssignableFrom(method.getReturnType());
if (isReturnCollection && null == resultClass) {
throw new RuntimeException(String.format("%s 请指名实体类型!", sign));
}
params = new Params().setSql(sql).setSelect(true).setResultType(resultClass).setReturnCollection(isReturnCollection);
} else if (method.isAnnotationPresent(Insert.class)) {
// 新增
Insert insert = method.getAnnotation(Insert.class);
String sql = insert.value();
if (StringUtil.isEmpty(sql)) {
throw new RuntimeException(String.format("%s sql不能为空!", sign));
}
params = new Params().setSql(sql).setInsert(true).setResultType(resultClass);
} else if (method.isAnnotationPresent(Delete.class)) {
// 删除
Delete delete = method.getAnnotation(Delete.class);
String sql = delete.value();
if (StringUtil.isEmpty(sql)) {
throw new RuntimeException(String.format("%s sql不能为空!", sign));
}
params = new Params().setSql(sql).setDelete(true).setResultType(resultClass);
} else if (method.isAnnotationPresent(Update.class)) {
// 更新
Update update = method.getAnnotation(Update.class);
String sql = update.value();
if (StringUtil.isEmpty(sql)) {
throw new RuntimeException(String.format("%s sql不能为空!", sign));
}
params = new Params().setSql(sql).setUpdate(true).setResultType(resultClass);
}
if (null == params) {
throw new RuntimeException(String.format("%s 缺失SQL注解!", sign));
}
if (null == params.getResultType() && !Collection.class.isAssignableFrom(method.getReturnType())) {
params.setResultType(method.getReturnType());
}
paramsCache.set(method, params);
},
() -> paramsCache.get(method)
);
}
@Accessors(chain = true)
@Data
static class Params {
private String sql;
private Class<?> resultType;
private boolean isReturnCollection;
private boolean isSelect;
private boolean isDelete;
private boolean isUpdate;
private boolean isInsert;
}
}
@@ -0,0 +1,31 @@
/**
* 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.mapper;
/**
* sql操作类型
* @author: aoshiguchen
* @date: 2022/8/3
*/
public enum SqlOperatorType {
SELECT,DELETE,UPDATE,INSERT
}
@@ -0,0 +1,168 @@
/**
* 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.mapper;
import fun.asgc.neutrino.core.cache.Cache;
import fun.asgc.neutrino.core.cache.MemoryCache;
import fun.asgc.neutrino.core.db.annotation.*;
import fun.asgc.neutrino.core.util.LockUtil;
import fun.asgc.neutrino.core.util.StringUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import java.lang.reflect.Method;
import java.util.Collection;
/**
* sql解析器
* @author: aoshiguchen
* @date: 2022/8/3
*/
@Data
@Slf4j
public class SqlParser {
/**
* sqlParser实例缓存
*/
private static final Cache<Method, SqlParser> sqlParserCache = new MemoryCache<>();
/**
* 目标执行方法
*/
private Method targetMethod;
/**
* 操作类型
*/
private SqlOperatorType operatorType;
/**
* 结果类型
*/
private Class<?> resultType;
/**
* 返回结果组成类型(集合类型的子类型)
*/
private Class<?> resultComponentType;
/**
* 目标方法签名
*/
private String targetMethodSign;
/**
* 返回数据是否是集合类型
*/
private boolean isReturnCollection;
/**
* sql语句
*/
private String sql;
private SqlParser(Method targetMethod) {
this.targetMethod = targetMethod;
this.resultType = targetMethod.getReturnType();
this.targetMethodSign = String.format("%s#%s", targetMethod.getDeclaringClass().getName(), targetMethod.getName());
this.initByAnnotation();
this.initByXml();
}
/**
* 根据注解进行初始化
*/
private void initByAnnotation() {
if (!StringUtil.isEmpty(this.sql)) {
return;
}
ResultType resultType = targetMethod.getAnnotation(ResultType.class);
Class<?> resultClass = (null == resultType) ? null : resultType.value();
this.resultComponentType = resultClass;
if (targetMethod.isAnnotationPresent(Select.class)) {
// 查询
this.operatorType = SqlOperatorType.SELECT;
Select select = targetMethod.getAnnotation(Select.class);
this.sql = select.value();
if (StringUtil.isEmpty(sql)) {
throw new RuntimeException(String.format("%s sql不能为空!", targetMethod));
}
this.isReturnCollection = Collection.class.isAssignableFrom(targetMethod.getReturnType());
if (isReturnCollection && null == resultClass) {
throw new RuntimeException(String.format("%s 请指名实体类型!", targetMethodSign));
}
} else if (targetMethod.isAnnotationPresent(Insert.class)) {
// 新增
this.operatorType = SqlOperatorType.INSERT;
Insert insert = targetMethod.getAnnotation(Insert.class);
this.sql = insert.value();
if (StringUtil.isEmpty(sql)) {
throw new RuntimeException(String.format("%s sql不能为空!", targetMethodSign));
}
} else if (targetMethod.isAnnotationPresent(Delete.class)) {
// 删除
this.operatorType = SqlOperatorType.DELETE;
Delete delete = targetMethod.getAnnotation(Delete.class);
this.sql = delete.value();
if (StringUtil.isEmpty(sql)) {
throw new RuntimeException(String.format("%s sql不能为空!", targetMethodSign));
}
} else if (targetMethod.isAnnotationPresent(Update.class)) {
// 更新
this.operatorType = SqlOperatorType.UPDATE;
Update update = targetMethod.getAnnotation(Update.class);
this.sql = update.value();
if (StringUtil.isEmpty(sql)) {
throw new RuntimeException(String.format("%s sql不能为空!", targetMethodSign));
}
}
}
/**
* 根据xml文件进行初始化
*/
private void initByXml() {
if (!StringUtil.isEmpty(this.sql)) {
return;
}
// TODO
}
public static SqlParser getInstance(Method targetMethod) throws Exception {
return LockUtil.doubleCheckProcess(
() -> !sqlParserCache.containsKey(targetMethod),
targetMethod,
() -> sqlParserCache.set(targetMethod, new SqlParser(targetMethod)),
() -> sqlParserCache.get(targetMethod)
);
}
public boolean isSelect() {
return this.operatorType == SqlOperatorType.SELECT;
}
public boolean isUpdate() {
return this.operatorType == SqlOperatorType.UPDATE;
}
public boolean isDelete() {
return this.operatorType == SqlOperatorType.DELETE;
}
public boolean isInsert() {
return this.operatorType == SqlOperatorType.INSERT;
}
}