简介

本文将会介绍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 ReactorMono<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/namer2dbc:h2:file///absolute/file/namer2dbc: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的博客

欢送关注我的公众号:「程序那些事」最艰深的解读,最粗浅的干货,最简洁的教程,泛滥你不晓得的小技巧等你来发现!