內存數據庫-H2簡介與實踐


一、H2數據庫介紹
  H2數據庫地址:http://www.h2database.com/html/main.html

  H2是一個開源的嵌入式(非嵌入式設備)數據庫引擎,它是一個用Java開發的類庫,可直接嵌入到應用程序中,與應用程序一起打包發布,不受平台限制。
  

1.1 與其他開源數據庫比較

  H2與Derby、HSQLDB、MySQL、PostgreSQL等開源數據庫相比,H2的優勢為:a.存Java開發,不受平台限制;b.H2只有一個jar包,占用空間小,適合嵌入式數據庫;c.有web控制台,用於管管理數據庫。具體特征如下:

特征 H2 Derby HSQLDB MySQL PostgreSQL
純Java yes yes yes no no
支持內存模式 yes yes yes no no
支持數據庫加密 yes yes yes no no
支持ODBC驅動 yes no no yes yes
支持全文檢索 yes no no yes yes
支持多版本並發控制 yes no yes yes yes
占用空間(jar/dll) ~1M ~2M ~1M ~4M ~6M
* 1.2 H2數據庫連接方式

  H2數據庫支持如下三種連接方式:

連接方式 描述
嵌入式模式 本地JDBC連接
服務器模式 JDBC或基於tcp/ip的ODBC遠程連接
混合模式 本地或遠程同時連接
注:三種模式都支持內存、持久化到文件兩種數據存儲方式。三種模式對同時開啟的數據庫數量和數據庫連接數量沒有限制。

嵌入式模式

  嵌入式模式是最簡單最快捷的一種連接方式,嵌入式模式下,應用在JVM中啟動H2數據庫並通過JDBC連接。該模式同時支持數據持久化和內容兩種方式,對同時開啟的數據庫數量和數據庫連接數量沒有限制。示意圖如下:

 

服務器模式

  服務器模式下,應用通過JDBC或ODBC API遠程開啟數據庫。該模式下,H2數據庫可以部署在不同的JVM或不同的物理機中,多個應用可以通過連接H2服務器同時連接到H2數據庫。因為數據需要通過TCP/IP協議遠程傳輸,因此服務器模式獲取數據比嵌入式模式慢。服務器模式示意圖如下:

 

混合模式

  混合模式結合了嵌入式模式和服務器模式的特點,第一個應用通過嵌入式模式打開H2數據庫,同時將數據庫開啟服務器模式,其他應用可以遠程連接到數據庫。數據庫服務器的開啟和關閉都在第一個應用中完成。混合模式示意圖如下:

 

1.3 H2數據庫JDBC URL格式

  H2數據庫支持多種連接方式和連接設置,連接URL格式如下,URL中的設置大小寫不敏感。

主題 URL格式 范例
本地嵌入式連接 jdbc:h2:[file:][]< databaseName> jdbc:h2:~/test
jdbc:h2:file:/data/sample
jdbc:h2:file:C:/data/sample (Windows only)
內存模式(private) jdbc:h2:mem:
內存模式(named) jdbc:h2:mem:< databaseName> jdbc:h2:mem:test_mem
服務器模式(TCP/IP) jdbc:h2:tcp://[:]/[]< databaseName> jdbc:h2:tcp://localhost/~/test
jdbc:h2:tcp://dbserv:8084/~/sample
jdbc:h2:tcp://localhost/mem:test
服務器模式(TLS) jdbc:h2:ssl://[:]/< databaseName> jdbc:h2:ssl://localhost:8085/~/sample;
加密方式 jdbc:h2:< url>;CIPHER=AES jdbc:h2:ssl://localhost/~/test;CIPHER=AES
jdbc:h2:file:~/secure;CIPHER=AES
文檔鎖定 jdbc:h2:< url>;FILE_LOCK={FILE|SOCKET|NO} jdbc:h2:file:~/private;CIPHER=AES;FILE_LOCK=SOCKET
僅存在時打開 jdbc:h2:< url>;IFEXISTS=TRUE jdbc:h2:file:~/sample;IFEXISTS=TRUE
VM存在時不關閉數據庫 jdbc:h2:< url>;DB_CLOSE_ON_EXIT=FALSE
用戶名、密碼 jdbc:h2:< url>[;USER=< username>][;PASSWORD=< value>] jdbc:h2:file:~/sample;USER=sa;PASSWORD=123
調試日志設置 jdbc:h2:< url>;TRACE_LEVEL_FILE=< level 0..3> jdbc:h2:file:~/sample;TRACE_LEVEL_FILE=3
忽略不明設置 jdbc:h2:;IGNORE_UNKNOWN_SETTINGS=TRUE
用戶文件訪問 jdbc:h2:;ACCESS_MODE_DATA=rws
zip格式數據庫文件 jdbc:h2:zip:< zipFileName>!/< databaseName> jdbc:h2:zip:~/db.zip!/test
兼容模式 jdbc:h2:< url>;MODE=< databaseType> jdbc:h2:~/test;MODE=MYSQL
自動重新連接 jdbc:h2:< url>;AUTO_RECONNECT=TRUE jdbc:h2:tcp://localhost/~/test;AUTO_RECONNECT=TRUE
自動混合模式 jdbc:h2:< url>;AUTO_SERVER=TRUE jdbc:h2:~/test;AUTO_SERVER=TRUE
頁面大小 jdbc:h2:< url>;PAGE_SIZE=512
修改其他設置 jdbc:h2:< url>;< setting>=< value>[;< setting>=< value>…] jdbc:h2:file:~/sample;TRACE_LEVEL_SYSTEM_OUT=3
二、H2數據庫控制台
  H2控制台應用允許通過瀏覽器的方式連接到H2數據庫,示意圖如下。這是典型Client/Server模式,因此同時需要服務器和客戶端。

 

  H2控制台在不同的操作系統下有不同的啟動方式,筆者系統是Mac os,下文通過命令行啟動,如下:

