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

2023-11-07

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数据库

  进入到h2\bin目录,如下图所示:

  

  确保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数据库的全部内容。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • 使用IntelliJ数据库客户端连接H2数据库

    我的 Grails 应用程序在开发模式下使用 h2 数据库 Grails 应用程序的默认行为 数据库连接设置DataSource groovy are dataSource pooled true jmxExport true driver
  • 为什么我的实体不能与 SpringBoot 一起工作,尽管它可以在没有 SpringBoot 的情况下工作

    请注意 在调查时这个问题 https stackoverflow com questions 52799706 springboot not an entity noredirect 1 comment92527948 52799706我更
  • 如何检查 h2 数据库健康状况和损坏情况

    我在 JavaFX 8 桌面应用程序中以嵌入模式使用 h2 数据库 并且我为用户开发了一个选项来备份和恢复数据库文件 在旧版本的程序中 我使用了 SQLite 数据库 并且使用 pragmaintegrity check 命令检查数据库文件
  • 如何检查h2数据库是否需要升级?

    On H2下载网站 http h2database com html download html有一个Database Upgrade Helper File用于从 1 1 升级到更新版本 我想知道是否有一种好的 干净的方法来检查数据库是否
  • H2 数据库表上的 SQL 查询抛出 ArrayIndexOutOfBoundsException

    我有一个 H2 数据库 一些查询在该数据库上工作 而其他查询则抛出一个ArrayIndexOutOfBoundsException 例如 SELECT COLUMN 1 FROM MY TABLE works fine SELECT COU
  • 如何在 Spring Integration 测试之间删除内存中的 h2db?

    我在 Spring Web 应用程序中使用 Liquibase 我有一堆实体 在每个实体 如用户 帐户 发票 许可证等 的集成测试中对 REST API 进行了数百次测试 我的所有集成测试在按类运行时都通过了 但其中很多在使用一起运行时失败
  • 从 DbVisualizer 连接到 H2 服务器

    我的 H2 数据库配置如下 Configuration Profile Profiles DEV public class DevDataSourceConfiguration Bean initMethod start destroyMe
  • 如何在playframework 2.0中配置FS数据库?

    这有可能吗 在框架的第一个版本中似乎很容易完成 而不是使用 Default database configuration db default driver org h2 Driver db default url jdbc h2 mem
  • 将 H2 数据库与 Android 集成 [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 有没有关于将 H2 数据库与 Android 集成并开始使用的教程 我正在寻找执行此操作的指南 Thanks The H2 中的 Android 文档
  • H2 in-mem-DB 与 hibernate 设置为创建给我表未找到错误

    我想在内存数据库中建立一个包含 hibernate spring mvc 和 H2 的项目 目前 当一切启动 在码头 时 我收到错误消息 指出表格尚未存在 这是我得到的错误 Okt 09 2013 3 42 47 PM org hibern
  • 定期重置嵌入式 H2 数据库

    我正在演示服务器中设置应用程序的新版本 并且希望找到一种每天重置数据库的方法 我想我总是可以有一个 cron 作业执行删除和创建查询 但我正在寻找一种更干净的方法 我尝试使用带有删除创建方法的特殊持久性单元 但它不起作用 因为系统频繁地 按
  • 使用 Spring Security (Spring Boot 3.0.2) 时如何访问 H2 控制台?

    所以我正在尝试学习 Spring 因为今年晚些时候我的一个项目将需要它 项目使用 Spring Boot 3 0 2 和 Java 17 我还使用 Spring Security 依赖项 这意味着我需要在不使用令牌的情况下授权某些 URL
  • 如何在H2中创建新数据库?

    我有一个在 MySQL 上本地运行的站点 我想在 H2 数据库上运行它 我刚刚在浏览器上运行了控制台的 h2 jar 文件 但每当我登录时我都会看到该列表jdbc h2 var www mysite data db MODE MySQL i
  • 有 H2 数据库的实际经验吗? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • SonarQube 内部 H2 数据库的默认凭据?

    我正在运行 SonarQube 5 6 1 并尝试保存我创建的视图 为此 我想看一下 Sonar 根据它自己的自述文件 用于内部嵌入式数据库的 H2 DB 我已经运行了 H2 jar 文件 并且在控制台中能够登录到虚拟数据库 如果 Sona
  • 如何显示本地h2数据库的内容(Web控制台)?

    最近我加入了一个新团队 这里的人使用 h2 进行存根服务 我想知道是否可以使用网络界面显示该数据库的内容 在工作中 可以通过访问localhost 5080 我有一个使用 h2 数据库的项目 但是当我点击时我看不到 h2 Web 控制台lo
  • 以编程方式嵌入 Java h2 数据库

    目前我们使用HSQLDB http www hsqldb org 作为嵌入式数据库 但随着数据量的增长 我们会寻找内存占用更少的数据库 德比 JavaDB http developers sun com javadb 目前不是一个选项 因为
  • 如何在 H2 中创建过程

    这似乎与具有相同标题的其他问题重复 但实际上并非如此 我们的业务逻辑主要作为 DB2 存储过程来实现 我看到 H2 有一个 DB2 兼容模式 很好 我们如何使用 H2 通过这些程序进行内存单元测试 不幸的是 H2 似乎缺少 CREATE P
  • H2 中的 IF 函数用于 MySQL 兼容性

    我正在使用 H2 具有 MySQL 兼容模式 针对我们使用 MySQL 的软件编写一些自动化测试 不幸的是 H2 似乎没有IF我们的许多查询都使用该函数 除了使用 DECODE 之类的东西重写我们的应用程序查询之外 它们是创建 if 函数
  • @Autowired jdbcTemplate 和 h2 内存数据库多次执行 runscript

    我继承了一个项目 并试图针对内存中的 h2 数据库运行一组集成测试 为了让他们传递一些表格 需要创建关系和参考数据 我可以看到问题在于引用的脚本RUNSCRIPT被执行多次 因此生成Index XXX IDX already exists错

随机推荐