一、搭建測試環境和項目
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數據庫的全部內容。