java -jar h2*.jar
1
  H2數據庫服務器啟動后會自動打開web控制台,也可以通過:http://localhost:8082 訪問。控制台界面如下:

 

可以在H2控制台設置數據庫連接模式,本文設置為服務器模式,首次進入可以設置用戶名和密碼,第一次測試連接后生效,連接進入到數據庫控制界面,如下。在該界面下可執行數據庫相關的DDL、DML語句。

 

注:如果數據庫開啟方式為嵌入式模式,則不允許其他應用在啟動控制台時同時連接到數據庫;如果開啟模式為服務器模式或混合模式,則允許其他應用同時連接到數據庫

三、H2數據庫實踐
  Spring+Mybatis+Mysql數據庫的相關配置參考:Spring事務管理-編程式事務、聲明式事務,本文介紹Spring+Mybatis+H2的數據庫訪問實踐。Spring+Mybatis配置參考上一篇文章,本次事件新添加H2數據庫依賴:

...
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.190</version>
</dependency>
...
1
2
3
4
5
6
7
  H2數據庫屬性文件配置如下,本文采用內存模式訪問H2數據庫:

driver=org.h2.Driver
# 內存模式
url=jdbc:h2:mem:testdb;MODE=MYSQL;DB_CLOSE_DELAY=-1
# 持久化模式
#url= jdbc:h2:tcp://localhost/~/test1;MODE=MYSQL;DB_CLOSE_DELAY=-1
1
2
3
4
5
  H2數據庫訪問的Spring配置文件為:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd">

<!-- 引入屬性文件 -->
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:config.properties</value>
</list>
</property>
</bean>

<!-- 自動掃描DAO -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.xiaofan.test" />
</bean>

<!-- 配置Mybatis sqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:mybatis_config.xml"/>
<property name="mapperLocations" value="classpath:user_mapper.xml"/>
</bean>

<!-- 配置數據源 -->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${driver}" />
<property name="url" value="${url}" />
<!--<property name="username" value="sa" />-->
<!--<property name="password" value="123" />-->
</bean>

<!-- 初始化數據庫 -->
<jdbc:initialize-database data-source="dataSource" ignore-failures="DROPS">
<jdbc:script location="classpath:sql/ddl.sql" />
<jdbc:script location="classpath:sql/dml.sql" />
</jdbc:initialize-database>

<!-- 配置事務管理 -->
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>

</beans>
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
  其中初始化數據庫的DDL語句文件為:

CREATE TABLE `user` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL,
`age` int(11) NOT NULL,
PRIMARY KEY (`id`)
);
1
2
3
4
5
6
  初始化數據庫的DML語句文件為:

insert into `user` (`id`,`name`,`age`) values (1, 'Jerry', 27);
insert into `user` (`id`,`name`,`age`) values (2, 'Angel', 25);
1
2
  編寫測試文件,如下:

/**
* Created by Jerry on 17/7/30.
*/
@ContextConfiguration(locations = {"classpath:config.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
public class Test extends AbstractJUnit4SpringContextTests{

@Resource
UserDAO userDAO;

@org.junit.Test
public void testInsert() {

int result = userDAO.insert(new User(null, "LiLei", 27));

Assert.assertTrue(result > 0);
}

@org.junit.Test
public void testUpdate() {
int result = userDAO.update(new User(2L, "Jerry update", 28));

Assert.assertTrue(result > 0);
}

@org.junit.Test
public void testSelect() {
User result = userDAO.findByName(new User(null, "Jerry", null));

Assert.assertTrue(result.getAge() != null);
}

@org.junit.Test
public void testDelete() {
int result = userDAO.delete("Jerry");

Assert.assertTrue(result > 0);
}

}
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
37
38
39
40
  測試結果通過!
---------------------
作者:Jerry的技術博客
來源:CSDN
原文:https://blog.csdn.net/xktxoo/article/details/78014739
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM