增加DataNativeSqlParser功能

This commit is contained in:
redkale
2023-08-09 23:54:39 +08:00
parent 398071a272
commit 302259e30d
7 changed files with 263 additions and 22 deletions

View File

@@ -39,6 +39,7 @@ module org.redkale {
uses org.redkale.mq.MessageAgentProvider;
uses org.redkale.source.CacheSourceProvider;
uses org.redkale.source.DataSourceProvider;
uses org.redkale.source.DataNativeSqlParserProvider;
uses org.redkale.util.ResourceAnnotationProvider;
}

View File

@@ -157,6 +157,9 @@ public final class Application {
private final ReentrantLock dataSourceLock = new ReentrantLock();
//原生sql解析器
private DataNativeSqlParser nativeSqlParser;
//NodeServer 资源, 顺序必须是sncps, others, watchs
final List<NodeServer> servers = new CopyOnWriteArrayList<>();
@@ -580,6 +583,23 @@ public final class Application {
this.excludelibs = excludelib0;
this.clusterAgent = cluster;
this.messageAgents = mqs;
{ //加载原生sql解析器
Iterator<DataNativeSqlParserProvider> it = ServiceLoader.load(DataNativeSqlParserProvider.class, classLoader).iterator();
RedkaleClassLoader.putServiceLoader(DataNativeSqlParserProvider.class);
List<DataNativeSqlParserProvider> providers = new ArrayList<>();
while (it.hasNext()) {
DataNativeSqlParserProvider provider = it.next();
if (provider != null && provider.acceptsConf(null)) {
RedkaleClassLoader.putReflectionPublicConstructors(provider.getClass(), provider.getClass().getName());
providers.add(provider);
}
}
for (DataNativeSqlParserProvider provider : InstanceProvider.sort(providers)) {
this.nativeSqlParser = provider.createInstance();
this.resourceFactory.register(DataNativeSqlParser.class, this.nativeSqlParser);
break;
}
}
if (compileMode || this.classLoader instanceof RedkaleClassLoader.RedkaleCacheClassLoader) {
this.serverClassLoader = this.classLoader;
} else {

View File

@@ -65,6 +65,9 @@ public abstract class AbstractDataSqlSource extends AbstractDataSource implement
@Resource(name = RESNAME_APP_EXECUTOR, required = false)
protected ExecutorService workExecutor;
@Resource(required = false)
protected DataNativeSqlParser nativeSqlParser;
protected BiFunction<EntityInfo, Object, CharSequence> sqlFormatter;
protected BiConsumer errorCompleteConsumer = (r, t) -> {
@@ -639,6 +642,13 @@ public abstract class AbstractDataSqlSource extends AbstractDataSource implement
return getSQLAttrValue(info, attr, val);
}
protected DataNativeSqlParser.NativeSqlInfo nativeParse(String nativeSql, Map<String, Object> params) {
if (nativeSqlParser == null) {
throw new SourceException("not found DataNativeSqlParser instance");
}
return nativeSqlParser.parse(nativeSql, params == null ? Collections.emptyMap() : params);
}
@Override
public void destroy(AnyValue config) {
super.destroy(config);
@@ -3276,4 +3286,5 @@ public abstract class AbstractDataSqlSource extends AbstractDataSource implement
entitys.add(entity);
}
}
}

View File

@@ -18,6 +18,7 @@ import org.redkale.annotation.*;
import org.redkale.annotation.ResourceListener;
import org.redkale.annotation.ResourceType;
import org.redkale.service.Local;
import org.redkale.source.DataNativeSqlParser.NativeSqlInfo;
import org.redkale.util.*;
/**
@@ -2481,19 +2482,6 @@ public class DataJdbcSource extends AbstractDataSqlSource {
return rs;
}
/**
* 直接本地执行SQL语句进行增删改操作远程模式不可用 <br>
* 通常用于复杂的更新操作 <br>
*
* @param sql SQL语句
*
* @return 结果数组
*/
@Override
public int nativeUpdate(String sql) {
return nativeUpdates(new String[]{sql})[0];
}
/**
* 直接本地执行SQL语句进行增删改操作远程模式不可用 <br>
* 通常用于复杂的更新操作 <br>
@@ -2515,7 +2503,7 @@ public class DataJdbcSource extends AbstractDataSqlSource {
final int[] rs = new int[sqls.length];
int i = -1;
for (String sql : sqls) {
rs[++i] = stmt.execute(sql) ? 1 : 0;
rs[++i] = stmt.executeUpdate(sql);
}
conn.offerUpdateStatement(stmt);
conn.commit();
@@ -2534,6 +2522,57 @@ public class DataJdbcSource extends AbstractDataSqlSource {
}
}
/**
* 直接本地执行SQL语句进行增删改操作远程模式不可用 <br>
* 通常用于复杂的更新操作 <br>
*
* @param sql SQL语句
*
* @return 结果数组
*/
@Override
public int nativeUpdate(String sql) {
return nativeUpdates(new String[]{sql})[0];
}
@Override
public int nativeUpdate(String sql, Map<String, Object> params) {
NativeSqlInfo sinfo = super.nativeParse(sql, params);
final long s = System.currentTimeMillis();
SourceConnection conn = writePool.pollConnection();
try {
conn.setAutoCommit(false);
int rs;
if (sinfo.isEmptyNamed()) {
final Statement stmt = conn.createUpdateStatement();
rs = stmt.executeUpdate(sinfo.nativeSql);
conn.offerUpdateStatement(stmt);
} else {
final PreparedStatement prestmt = conn.prepareQueryStatement(sinfo.nativeSql);
Map<String, Object> paramValues = sinfo.getParamValues();
int index = 0;
for (String n : sinfo.getParamNames()) {
prestmt.setObject(++index, paramValues.get(n));
}
rs = prestmt.executeUpdate();
conn.offerUpdateStatement(prestmt);
}
conn.commit();
slowLog(s, sinfo.nativeSql);
return rs;
} catch (SQLException e) {
try {
conn.rollback();
} catch (SQLException se) {
}
throw new SourceException(e);
} finally {
if (conn != null) {
writePool.offerConnection(conn);
}
}
}
/**
* 直接本地执行SQL语句进行查询远程模式不可用 <br>
* 通常用于复杂的关联查询 <br>
@@ -2571,14 +2610,49 @@ public class DataJdbcSource extends AbstractDataSqlSource {
}
}
@Override
public int nativeUpdate(String sql, Map<String, Object> params) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public <V> V nativeQuery(String sql, BiConsumer<Object, Object> consumer, Function<DataResultSet, V> handler, Map<String, Object> params) {
throw new UnsupportedOperationException("Not supported yet.");
NativeSqlInfo sinfo = super.nativeParse(sql, params);
final long s = System.currentTimeMillis();
final SourceConnection conn = readPool.pollConnection();
try {
if (logger.isLoggable(Level.FINEST)) {
logger.finest("executeQuery sql=" + sinfo.nativeSql);
}
V rs;
if (sinfo.isEmptyNamed()) {
final Statement stmt = conn.createQueryStatement();
if (consumer != null) {
consumer.accept(conn, stmt);
}
ResultSet set = stmt.executeQuery(sql);
rs = handler.apply(createDataResultSet(null, set));
set.close();
conn.offerQueryStatement(stmt);
} else {
final PreparedStatement prestmt = conn.prepareQueryStatement(sinfo.nativeSql);
Map<String, Object> paramValues = sinfo.getParamValues();
int index = 0;
for (String n : sinfo.getParamNames()) {
prestmt.setObject(++index, paramValues.get(n));
}
if (consumer != null) {
consumer.accept(conn, prestmt);
}
ResultSet set = prestmt.executeQuery(sql);
rs = handler.apply(createDataResultSet(null, set));
set.close();
conn.offerQueryStatement(prestmt);
}
slowLog(s, sql);
return rs;
} catch (Exception ex) {
throw new SourceException(ex);
} finally {
if (conn != null) {
readPool.offerConnection(conn);
}
}
}
@Deprecated

View File

@@ -0,0 +1,74 @@
/*
*
*/
package org.redkale.source;
import java.util.*;
import org.redkale.convert.ConvertDisabled;
import org.redkale.convert.json.JsonConvert;
/**
*
* 原生的sql解析器
*
* <p>
* 详情见: https://redkale.org
*
* @author zhangjx
* @since 2.8.0
*/
public interface DataNativeSqlParser {
NativeSqlInfo parse(String nativeSql, Map<String, Object> params);
public static class NativeSqlInfo {
//根据参数值集合重新生成的可执行的sql
protected String nativeSql;
//需要预编译的参数名
protected List<String> paramNames;
//参数值集合
protected Map<String, Object> paramValues;
/**
* 是否带有参数
*
* @return 是否带有参数
*/
@ConvertDisabled
public boolean isEmptyNamed() {
return paramNames == null || paramNames.isEmpty();
}
public String getNativeSql() {
return nativeSql;
}
public void setNativeSql(String nativeSql) {
this.nativeSql = nativeSql;
}
public List<String> getParamNames() {
return paramNames;
}
public void setParamNames(List<String> paramNames) {
this.paramNames = paramNames;
}
public Map<String, Object> getParamValues() {
return paramValues;
}
public void setParamValues(Map<String, Object> paramValues) {
this.paramValues = paramValues;
}
@Override
public String toString() {
return JsonConvert.root().convertTo(this);
}
}
}

View File

@@ -0,0 +1,20 @@
/*
*
*/
package org.redkale.source;
import org.redkale.util.InstanceProvider;
/**
*
* 自定义的DataNativeSqlParser加载器, 如果标记&#64;Priority加载器的优先级需要大于1000 1000以下预留给官方加载器
*
* <p>
* 详情见: https://redkale.org
*
* @author zhangjx
* @since 2.8.0
*/
public interface DataNativeSqlParserProvider extends InstanceProvider<DataNativeSqlParser> {
}

View File

@@ -21,16 +21,57 @@ import org.redkale.util.Copier;
*/
public interface DataSqlSource extends DataSource {
/**
* 执行多条原生无参数的sql
*
* @param sql 无参数的sql语句
*
* @return 执行条数
*/
public int[] nativeUpdates(String... sqls);
/**
* 执行原生无参数的sql
*
* @param sql 无参数的sql语句
*
* @return 执行条数
*/
public int nativeUpdate(String sql);
/**
* 执行原生带参数的sql
*
* @param sql 带参数的sql语句
* @param params 参数值集合
*
* @return 执行条数
*/
public int nativeUpdate(String sql, Map<String, Object> params);
//BiConsumer 参数1: connection, 参数2: statement
/**
* 通过原生的sql查询结果
*
* @param <V> 泛型
* @param sql 无参数的sql语句
* @param consumer BiConsumer 参数1: connection, 参数2: statement
* @param handler DataResultSet的回调函数
*
* @return 结果对象
*/
public <V> V nativeQuery(String sql, BiConsumer<Object, Object> consumer, Function<DataResultSet, V> handler);
//BiConsumer 参数1: connection, 参数2: statement
/**
* 通过原生带参数的sql查询结果
*
* @param <V> 泛型
* @param sql 带参数的sql语句
* @param consumer BiConsumer 参数1: connection, 参数2: statement
* @param handler DataResultSet的回调函数
* @param params 参数值集合
*
* @return 结果对象
*/
public <V> V nativeQuery(String sql, BiConsumer<Object, Object> consumer, Function<DataResultSet, V> handler, Map<String, Object> params);
//----------------------------- 无参数 -----------------------------