H2db使用技巧笔记

一、基础知识:
1、h2是一个开源的纯java编写的轻量级数据库,是一个用Java开发的嵌入式数据库,只有一个jar文件,可以直接嵌入到应用项目中。
      h2最大的用途在于可以同应用程序打包在一起发布,这样可以非常方便地存储少量结构化数据,它的另一个用途是用于单元测试。
           启动速度快,而且可以关闭持久化功能,每一个用例执行完随即还原到初始状态。h2的第三个用处是作为缓存,作为NoSQL的一个补充。
    官方网址:http://www.h2database.com
        CSDN的使用参考例子:http://blog.csdn.net/qq_25033135/article/details/44921587


    2、与h2一样作为开源的数据库还有Derby、HSQLDB、MySQL、PostgreSQL、SQLite等。其中h2和HSQLDB类似,十分适合作为嵌入式数据库使用,
   其它的数据库大部分都需要安装独立的客户端和服务器端。所谓嵌入式数据库,就是直接在项目中引入h2的jar包,通过java代码
   启动h2的服务,项目即可使用h2的数据库功能,而不需要额外的安装h2服务器。故h2非常适合作为桌面软件的嵌入式数据库,用户
   只需要安装和运行桌面软件即可,而无须额外处理数据库的服务问题。

3、h2的数据库服务,可通过安装服务端软件(windows和linux均支持)来提供数据库服务,单也可以直接通过h2.jar包直接通过java代码
   创建服务,从而提供相应的数据库服务。通常使用h2.jar包形式来提供服务,一般都是便于用作嵌入式数据库服务时使用。如果作为普通
   的数据库服务,通常都是安装服务端软件。
   
   
   
4、h2支持多种服务模式,在启动的时候就需要指定服务模式,并且不同模式下客户端的url连接会有区别。h2数据库总体来说分为两类:
   (1)嵌入模式(本地连接方式):
这种连接方式默认情况下只允许有一个客户端连接到H2数据库,有客户端连接到H2数据库之后,此时数据库文件就会被锁定,
    那么其他客户端就无法再连接了。使用嵌入模式,不需要先启动h2的服务器,直接执行客户端即可。
jdbc的url连接格式:
jdbc:h2:[file:][<path>]<databaseName>
例如:
    jdbc:h2:~/test //连接位于当前系统用户目录下的test数据库(如果数据库不存在会自动创建)
    jdbc:h2:file:/data/sample //连接/data目录下的sample数据库(如果数据库不存在会自动创建)
    jdbc:h2:file:E:/H2/gacl   //连接E:/H2目录下的gacl数据库(如果数据库不存在会自动创建)

   (2)服务器模式(远程连接方式):
    这种连接方式就和其他数据库类似了,是基于Service的形式进行连接的,因此允许多个客户端同时连接到H2数据库。
使用服务器模式,必须先启动h2的服务器,客户端才能连接并执行sql脚本。
jdbc的url连接格式(TCP连接):
jdbc:h2:tcp://<server>[:<port>]/[<path>]<databaseName>
例如:
jdbc:h2:tcp://localhost/~/test

补充说明:
如果再细分h2的连接模式,还可以分析内存模式,TCL服务器模式,SSL服务器模式,混合模式等。
具体参考图片 h2不同模式的url连接.png

5、如果项目中使用h2数据库的嵌入模式,并且可能会在多线程中操作h2数据库,那么建议将嵌入模式改为混合模式,即基于嵌入模式的基础上,
           允许多个客户端进行连接,而不是针对单一客户端连接而进行数据库文件加锁,这样可以在多线程操作数据库的情况下增加性能。混动模式
   的使用,只需修改客户端的url地址。
   格式为:
jdbc:h2:[file:][<path>]<databaseName>;AUTO_SERVER=TRUE,
   例如:
jdbc:h2:~/test;AUTO_SERVER=TRUE


6、h2.jar不但拥有数据库服务端的功能,而且还提供了一个web版本的客户端,此客户端不仅支持h2,还支持Derby、MySQL、Oracle、HSQLDB
   等数据库连接,但是需要额外引入其他数据库的jdbc规范的jar包才可以使用。


   特别说明:h2的web客户端是在连接数据库后,使用的是connection对象的连接池,如果是嵌入式模式,则连接池只有一个connection对象。
             当打开多个web页面来操作数据库的时候,其实使用的都是同一个connection对象,而不是一个web页面就一个连接对象。


