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

1、搭建测试环境和项目

1.一、搭建JavaWeb测试项目

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

  

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

  

1.二、开启H2数据库

  进入到h2\bin目录,以下图所示:数据库

  

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

  

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

2、在Java中操做H2数据库

2.一、以嵌入式(本地)链接方式链接H2数据库

  这种链接方式默认状况下只容许有一个客户端链接到H2数据库,有客户端链接到H2数据库以后,此时数据库文件就会被锁定,那么其余客户端就没法再链接了。tcp

  链接语法:jdbc:h2:[file:][<path>]<databaseName>测试

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

  编写测试代码,以下:spa

 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 }

  执行结果以下:code

  

  登陆到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.二、使用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.三、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数据库的所有内容。

相关文章
相关标签/搜索