H2 数据库介绍(2)--使用

打印 上一主题 下一主题

主题 873|帖子 873|积分 2629

本文紧张介绍 H2 的根本使用,文中所使用到的软件版本:Java 1.8.0_341、H2 2.2.224、PostgreSQL 驱动 42.5.5。
1、嵌入式(本地)模式

直接使用 JDBC 连接数据库即可,如果数据库不存在会自动创建。
1.1、持久数据库
  1. @Test
  2. public void localFile() throws SQLException {
  3.     String dbName = "test";
  4.     //用户名密码为第一次连接设置的密码
  5.     Connection con = JdbcUtil.getConnection("org.h2.Driver", "jdbc:h2:file:d:/temp/" + dbName, "admin", "123456");
  6.     business(con, dbName);
  7.     con.close();
  8. }
  9. private void business(Connection con, String dbName) throws SQLException {
  10.     String tableName = "a_student";
  11.     Statement st = con.createStatement();
  12.     ResultSet rs = st.executeQuery("select * from INFORMATION_SCHEMA.TABLES");
  13.     while (rs.next()) {
  14.         log.info("table_catalog={},table_schema={},table_name={}", rs.getString("table_catalog"), rs.getString("table_schema"), rs.getString("table_name"));
  15.     }
  16.     String sql = "select 1 from INFORMATION_SCHEMA.TABLES where upper(table_catalog)=? and upper(table_schema)=? and upper(table_name)=?";
  17.     PreparedStatement pst = con.prepareStatement(sql);
  18.     pst.setString(1, dbName.toUpperCase());
  19.     pst.setString(2, "PUBLIC");
  20.     pst.setString(3, tableName.toUpperCase());
  21.     rs = pst.executeQuery();
  22.     if (!rs.next()) {//表不存在则创建并初始化数据,这里根据业务需要进行操作
  23.         st.executeUpdate("create table " + tableName + "(id int, name varchar(32))");
  24.         st.executeUpdate("insert into " + tableName + "(id,name) values (1,'李白')");
  25.         st.executeUpdate("insert into " + tableName + "(id,name) values (2,'杜甫')");
  26.     }
  27.     rs = st.executeQuery("select * from " + tableName);
  28.     while (rs.next()) {
  29.         log.info("id={},name={}", rs.getInt("id"), rs.getString("name"));
  30.     }
  31. }
复制代码
1.2、内存数据库
  1. @Test
  2. public void localMem() throws SQLException {
  3.     String dbName = "test";
  4.     //用户名密码为第一次连接设置的密码
  5.     Connection con = JdbcUtil.getConnection("org.h2.Driver", "jdbc:h2:mem:" + dbName, "admin", "123456");
  6.     business(con, dbName);
  7.     con.close();
  8. }
复制代码
2、服务器模式

可以通过 bin/h2.bat(或 bin/h2.sh) 命令启动 H2 控制台,同时会启动 Web 服务器合 PG 服务器,也可以通过以下方式启动服务器:
  1. java -cp h2*.jar org.h2.tools.Server [param1] [param2] [...]
复制代码
改方式可以添加参数来调整服务器的默认行为,检察所有参数:
  1. java -cp h2*.jar org.h2.tools.Server -?
复制代码
相关参数如下:
  1. [-web]                  Start the web server with the H2 Console
  2. [-webAllowOthers]       Allow other computers to connect - see below
  3. [-webExternalNames]       The comma-separated list of external names and IP addresses of this server, used together with -webAllowOthers
  4. [-webDaemon]            Use a daemon thread
  5. [-webPort <port>]       The port (default: 8082)
  6. [-webSSL]               Use encrypted (HTTPS) connections
  7. [-webAdminPassword]     Password of DB Console administrator
  8. [-browser]              Start a browser connecting to the web server
  9. [-tcp]                  Start the TCP server
  10. [-tcpAllowOthers]       Allow other computers to connect - see below
  11. [-tcpDaemon]            Use a daemon thread
  12. [-tcpPort <port>]       The port (default: 9092)
  13. [-tcpSSL]               Use encrypted (SSL) connections
  14. [-tcpPassword <pwd>]    The password for shutting down a TCP server
  15. [-tcpShutdown "<url>"]  Stop the TCP server; example: tcp://localhost
  16. [-tcpShutdownForce]     Do not wait until all connections are closed
  17. [-pg]                   Start the PG server
  18. [-pgAllowOthers]        Allow other computers to connect - see below
  19. [-pgDaemon]             Use a daemon thread
  20. [-pgPort <port>]        The port (default: 5435)
  21. [-properties "<dir>"]   Server properties (default: ~, disable: null)
  22. [-baseDir <dir>]        The base directory for H2 databases (all servers)
  23. [-ifExists]             Only existing databases may be opened (all servers)
  24. [-ifNotExists]          Databases are created when accessed
  25. [-trace]                Print additional trace information (all servers)
  26. [-key <from> <to>]      Allows to map a database name to another (all servers)