7、h2存储数据的数据库目录下,会有两个db文件,例如数据库名叫myh2db,则会有myh2db.mv.db和myh2db.trace.db文件,其中myh2db.mv.db
   存储的是数据库的数据,myh2db.trace.db文件存储的是操作日志(包括错误信息),通过myh2db.trace.文件操作日志可以非常方便的查看
   数据库的操作情况。


8、h2数据库默认有个INFORMATION_SCHEMA约束,此约束下面有一序列的系统表,例如用户表、帮助表等,可以根据需要查询此约束下的表,
   查询时需要带上INFORMATION_SCHEMA.表名来可以查询。例如:SELECT * FROM INFORMATION_SCHEMA.HELP;
   

9、h2提供的web客户端项目原理:将web的jsp等页面都打包在data.zip包下,此data.zip包在h2.jar包里面的org.h2.util包目录下,
   通过org.h2.util.Utils.getResource(String)工具类来读取data.zip包目录里面的资源,读取的资源使用byte[]缓存到HashMap
   集合中,如果集合中没有此资源的字节数组缓存,则通过ZipInputStream读取zip包里面指定名称的资源,存储到byte[]中,供
   项目调用此资源。例如将页面的byte[]写入到HttpServletResponse对象中,从而在客户端能显示到正常的页面。页面的内容显示
   主要还是靠js来显示,把相应的数据转换为js代码来显示,并且页面中对JSTL的if和foreach标签做了伪支持,即使用JSTL标签的
   语法,但是并不是真由JSTL来解析,而是服务器端自己来解析JSTL标签,达到JSTL标签的效果而已。自己来解析JSTL标签,是因为
   有可能是使用org.h2.server.web.WebServer通过ServerSocket来提供web客户端服务,则需要自己解析JSTL标签。


10、h2的内存模式,按功能可以分为私有内存模式和公共内存模式,按服务可以分为嵌入式内存模式和服务器内存模式。
私有内存模式:
私有内存模式是没有指定数据库名的,属于私有化,只与当前数据库连接相关联,当前连接关闭后则数据就会丢失。
嵌入式内存模式url格式:jdbc:h2:tcp://localhost/mem:
服务器内存模式url格式:jdbc:h2:mem:


公共内存模式(注意所有连接都关闭时数据也会丢失):
指定内存模式的数据库名,例如mydb,其他连接也可以连接此内存数据库,当所有连接对象都关闭或服务器关闭的时候数据才丢失。
嵌入式内存模式url格式:jdbc:h2:tcp://localhost/mem:mydb
服务器内存模式url格式:jdbc:h2:mem:mydb


11、h2是支持主键和索引的,可以手动的创建索引来提升查询效率,并且支持 auto_increment 自动增长功能。


12、h2是支持事务的,如果设置Connection.setAutoCommit(false),则在关闭前必须要执行Connection.commit(),否则数据的修改是
    不会提交到数据库的。Connection.close()方法并不会直接提交事务,而是回滚后提交。

二、使用笔记:
1、使用h2.jar的web版本的客户端,只需要引入此jar包,然后web.xml文件配置Servlet即可:
<servlet>
<servlet-name>h2Console</servlet-name>
<servlet-class>org.h2.server.web.WebServlet</servlet-class>
<!--
  增加 trace参数,可以在控制台打印出更详细的信息,
  更多参数可看org.h2.server.web.WebServer.init(String...)方法
-->
<init-param>
<param-name>trace</param-name>
<param-value></param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>


