add BoundSql

This commit is contained in:
Looly 2024-01-09 23:04:16 +08:00
parent 4a545e3f1a
commit 64c1dc554b
6 changed files with 93 additions and 36 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2023 looly(loolly@aliyun.com) * Copyright (c) 2023-2024. looly(loolly@aliyun.com)
* Hutool is licensed under Mulan PSL v2. * Hutool is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at: * You may obtain a copy of Mulan PSL v2 at:

View File

@ -0,0 +1,65 @@
/*
* Copyright (c) 2024. looly(loolly@aliyun.com)
* Hutool is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* https://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.dromara.hutool.db.sql;
import java.util.List;
/**
* 参数绑定的SQL封装用于表示SQL语句模板'?'表示参数占位符和参数值的封装<br>
* SQL中的'?'占位符必须和params列表中的参数值一一对应
*
* @author Looly
*/
public class BoundSql {
protected String sql;
protected final List<Object> params;
/**
* 构造
*
* @param sql SQL语句参数占位符使用'?'表示
* @param params 参数列表每个参数对应一个'?'
*/
public BoundSql(final String sql, final List<Object> params) {
this.sql = sql;
this.params = params;
}
/**
* 获取SQL
*
* @return SQL
*/
public String getSql() {
return this.sql;
}
/**
* 获取参数列表按照占位符顺序
*
* @return 参数列表
*/
public List<Object> getParams() {
return this.params;
}
/**
* 获取参数列表按照占位符顺序
*
* @return 参数数组
*/
public Object[] getParamArray() {
return this.params.toArray(new Object[0]);
}
}

View File

