在本系列的上一篇文章中, 给大家演示了如何统一 Rest API 的输出格式,本文我们将介绍如何通过 Vertx 的 API 访问关系数据库。
在课堂案例中,我们使用 MySQL 作为后台数据库,如果没有已经安装好的 MySQL , 可以参考 在Docker中使用MySQL服务器 使用 docker 进行安装。
首先需要了解的是,因为 Vertx 框架提供的响应式 (Reactive) 的编程风格和基础设施,因此原有的 JDBC API 已经不能使用
准备数据库和表
在 安装好的 MySQL 中建立一个名为: Todo 的数据库,再建立一个名为: todo_user 的用户,让它拥有访问 Todo 库的权力。
用下面的脚本建立一张简单的表
1 2 3 4 5 6 7 8
| CREATE TABLE `tbl_todo` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `title` VARCHAR(50) NOT NULL COLLATE 'utf8_bin', `desc` VARCHAR(400) NULL DEFAULT NULL COLLATE 'utf8_bin', PRIMARY KEY (`id`) USING BTREE ) COLLATE='utf8_bin' ENGINE=InnoDB
|
安装依赖库
打开项目的 pom.xml 文件,加入以下依赖库
1 2 3 4 5 6 7 8 9 10 11 12
| <dependency> <groupId>io.vertx</groupId> <artifactId>vertx-jdbc-client</artifactId> <version>3.9.0</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.21</version> </dependency>
|
管理Datasouce
因为我们需要在程序的不同地方共享 Datasouce, 为了方便存取,我们建立一个名为 DBManager 的单例类,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| @Slf4j public class DBManager {
private static final DBManager instance = new DBManager();
private DBManager() {
}
private static final String DATASOURCE_NAME = "todo-ds";
private static final JsonObject props = new JsonObject();
static { props.put("driver_class", "com.mysql.cj.jdbc.Driver"); props.put("url", "jdbc:mysql://localhost:3306/Todo"); props.put("user", "todo_user"); props.put("password", "Password123"); }
public static DBManager getInstance() { return instance; }
public SQLClient getClient(Vertx vertx) { return JDBCClient.createShared(vertx, props, DATASOURCE_NAME); } }
|
这样在程序其它地方需要使用数据库时,就只需要调用 getInstance().getClient() 就可以了。
改造API
改造 API, 让其从数据库表中去取数, 改造后的程序如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| router.route("/api/v1/auth/todo").handler(ctx -> {
ApiResult<List<JsonObject>> res = new ApiResult<>();
SQLClient client = DBManager.getInstance().getClient(vertx); client.getConnection(dbres -> { if (dbres.succeeded()) {
SQLConnection conn = dbres.result(); conn.query("SELECT * FROM tbl_todo", dbres2 -> {
if (dbres2.succeeded()) {
ResultSet rSet = dbres2.result();
res.setSucc(true); res.setData(rSet.getRows()); ctx.response().end(JsonObject.mapFrom(res).toString());
} else {
log.error("Fail to query data: ", dbres2.cause()); ctx.response().end(JsonObject.mapFrom(res).toString()); }
}); } else {
log.error("Fail to get connection: ", dbres.cause()); ctx.response().end(JsonObject.mapFrom(res).toString()); }
});
});
|