簡介
本文將會介紹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的部落格
歡迎關注我的公眾號:「程式那些事」最通俗的解讀,最深刻的乾貨,最簡潔的教程,眾多你不知道的小技巧等你來發現!