Compare commits

..

9 Commits

Author SHA1 Message Date
52f82d69e8 chore: add lincese header 2025-07-29 17:35:24 +08:00
e0c8b0d46e docs: 更新 author 信息 2025-07-29 17:08:57 +08:00
d21a935647 docs: 更新项目文档与配置 (#1 from gitee)
* docs(README): 更新项目文档
* chore: 修改 Markdown 文件的缩进设置
* chore: 更新 .gitignore
* chore: 删除 IntelliJ IDEA 的配置
2025-07-29 09:00:23 +00:00
94e38d062d style: 优化测试数据库表的创建语句格式 (plusone/simple-jdbc#8 from gitea)
- 使用反引号括起字段名
- 调整字段间的空格和换行

Signed-off-by: ZhouXY108 <luquanlion@outlook.com>
2025-07-26 03:25:20 +08:00
15c8970522 build: 更新项目配置和依赖版本 (plusone/simple-jdbc#7 from gitea)
- 添加项目名称、描述和 URL
- 更新 plusone-dependencies 和 plusone-commons 依赖版本
2025-07-26 03:17:47 +08:00
748cf430b3 chore: 设置 SQL 文件缩进为 2 个空格 (plusone/simple-jdbc#6 from gitea)
在 .editorconfig 文件中设置 SQL 文件的 indent_size 为 2
2025-07-26 03:04:01 +08:00
ad7320c280 docs: 优化 javadoc 2025-06-02 00:18:29 +08:00
973552b7d1 build: 简化 JUnit 依赖声明
Reviewed-on: http://zhouxy.xyz:3000/ZhouXY108/simple-jdbc/pulls/5
Co-authored-by: ZhouXY108 <luquanlion@outlook.com>
Co-committed-by: ZhouXY108 <luquanlion@outlook.com>
2025-05-28 20:28:51 +08:00
07b5199219 refactor: 重构单元测试中的表和数据的初始化
将表结构和初始数据的SQL放在 *.sql 文件中,使单元测试代码更清晰。

Reviewed-on: http://zhouxy.xyz:3000/ZhouXY108/simple-jdbc/pulls/4
Co-authored-by: ZhouXY108 <luquanlion@outlook.com>
Co-committed-by: ZhouXY108 <luquanlion@outlook.com>
2025-05-28 20:27:32 +08:00
19 changed files with 306 additions and 126 deletions

View File

@@ -10,3 +10,9 @@ end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.sql]
indent_size = 2
[*.md]
indent_size = 2

5
.gitignore vendored
View File

@@ -4,10 +4,7 @@ target/
!**/src/test/**/target/
### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
.idea/
*.iws
*.iml
*.ipr

3
.idea/.gitignore generated vendored
View File

@@ -1,3 +0,0 @@
# 默认忽略的文件
/shelf/
/workspace.xml

7
.idea/encodings.xml generated
View File

@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
</component>
</project>

View File

@@ -1,6 +0,0 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="NonSerializableWithSerialVersionUIDField" enabled="true" level="WARNING" enabled_by_default="true" />
</profile>
</component>

14
.idea/misc.xml generated
View File

@@ -1,14 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

6
.idea/vcs.xml generated
View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

179
README.md
View File

@@ -1,6 +1,181 @@
# SimpleJDBC
对 JDBC 的简单封装。
之前遇到的一个老项目,没有引入任何 ORM 框架,使用的 JDK7 明明支持泛型,所依赖的 spring-jdbc 居然是没有泛型的远古版本,该项目又不允许随意添加依赖,对数据库的操作几乎都在写原生 JDBC。故自己写了几个工具类对 JDBC 进行简单封装,后来逐渐改进完善
之前遇到的一个老项目,没有引入任何 ORM 框架,对数据库的操作几乎都在写原生 JDBC。故自己写了几个工具类对 JDBC 进行简单封装。
本项目不比成熟的工具,如若使用请自行承担风险。建议仅作为 JDBC 的学习参考。
## 查询
### 查询方法
- `query`**最基础的查询方法**。可使用 `ResultHandler` 将查询结果映射为 Java 对象。
- `queryList`**查询列表**。可使用 `RowMapper` 将结果的每一行数据映射为 Java 对象,返回列表。
- `queryFirst`**查询,并获取第一行数据**。一般可以结合 `LIMIT 1` 使用。可使用 `RowMapper` 将结果的第一行数据映射为 Java 对象,返回 `Optional`
- `queryFirstXXX`**查询,并获取第一行数据的第一个字段**,并转换为对应类型,返回对应的类型的 `Optional`
- `queryAsBoolean`**查询,并获取第一行数据的第一个字段**,并转换为布尔类型。如果结果为空,则返回 `false`
### 结果映射
- `ResultHandler` 用于处理查询结果,自定义逻辑将完整的 `ResultSet` 映射为 Java 对象。 *结果可以是任意类型(包括集合)。*
- `RowMapper` 用于将 `ResultSet` 中的一行数据映射为 Java 对象。
- `RowMapper#HASH_MAP_MAPPER`:将 `ResultSet` 中的一行数据映射为 `HashMap`
- `RowMapper#beanRowMapper`:返回将 `ResultSet` 转换为 Java Bean 的默认实现。
## 更新
- `int update`**执行 DML**,包括 `INSERT``UPDATE``DELETE` 等。返回受影响行数。
- `<T> List<T> update`**执行 DML**,自动生成的字段将使用 `rowMapper` 进行映射,并返回列表。
- `List<int[]> batchUpdate`**分批次执行 DML**,返回每个批次的每条 SQL 语句影响的行数。
- `List<int[]> batchUpdateAndIgnoreException`**分批次执行 DML如果某个批次出现异常继续执行下一个批次**。返回每个批次的每条 SQL 语句影响的行数。
## 事务
- `executeTransaction`**执行事务**。传入一个 `ThrowingConsumer` 函数,入参是一个 `JdbcExecutor` 对象,在 `ThrowingConsumer` 内使用该入参执行 jdbc 操作。如果 `ThrowingConsumer` 内部有异常抛出,这些操作将被回滚。
- `commitIfTrue`**执行事务**。传入一个 `ThrowingPredicate` 函数,入参是一个 `JdbcExecutor` 对象,在 `ThrowingPredicate` 内使用该入参执行 jdbc 操作。如果`ThrowingPredicate` 返回 `true`,则提交事务;如果返回 `false` 或有异常抛出,则回滚这些操作。
## 参数构建
此项目中的所有查询和更新的方法,都**不使用可变长入参**,避免强行将 SQL 语句的参数列表放在最后,也避免和数组发生歧义。
### 构建参数列表
可使用 `ParamBuilder#buildParams` 构建 `Object[]` 数组作为 SQL 的参数列表。该方法会自动将 `Optional` 中的值“拆”出来。
### 批量构建参数列表
使用 `ParamBuilder#buildBatchParams`,将使用传入的函数,将集合中的每一个元素转为 `Object[]`,并返回一个 `List<Object[]>`
## 示例
创建 SimpleJdbcTemplate 对象
```java
SimpleJdbcTemplate jdbcTemplate = new SimpleJdbcTemplate(dataSource);
```
查询
```java
// 查询
List<Account> list = jdbcTemplate.query(
"SELECT * FROM account WHERE deleted = 0 AND username LIKE ? AND org_no = ?",
buildParams("admin%", "0000"),
rs -> {
List<T> result = new ArrayList<>();
while (rs.next()) {
result.add(new Account(
rs.getLong("id"),
rs.getString("username"),
rs.getString("password"),
rs.getString("org_no"),
rs.getTimestamp("create_time"),
rs.getTimestamp("update_time")
));
}
return result;
}
);
// 查询列表
List<Account> list = jdbcTemplate.queryList(
"SELECT * FROM account WHERE deleted = 0 AND username LIKE ? AND org_no = ?",
buildParams("admin%", "0000"),
(rs, rowNum) -> new Account(
rs.getLong("id"),
rs.getString("username"),
rs.getString("password"),
rs.getString("org_no"),
rs.getTimestamp("create_time"),
rs.getTimestamp("update_time")
)
);
// 查询一行数据
Optional<Account> account = jdbcTemplate.queryFirst(
"SELECT * FROM account WHERE deleted = 0 AND id = ?",
buildParams(10000L),
(rs, rowNum) -> new Account(
rs.getLong("id"),
rs.getString("username"),
rs.getString("password"),
rs.getString("org_no"),
rs.getTimestamp("create_time"),
)
)
// 查询一行数据,并获取第一个字段
OptionalInt age = jdbcTemplate.queryFirstInt(
"SELECT age FROM view_account WHERE deleted = 0 AND id = ?",
buildParams(10000L)
);
// 查询 boolean
boolean exists = jdbcTemplate.queryAsBoolean(
"SELECT EXISTS(SELECT 1 FROM account WHERE deleted = 0 AND id = ? LIMIT 1)",
buildParams(10000L)
);
```
更新
```java
// 执行 DML
int affectedRows = jdbcTemplate.update(
"UPDATE account SET deleted = 1 WHERE id = ?",
buildParams(10000L)
);
// 执行 DML并获取生成的主键
List<Pair<Long, LocalDateTime>> keys = jdbcTemplate.update(
"INSERT INTO account (username, password, org_no) VALUES (?, ?, ?)",
buildParams("admin", "123456", "0000"),
(rs, rowNum) -> Pair.of(
rs.getLong("id"),
rs.getObject("create_time", LocalDateTime.class)
)
);
```
批量更新
```java
jdbcTemplate.batchUpdate(
"INSERT INTO account (username, password, org_no) VALUES (?, ?, ?)",
buildBatchParams(accountList, account -> buildParams(
account.getUsername(),
account.getPassword(),
account.getOrgNo()
)),
100 // 每100条数据一个批次
);
```
事务
```java
jdbcTemplate.executeTransaction(jdbc -> {
...
jdbc.update(...);
...
jdbc.update(...);
...
});
jdbcTemplate.commitIfTrue(jdbc -> {
...
jdbc.update(...);
...
if (...) {
// 中断操作并回滚
return false;
}
...
if (...) {
// 某些条件下提前结束并提交事务
return true;
}
...
jdbc.update(...);
...
// 提交事务
return true;
});
```
>**!!!本项目不比成熟的工具,如若使用请自行承担风险。建议仅作为 JDBC 的学习参考。**

17
pom.xml
View File

@@ -8,10 +8,16 @@
<artifactId>simple-jdbc</artifactId>
<version>1.0.0-alpha</version>
<name>Simple JDBC</name>
<description>对 JDBC 的简单封装。</description>
<url>http://gitea.zhouxy.xyz/plusone/simple-jdbc</url>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<plusone-commons.version>1.1.0-RC1</plusone-commons.version>
</properties>
<dependencyManagement>
@@ -19,7 +25,7 @@
<dependency>
<groupId>xyz.zhouxy.plusone</groupId>
<artifactId>plusone-dependencies</artifactId>
<version>1.1.0-SNAPSHOT</version>
<version>${plusone-commons.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
@@ -30,17 +36,12 @@
<dependency>
<groupId>xyz.zhouxy.plusone</groupId>
<artifactId>plusone-commons</artifactId>
<version>1.1.0-SNAPSHOT</version>
<version>${plusone-commons.version}</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2022-2024 the original author or authors.
* Copyright 2022-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -48,7 +48,7 @@ import xyz.zhouxy.plusone.commons.annotation.StaticFactoryMethod;
* <b>NOTE: 使用反射获取类型信息,也是使用反射调用无参构造器和 {@code setter} 方法。
* 实际使用中还是建议针对目标类型自定义 {@link RowMapper}。</b>
* </p>
* @author <a href="http://zhouxy.xyz:3000/ZhouXY108">ZhouXY</a>
* @author ZhouXY108 <luquanlion@outlook.com>
* @since 1.0.0
*/
public class DefaultBeanRowMapper<T> implements RowMapper<T> {
@@ -65,12 +65,12 @@ public class DefaultBeanRowMapper<T> implements RowMapper<T> {
}
/**
* 创建一个 DefaultBeanRowMapper
* 创建一个 {@code DefaultBeanRowMapper}
*
* @param <T> Bean 类型
* @param beanType Bean 类型
* @return DefaultBeanRowMapper 对象
* @throws SQLException 创建 DefaultBeanRowMapper 出现错误的异常时抛出
* @throws SQLException 创建 {@code DefaultBeanRowMapper} 出现错误的异常时抛出
*/
@StaticFactoryMethod(DefaultBeanRowMapper.class)
public static <T> DefaultBeanRowMapper<T> of(Class<T> beanType) throws SQLException {
@@ -78,13 +78,13 @@ public class DefaultBeanRowMapper<T> implements RowMapper<T> {
}
/**
* 创建一个 DefaultBeanRowMapper
* 创建一个 {@code DefaultBeanRowMapper}
*
* @param <T> Bean 类型
* @param beanType Bean 类型
* @param propertyColMap Bean 字段与列名的映射关系。key 是字段value 是列名。
* @return DefaultBeanRowMapper 对象
* @throws SQLException 创建 DefaultBeanRowMapper 出现错误的异常时抛出
* @return {@code DefaultBeanRowMapper} 对象
* @throws SQLException 创建 {@code DefaultBeanRowMapper} 出现错误的异常时抛出
*/
@StaticFactoryMethod(DefaultBeanRowMapper.class)
public static <T> DefaultBeanRowMapper<T> of(Class<T> beanType, @Nullable Map<String, String> propertyColMap)

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2024 the original author or authors.
* Copyright 2024-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -43,7 +43,7 @@ import xyz.zhouxy.plusone.commons.util.AssertTools;
* 提供静态方法,封装 JDBC 基础操作
* </p>
*
* @author <a href="http://zhouxy.xyz:3000/ZhouXY108">ZhouXY</a>
* @author ZhouXY108 <luquanlion@outlook.com>
* @since 1.0.0
*/
class JdbcOperationSupport {

View File

@@ -1,3 +1,19 @@
/*
* Copyright 2024-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package xyz.zhouxy.jdbc;
import java.math.BigDecimal;
@@ -20,7 +36,7 @@ import javax.annotation.Nullable;
* 定义 JdbcTemplate 的 API
* </p>
*
* @author <a href="http://zhouxy.xyz:3000/ZhouXY108">ZhouXY</a>
* @author ZhouXY108 <luquanlion@outlook.com>
* @since 1.0.0
*/
interface JdbcOperations {

View File

@@ -41,7 +41,7 @@ import xyz.zhouxy.plusone.commons.util.OptionalTools;
* JDBC 参数构造器,将数据转换为 {@code Object[]} 类型,以传给 {@link PreparedStatement}
* </p>
*
* @author <a href="http://zhouxy.xyz:3000/ZhouXY108">ZhouXY</a>
* @author ZhouXY108 <luquanlion@outlook.com>
* @since 1.0.0
*/
public class ParamBuilder {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2024 the original author or authors.
* Copyright 2024-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,7 +26,7 @@ import java.sql.SQLException;
* 处理 {@link ResultSet}
* </p>
*
* @author <a href="http://zhouxy.xyz:3000/ZhouXY108">ZhouXY</a>
* @author ZhouXY108 <luquanlion@outlook.com>
* @since 1.0.0
*/
@FunctionalInterface

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2022-2024 the original author or authors.
* Copyright 2022-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,7 +29,7 @@ import java.util.Map;
* {@link ResultSet} 中每一行数据的处理逻辑。
* </p>
*
* @author <a href="http://zhouxy.xyz:3000/ZhouXY108">ZhouXY</a>
* @author ZhouXY108 <luquanlion@outlook.com>
* @since 1.0.0
*/
@FunctionalInterface

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2022-2024 the original author or authors.
* Copyright 2022-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -43,7 +43,7 @@ import xyz.zhouxy.plusone.commons.util.OptionalTools;
* 对 JDBC 的简单封装,方便数据库操作,支持事务,支持批量操作,支持自定义结果集映射
* </p>
*
* @author <a href="http://zhouxy.xyz:3000/ZhouXY108">ZhouXY</a>
* @author ZhouXY108 <luquanlion@outlook.com>
* @since 1.0.0
*/
public class SimpleJdbcTemplate implements JdbcOperations {

View File

@@ -1,10 +1,27 @@
/*
* Copyright 2023-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package xyz.zhouxy.jdbc.test;
import static org.junit.jupiter.api.Assertions.*;
import static xyz.zhouxy.jdbc.ParamBuilder.*;
import static xyz.zhouxy.jdbc.ParamBuilder.buildParams;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.sql.SQLException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
@@ -18,8 +35,9 @@ import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.io.Resources;
import xyz.zhouxy.jdbc.RowMapper;
import xyz.zhouxy.jdbc.SimpleJdbcTemplate;
@@ -31,83 +49,53 @@ class SimpleJdbcTemplateTests {
private static final Logger log = LoggerFactory.getLogger(SimpleJdbcTemplateTests.class);
private static final SimpleJdbcTemplate jdbcTemplate;
private static SimpleJdbcTemplate jdbcTemplate;
static {
@BeforeAll
static void initH2() throws IOException, SQLException {
JdbcDataSource dataSource = new JdbcDataSource();
dataSource.setURL("jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=FALSE;MODE=MySQL");
dataSource.setUser("sa");
dataSource.setPassword("");
jdbcTemplate = new SimpleJdbcTemplate(dataSource);
}
@BeforeAll
static void createTable() throws SQLException {
jdbcTemplate.update("CREATE TABLE sys_account ("
+ "\n" + " id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY"
+ "\n" + " ,username VARCHAR(255) NOT NULL"
+ "\n" + " ,account_status VARCHAR(2) NOT NULL"
+ "\n" + " ,create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP"
+ "\n" + " ,created_by BIGINT NOT NULL"
+ "\n" + " ,update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP"
+ "\n" + " ,updated_by BIGINT DEFAULT NULL"
+ "\n" + " ,version BIGINT NOT NULL DEFAULT 0"
+ "\n" + ")");
// 建表
executeSqlFile("schema.sql");
}
@BeforeEach
void initData() throws SQLException {
jdbcTemplate.update("truncate table sys_account");
jdbcTemplate.batchUpdate("INSERT INTO sys_account(id, username, account_status, created_by) VALUES (?, ?, ?, ?)", Lists.newArrayList(
buildParams(2L, "zhouxy2", "0", 108L),
buildParams(3L, "zhouxy3", "0", 108L),
buildParams(4L, "zhouxy4", "0", 108L),
buildParams(5L, "zhouxy5", "0", 108L),
buildParams(6L, "zhouxy6", "0", 108L),
buildParams(7L, "zhouxy7", "0", 108L),
buildParams(8L, "zhouxy8", "0", 108L),
buildParams(9L, "zhouxy9", "0", 108L)
), 10);
jdbcTemplate.batchUpdate("INSERT INTO sys_account(id, username, account_status, created_by, create_time, update_time, version) VALUES (?, ?, ?, ?, ?, ?, ?)", Lists.newArrayList(
buildParams(10L, "zhouxy10", "1", 118L, LocalDate.of(2000, 1, 1), LocalDate.of(2000, 1, 29), 31),
buildParams(11L, "zhouxy11", "1", 118L, LocalDate.of(2000, 1, 1), LocalDate.of(2000, 1, 29), 28),
buildParams(12L, "zhouxy12", "1", 118L, LocalDate.of(2000, 1, 1), LocalDate.of(2000, 1, 29), 25),
buildParams(13L, "zhouxy13", "1", 118L, LocalDate.of(2000, 1, 1), LocalDate.of(2000, 1, 29), 22),
buildParams(14L, "zhouxy14", "1", 118L, LocalDate.of(2000, 1, 1), LocalDate.of(2000, 1, 29), 19),
buildParams(15L, "zhouxy15", "1", 118L, LocalDate.of(2000, 1, 1), LocalDate.of(2000, 1, 29), 16),
buildParams(16L, "zhouxy16", "1", 118L, LocalDate.of(2000, 1, 1), LocalDate.of(2000, 1, 29), 13),
buildParams(17L, "zhouxy17", "1", 118L, LocalDate.of(2000, 1, 1), LocalDate.of(2000, 1, 29), 10),
buildParams(18L, "zhouxy18", "1", 118L, LocalDate.of(2000, 1, 1), LocalDate.of(2000, 1, 29), 7),
buildParams(19L, "zhouxy19", "1", 118L, LocalDate.of(2000, 1, 1), LocalDate.of(2000, 1, 29), 0)
), 10);
jdbcTemplate.update("INSERT INTO sys_account(id, username, account_status, created_by, create_time, updated_by, update_time, version) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
buildParams(20L, "zhouxy20", "2", 118L, LocalDateTime.of(2008, 8, 8, 20, 8), 31L, LocalDateTime.now(), 88L));
void initData() throws IOException, SQLException {
// 初始化数据
executeSqlFile("data.sql");
}
static void executeSqlFile(String filePath) throws IOException, SQLException {
String[] sqls = Resources
.toString(Resources.getResource(filePath), StandardCharsets.UTF_8)
.split(";");
for (String sql : sqls) {
jdbcTemplate.update(sql);
}
}
@Test
void testQuery() throws SQLException {
Object[] ids = buildParams(5, 9, 13, 14, 17, 20, 108);
String sql = "SELECT id, username, account_status"
+ "\n FROM sys_account"
+ "\n WHERE id IN ("
+ "\n ?, ?, ?, ?, ?, ?, ?"
+ "\n )";
String sql = "SELECT id, username, account_status FROM sys_account WHERE id IN (?, ?, ?, ?, ?, ?, ?)";
log.info(sql);
List<Map<String, Object>> rs = jdbcTemplate.queryList(sql, ids);
for (Map<String, Object> dbRecord : rs) {
log.info("{}", dbRecord);
}
assertEquals(
Lists.newArrayList(
ImmutableMap.of("id", 5L, "account_status", "0", "username", "zhouxy5"),
ImmutableMap.of("id", 9L, "account_status", "0", "username", "zhouxy9"),
ImmutableMap.of("id", 13L, "account_status", "1", "username", "zhouxy13"),
ImmutableMap.of("id", 14L, "account_status", "1", "username", "zhouxy14"),
ImmutableMap.of("id", 17L, "account_status", "1", "username", "zhouxy17"),
ImmutableMap.of("id", 20L, "account_status", "2", "username", "zhouxy20")
),
rs
List<ImmutableMap<String, Object>> expected = ImmutableList.of(
ImmutableMap.of("id", 5L, "account_status", "0", "username", "zhouxy5"),
ImmutableMap.of("id", 9L, "account_status", "0", "username", "zhouxy9"),
ImmutableMap.of("id", 13L, "account_status", "1", "username", "zhouxy13"),
ImmutableMap.of("id", 14L, "account_status", "1", "username", "zhouxy14"),
ImmutableMap.of("id", 17L, "account_status", "1", "username", "zhouxy17"),
ImmutableMap.of("id", 20L, "account_status", "2", "username", "zhouxy20")
);
assertEquals(expected, rs);
}
@Test

View File

@@ -0,0 +1,23 @@
truncate table sys_account;
INSERT INTO sys_account(id, username, account_status, created_by) VALUES (2, 'zhouxy2', '0', 108);
INSERT INTO sys_account(id, username, account_status, created_by) VALUES (3, 'zhouxy3', '0', 108);
INSERT INTO sys_account(id, username, account_status, created_by) VALUES (4, 'zhouxy4', '0', 108);
INSERT INTO sys_account(id, username, account_status, created_by) VALUES (5, 'zhouxy5', '0', 108);
INSERT INTO sys_account(id, username, account_status, created_by) VALUES (6, 'zhouxy6', '0', 108);
INSERT INTO sys_account(id, username, account_status, created_by) VALUES (7, 'zhouxy7', '0', 108);
INSERT INTO sys_account(id, username, account_status, created_by) VALUES (8, 'zhouxy8', '0', 108);
INSERT INTO sys_account(id, username, account_status, created_by) VALUES (9, 'zhouxy9', '0', 108);
INSERT INTO sys_account(id, username, account_status, created_by, create_time, update_time, `version`) VALUES (10, 'zhouxy10', '1', 118, '2000-01-01', '2000-01-29', 31);
INSERT INTO sys_account(id, username, account_status, created_by, create_time, update_time, `version`) VALUES (11, 'zhouxy11', '1', 118, '2000-01-01', '2000-01-29', 28);
INSERT INTO sys_account(id, username, account_status, created_by, create_time, update_time, `version`) VALUES (12, 'zhouxy12', '1', 118, '2000-01-01', '2000-01-29', 25);
INSERT INTO sys_account(id, username, account_status, created_by, create_time, update_time, `version`) VALUES (13, 'zhouxy13', '1', 118, '2000-01-01', '2000-01-29', 22);
INSERT INTO sys_account(id, username, account_status, created_by, create_time, update_time, `version`) VALUES (14, 'zhouxy14', '1', 118, '2000-01-01', '2000-01-29', 19);
INSERT INTO sys_account(id, username, account_status, created_by, create_time, update_time, `version`) VALUES (15, 'zhouxy15', '1', 118, '2000-01-01', '2000-01-29', 16);
INSERT INTO sys_account(id, username, account_status, created_by, create_time, update_time, `version`) VALUES (16, 'zhouxy16', '1', 118, '2000-01-01', '2000-01-29', 13);
INSERT INTO sys_account(id, username, account_status, created_by, create_time, update_time, `version`) VALUES (17, 'zhouxy17', '1', 118, '2000-01-01', '2000-01-29', 10);
INSERT INTO sys_account(id, username, account_status, created_by, create_time, update_time, `version`) VALUES (18, 'zhouxy18', '1', 118, '2000-01-01', '2000-01-29', 7 );
INSERT INTO sys_account(id, username, account_status, created_by, create_time, update_time, `version`) VALUES (19, 'zhouxy19', '1', 118, '2000-01-01', '2000-01-29', 0 );
INSERT INTO sys_account(id, username, account_status, created_by, create_time, updated_by, update_time, version) VALUES (20, 'zhouxy20', '2', 118, '2008-08-08 20:08:00', 31, now(), 88);

View File

@@ -0,0 +1,10 @@
CREATE TABLE sys_account (
`id` BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY
, `username` VARCHAR(255) NOT NULL
, `account_status` VARCHAR(2) NOT NULL
, `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
, `created_by` BIGINT NOT NULL
, `update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
, `updated_by` BIGINT DEFAULT NULL
, `version` BIGINT NOT NULL DEFAULT 0
)