复制代码
2.1、启动 Web 服务器
  1. java -cp h2-2.2.224.jar  org.h2.tools.Server -web -webAllowOthers
复制代码
使用浏览器访问 H2 控制台:http://localhost:8082
2.2、启动 TCP 服务器
  1. java -cp h2-2.2.224.jar  org.h2.tools.Server -tcp -tcpAllowOthers -ifNotExists
复制代码
应用程序使用 JDBC 访问数据库。
2.2.1、持久数据库
  1. @Test
  2. public void tcpFile() throws SQLException {
  3.     String dbName = "test";
  4.     //用户名密码为第一次连接设置的密码
  5.     Connection con = JdbcUtil.getConnection("org.h2.Driver", "jdbc:h2:tcp://localhost:9092/file:d:/temp/" + dbName, "admin", "123456");
  6.     business(con, dbName);
  7.     con.close();
  8. }
复制代码
2.2.2、内存数据库
  1. @Test
  2. public void tcpMem() throws Exception {
  3.     String dbName = "test";
  4.     Connection con = JdbcUtil.getConnection("org.h2.Driver", "jdbc:h2:tcp://localhost:9092/mem:" + dbName, "admin", "123456");
  5.     business(con, dbName);
  6.     con.close();
  7. }
复制代码
2.3、启动 PG 服务器
  1. java -cp h2-2.2.224.jar  org.h2.tools.Server -pg -pgAllowOthers -baseDir d:/temp -ifNotExists
复制代码
应用程序引入 PG JDBC 驱动并访问数据库。
  1. <dependency>
  2.     <groupId>org.postgresql</groupId>
  3.     <artifactId>postgresql</artifactId>
  4.     <version>42.5.5</version>
  5. </dependency>
复制代码
  1. @Test
  2. public void pg() throws Exception {
  3.     String dbName = "test";
  4.     //用户名密码为第一次连接设置的密码
  5.     Connection con = JdbcUtil.getConnection("org.postgresql.Driver", "jdbc:postgresql://localhost:5435/" + dbName, "admin", "123456");
  6.     business(con, dbName);
  7.     con.close();
  8. }
复制代码
使用 PG 客户端访问时,默认的 schema 为小写:public,而使用本地或 TCP 模式访问时,默认的 schema 为大写:PBBLIC;因此不能使用 PG 客户端访问本地或 TCP模式创建的库,也不能使用本地或 TCP模式访问 PG 客户端创建的库,否则会报错误:"Schema "UBLIC" not found" 或 "Schema "public" not found"。
3、混合模式

混合模式本应用使用本地模式访问,其他应用使用远程模式访问,需要在应用中通过 API 访问相应的服务器。
3.1、启动 Web 服务器
  1. @Test
  2. public void web() throws Exception {
  3.     Server server = Server.createWebServer().start();
  4.     Thread.sleep(1000 * 100);
  5.     server.stop();
  6. }
复制代码
使用浏览器访问 H2 控制台:http://localhost:8082
3.2、启动 TCP 服务器

应用中启动 TCP 服务器,其他应用通过 JDBC 访问数据库。
3.2.1、持久数据库
  1. @Test
  2. public void tcpFile2() throws Exception {
  3.     //如果数据库不存在,tcp方式默认不允许创建数据库,使用 -ifNotExists 参数允许创建数据库
  4.     Server server = Server.createTcpServer("-ifNotExists").start();
  5.     CountDownLatch countDownLatch = new CountDownLatch(1);
  6.     new Thread(() -> {
  7.         try {
  8.             //模拟其他应用访问
  9.             tcpFile();
  10.         } catch (Exception e) {
  11.             e.printStackTrace();
  12.         }
  13.         countDownLatch.countDown();
  14.     }).start();
  15.     countDownLatch.await();
  16.     server.stop();
  17. }
