一、搭建测试环境和项目

1.1、搭建JavaWeb测试项目

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

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

1.2、开启H2数据库

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

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

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

二、在Java中操作H2数据库

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

  这种连接方式默认情况下只允许有一个客户端连接到H2数据库,有客户端连接到H2数据库之后,此时数据库文件就会被锁定,那么其他客户端就无法再连接了。
  连接语法:jdbc:h2:[file:][]
  例如:
    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. import java.sql.Connection;
  6. import java.sql.DriverManager;
  7. import java.sql.ResultSet;
  8. import java.sql.Statement;
  9. import java.util.UUID;
  10. /**
  11. * <p>ClassName: H2ConnTest1<p>
  12. * <p>Description: Java通过JDBC方式连接H2数据库<p>
  13. * @author xudp
  14. * @version 1.0 V
  15. * @createTime 2014-12-18 上午11:22:12
  16. */
  17. public class H2ConnTest1 {
  18. //数据库连接URL,当前连接的是E:/H2目录下的gacl数据库
  19. private static final String JDBC_URL = "jdbc:h2:E:/H2/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. public static void main(String[] args) throws Exception {
  27. // 加载H2数据库驱动
  28. Class.forName(DRIVER_CLASS);
  29. // 根据连接URL,用户名,密码获取数据库连接
  30. Connection conn = DriverManager.getConnection(JDBC_URL, USER, PASSWORD);
  31. Statement stmt = conn.createStatement();
  32. //如果存在USER_INFO表就先删除USER_INFO表
  33. stmt.execute("DROP TABLE IF EXISTS USER_INFO");
  34. //创建USER_INFO表
  35. stmt.execute("CREATE TABLE USER_INFO(id VARCHAR(36) PRIMARY KEY,name VARCHAR(100),sex VARCHAR(4))");
  36. //新增
  37. stmt.executeUpdate("INSERT INTO USER_INFO VALUES('" + UUID.randomUUID()+ "','大日如来','男')");
  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. //删除
  44. stmt.executeUpdate("DELETE FROM USER_INFO WHERE name='大日如来'");
  45. //修改
  46. stmt.executeUpdate("UPDATE USER_INFO SET name='孤傲苍狼' WHERE name='苍狼'");
  47. //查询
  48. ResultSet rs = stmt.executeQuery("SELECT * FROM USER_INFO");
  49. //遍历结果集
  50. while (rs.next()) {
  51. System.out.println(rs.getString("id") + "," + rs.getString("name")+ "," + rs.getString("sex"));
  52. }
  53. //释放资源
  54. stmt.close();
  55. //关闭连接
  56. conn.close();
  57. }
  58. }

  执行结果如下:
  image.png

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

  image.png

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

  此时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控制台那边的连接先断开,
  image.png
  断开数据库连接之后,Java代码这边就可以连接上去了。

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

  这种连接方式就和其他数据库类似了,是基于Service的形式进行连接的,因此允许多个客户端同时连接到H2数据库
  连接语法:jdbc:h2:tcp://[:]/[]
  范例:jdbc:h2:tcp://localhost/~/test
  测试代码如下:

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

2.3、H2数据库的内存模式

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

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

  运行结果如下:
  H2数据库(二) Web应用程序中使用H2数据库 - 图9
  注意:如果使用H2数据库的内存模式,那么我们创建的数据库和表都只是保存在内存中,一旦服务器重启,那么内存中的数据库和表就不存在了。
  以上就是关于在Web应用程序中使用H2数据库的全部内容。