• Java嵌入式数据库H2学习总结(二)——在Web应用程序中使用H2数据库


    一、搭建测试环境和项目

    1.1、搭建JavaWeb测试项目

      创建一个【H2DBTest】JavaWeb项目,找到H2数据库的jar文件,如下图所示:

      

      H2数据库就一个jar文件,这个Jar文件里面包含了使用JDBC方式连接H2数据库时使用的驱动类,将"h2-1.4.183.jar"加入到【H2DBTest】项目中,如下图所示:

      

    1.2、开启H2数据库

      进入到h2in目录,如下图所示:

      

      确保H2数据库使用的8082端口没有被其他应用程序占用,正常启动之后输入"http://localhost:8082"进行简单的测试,如下图所示:

      

      到此,使用Java操作H2数据库的测试环境就算是搭建完成了。

    二、在Java中操作H2数据库

    2.1、以嵌入式(本地)连接方式连接H2数据库

      这种连接方式默认情况下只允许有一个客户端连接到H2数据库,有客户端连接到H2数据库之后,此时数据库文件就会被锁定,那么其他客户端就无法再连接了。

      连接语法:jdbc:h2:[file:][<path>]<databaseName>

      例如:
        jdbc:h2:~/test //连接位于用户目录下的test数据库
        jdbc:h2:file:/data/sample
        jdbc:h2:file:E:/H2/gacl(Windows only)

      编写测试代码,如下:

    复制代码
     1 /**
     2  * 
     3  */
     4 package jdbc.conn.h2.test;
     5 
     6 import java.sql.Connection;
     7 import java.sql.DriverManager;
     8 import java.sql.ResultSet;
     9 import java.sql.Statement;
    10 import java.util.UUID;
    11 
    12 /**
    13  * <p>ClassName: H2ConnTest1<p>
    14  * <p>Description: Java通过JDBC方式连接H2数据库<p>
    15  * @author xudp
    16  * @version 1.0 V
    17  * @createTime 2014-12-18 上午11:22:12
    18  */
    19 public class H2ConnTest1 {
    20     //数据库连接URL,当前连接的是E:/H2目录下的gacl数据库
    21     private static final String JDBC_URL = "jdbc:h2:E:/H2/gacl";
    22     //连接数据库时使用的用户名
    23     private static final String USER = "gacl";
    24     //连接数据库时使用的密码
    25     private static final String PASSWORD = "123";
    26     //连接H2数据库时使用的驱动类,org.h2.Driver这个类是由H2数据库自己提供的,在H2数据库的jar包中可以找到
    27     private static final String DRIVER_CLASS="org.h2.Driver";
    28     
    29     public static void main(String[] args) throws Exception {
    30         // 加载H2数据库驱动
    31         Class.forName(DRIVER_CLASS);
    32         // 根据连接URL,用户名,密码获取数据库连接
    33         Connection conn = DriverManager.getConnection(JDBC_URL, USER, PASSWORD);
    34         Statement stmt = conn.createStatement();
    35         //如果存在USER_INFO表就先删除USER_INFO表
    36         stmt.execute("DROP TABLE IF EXISTS USER_INFO");
    37         //创建USER_INFO表
    38         stmt.execute("CREATE TABLE USER_INFO(id VARCHAR(36) PRIMARY KEY,name VARCHAR(100),sex VARCHAR(4))");
    39         //新增
    40         stmt.executeUpdate("INSERT INTO USER_INFO VALUES('" + UUID.randomUUID()+ "','大日如来','男')");
    41         stmt.executeUpdate("INSERT INTO USER_INFO VALUES('" + UUID.randomUUID()+ "','青龙','男')");
    42         stmt.executeUpdate("INSERT INTO USER_INFO VALUES('" + UUID.randomUUID()+ "','白虎','男')");
    43         stmt.executeUpdate("INSERT INTO USER_INFO VALUES('" + UUID.randomUUID()+ "','朱雀','女')");
    44         stmt.executeUpdate("INSERT INTO USER_INFO VALUES('" + UUID.randomUUID()+ "','玄武','男')");
    45         stmt.executeUpdate("INSERT INTO USER_INFO VALUES('" + UUID.randomUUID()+ "','苍狼','男')");
    46         //删除
    47         stmt.executeUpdate("DELETE FROM USER_INFO WHERE name='大日如来'");
    48         //修改
    49         stmt.executeUpdate("UPDATE USER_INFO SET name='孤傲苍狼' WHERE name='苍狼'");
    50         //查询
    51         ResultSet rs = stmt.executeQuery("SELECT * FROM USER_INFO");
    52         //遍历结果集
    53         while (rs.next()) {
    54             System.out.println(rs.getString("id") + "," + rs.getString("name")+ "," + rs.getString("sex"));
    55         }
    56         //释放资源
    57         stmt.close();
    58         //关闭连接
    59         conn.close();
    60     }
    61 }
    复制代码

      执行结果如下:

      

      登录到H2控制台当中也可以看到创建好的USER_INFO表和表里面的数据,如下图所示:

      

      这里需要说明一下使用这种"jdbc:h2:E:/H2/gacl"这种方式连接H2数据库容易遇到的问题,如果已经在H2的WebConsole控制台中登录gacl数据库,如下图所示:

      

      此时gacl数据库就会被锁定,此时通过java代码连接gacl数据库时就会出现如下的错误,如所示:

    复制代码
     1 Exception in thread "main" org.h2.jdbc.JdbcSQLException: Database may be already in use: "E:/H2/gacl.mv.db". Possible solutions: close all other connection(s); use the server mode [90020-183]
     2     at org.h2.message.DbException.getJdbcSQLException(DbException.java:345)
     3     at org.h2.message.DbException.get(DbException.java:168)
     4     at org.h2.mvstore.db.MVTableEngine.init(MVTableEngine.java:108)
     5     at org.h2.engine.Database.getPageStore(Database.java:2376)
     6     at org.h2.engine.Database.open(Database.java:666)
     7     at org.h2.engine.Database.openDatabase(Database.java:266)
     8     at org.h2.engine.Database.<init>(Database.java:260)
     9     at org.h2.engine.Engine.openSession(Engine.java:60)
    10     at org.h2.engine.Engine.openSession(Engine.java:167)
    11     at org.h2.engine.Engine.createSessionAndValidate(Engine.java:145)
    12     at org.h2.engine.Engine.createSession(Engine.java:128)
    13     at org.h2.engine.Engine.createSession(Engine.java:26)
    14     at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:347)
    15     at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:108)
    16     at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:92)
    17     at org.h2.Driver.connect(Driver.java:72)
    18     at java.sql.DriverManager.getConnection(DriverManager.java:571)
    19     at java.sql.DriverManager.getConnection(DriverManager.java:215)
    20     at jdbc.conn.h2.test.H2ConnTest1.main(H2ConnTest1.java:33)
    21 Caused by: java.lang.IllegalStateException: The file is locked: nio:E:/H2/gacl.mv.db [1.4.183/7]
    22     at org.h2.mvstore.DataUtils.newIllegalStateException(DataUtils.java:768)
    23     at org.h2.mvstore.FileStore.open(FileStore.java:170)
    24     at org.h2.mvstore.MVStore.<init>(MVStore.java:346)
    25     at org.h2.mvstore.MVStore$Builder.open(MVStore.java:2754)
    26     at org.h2.mvstore.db.MVTableEngine$Store.<init>(MVTableEngine.java:162)
    27     at org.h2.mvstore.db.MVTableEngine.init(MVTableEngine.java:98)
    28     ... 16 more
    复制代码

       引起这个错误的原因是因为gacl数据库对应的文件已经被锁定了,所以java代码这边无法再访问,为了能够让Java代码能够正常访问,必须把WebConsole控制台那边的连接先断开,

      

      断开数据库连接之后,Java代码这边就可以连接上去了。

    2.2、使用TCP/IP的服务器模式(远程连接)方式连接H2数据库(推荐)

      这种连接方式就和其他数据库类似了,是基于Service的形式进行连接的,因此允许多个客户端同时连接到H2数据库

      连接语法:jdbc:h2:tcp://<server>[:<port>]/[<path>]<databaseName>
      范例:jdbc:h2:tcp://localhost/~/test

      测试代码如下:

    复制代码
     1 /**
     2  * 
     3  */
     4 package jdbc.conn.h2.test;
     5 
     6 import java.sql.Connection;
     7 import java.sql.DriverManager;
     8 import java.sql.ResultSet;
     9 import java.sql.Statement;
    10 import java.util.UUID;
    11 
    12 /**
    13  * <p>ClassName: H2ConnTest1<p>
    14  * <p>Description: Java通过JDBC方式连接H2数据库<p>
    15  * @author xudp
    16  * @version 1.0 V
    17  * @createTime 2014-12-18 上午11:22:12
    18  */
    19 public class H2ConnTest2 {
    20     //数据库连接URL,通过使用TCP/IP的服务器模式(远程连接),当前连接的是E:/H2目录下的gacl数据库
    21     //private static final String JDBC_URL = "jdbc:h2:tcp://localhost/E:/H2/gacl";
    22     //private static final String JDBC_URL = "jdbc:h2:tcp://127.0.0.1/E:/H2/gacl";
    23     private static final String JDBC_URL = "jdbc:h2:tcp://192.168.1.144/data/gacl";
    24     //连接数据库时使用的用户名
    25     private static final String USER = "gacl";
    26     //连接数据库时使用的密码
    27     private static final String PASSWORD = "123";
    28     //连接H2数据库时使用的驱动类,org.h2.Driver这个类是由H2数据库自己提供的,在H2数据库的jar包中可以找到
    29     private static final String DRIVER_CLASS="org.h2.Driver";
    30     
    31     public static void main(String[] args) throws Exception {
    32         // 加载H2数据库驱动
    33         Class.forName(DRIVER_CLASS);
    34         // 根据连接URL,用户名,密码获取数据库连接
    35         Connection conn = DriverManager.getConnection(JDBC_URL, USER, PASSWORD);
    36         Statement stmt = conn.createStatement();
    37         //如果存在USER_INFO表就先删除USER_INFO表
    38         stmt.execute("DROP TABLE IF EXISTS USER_INFO");
    39         //创建USER_INFO表
    40         stmt.execute("CREATE TABLE USER_INFO(id VARCHAR(36) PRIMARY KEY,name VARCHAR(100),sex VARCHAR(4))");
    41         //新增
    42         stmt.executeUpdate("INSERT INTO USER_INFO VALUES('" + UUID.randomUUID()+ "','大日如来','男')");
    43         stmt.executeUpdate("INSERT INTO USER_INFO VALUES('" + UUID.randomUUID()+ "','青龙','男')");
    44         stmt.executeUpdate("INSERT INTO USER_INFO VALUES('" + UUID.randomUUID()+ "','白虎','男')");
    45         stmt.executeUpdate("INSERT INTO USER_INFO VALUES('" + UUID.randomUUID()+ "','朱雀','女')");
    46         stmt.executeUpdate("INSERT INTO USER_INFO VALUES('" + UUID.randomUUID()+ "','玄武','男')");
    47         stmt.executeUpdate("INSERT INTO USER_INFO VALUES('" + UUID.randomUUID()+ "','苍狼','男')");
    48         //删除
    49         stmt.executeUpdate("DELETE FROM USER_INFO WHERE name='大日如来'");
    50         //修改
    51         stmt.executeUpdate("UPDATE USER_INFO SET name='孤傲苍狼' WHERE name='苍狼'");
    52         //查询
    53         ResultSet rs = stmt.executeQuery("SELECT * FROM USER_INFO");
    54         //遍历结果集
    55         while (rs.next()) {
    56             System.out.println(rs.getString("id") + "," + rs.getString("name")+ "," + rs.getString("sex"));
    57         }
    58         //释放资源
    59         stmt.close();
    60         //关闭连接
    61         conn.close();
    62     }
    63 }
    复制代码

     2.3、H2数据库的内存模式

      H2数据库被称为内存数据库,因为它支持在内存中创建数据库和表

      范例如下:

    复制代码
     1 package jdbc.conn.h2.test;
     2 
     3 import java.sql.Connection;
     4 import java.sql.DriverManager;
     5 import java.sql.ResultSet;
     6 import java.sql.Statement;
     7 import java.util.UUID;
     8 
     9 /**
    10 * @ClassName: TestMemH2
    11 * @Description:H2数据库的内存模式(数据只保存在内存中)
    12 * @author: 孤傲苍狼
    13 * @date: 2014-12-18 下午10:47:01
    14 *
    15 */ 
    16 public class TestMemH2 {
    17 
    18         //数据库连接URL,通过使用TCP/IP的服务器模式(远程连接),当前连接的是内存里面的gacl数据库
    19         private static final String JDBC_URL = "jdbc:h2:tcp://localhost/mem:gacl";
    20         //连接数据库时使用的用户名
    21         private static final String USER = "gacl";
    22         //连接数据库时使用的密码
    23         private static final String PASSWORD = "123";
    24         //连接H2数据库时使用的驱动类,org.h2.Driver这个类是由H2数据库自己提供的,在H2数据库的jar包中可以找到
    25         private static final String DRIVER_CLASS="org.h2.Driver";
    26         
    27         public static void main(String[] args) throws Exception {
    28             // 加载H2数据库驱动
    29             Class.forName(DRIVER_CLASS);
    30             // 根据连接URL,用户名,密码获取数据库连接
    31             Connection conn = DriverManager.getConnection(JDBC_URL, USER, PASSWORD);
    32             Statement stmt = conn.createStatement();
    33             //如果存在USER_INFO表就先删除USER_INFO表
    34             stmt.execute("DROP TABLE IF EXISTS USER_INFO");
    35             //创建USER_INFO表
    36             stmt.execute("CREATE TABLE USER_INFO(id VARCHAR(36) PRIMARY KEY,name VARCHAR(100),sex VARCHAR(4))");
    37             //新增
    38             stmt.executeUpdate("INSERT INTO USER_INFO VALUES('" + UUID.randomUUID()+ "','大日如来','男')");
    39             stmt.executeUpdate("INSERT INTO USER_INFO VALUES('" + UUID.randomUUID()+ "','青龙','男')");
    40             stmt.executeUpdate("INSERT INTO USER_INFO VALUES('" + UUID.randomUUID()+ "','白虎','男')");
    41             stmt.executeUpdate("INSERT INTO USER_INFO VALUES('" + UUID.randomUUID()+ "','朱雀','女')");
    42             stmt.executeUpdate("INSERT INTO USER_INFO VALUES('" + UUID.randomUUID()+ "','玄武','男')");
    43             stmt.executeUpdate("INSERT INTO USER_INFO VALUES('" + UUID.randomUUID()+ "','苍狼','男')");
    44             //删除
    45             stmt.executeUpdate("DELETE FROM USER_INFO WHERE name='大日如来'");
    46             //修改
    47             stmt.executeUpdate("UPDATE USER_INFO SET name='孤傲苍狼' WHERE name='苍狼'");
    48             //查询
    49             ResultSet rs = stmt.executeQuery("SELECT * FROM USER_INFO");
    50             //遍历结果集
    51             while (rs.next()) {
    52                 System.out.println(rs.getString("id") + "," + rs.getString("name")+ "," + rs.getString("sex"));
    53             }
    54             //释放资源
    55             stmt.close();
    56             //关闭连接
    57             conn.close();
    58         }
    59 }
    复制代码

      运行结果如下:

      

      注意:如果使用H2数据库的内存模式,那么我们创建的数据库和表都只是保存在内存中,一旦服务器重启,那么内存中的数据库和表就不存在了。

      以上就是关于在Web应用程序中使用H2数据库的全部内容。

  • 相关阅读:
    Python学习笔记:pip使用技巧
    机器学习笔记:训练集、验证集和测试集区别
    MySQL学习笔记:3道面试题小测
    Python学习笔记:精确的四舍五入
    Hive学习笔记:列转行之collect_list/collect_set/concat_ws
    Python学习笔记:6个代码性能坏习惯
    爬虫学习笔记:打造自己的代理池
    Mysql学习笔记:5.5升级至8.0版本
    机器学习笔记:sklearn.model_selection.train_test_split切分训练、测试集
    HashSet其实就那么一回事儿之源码浅析
  • 原文地址:https://www.cnblogs.com/telwanggs/p/5311907.html
Copyright © 2020-2023  润新知