zoukankan      html  css  js  c++  java
  • 内存数据库-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
    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    python的数据类型+常用操作符
    厉害了
    git merge ignore line ending
    CNAME , DNS , A Record , Domain Name

    setcookie无效
    magic quote gpc htmlspecialchars
    整型 浮点型 不能转化
    git push -f带来的conflict如何解决
    git pull --rebase
  • 原文地址:https://www.cnblogs.com/GarfieldEr007/p/10198030.html
Copyright © 2011-2022 走看看