复制代码
3.2.2、内存数据库
  1. @Test
  2. public void tcpMem2() throws Exception {
  3.     //如果数据库不存在,tcp方式默认不允许创建数据库,使用 -ifNotExists 参数允许创建数据库
  4.     Server server = Server.createTcpServer("-ifNotExists").start();
  5.     CountDownLatch countDownLatch = new CountDownLatch(1);
  6.     new Thread(() -> {
  7.         try {
  8.             //模拟其他应用访问
  9.             tcpMem();
  10.         } catch (Exception e) {
  11.             e.printStackTrace();
  12.         }
  13.         countDownLatch.countDown();
  14.     }).start();
  15.     countDownLatch.await();
  16.     server.stop();
  17. }
复制代码
3.3、启动 PG 服务器

应用中启动 PG 服务器,其他应用通过 PG 驱动访问数据库。
  1. @Test
  2. public void pg2() throws Exception {
  3.     //如果数据库不存在,该方式默认不允许创建数据库,使用 -ifNotExists 参数允许创建数据库;该方式还需要指定数据库文件目录
  4.     Server server = Server.createPgServer("-baseDir", "d:/temp", "-ifNotExists").start();
  5.     CountDownLatch countDownLatch = new CountDownLatch(1);
  6.     new Thread(() -> {
  7.         try {
  8.             //模拟其他应用访问
  9.             pg();
  10.         } catch (Exception e) {
  11.             e.printStackTrace();
  12.         }
  13.         countDownLatch.countDown();
  14.     }).start();
  15.     countDownLatch.await();
  16.     server.stop();
  17. }
复制代码
 
