refactor: 将单列查询 Class 重载标记为过时,新增语义明确的方法
- 新增 queryValues(sql, args, Class) 替代 queryList(sql, args, Class) - 新增 queryValue(sql, args, Class) 替代 queryFirst(sql, args, Class) - 新增 queryValueOrDefault(sql, args, Class, defaultVal) 聚合查询便捷方法 - 旧方法标记 @Deprecated,委托至新方法,后续版本移除 - 更新 README 方法列表和示例代码 - 补充 queryValueOrDefault 单元测试 6 个
This commit is contained in:
19
CHANGELOG.md
19
CHANGELOG.md
@@ -6,6 +6,25 @@
|
||||
|
||||
- **`DefaultBeanRowMapper.of()` 不再抛出 `SQLException`**:工厂方法在反射异常时改为抛出非受检异常 `IllegalStateException`。调用方如果 `catch (SQLException e)` 包裹 `of()` 调用,该捕获将失效,需移除相关 `catch` 块或改为捕获 `IllegalStateException`。
|
||||
|
||||
### 新增
|
||||
|
||||
- `queryValueOrDefault(sql, params, Class<T>, T defaultValue)`:查询单行单列,结果为空时返回指定默认值
|
||||
- `queryValueOrDefault(sql, Class<T>, T defaultValue)`:无参数重载
|
||||
- 补充 `QueryTest` 中 `queryValueOrDefault` 单元测试 6 个
|
||||
|
||||
### 重构
|
||||
|
||||
**将单列查询方法标记为过时,消除 Class 参数重载歧义**
|
||||
|
||||
- `queryList(sql, params, Class<T>)` → 已过时,请使用 `queryValues(sql, params, Class<T>)`
|
||||
语义明确为"多行单列 → 值列表",不与整行 `RowMapper` 重载混淆
|
||||
- `queryFirst(sql, params, Class<T>)` → 已过时,请使用 `queryValue(sql, params, Class<T>)`
|
||||
语义明确为"单行单列 → 单值",不与整行 `RowMapper` 重载混淆
|
||||
- 同时将对应的无参数重载标记为过时:
|
||||
- `queryList(sql, Class<T>)` → 请使用 `queryValues(sql, Class<T>)`
|
||||
- `queryFirst(sql, Class<T>)` → 请使用 `queryValue(sql, Class<T>)`
|
||||
- 旧方法将在后续版本中移除
|
||||
|
||||
### 文档
|
||||
|
||||
- 优化 `DefaultBeanRowMapper` 类注释,明确性能限制和使用建议
|
||||
|
||||
18
README.md
18
README.md
@@ -78,7 +78,7 @@ List<Account> accounts = jdbcTemplate.query(
|
||||
);
|
||||
|
||||
// 查询列表(单列)
|
||||
List<String> usernames = jdbcTemplate.queryList(
|
||||
List<String> usernames = jdbcTemplate.queryValues(
|
||||
"SELECT username FROM account WHERE deleted = 0 AND username LIKE ? AND org_no = ?",
|
||||
buildParams("admin%", "0000"),
|
||||
String.class
|
||||
@@ -117,11 +117,18 @@ Optional<Account> account = jdbcTemplate.queryFirst(
|
||||
);
|
||||
|
||||
// 查询单个值(所有 ResultSet.getObject 支持的类型)
|
||||
Long count = jdbcTemplate.queryFirst(
|
||||
Long count = jdbcTemplate.queryValue(
|
||||
"SELECT COUNT(*) FROM account WHERE deleted = 0 AND username LIKE ? AND org_no = ?",
|
||||
buildParams("admin%", "0000"),
|
||||
Long.class
|
||||
).orElse(0L);
|
||||
// 或者
|
||||
Long count = jdbcTemplate.queryValueOrDefault(
|
||||
"SELECT COUNT(*) FROM account WHERE deleted = 0 AND username LIKE ? AND org_no = ?",
|
||||
buildParams("admin%", "0000"),
|
||||
Long.class,
|
||||
0L
|
||||
);
|
||||
|
||||
// 查询 Boolean 值
|
||||
boolean exists = jdbcTemplate.queryBoolean(
|
||||
@@ -245,14 +252,15 @@ jdbcTemplate.transaction().commitIfTrue(jdbc -> {
|
||||
| :--- | :--- |
|
||||
| `query(sql, params, resultHandler)` | 最基础的查询,通过 `ResultHandler` 自定义完整的映射逻辑。 |
|
||||
| `queryList(sql, params, rowMapper)` | 查询列表,通过 `RowMapper` 逐行映射。 |
|
||||
| `queryList(sql, params, Class)` | 单列查询列表,每行提取第一列并转换为指定类型。 |
|
||||
| `queryList(sql, params)` | 查询列表,每行自动转换为 `Map<String, Object>`。 |
|
||||
| `queryFirst(sql, params, rowMapper)` | 查询第一行,通过 `RowMapper` 映射,返回 `Optional<T>`。 |
|
||||
| `queryFirst(sql, params, Class)` | 查询第一行第一列,返回 `Optional<T>`。 |
|
||||
| `queryFirst(sql, params)` | 查询第一行,返回 `Optional<Map<String, Object>>`。 |
|
||||
| `queryValues(sql, params, Class)` | 单列查询列表,每行提取第一列并转换为指定类型。 |
|
||||
| `queryValue(sql, params, Class)` | 查询第一行第一列,返回 `Optional<T>`。 |
|
||||
| `queryValueOrDefault(sql, params, Class, default)` | 查询第一行第一列,结果为空时返回默认值。适用于 COUNT/SUM 等聚合查询。 |
|
||||
| `queryBoolean(sql, params)` | 查询第一行第一列并转换为 `boolean`,若结果为空则返回 `false`。 |
|
||||
|
||||
*💡 提示:以上方法均有省略 `params` 的重载(如 `queryList(sql, rowMapper)`),适用于不含占位符的 SQL 语句。*
|
||||
*💡 提示:以上方法均有省略 `params` 的重载(如 `queryList(sql, rowMapper)`),适用于不含占位符的 SQL 语句。`queryValues`、`queryValue`、`queryValueOrDefault` 同理。*
|
||||
|
||||
### 4.2 结果映射策略
|
||||
|
||||
|
||||
@@ -93,14 +93,14 @@ class JdbcOperationSupport {
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行查询,返回结果映射为指定的类型。当结果为单列时使用
|
||||
* 执行查询,只取结果集每行第一列的值,映射为指定类型并返回列表
|
||||
*
|
||||
* @param conn 数据库连接
|
||||
* @param sql SQL
|
||||
* @param params 参数
|
||||
* @param clazz 将结果映射为指定的类型
|
||||
*/
|
||||
static <T> List<T> queryList(Connection conn, String sql, Object[] params, Class<T> clazz)
|
||||
static <T> List<T> queryValues(Connection conn, String sql, Object[] params, Class<T> clazz)
|
||||
throws SQLException {
|
||||
assertConnectionNotNull(conn);
|
||||
assertSqlNotNull(sql);
|
||||
@@ -129,14 +129,15 @@ class JdbcOperationSupport {
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询第一行第一列,并转换为指定类型
|
||||
* 执行查询,只取结果集第一行第一列的值,映射为指定类型并返回
|
||||
*
|
||||
* @param conn 数据库连接
|
||||
* @param <T> 目标类型
|
||||
* @param sql SQL
|
||||
* @param params 参数
|
||||
* @param clazz 目标类型
|
||||
*/
|
||||
static <T> T queryFirst(Connection conn, String sql, Object[] params, Class<T> clazz)
|
||||
static <T> T queryValue(Connection conn, String sql, Object[] params, Class<T> clazz)
|
||||
throws SQLException {
|
||||
assertConnectionNotNull(conn);
|
||||
assertSqlNotNull(sql);
|
||||
|
||||
@@ -87,17 +87,18 @@ public interface JdbcOperations {
|
||||
throws SQLException;
|
||||
|
||||
/**
|
||||
* 执行查询,返回结果映射为指定的类型。当结果为单列时使用
|
||||
* 执行查询,只取结果集每行第一列的值,映射为指定类型并返回列表。
|
||||
* 适用于 {@code SELECT single_column FROM ...} 单列查询场景。
|
||||
*
|
||||
* @param <T> 目标类型
|
||||
* @param <T> 目标类型(对应结果集第一列的 Java 类型)
|
||||
* @param sql SQL
|
||||
* @param params 参数
|
||||
* @param clazz 目标类型
|
||||
*
|
||||
* @return 映射结果。如果查询结果为空,则返回空列表
|
||||
* @return 每一行第一列的值列表。如果查询结果为空,则返回空列表
|
||||
* @throws SQLException SQL异常
|
||||
*/
|
||||
<T> List<T> queryList(String sql, Object[] params, Class<T> clazz)
|
||||
<T> List<T> queryValues(String sql, Object[] params, Class<T> clazz)
|
||||
throws SQLException;
|
||||
|
||||
/**
|
||||
@@ -128,18 +129,39 @@ public interface JdbcOperations {
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行查询,返回结果映射为指定的类型。当结果为单列时使用
|
||||
* 执行查询,只取结果集每行第一列的值,映射为指定类型并返回列表。
|
||||
* 适用于 {@code SELECT single_column FROM ...} 单列查询场景。
|
||||
*
|
||||
* @param <T> 目标类型
|
||||
* @param sql SQL
|
||||
* @param clazz 将结果映射为指定的类型
|
||||
*
|
||||
* @return 查询结果
|
||||
* @return 每一行第一列的值列表。如果查询结果为空,则返回空列表
|
||||
* @throws SQLException SQL 异常
|
||||
*/
|
||||
default <T> List<T> queryValues(String sql, Class<T> clazz)
|
||||
throws SQLException {
|
||||
return queryValues(sql, ParamBuilder.EMPTY_OBJECT_ARRAY, clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 自 1.1.0 起,请使用 {@link #queryValues(String, Object[], Class)}。
|
||||
* 此方法将在后续版本中移除。
|
||||
*/
|
||||
@Deprecated
|
||||
default <T> List<T> queryList(String sql, Object[] params, Class<T> clazz)
|
||||
throws SQLException {
|
||||
return queryValues(sql, params, clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 自 1.1.0 起,请使用 {@link #queryValues(String, Class)}。
|
||||
* 此方法将在后续版本中移除。
|
||||
*/
|
||||
@Deprecated
|
||||
default <T> List<T> queryList(String sql, Class<T> clazz)
|
||||
throws SQLException {
|
||||
return queryList(sql, ParamBuilder.EMPTY_OBJECT_ARRAY, clazz);
|
||||
return queryValues(sql, clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -174,17 +196,18 @@ public interface JdbcOperations {
|
||||
throws SQLException;
|
||||
|
||||
/**
|
||||
* 查询第一行第一列,并转换为指定类型
|
||||
* 执行查询,只取结果集第一行第一列的值,映射为指定类型并返回。
|
||||
* 适用于 {@code SELECT single_column FROM ... WHERE ...} 单列单行查询场景。
|
||||
*
|
||||
* @param <T> 目标类型
|
||||
* @param sql SQL
|
||||
* @param params 参数
|
||||
* @param clazz 目标类型
|
||||
*
|
||||
* @return 查询结果
|
||||
* @return 第一行第一列的值。如果查询结果为空,则返回 {@code Optional.empty()}
|
||||
* @throws SQLException SQL 异常
|
||||
*/
|
||||
<T> Optional<T> queryFirst(String sql, Object[] params, Class<T> clazz)
|
||||
<T> Optional<T> queryValue(String sql, Object[] params, Class<T> clazz)
|
||||
throws SQLException;
|
||||
|
||||
/**
|
||||
@@ -215,18 +238,39 @@ public interface JdbcOperations {
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询第一行第一列,并转换为指定类型
|
||||
* 执行查询,只取结果集第一行第一列的值,映射为指定类型并返回。
|
||||
* 适用于 {@code SELECT single_column FROM ... WHERE ...} 单列单行查询场景。
|
||||
*
|
||||
* @param <T> 目标类型
|
||||
* @param sql SQL
|
||||
* @param clazz 目标类型
|
||||
*
|
||||
* @return 第一行第一列的值,如果查询结果为空,则返回 {@code Optional#empty()}
|
||||
* @return 第一行第一列的值,如果查询结果为空,则返回 {@code Optional.empty()}
|
||||
* @throws SQLException SQL 异常
|
||||
*/
|
||||
default <T> Optional<T> queryValue(String sql, Class<T> clazz)
|
||||
throws SQLException {
|
||||
return queryValue(sql, ParamBuilder.EMPTY_OBJECT_ARRAY, clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 自 1.1.0 起,请使用 {@link #queryValue(String, Object[], Class)}。
|
||||
* 此方法将在后续版本中移除。
|
||||
*/
|
||||
@Deprecated
|
||||
default <T> Optional<T> queryFirst(String sql, Object[] params, Class<T> clazz)
|
||||
throws SQLException {
|
||||
return queryValue(sql, params, clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 自 1.1.0 起,请使用 {@link #queryValue(String, Class)}。
|
||||
* 此方法将在后续版本中移除。
|
||||
*/
|
||||
@Deprecated
|
||||
default <T> Optional<T> queryFirst(String sql, Class<T> clazz)
|
||||
throws SQLException {
|
||||
return queryFirst(sql, ParamBuilder.EMPTY_OBJECT_ARRAY, clazz);
|
||||
return queryValue(sql, clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -242,6 +286,43 @@ public interface JdbcOperations {
|
||||
return queryFirst(sql, ParamBuilder.EMPTY_OBJECT_ARRAY);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行查询,只取结果集第一行第一列的值,映射为指定类型并返回。
|
||||
* 如果查询结果为空,则返回指定的默认值。
|
||||
* 适用于 {@code SELECT COUNT(*)}、{@code SELECT MAX(...)} 等聚合查询场景。
|
||||
*
|
||||
* @param <T> 目标类型
|
||||
* @param sql SQL
|
||||
* @param params 参数
|
||||
* @param clazz 目标类型
|
||||
* @param defaultValue 查询结果为空时返回的默认值
|
||||
*
|
||||
* @return 第一行第一列的值,如果查询结果为空则返回 {@code defaultValue}
|
||||
* @throws SQLException SQL 异常
|
||||
*/
|
||||
default <T> T queryValueOrDefault(String sql, Object[] params, Class<T> clazz, T defaultValue)
|
||||
throws SQLException {
|
||||
return queryValue(sql, params, clazz).orElse(defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行查询,只取结果集第一行第一列的值,映射为指定类型并返回。
|
||||
* 如果查询结果为空,则返回指定的默认值。
|
||||
* 适用于 {@code SELECT COUNT(*)}、{@code SELECT MAX(...)} 等聚合查询场景。
|
||||
*
|
||||
* @param <T> 目标类型
|
||||
* @param sql SQL
|
||||
* @param clazz 目标类型
|
||||
* @param defaultValue 查询结果为空时返回的默认值
|
||||
*
|
||||
* @return 第一行第一列的值,如果查询结果为空则返回 {@code defaultValue}
|
||||
* @throws SQLException SQL 异常
|
||||
*/
|
||||
default <T> T queryValueOrDefault(String sql, Class<T> clazz, T defaultValue)
|
||||
throws SQLException {
|
||||
return queryValueOrDefault(sql, ParamBuilder.EMPTY_OBJECT_ARRAY, clazz, defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询第一行第一列并转换为 boolean
|
||||
*
|
||||
|
||||
@@ -96,10 +96,10 @@ public class SimpleJdbcTemplate implements JdbcOperations {
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public <T> List<T> queryList(String sql, Object[] params, Class<T> clazz)
|
||||
public <T> List<T> queryValues(String sql, Object[] params, Class<T> clazz)
|
||||
throws SQLException {
|
||||
try (Connection conn = this.dataSource.getConnection()) {
|
||||
return JdbcOperationSupport.queryList(conn, sql, params, clazz);
|
||||
return JdbcOperationSupport.queryValues(conn, sql, params, clazz);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,10 +128,10 @@ public class SimpleJdbcTemplate implements JdbcOperations {
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public <T> Optional<T> queryFirst(String sql, Object[] params, Class<T> clazz)
|
||||
public <T> Optional<T> queryValue(String sql, Object[] params, Class<T> clazz)
|
||||
throws SQLException {
|
||||
try (Connection conn = this.dataSource.getConnection()) {
|
||||
final T result = JdbcOperationSupport.queryFirst(conn, sql, params, clazz);
|
||||
final T result = JdbcOperationSupport.queryValue(conn, sql, params, clazz);
|
||||
return Optional.ofNullable(result);
|
||||
}
|
||||
}
|
||||
@@ -153,7 +153,7 @@ public class SimpleJdbcTemplate implements JdbcOperations {
|
||||
throws SQLException {
|
||||
try (Connection conn = this.dataSource.getConnection()) {
|
||||
final Boolean result = JdbcOperationSupport
|
||||
.queryFirst(conn, sql, params, Boolean.class);
|
||||
.queryValue(conn, sql, params, Boolean.class);
|
||||
return Boolean.TRUE.equals(result);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,9 +181,9 @@ public class TransactionTemplate {
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public <T> List<T> queryList(String sql, Object[] params, Class<T> clazz)
|
||||
public <T> List<T> queryValues(String sql, Object[] params, Class<T> clazz)
|
||||
throws SQLException {
|
||||
return JdbcOperationSupport.queryList(this.conn, sql, params, clazz);
|
||||
return JdbcOperationSupport.queryValues(this.conn, sql, params, clazz);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@@ -207,9 +207,9 @@ public class TransactionTemplate {
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public <T> Optional<T> queryFirst(String sql, Object[] params, Class<T> clazz)
|
||||
public <T> Optional<T> queryValue(String sql, Object[] params, Class<T> clazz)
|
||||
throws SQLException {
|
||||
final T result = JdbcOperationSupport.queryFirst(this.conn, sql, params, clazz);
|
||||
final T result = JdbcOperationSupport.queryValue(this.conn, sql, params, clazz);
|
||||
return Optional.ofNullable(result);
|
||||
}
|
||||
|
||||
@@ -227,7 +227,7 @@ public class TransactionTemplate {
|
||||
public boolean queryBoolean(String sql, Object[] params)
|
||||
throws SQLException {
|
||||
final Boolean result = JdbcOperationSupport
|
||||
.queryFirst(this.conn, sql, params, Boolean.class);
|
||||
.queryValue(this.conn, sql, params, Boolean.class);
|
||||
return Boolean.TRUE.equals(result);
|
||||
}
|
||||
|
||||
|
||||
@@ -199,7 +199,7 @@ class BatchUpdateTest extends BaseH2Test {
|
||||
void testBatchUpdateQuietlyFalseInterrupted() throws SQLException {
|
||||
SimpleJdbcTemplate template = createTemplate();
|
||||
|
||||
int count0 = template.queryFirst("SELECT COUNT(*) FROM users", Integer.class)
|
||||
int count0 = template.queryValue("SELECT COUNT(*) FROM users", Integer.class)
|
||||
.orElse(0);
|
||||
|
||||
List<Object[]> params = buildBatchParams(userListContainingInvalidData, a -> new Object[] { a.getUsername(), a.getEmail(), a.getAge(), a.getBalance(), a.getActive() });
|
||||
@@ -231,7 +231,7 @@ class BatchUpdateTest extends BaseH2Test {
|
||||
assertNull(result.getUpdateCounts(3));
|
||||
assertNull(result.getUpdateCounts(4));
|
||||
|
||||
Optional<Integer> count8 = template.queryFirst("SELECT COUNT(*) FROM users", Integer.class);
|
||||
Optional<Integer> count8 = template.queryValue("SELECT COUNT(*) FROM users", Integer.class);
|
||||
assertEquals(count0 + 8, count8.get().intValue());
|
||||
}
|
||||
|
||||
@@ -242,7 +242,7 @@ class BatchUpdateTest extends BaseH2Test {
|
||||
void testBatchUpdateQuietlyTrue() throws SQLException {
|
||||
SimpleJdbcTemplate template = createTemplate();
|
||||
|
||||
int count0 = template.queryFirst("SELECT COUNT(*) FROM users", Integer.class)
|
||||
int count0 = template.queryValue("SELECT COUNT(*) FROM users", Integer.class)
|
||||
.orElse(0);
|
||||
|
||||
List<Object[]> params = buildBatchParams(userListContainingInvalidData, a -> new Object[] { a.getUsername(), a.getEmail(), a.getAge(), a.getBalance(), a.getActive() });
|
||||
@@ -261,7 +261,7 @@ class BatchUpdateTest extends BaseH2Test {
|
||||
assertArrayEquals(new int[] { Statement.EXECUTE_FAILED, 1, 1 }, result.getUpdateCounts(3));
|
||||
assertArrayEquals(new int[] { 1 }, result.getUpdateCounts(4));
|
||||
|
||||
Optional<Integer> count11 = template.queryFirst("SELECT COUNT(*) FROM users", Integer.class);
|
||||
Optional<Integer> count11 = template.queryValue("SELECT COUNT(*) FROM users", Integer.class);
|
||||
assertEquals(count0 + 11, count11.get().intValue());
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ import xyz.zhouxy.jdbc.ResultHandler;
|
||||
import xyz.zhouxy.jdbc.SimpleJdbcTemplate;
|
||||
|
||||
/**
|
||||
* 查询 API 测试:query、queryList、queryFirst、queryBoolean。
|
||||
* 查询 API 测试:query、queryList、queryFirst、queryValues、queryValue、queryBoolean。
|
||||
*/
|
||||
@DisplayName("SimpleJdbcTemplate 查询操作")
|
||||
class QueryTest extends BaseH2Test {
|
||||
@@ -119,28 +119,28 @@ class QueryTest extends BaseH2Test {
|
||||
assertEquals(5, users.size());
|
||||
}
|
||||
|
||||
// ==================== queryList(Class) ====================
|
||||
// ==================== queryValues(Class) ====================
|
||||
|
||||
@Test
|
||||
@DisplayName("queryList(Class):单列查询返回 String 列表")
|
||||
void testQueryListWithClassString() throws SQLException {
|
||||
@DisplayName("queryValues(Class):单列查询返回 String 列表")
|
||||
void testQueryValuesWithClassString() throws SQLException {
|
||||
SimpleJdbcTemplate template = createTemplate();
|
||||
|
||||
List<String> usernames = template.queryList(
|
||||
List<String> usernames = template.queryValues(
|
||||
"SELECT username FROM users ORDER BY id",
|
||||
String.class);
|
||||
|
||||
logger.info("queryList(Class) 返回用户名: {}", usernames);
|
||||
logger.info("queryValues(Class) 返回用户名: {}", usernames);
|
||||
assertEquals(5, usernames.size());
|
||||
assertTrue(usernames.contains("alice"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("queryList(Class):空结果集返回空列表")
|
||||
void testQueryListEmptyResult() throws SQLException {
|
||||
@DisplayName("queryValues(Class):空结果集返回空列表")
|
||||
void testQueryValuesEmptyResult() throws SQLException {
|
||||
SimpleJdbcTemplate template = createTemplate();
|
||||
|
||||
List<String> result = template.queryList(
|
||||
List<String> result = template.queryValues(
|
||||
"SELECT username FROM users WHERE id = ?",
|
||||
buildParams(999), String.class);
|
||||
|
||||
@@ -215,14 +215,14 @@ class QueryTest extends BaseH2Test {
|
||||
assertTrue(user.isPresent());
|
||||
}
|
||||
|
||||
// ==================== queryFirst(Class) ====================
|
||||
// ==================== queryValue(Class) ====================
|
||||
|
||||
@Test
|
||||
@DisplayName("queryFirst(Class):查询第一行第一列")
|
||||
void testQueryFirstWithClass() throws SQLException {
|
||||
@DisplayName("queryValue(Class):查询第一行第一列")
|
||||
void testQueryValueWithClass() throws SQLException {
|
||||
SimpleJdbcTemplate template = createTemplate();
|
||||
|
||||
Optional<String> username = template.queryFirst(
|
||||
Optional<String> username = template.queryValue(
|
||||
"SELECT username FROM users ORDER BY id",
|
||||
String.class);
|
||||
|
||||
@@ -231,11 +231,11 @@ class QueryTest extends BaseH2Test {
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("queryFirst(Class):空结果返回 Optional.empty()")
|
||||
void testQueryFirstClassEmpty() throws SQLException {
|
||||
@DisplayName("queryValue(Class):空结果返回 Optional.empty()")
|
||||
void testQueryValueClassEmpty() throws SQLException {
|
||||
SimpleJdbcTemplate template = createTemplate();
|
||||
|
||||
Optional<String> result = template.queryFirst(
|
||||
Optional<String> result = template.queryValue(
|
||||
"SELECT username FROM users WHERE id = ?",
|
||||
buildParams(999), String.class);
|
||||
|
||||
@@ -244,11 +244,11 @@ class QueryTest extends BaseH2Test {
|
||||
|
||||
|
||||
@Test
|
||||
@DisplayName("queryFirst + Class:统计总行数")
|
||||
void testQueryFirstWithClass_queryCount() throws SQLException {
|
||||
@DisplayName("queryValue + Class:统计总行数")
|
||||
void testQueryValueWithClass_queryCount() throws SQLException {
|
||||
SimpleJdbcTemplate template = createTemplate();
|
||||
|
||||
int count = template.queryFirst(
|
||||
int count = template.queryValue(
|
||||
"SELECT COUNT(*) FROM users",
|
||||
new Object[0],
|
||||
Integer.class)
|
||||
@@ -259,11 +259,11 @@ class QueryTest extends BaseH2Test {
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("queryFirst + Class:聚合求和")
|
||||
void testQueryFirstWithClass_queryAggregation() throws SQLException {
|
||||
@DisplayName("queryValue + Class:聚合求和")
|
||||
void testQueryValueWithClass_queryAggregation() throws SQLException {
|
||||
SimpleJdbcTemplate template = createTemplate();
|
||||
|
||||
Long totalBalance = template.queryFirst(
|
||||
Long totalBalance = template.queryValue(
|
||||
"SELECT SUM(balance) FROM users",
|
||||
new Object[0],
|
||||
Long.class)
|
||||
@@ -273,6 +273,81 @@ class QueryTest extends BaseH2Test {
|
||||
assertNotNull(totalBalance);
|
||||
}
|
||||
|
||||
// ==================== queryValueOrDefault ====================
|
||||
|
||||
@Test
|
||||
@DisplayName("queryValueOrDefault:有结果时返回值")
|
||||
void testQueryValueOrDefaultWithResult() throws SQLException {
|
||||
SimpleJdbcTemplate template = createTemplate();
|
||||
|
||||
String username = template.queryValueOrDefault(
|
||||
"SELECT username FROM users WHERE id = ?",
|
||||
new Object[]{1}, String.class, "default");
|
||||
|
||||
assertEquals("alice", username);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("queryValueOrDefault:无结果时返回默认值")
|
||||
void testQueryValueOrDefaultWithDefault() throws SQLException {
|
||||
SimpleJdbcTemplate template = createTemplate();
|
||||
|
||||
String username = template.queryValueOrDefault(
|
||||
"SELECT username FROM users WHERE id = ?",
|
||||
new Object[]{999}, String.class, "unknown");
|
||||
|
||||
assertEquals("unknown", username);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("queryValueOrDefault:COUNT 聚合查询")
|
||||
void testQueryValueOrDefaultCount() throws SQLException {
|
||||
SimpleJdbcTemplate template = createTemplate();
|
||||
|
||||
long count = template.queryValueOrDefault(
|
||||
"SELECT COUNT(*) FROM users",
|
||||
new Object[0], Long.class, 0L);
|
||||
|
||||
assertEquals(5L, count);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("queryValueOrDefault:SUM 聚合查询")
|
||||
void testQueryValueOrDefaultSum() throws SQLException {
|
||||
SimpleJdbcTemplate template = createTemplate();
|
||||
|
||||
long totalBalance = template.queryValueOrDefault(
|
||||
"SELECT SUM(balance) FROM users",
|
||||
new Object[0], Long.class, 0L);
|
||||
|
||||
assertTrue(totalBalance > 0);
|
||||
logger.info("queryValueOrDefault SUM 结果: {}", totalBalance);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("queryValueOrDefault:无参数重载")
|
||||
void testQueryValueOrDefaultNoParams() throws SQLException {
|
||||
SimpleJdbcTemplate template = createTemplate();
|
||||
|
||||
long count = template.queryValueOrDefault(
|
||||
"SELECT COUNT(*) FROM users",
|
||||
Long.class, 0L);
|
||||
|
||||
assertEquals(5L, count);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("queryValueOrDefault:空表 COUNT 返回默认值 0")
|
||||
void testQueryValueOrDefaultEmptyTable() throws SQLException {
|
||||
SimpleJdbcTemplate template = createTemplate();
|
||||
|
||||
long count = template.queryValueOrDefault(
|
||||
"SELECT COUNT(*) FROM users WHERE id = ?",
|
||||
new Object[]{999}, Long.class, 0L);
|
||||
|
||||
assertEquals(0L, count);
|
||||
}
|
||||
|
||||
// ==================== queryFirst(Map) ====================
|
||||
|
||||
@Test
|
||||
@@ -385,7 +460,7 @@ class QueryTest extends BaseH2Test {
|
||||
SimpleJdbcTemplate template = createTemplate();
|
||||
|
||||
assertThrows(SQLException.class, () ->
|
||||
template.queryList("SELECT * FROM non_existent_table",
|
||||
template.queryValues("SELECT * FROM non_existent_table",
|
||||
new Object[0], String.class));
|
||||
}
|
||||
|
||||
@@ -395,7 +470,7 @@ class QueryTest extends BaseH2Test {
|
||||
SimpleJdbcTemplate template = createTemplate();
|
||||
|
||||
assertThrows(SQLException.class, () ->
|
||||
template.queryList("SELEC * FROM users",
|
||||
template.queryValues("SELEC * FROM users",
|
||||
new Object[0], String.class));
|
||||
}
|
||||
|
||||
|
||||
@@ -44,12 +44,12 @@ class TransactionTest extends BaseH2Test {
|
||||
});
|
||||
|
||||
// 验证事务已提交
|
||||
Optional<String> newUser = template.queryFirst(
|
||||
Optional<String> newUser = template.queryValue(
|
||||
"SELECT username FROM users WHERE username = ?",
|
||||
buildParams("txUser1"), String.class);
|
||||
assertTrue(newUser.isPresent());
|
||||
|
||||
Optional<Long> balance = template.queryFirst(
|
||||
Optional<Long> balance = template.queryValue(
|
||||
"SELECT balance FROM users WHERE username = ?",
|
||||
buildParams("alice"), Long.class);
|
||||
assertEquals(Long.valueOf(99999L), balance.orElse(null));
|
||||
@@ -65,7 +65,7 @@ class TransactionTest extends BaseH2Test {
|
||||
SimpleJdbcTemplate template = createTemplate();
|
||||
|
||||
// 记录原始 balance
|
||||
Optional<Long> originalBalance = template.queryFirst(
|
||||
Optional<Long> originalBalance = template.queryValue(
|
||||
"SELECT balance FROM users WHERE username = ?",
|
||||
buildParams("alice"), Long.class);
|
||||
|
||||
@@ -85,13 +85,13 @@ class TransactionTest extends BaseH2Test {
|
||||
assertEquals("模拟业务异常", ex.getCause().getMessage());
|
||||
|
||||
// 验证更新已回滚
|
||||
Optional<Long> currentBalance = template.queryFirst(
|
||||
Optional<Long> currentBalance = template.queryValue(
|
||||
"SELECT balance FROM users WHERE username = ?",
|
||||
buildParams("alice"), Long.class);
|
||||
assertEquals(originalBalance.orElse(null), currentBalance.orElse(null));
|
||||
|
||||
// 验证插入已回滚
|
||||
Optional<String> rolledBackUser = template.queryFirst(
|
||||
Optional<String> rolledBackUser = template.queryValue(
|
||||
"SELECT username FROM users WHERE username = ?",
|
||||
buildParams("txUser2"), String.class);
|
||||
assertFalse(rolledBackUser.isPresent());
|
||||
@@ -114,7 +114,7 @@ class TransactionTest extends BaseH2Test {
|
||||
|
||||
// 验证插入已回滚
|
||||
assertDoesNotThrow(() -> {
|
||||
Optional<String> user = template.queryFirst(
|
||||
Optional<String> user = template.queryValue(
|
||||
"SELECT username FROM users WHERE username = ?",
|
||||
buildParams("validUser"), String.class);
|
||||
assertFalse(user.isPresent());
|
||||
@@ -135,7 +135,7 @@ class TransactionTest extends BaseH2Test {
|
||||
});
|
||||
|
||||
// 验证数据已持久化
|
||||
Optional<String> user = template.queryFirst(
|
||||
Optional<String> user = template.queryValue(
|
||||
"SELECT username FROM users WHERE username = ?",
|
||||
buildParams("cftUser"), String.class);
|
||||
assertTrue(user.isPresent());
|
||||
@@ -155,7 +155,7 @@ class TransactionTest extends BaseH2Test {
|
||||
});
|
||||
|
||||
// 验证数据已回滚
|
||||
Optional<String> user = template.queryFirst(
|
||||
Optional<String> user = template.queryValue(
|
||||
"SELECT username FROM users WHERE username = ?",
|
||||
buildParams("cffUser"), String.class);
|
||||
assertFalse(user.isPresent());
|
||||
@@ -177,7 +177,7 @@ class TransactionTest extends BaseH2Test {
|
||||
|
||||
// 验证回滚
|
||||
assertDoesNotThrow(() -> {
|
||||
Optional<String> user = template.queryFirst(
|
||||
Optional<String> user = template.queryValue(
|
||||
"SELECT username FROM users WHERE username = ?",
|
||||
buildParams("exUser"), String.class);
|
||||
assertFalse(user.isPresent());
|
||||
@@ -196,7 +196,7 @@ class TransactionTest extends BaseH2Test {
|
||||
buildParams("visible", "visible@test.com"));
|
||||
|
||||
// 在同一事务内可以查询到刚插入的数据
|
||||
Optional<String> user = ops.queryFirst(
|
||||
Optional<String> user = ops.queryValue(
|
||||
"SELECT username FROM users WHERE username = ?",
|
||||
buildParams("visible"), String.class);
|
||||
assertTrue(user.isPresent());
|
||||
|
||||
Reference in New Issue
Block a user