@ -12,13 +12,12 @@
package org.dromara.hutool.db.sql; package org.dromara.hutool.db.sql;
import org.dromara.hutool.core.array.ArrayUtil;
import org.dromara.hutool.core.map.MapUtil; import org.dromara.hutool.core.map.MapUtil;
import org.dromara.hutool.core.text.StrUtil; import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.core.array.ArrayUtil;
import java.util.Collection; import java.util.Collection;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
@ -33,12 +32,12 @@ import java.util.Map;
* @author looly * @author looly
* @since 4.0.10 * @since 4.0.10
*/ */
public class NamedSql { public class NamedSql extends BoundSql {
private static final char[] NAME_START_CHARS = {':', '@', '?'}; private static final char[] NAME_START_CHARS = {':', '@', '?'};
private String sql; private final String namedSql;
private final List<Object> params; private final Map<String, Object> paramMap;
/** /**
* 构造 * 构造
@ -47,35 +46,28 @@ public class NamedSql {
* @param paramMap 名和参数的对应Map * @param paramMap 名和参数的对应Map
*/ */
public NamedSql(final String namedSql, final Map<String, Object> paramMap) { public NamedSql(final String namedSql, final Map<String, Object> paramMap) {
this.params = new LinkedList<>(); super(null, new LinkedList<>());
this.namedSql = namedSql;
this.paramMap = paramMap;
parse(namedSql, paramMap); parse(namedSql, paramMap);
} }
/** /**
* 获取SQL * 获取原始地带名称占位符的SQL语句
* *
* @return SQL * @return 名称占位符的SQL
*/ */
public String getSql() { public String getNamedSql() {
return this.sql; return namedSql;
} }
/** /**
* 获取参数列表按照占位符顺序 * 获取原始参数名和参数值对应关系参数表
* *
* @return 参数数组 * @return 参数名和参数值对应关系参数表
*/ */
public Object[] getParams() { public Map<String, Object> getParamMap() {
return this.params.toArray(new Object[0]); return paramMap;
}
/**
* 获取参数列表按照占位符顺序
*
* @return 参数列表
*/
public List<Object> getParamList() {
return this.params;
} }
/** /**

View File

@ -44,7 +44,7 @@ public class SqlExecutor {
*/ */
public static int execute(final Connection conn, final String sql, final Map<String, Object> paramMap) throws DbRuntimeException { public static int execute(final Connection conn, final String sql, final Map<String, Object> paramMap) throws DbRuntimeException {
final NamedSql namedSql = new NamedSql(sql, paramMap); final NamedSql namedSql = new NamedSql(sql, paramMap);
return execute(conn, namedSql.getSql(), namedSql.getParams()); return execute(conn, namedSql.getSql(), namedSql.getParamArray());
} }
/** /**
@ -125,7 +125,7 @@ public class SqlExecutor {
*/ */
public static Long executeForGeneratedKey(final Connection conn, final String sql, final Map<String, Object> paramMap) throws DbRuntimeException { public static Long executeForGeneratedKey(final Connection conn, final String sql, final Map<String, Object> paramMap) throws DbRuntimeException {
final NamedSql namedSql = new NamedSql(sql, paramMap); final NamedSql namedSql = new NamedSql(sql, paramMap);
return executeForGeneratedKey(conn, namedSql.getSql(), namedSql.getParams()); return executeForGeneratedKey(conn, namedSql.getSql(), namedSql.getParamArray());
} }
/** /**
@ -241,7 +241,7 @@ public class SqlExecutor {
*/ */
public static <T> T query(final Connection conn, final String sql, final RsHandler<T> rsh, final Map<String, Object> paramMap) throws DbRuntimeException { public static <T> T query(final Connection conn, final String sql, final RsHandler<T> rsh, final Map<String, Object> paramMap) throws DbRuntimeException {
final NamedSql namedSql = new NamedSql(sql, paramMap); final NamedSql namedSql = new NamedSql(sql, paramMap);
return query(conn, namedSql.getSql(), rsh, namedSql.getParams()); return query(conn, namedSql.getSql(), rsh, namedSql.getParamArray());
} }
/** /**

View File

@ -200,7 +200,7 @@ public class StatementBuilder implements Builder<StatementWrapper> {
// 检查参数是否为命名方式的参数 // 检查参数是否为命名方式的参数
final NamedSql namedSql = new NamedSql(sql, Convert.toMap(String.class, Object.class, params[0])); final NamedSql namedSql = new NamedSql(sql, Convert.toMap(String.class, Object.class, params[0]));
sql = namedSql.getSql(); sql = namedSql.getSql();
params = namedSql.getParams(); params = namedSql.getParamArray();
} }
sqlLog.log(sql, ArrayUtil.isEmpty(params) ? null : params); sqlLog.log(sql, ArrayUtil.isEmpty(params) ? null : params);

View File

@ -36,8 +36,8 @@ public class NamedSqlTest {
final NamedSql namedSql = new NamedSql(sql, paramMap); final NamedSql namedSql = new NamedSql(sql, paramMap);
//未指定参数原样输出 //未指定参数原样输出
Assertions.assertEquals("select * from table where id=@id and name = ? and nickName = ?", namedSql.getSql()); Assertions.assertEquals("select * from table where id=@id and name = ? and nickName = ?", namedSql.getSql());
Assertions.assertEquals("张三", namedSql.getParams()[0]); Assertions.assertEquals("张三", namedSql.getParamArray()[0]);
Assertions.assertEquals("小豆豆", namedSql.getParams()[1]); Assertions.assertEquals("小豆豆", namedSql.getParamArray()[1]);
} }
@Test @Test
@ -54,9 +54,9 @@ public class NamedSqlTest {
final NamedSql namedSql = new NamedSql(sql, paramMap); final NamedSql namedSql = new NamedSql(sql, paramMap);
Assertions.assertEquals("select * from table where id=? and name = ? and nickName = ?", namedSql.getSql()); Assertions.assertEquals("select * from table where id=? and name = ? and nickName = ?", namedSql.getSql());
//指定了null参数的依旧替换参数值为null //指定了null参数的依旧替换参数值为null
Assertions.assertNull(namedSql.getParams()[0]); Assertions.assertNull(namedSql.getParamArray()[0]);
Assertions.assertEquals("张三", namedSql.getParams()[1]); Assertions.assertEquals("张三", namedSql.getParamArray()[1]);
Assertions.assertEquals("小豆豆", namedSql.getParams()[2]); Assertions.assertEquals("小豆豆", namedSql.getParamArray()[2]);
} }
@Test @Test
@ -92,9 +92,9 @@ public class NamedSqlTest {
final NamedSql namedSql = new NamedSql(sql, paramMap); final NamedSql namedSql = new NamedSql(sql, paramMap);
Assertions.assertEquals("select * from user where id in (?,?,?)", namedSql.getSql()); Assertions.assertEquals("select * from user where id in (?,?,?)", namedSql.getSql());
Assertions.assertEquals(1, namedSql.getParams()[0]); Assertions.assertEquals(1, namedSql.getParamArray()[0]);
Assertions.assertEquals(2, namedSql.getParams()[1]); Assertions.assertEquals(2, namedSql.getParamArray()[1]);
Assertions.assertEquals(3, namedSql.getParams()[2]); Assertions.assertEquals(3, namedSql.getParamArray()[2]);
} }
@Test @Test