共计 4630 个字符,预计需要花费 12 分钟才能阅读完成。
简介
本文将会介绍 R2DBC 的 H2 实现 r2dbc-h2 的应用办法和要留神的事项。一起来看看吧。
H2 数据库简介
什么是 H2 数据库呢?
H2 是一个 Java SQL database,它是一个开源的数据库,运行起来十分快。
H2 风行的起因是它既能够当做一个独立的服务器,也能够以一个嵌套的服务运行,并且反对纯内存模式运行。
H2 的 jar 包十分小,只有 2M 大小,所以非常适合做嵌套式数据库。
如果作为嵌入式数据库,则须要将 h2*.jar 增加到 classpath 中。
上面是一个简略的建设 H2 连贯的代码:
import java.sql.*;
public class Test {public static void main(String[] a)
throws Exception {
Connection conn = DriverManager.
getConnection("jdbc:h2:~/test", "sa", "");
// add application code here
conn.close();}
}
如果给定地址的数据库并不存在,
同时 H2 还提供了一个简略的治理界面,应用上面的命令就能够启动 H2 治理界面:
java -jar h2*.jar
默认状况下拜访 http://localhost:8082 就能够拜访到治理界面:
r2dbc-h2
r2dbc-h2 是 r2dbc spi 的一种实现。同样的应用 r2dbc-h2 也提供了两种 h2 的模式,一种是文件系统,一种是内存。
同时还提供了事务反对,prepared statements 和 batch statements 等个性的反对。
r2dbc-h2 的 Maven 依赖
要想应用 r2dbc-h2,咱们须要增加如下依赖:
<dependency>
<groupId>io.r2dbc</groupId>
<artifactId>r2dbc-h2</artifactId>
<version>${version}</version>
</dependency>
如果你体验 snapshot 版本,能够增加上面的依赖:
<dependency>
<groupId>io.r2dbc</groupId>
<artifactId>r2dbc-h2</artifactId>
<version>${version}.BUILD-SNAPSHOT</version>
</dependency>
<repository>
<id>spring-libs-snapshot</id>
<name>Spring Snapshot Repository</name>
<url>https://repo.spring.io/libs-snapshot</url>
</repository>
建设连贯
h2 有两种连贯形式,file 和内存,咱们别离看一下都是怎么建设连贯的:
ConnectionFactory connectionFactory = ConnectionFactories.get("r2dbc:h2:mem:///testdb");
Publisher<? extends Connection> connectionPublisher = connectionFactory.create();
ConnectionFactory connectionFactory = ConnectionFactories.get("r2dbc:h2:file//my/relative/path");
Publisher<? extends Connection> connectionPublisher = connectionFactory.create();
咱们还能够通过 ConnectionFactoryOptions 来创立更加具体的连贯信息:
ConnectionFactoryOptions options = builder()
.option(DRIVER, "h2")
.option(PROTOCOL, "...") // file, mem
.option(HOST, "…")
.option(USER, "…")
.option(PASSWORD, "…")
.option(DATABASE, "…")
.build();
ConnectionFactory connectionFactory = ConnectionFactories.get(options);
Publisher<? extends Connection> connectionPublisher = connectionFactory.create();
// Alternative: Creating a Mono using Project Reactor
Mono<Connection> connectionMono = Mono.from(connectionFactory.create());
下面的例子中,咱们应用到了 driver,protocol, host,username,password 和 database 这几个选项,除此之外 H2ConnectionOption 中定义了其余能够应用的 Option:
public enum H2ConnectionOption {
/**
* FILE|SOCKET|NO
*/
FILE_LOCK,
/**
* TRUE|FALSE
*/
IFEXISTS,
/**
* Seconds to stay open or {@literal -1} to to keep in-memory DB open as long as the virtual machine is alive.
*/
DB_CLOSE_DELAY,
/**
* TRUE|FALSE
*/
DB_CLOSE_ON_EXIT,
/**
* DML or DDL commands on startup, use "\\;" to chain multiple commands
*/
INIT,
/**
* 0..3 (0=OFF, 1=ERROR, 2=INFO, 3=DEBUG)
*/
TRACE_LEVEL_FILE,
/**
* Megabytes (to override the 16mb default, e.g. 64)
*/
TRACE_MAX_FILE_SIZE,
/**
* 0..3 (0=OFF, 1=ERROR, 2=INFO, 3=DEBUG)
*/
TRACE_LEVEL_SYSTEM_OUT,
LOG,
/**
* TRUE|FALSE
*/
IGNORE_UNKNOWN_SETTINGS,
/**
* r|rw|rws|rwd (r=read, rw=read/write)
*/
ACCESS_MODE_DATA,
/**
* DB2|Derby|HSQLDB|MSSQLServer|MySQL|Oracle|PostgreSQL|Ignite
*/
MODE,
/**
* TRUE|FALSE
*/
AUTO_SERVER,
/**
* A port number
*/
AUTO_SERVER_PORT,
/**
* Bytes (e.g. 512)
*/
PAGE_SIZE,
/**
* Number of threads (e.g. 4)
*/
MULTI_THREADED,
/**
* TQ|SOFT_LRU
*/
CACHE_TYPE,
/**
* TRUE|FALSE
*/
PASSWORD_HASH;
}
当然还有最间接的 database 选项:
r2dbc:h2:file//../relative/file/name
r2dbc:h2:file///absolute/file/name
r2dbc:h2:mem:///testdb
咱们还能够通过 H2 特有的代码 H2ConnectionFactory 来创立:
H2ConnectionFactory connectionFactory = new H2ConnectionFactory(H2ConnectionConfiguration.builder()
.inMemory("...")
.option(H2ConnectionOption.DB_CLOSE_DELAY, "-1")
.build());
Mono<Connection> connection = connectionFactory.create();
CloseableConnectionFactory connectionFactory = H2ConnectionFactory.inMemory("testdb");
Mono<Connection> connection = connectionFactory.create();
参数绑定
在应用 prepare statement 的时候,咱们须要进行参数绑定:
connection
.createStatement("INSERT INTO person (id, first_name, last_name) VALUES ($1, $2, $3)")
.bind("$1", 1)
.bind("$2", "Walter")
.bind("$3", "White")
.execute()
除了 $ 符号绑定之外,还反对 index 绑定,如下所示:
Statement statement = connection.createStatement("SELECT title FROM books WHERE author = $1 and publisher = $2");
statement.bind(0, "John Doe");
statement.bind(1, "Happy Books LLC");
批处理
咱们来看下 r2dbc-h2 是怎么来进行批处理的:
Batch batch = connection.createBatch();
Publisher<? extends Result> publisher = batch.add("SELECT title, author FROM books")
.add("INSERT INTO books VALUES('John Doe','HappyBooks LLC')")
.execute();
事务和 Savepoint
r2dbc 还反对事务和 savepoint, 咱们能够在事务中 rollback 到特定的 savepoint。具体的代码如下:
Publisher<Void> begin = connection.beginTransaction();
Publisher<Void> insert1 = connection.createStatement("INSERT INTO books VALUES ('John Doe')").execute();
Publisher<Void> savepoint = connection.createSavepoint("savepoint");
Publisher<Void> insert2 = connection.createStatement("INSERT INTO books VALUES ('Jane Doe')").execute();
Publisher<Void> partialRollback = connection.rollbackTransactionToSavepoint("savepoint");
Publisher<Void> commit = connection.commit();
本文作者:flydean 程序那些事
本文链接:http://www.flydean.com/r2dbc-h2-in-depth/
本文起源:flydean 的博客
欢送关注我的公众号:「程序那些事」最艰深的解读,最粗浅的干货,最简洁的教程,泛滥你不晓得的小技巧等你来发现!