<servlet-mapping>
<servlet-name>h2Console</servlet-name>
<url-pattern>/h2/*</url-pattern>
</servlet-mapping>


2、h2数据库默认创建一个管理员权限的sa用户名,密码为空字符串,连接数据库时可以直接使用sa用户来登录。操作h2数据库用户的sql语法:
(1)修改数据库密码
//sa 为用户名 'nms'为修改的密码(可以'')
ALTER USER sa SET { PASSWORD 'nms' } 

(2)创建用户
//bob为用户名 'x'为密码(可以'')
CREATE USER IF NOT EXISTS bob
{ PASSWORD 'x'  }

(3)删除用户
//bob为用户名
DROP USER [IF EXISTS] bob

(4)修改用户权限
ALTER USER bob ADMIN { TRUE }

(5)重命名用户
//把bob重命名为json
ALTER USER bob RENAME TO json

(6)查询所有的数据库用户
SELECT * FROM INFORMATION_SCHEMA.USERS ORDER BY NAME;


3、当指定h2的数据库目录不存在时,会自动创建目录,如果数据库目录不存在,会自动创建数据库目录。


4、当使用嵌入模式时,不需要使用启动服务器。当使用服务器模式时,则需要先开启服务器,提供服务器的门面类是org.h2.tools.Server。
   h2的服务功能又细分为三种(如果启动的时候不指定则默认三种服务器都启动):
web server(启动参数 -web):
功能:提供h2的web客户端服务。通过ServerSocket实现支持使用浏览器访问H2 Console,默认端口为8082,但没有针对性能优化。    
实现类:org.h2.server.web.WebServer

TCP server(启动参数 -tcp):
功能:提供h2数据库功能。实现了h2本地数据库协议,通过TCP连接,默认端口为9092,允许多数据库多客户端连接,
  还可以与嵌入模式进行混合使用同一数据库。
    实现类:org.h2.server.TcpServer

PG server(启动参数 -pg):
功能:提供PostgreSQL(另外一种数据库)的客户端服务。        
实现类:org.h2.server.pg.PgServer

附加:
TCP server服务是提供H2服务的,必须启动,其余两个服务可以根据需要选择启动。如果是在Web项目中,可以不使用web server,
而是使用org.h2.server.web.WebServlet来提供web客户端服务。

 
 

5、使用h2数据库可以非常方便的增加扩展函数,只需要创建个普通的java类,定义public static形式的方法,然后在连接h2数据库,注册定义
   的扩展函数。
    格式为:CREATE ALIAS [IF NOT EXISTS] 函数名 FOR "方法全限定名" 
例如:CREATE ALIAS IF NOT EXISTS MYUUID FOR "cn.h2.fun.H2FunctionExt.generateUUID"

三、h2服务器集群:
1、h2服务器官方有提供集群功能,通过org.h2.tools.CreateCluster.CreateCluster工具类来实现集群,此工具类主要参数如下(选填):
-urlSource :必传。指定源服务器地址,即相当于主服务器。
-urlTarget :必传。指定目的服务器地址,即相当于备份服务器,会将源服务器的数据文件覆盖到目的服务器,使其与源服务器数据一致。
-user :数据库账号
-password :数据库密码
-serverList :必传。集群服务器表。可以是ip地址,也可以是域名。多个服务器地址之间使用逗号隔开。
-help :输出帮助信息。使用此参数后,其余参数都无效(即集群不生效),仅仅只会在控制台输出帮助信息。

注意:此工具类只需要配置相关参数执行一次就行,此工具本身不是一个服务,运行完就关闭。它只是帮助将集群的数据写到各个
  数据库文件中,各服务器都能读取到自己数据库文件的集群信息,使得实现服务器的集群。


2、客户端连接集群环境的地址格式例子: jdbc:h2:tcp://localhost:9101,localhost:9102,localhost:9103/./newh2test
   上述地址中连接了集群中的三台服务器,注意ip地址的顺序,查询结果将优先读取第一个ip数据库,如果第一个ip地址的数据库
   宕机了,将读取第二个ip地址数据库,以此类推。同时,集群的数据库文件名是一致的,./newh2test表示基本目录的newh2test
   数据库。如果是同一台服务器下运行多个h2数据库,可以在启动的时候指定基本目录(-baseDir)。
   
   


3、查询集群节点的sql语句: SELECT VALUE FROM INFORMATION_SCHEMA.SETTINGS WHERE NAME='CLUSTER'


4、在集群中,不允许使用auto_increment自增长序列、RAND()、RANDOM_UUID(), SECURE_RAND(), SESSION_ID(), MEMORY_FREE(), 
   MEMORY_USED(), CSVREAD(), CSVWRITE()等函数,因为在不同数据库中不能保证其数据的一致性,故不能在修改语句(update/insert/merge)
   中使用。
   
   
   
   
5、在集群环境下,对数据进行修改操作时,会自动要求所有运行中的集群服务器都执行成功,最终数据才操作成功,如果有其中一台服务器报错
   则都会回滚事务的操作。(只针对运行中的服务器,如果服务器已经停止运行不可访问的,则直接忽略。)


5、h2的官方集群模式性能并不佳,在集群环境下,执行更新操作,要比单机单数据库服务情况性能要下降50%-70%。执行查询操作时,也因为会对
   所有可运行数据库进行请求查询,故也有一定的性能消耗。故谨慎使用集群模式,并且不建议集群的数据库过多,通常两台数据库比较适合。




原文:https://blog.csdn.net/u013777382/article/details/78932310 
 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值