h2数据库初探

Posted by hcy on February 26, 2020

首先是这个h2数据库的官网http://www.h2database.com

当前最新的maven:

1
2
3
4
5
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>1.4.200</version>
        </dependency>

1.两种运行模式

纯内存模式,类比于java的HashMap

嵌入模式,类比于Redis(开启实时保存到本地)

2. 先启动起来再说

首先引入maven

1
2
3
4
5
6
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>1.4.200</version>
            <scope>test</scope>
        </dependency>

然后在测试类里面写一个main方法

1
2
3
4
    public static void main(String[] args) throws SQLException, ClassNotFoundException {
        Class.forName("org.h2.Driver");
        Connection conn = DriverManager.getConnection("jdbc:h2:mem:h2db", "sa", "");
    }

上面使用内存模式启动H2,数据库名为h2db,对这个数据库做的操作重启程序后都会被删除。

1
2
3
4
public static void main(String[] args) throws SQLException, ClassNotFoundException {
    Class.forName("org.h2.Driver");
    Connection conn = DriverManager.getConnection("jdbc:h2:~/test", "sa", "");
}

简单修改了了连接url,h2就从纯内存模式转变成了嵌入模式,他会在~/目录下创建一个test.db的文件,对数据库的所有操作都会反应到此文件上,且重启也不会丢失数据。

3. 网页服务模式

上面创建了一个数据库,但数据库是空的,且没办法直观的看到数据,这是可以使用它内置的网页管理工具,我们在网页上就能连上。

1
2
3
4
5
6
7
    public static void main(String[] args) throws SQLException, ClassNotFoundException {

        Class.forName("org.h2.Driver");
        Connection conn = DriverManager.getConnection("jdbc:h2:~/test", "sa", "");
		//创建一个网页管理服务,并启动
        Server.createWebServer().start();
    }

开启了一个网页管理服务,因为上面执行获取Connection时已经创建的test.db,所以第1,2行代码不执行也可以的。有了网页服务,我们打开浏览器输入http://localhost:8082,进入

image-20200226215023374

网页内容如上,我们正确填写了 jdbc url用户名密码,这些就是创建数据库时一致的,就能进入管理后台。

image-20200226215137165

这也很好理解,第一次我们使用DriverManager获取连接时,h2为我们在指定位置生成了一个test.db文件,这个文件就是我们的数据库,且使用给定的用户名密码加密了。第二次我们启动了一个WebServer,通过网页我们可以告诉WebServer去哪里查找数据库,使用的用户名密码是什么,这样我们第二次启动的程序就能再把test.db加载到内存里,读写它。

4. tcp服务模式

如果我们想要程序A开启一个嵌入数据库,程序B通过jdbc连接上来读取数据,那该怎么办呢?

我们可以在程序A中开启一个TcpServer,提供一个服务出去供其他程序访问,比如我们在A程序中

1
2
3
    public static void main(String[] args) throws SQLException {
        Server.createTcpServer().start();
    }

程序B里面这样写

1
2
Class.forName("org.h2.Driver");
Connection conn = DriverManager.getConnection("jdbc:h2:tcp:localhost:9092/~/test", "sa", "");

注意url变了,这样我们就能在程序B里面获取A开启的9092端口的监听,程序B里面做的数据库操作或通过Tcp传送到A上,最终反映到数据库上,A就成了一个B的代理。

5.PG服务模式

1
2
3
public static void main(String[] args) throws SQLException {
    Server.createPgServer().start()
}

支持PostgreSQL客户端,我没试。

6.总结

h2还为我们提供了简单的连接池,使用方式如:

1
2
3
4
JdbcConnectionPool cp = JdbcConnectionPool.create("jdbc:h2:~/test", "", "");
Connection conn = cp.getConnection();
conn.close();
cp.dispose();

连接字符串参数

1
2
3
4
5
6
DB_CLOSE_DELAY:要求最后一个正在连接的连接断开后,不要关闭数据库
MODE=MySQL:兼容模式,H2兼容多种数据库,该值可以为:DB2DerbyHSQLDBMSSQLServerMySQLOraclePostgreSQL
AUTO_RECONNECT=TRUE:连接丢失后自动重新连接
AUTO_SERVER=TRUE:启动自动混合模式,允许开启多个连接,该参数不支持在内存中运行模式
TRACE_LEVEL_SYSTEM_OUTTRACE_LEVEL_FILE:输出跟踪日志到控制台或文件, 取值0OFF1ERROR(默认值),2INFO3DEBUG
SET TRACE_MAX_FILE_SIZE mb:设置跟踪日志文件的大小,默认为16M

连接参数是这样用的:

1
2
3
jdbc:h2:mem:DBName;DB_CLOSE_DELAY=-1;MODE=MySQL

jdbc:h2:file:~/.h2/DBName;AUTO_SERVER=TRUE

文档里,这一段也要看看哦

1
2
3
4
To access an in-memory database from another process or from another computer, you need to start a TCP server in the same process as the in-memory database was created. The other processes then need to access the database over TCP/IP or SSL/TLS, using a database URL such as: jdbc:h2:tcp://localhost/mem:db1. 


By default, closing the last connection to a database closes the database. For an in-memory database, this means the content is lost. To keep the database open, add ;DB_CLOSE_DELAY=-1 to the database URL. To keep the content of an in-memory database as long as the virtual machine is alive, use jdbc:h2:mem:test;DB_CLOSE_DELAY=-1. 

转载请注明出处:https://www.huangchaoyu.com/2020/02/26/h2数据库初探/