完整代码:
  1. package com.abc.demo.db;
  2. import lombok.extern.slf4j.Slf4j;
  3. import org.h2.tools.Server;
  4. import org.junit.Test;
  5. import java.sql.*;
  6. import java.util.concurrent.CountDownLatch;
  7. @Slf4j
  8. public class H2Case {
  9.     @Test
  10.     public void localFile() throws SQLException {
  11.         String dbName = "test";
  12.         //用户名密码为第一次连接设置的密码
  13.         Connection con = JdbcUtil.getConnection("org.h2.Driver", "jdbc:h2:file:d:/temp/" + dbName, "admin", "123456");
  14.         log.info("con={}", con);
  15.         business(con, dbName);
  16.         con.close();
  17.     }
  18.     @Test
  19.     public void localMem() throws SQLException {
  20.         String dbName = "test";
  21.         //用户名密码为第一次连接设置的密码
  22.         Connection con = JdbcUtil.getConnection("org.h2.Driver", "jdbc:h2:mem:" + dbName, "admin", "123456");
  23.         business(con, dbName);
  24.         con.close();
  25.     }
  26.     @Test
  27.     public void tcpFile() throws SQLException {
  28.         String dbName = "test";
  29.         //用户名密码为第一次连接设置的密码
  30.         Connection con = JdbcUtil.getConnection("org.h2.Driver", "jdbc:h2:tcp://localhost:9092/file:d:/temp/" + dbName, "admin", "123456");
  31.         business(con, dbName);
  32.         con.close();
  33.     }
  34.     @Test
  35.     public void tcpMem() throws Exception {
  36.         String dbName = "test";
  37.         Connection con = JdbcUtil.getConnection("org.h2.Driver", "jdbc:h2:tcp://localhost:9092/mem:" + dbName, "admin", "123456");
  38.         business(con, dbName);
  39.         con.close();
  40.     }
  41.     @Test
  42.     public void pg() throws Exception {
  43.         String dbName = "test";
  44.         //用户名密码为第一次连接设置的密码
  45.         Connection con = JdbcUtil.getConnection("org.postgresql.Driver", "jdbc:postgresql://localhost:5435/" + dbName, "admin", "123456");
  46.         business(con, dbName);
  47.         con.close();
  48.     }
  49.     @Test
  50.     public void web() throws Exception {
  51.         Server server = Server.createWebServer().start();
  52.         Thread.sleep(1000 * 10);
  53.         server.stop();
  54.     }
  55.     @Test
  56.     public void tcpFile2() throws Exception {
  57.         //如果数据库不存在,tcp方式默认不允许创建数据库,使用 -ifNotExists 参数允许创建数据库
  58.         Server server = Server.createTcpServer("-ifNotExists").start();
  59.         CountDownLatch countDownLatch = new CountDownLatch(1);
  60.         new Thread(() -> {
  61.             try {
  62.                 //模拟其他应用访问
  63.                 tcpFile();
  64.             } catch (Exception e) {
  65.                 e.printStackTrace();
  66.             }
  67.             countDownLatch.countDown();
  68.         }).start();
  69.         countDownLatch.await();
  70.         server.stop();
  71.     }
  72.     @Test
  73.     public void tcpMem2() throws Exception {
  74.         //如果数据库不存在,tcp方式默认不允许创建数据库,使用 -ifNotExists 参数允许创建数据库
  75.         Server server = Server.createTcpServer("-ifNotExists").start();
  76.         CountDownLatch countDownLatch = new CountDownLatch(1);
  77.         new Thread(() -> {
  78.             try {
  79.                 //模拟其他应用访问
  80.                 tcpMem();
  81.             } catch (Exception e) {
  82.                 e.printStackTrace();
  83.             }
  84.             countDownLatch.countDown();
  85.         }).start();
  86.         countDownLatch.await();
  87.         server.stop();
  88.     }
  89.     @Test
  90.     public void pg2() throws Exception {
  91.         //如果数据库不存在,该方式默认不允许创建数据库,使用 -ifNotExists 参数允许创建数据库;该方式还需要指定数据库文件目录
  92.         Server server = Server.createPgServer("-baseDir", "d:/temp", "-ifNotExists").start();
  93.         CountDownLatch countDownLatch = new CountDownLatch(1);
  94.         new Thread(() -> {
  95.             try {
  96.                 //模拟其他应用访问
  97.                 pg();
  98.             } catch (Exception e) {
  99.                 e.printStackTrace();
  100.             }
  101.             countDownLatch.countDown();
  102.         }).start();
  103.         countDownLatch.await();
  104.         server.stop();
  105.     }
  106.     private void business(Connection con, String dbName) throws SQLException {
  107.         String tableName = "a_student";
  108.         Statement st = con.createStatement();
  109.         String sql = "select 1 from INFORMATION_SCHEMA.TABLES where upper(table_catalog)=? and upper(table_schema)=? and upper(table_name)=?";
  110.         PreparedStatement pst = con.prepareStatement(sql);
  111.         pst.setString(1, dbName.toUpperCase());
  112.         pst.setString(2, "PUBLIC");
  113.         pst.setString(3, tableName.toUpperCase());
  114.         ResultSet rs = pst.executeQuery();
  115.         if (!rs.next()) {//表不存在则创建并初始化数据,这里根据业务需要进行操作
  116.             st.executeUpdate("create table " + tableName + "(id int, name varchar(32))");
  117.             st.executeUpdate("insert into " + tableName + "(id,name) values (1,'李白')");
  118.             st.executeUpdate("insert into " + tableName + "(id,name) values (2,'杜甫')");
  119.         }
  120.         rs = st.executeQuery("select * from " + tableName);
  121.         while (rs.next()) {
  122.             log.info("id={},name={}", rs.getInt("id"), rs.getString("name"));
  123.         }
  124.     }
  125. }
复制代码
H2Case.java
  1. package com.abc.demo.db;
  2. import lombok.extern.slf4j.Slf4j;
  3. import java.sql.*;
  4. @Slf4j
  5. public class JdbcUtil {
  6.     private JdbcUtil() {}
  7.     public static Connection getConnection(String driver, String url, String username, String password) {
  8.         Connection con = null;
  9.         try {
  10.             Class.forName(driver);
  11.             con = DriverManager.getConnection(url, username, password);
  12.         } catch (ClassNotFoundException | SQLException e) {
  13.             log.warn("url={},username={},password={}", url, username, password);
  14.             e.printStackTrace();
  15.         }
  16.         return con;
  17.     }
  18. }
复制代码
JdbcUtil.java 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

泉缘泉

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表