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

news/2024/11/17 15:57:07/文章来源:https://www.cnblogs.com/wuyongyin/p/18053372

本文主要介绍 H2 的基本使用,文中所使用到的软件版本:Java 1.8.0_341、H2 2.2.224、PostgreSQL 驱动 42.5.5。

1、嵌入式(本地)模式

直接使用 JDBC 连接数据库即可,如果数据库不存在会自动创建。

1.1、持久数据库

@Test
public void localFile() throws SQLException {String dbName = "test";//用户名密码为第一次连接设置的密码Connection con = JdbcUtil.getConnection("org.h2.Driver", "jdbc:h2:file:d:/temp/" + dbName, "admin", "123456");business(con, dbName);con.close();
}private void business(Connection con, String dbName) throws SQLException {String tableName = "a_student";Statement st = con.createStatement();ResultSet rs = st.executeQuery("select * from INFORMATION_SCHEMA.TABLES");while (rs.next()) {log.info("table_catalog={},table_schema={},table_name={}", rs.getString("table_catalog"), rs.getString("table_schema"), rs.getString("table_name"));}String sql = "select 1 from INFORMATION_SCHEMA.TABLES where upper(table_catalog)=? and upper(table_schema)=? and upper(table_name)=?";PreparedStatement pst = con.prepareStatement(sql);pst.setString(1, dbName.toUpperCase());pst.setString(2, "PUBLIC");pst.setString(3, tableName.toUpperCase());rs = pst.executeQuery();if (!rs.next()) {//表不存在则创建并初始化数据,这里根据业务需要进行操作st.executeUpdate("create table " + tableName + "(id int, name varchar(32))");st.executeUpdate("insert into " + tableName + "(id,name) values (1,'李白')");st.executeUpdate("insert into " + tableName + "(id,name) values (2,'杜甫')");}rs = st.executeQuery("select * from " + tableName);while (rs.next()) {log.info("id={},name={}", rs.getInt("id"), rs.getString("name"));}
}

1.2、内存数据库

@Test
public void localMem() throws SQLException {String dbName = "test";//用户名密码为第一次连接设置的密码Connection con = JdbcUtil.getConnection("org.h2.Driver", "jdbc:h2:mem:" + dbName, "admin", "123456");business(con, dbName);con.close();
}

2、服务器模式

可以通过 bin/h2.bat(或 bin/h2.sh) 命令启动 H2 控制台,同时会启动 Web 服务器合 PG 服务器,也可以通过以下方式启动服务器:

java -cp h2*.jar org.h2.tools.Server [param1] [param2] [...]

改方式可以添加参数来调整服务器的默认行为,查看所有参数:

java -cp h2*.jar org.h2.tools.Server -?

相关参数如下:

[-web]                  Start the web server with the H2 Console
[-webAllowOthers]       Allow other computers to connect - see below
[-webExternalNames]       The comma-separated list of external names and IP addresses of this server, used together with -webAllowOthers
[-webDaemon]            Use a daemon thread
[-webPort <port>]       The port (default: 8082)
[-webSSL]               Use encrypted (HTTPS) connections
[-webAdminPassword]     Password of DB Console administrator
[-browser]              Start a browser connecting to the web server
[-tcp]                  Start the TCP server
[-tcpAllowOthers]       Allow other computers to connect - see below
[-tcpDaemon]            Use a daemon thread
[-tcpPort <port>]       The port (default: 9092)
[-tcpSSL]               Use encrypted (SSL) connections
[-tcpPassword <pwd>]    The password for shutting down a TCP server
[-tcpShutdown "<url>"]  Stop the TCP server; example: tcp://localhost
[-tcpShutdownForce]     Do not wait until all connections are closed
[-pg]                   Start the PG server
[-pgAllowOthers]        Allow other computers to connect - see below
[-pgDaemon]             Use a daemon thread
[-pgPort <port>]        The port (default: 5435)
[-properties "<dir>"]   Server properties (default: ~, disable: null)
[-baseDir <dir>]        The base directory for H2 databases (all servers)
[-ifExists]             Only existing databases may be opened (all servers)
[-ifNotExists]          Databases are created when accessed
[-trace]                Print additional trace information (all servers)
[-key <from> <to>]      Allows to map a database name to another (all servers)

2.1、启动 Web 服务器

java -cp h2-2.2.224.jar  org.h2.tools.Server -web -webAllowOthers

使用浏览器访问 H2 控制台:http://localhost:8082

2.2、启动 TCP 服务器

java -cp h2-2.2.224.jar  org.h2.tools.Server -tcp -tcpAllowOthers -ifNotExists

应用程序使用 JDBC 访问数据库。

2.2.1、持久数据库

@Test
public void tcpFile() throws SQLException {String dbName = "test";//用户名密码为第一次连接设置的密码Connection con = JdbcUtil.getConnection("org.h2.Driver", "jdbc:h2:tcp://localhost:9092/file:d:/temp/" + dbName, "admin", "123456");business(con, dbName);con.close();
}

2.2.2、内存数据库

@Test
public void tcpMem() throws Exception {String dbName = "test";Connection con = JdbcUtil.getConnection("org.h2.Driver", "jdbc:h2:tcp://localhost:9092/mem:" + dbName, "admin", "123456");business(con, dbName);con.close();
}

2.3、启动 PG 服务器

java -cp h2-2.2.224.jar  org.h2.tools.Server -pg -pgAllowOthers -baseDir d:/temp -ifNotExists

应用程序引入 PG JDBC 驱动并访问数据库。

<dependency><groupId>org.postgresql</groupId><artifactId>postgresql</artifactId><version>42.5.5</version>
</dependency>
@Test
public void pg() throws Exception {String dbName = "test";//用户名密码为第一次连接设置的密码Connection con = JdbcUtil.getConnection("org.postgresql.Driver", "jdbc:postgresql://localhost:5435/" + dbName, "admin", "123456");business(con, dbName);con.close();
}

使用 PG 客户端访问时,默认的 schema 为小写:public,而使用本地或 TCP 模式访问时,默认的 schema 为大写:PBBLIC;因此不能使用 PG 客户端访问本地或 TCP模式创建的库,也不能使用本地或 TCP模式访问 PG 客户端创建的库,否则会报错误:"Schema "PUBLIC" not found" 或 "Schema "public" not found"。

3、混合模式

混合模式本应用使用本地模式访问,其他应用使用远程模式访问,需要在应用中通过 API 访问相应的服务器。

3.1、启动 Web 服务器

@Test
public void web() throws Exception {Server server = Server.createWebServer().start();Thread.sleep(1000 * 100);server.stop();
}

使用浏览器访问 H2 控制台:http://localhost:8082

3.2、启动 TCP 服务器

应用中启动 TCP 服务器,其他应用通过 JDBC 访问数据库。

3.2.1、持久数据库

@Test
public void tcpFile2() throws Exception {//如果数据库不存在,tcp方式默认不允许创建数据库,使用 -ifNotExists 参数允许创建数据库Server server = Server.createTcpServer("-ifNotExists").start();CountDownLatch countDownLatch = new CountDownLatch(1);new Thread(() -> {try {//模拟其他应用访问
            tcpFile();} catch (Exception e) {e.printStackTrace();}countDownLatch.countDown();}).start();countDownLatch.await();server.stop();
}

3.2.2、内存数据库

@Test
public void tcpMem2() throws Exception {//如果数据库不存在,tcp方式默认不允许创建数据库,使用 -ifNotExists 参数允许创建数据库Server server = Server.createTcpServer("-ifNotExists").start();CountDownLatch countDownLatch = new CountDownLatch(1);new Thread(() -> {try {//模拟其他应用访问
            tcpMem();} catch (Exception e) {e.printStackTrace();}countDownLatch.countDown();}).start();countDownLatch.await();server.stop();
}

3.3、启动 PG 服务器

应用中启动 PG 服务器,其他应用通过 PG 驱动访问数据库。

@Test
public void pg2() throws Exception {//如果数据库不存在,该方式默认不允许创建数据库,使用 -ifNotExists 参数允许创建数据库;该方式还需要指定数据库文件目录Server server = Server.createPgServer("-baseDir", "d:/temp", "-ifNotExists").start();CountDownLatch countDownLatch = new CountDownLatch(1);new Thread(() -> {try {//模拟其他应用访问
            pg();} catch (Exception e) {e.printStackTrace();}countDownLatch.countDown();}).start();countDownLatch.await();server.stop();
}

 

完整代码:

package com.abc.demo.db;import lombok.extern.slf4j.Slf4j;
import org.h2.tools.Server;
import org.junit.Test;import java.sql.*;
import java.util.concurrent.CountDownLatch;@Slf4j
public class H2Case {@Testpublic void localFile() throws SQLException {String dbName = "test";//用户名密码为第一次连接设置的密码Connection con = JdbcUtil.getConnection("org.h2.Driver", "jdbc:h2:file:d:/temp/" + dbName, "admin", "123456");log.info("con={}", con);business(con, dbName);con.close();}@Testpublic void localMem() throws SQLException {String dbName = "test";//用户名密码为第一次连接设置的密码Connection con = JdbcUtil.getConnection("org.h2.Driver", "jdbc:h2:mem:" + dbName, "admin", "123456");business(con, dbName);con.close();}@Testpublic void tcpFile() throws SQLException {String dbName = "test";//用户名密码为第一次连接设置的密码Connection con = JdbcUtil.getConnection("org.h2.Driver", "jdbc:h2:tcp://localhost:9092/file:d:/temp/" + dbName, "admin", "123456");business(con, dbName);con.close();}@Testpublic void tcpMem() throws Exception {String dbName = "test";Connection con = JdbcUtil.getConnection("org.h2.Driver", "jdbc:h2:tcp://localhost:9092/mem:" + dbName, "admin", "123456");business(con, dbName);con.close();}@Testpublic void pg() throws Exception {String dbName = "test";//用户名密码为第一次连接设置的密码Connection con = JdbcUtil.getConnection("org.postgresql.Driver", "jdbc:postgresql://localhost:5435/" + dbName, "admin", "123456");business(con, dbName);con.close();}@Testpublic void web() throws Exception {Server server = Server.createWebServer().start();Thread.sleep(1000 * 10);server.stop();}@Testpublic void tcpFile2() throws Exception {//如果数据库不存在,tcp方式默认不允许创建数据库,使用 -ifNotExists 参数允许创建数据库Server server = Server.createTcpServer("-ifNotExists").start();CountDownLatch countDownLatch = new CountDownLatch(1);new Thread(() -> {try {//模拟其他应用访问
                tcpFile();} catch (Exception e) {e.printStackTrace();}countDownLatch.countDown();}).start();countDownLatch.await();server.stop();}@Testpublic void tcpMem2() throws Exception {//如果数据库不存在,tcp方式默认不允许创建数据库,使用 -ifNotExists 参数允许创建数据库Server server = Server.createTcpServer("-ifNotExists").start();CountDownLatch countDownLatch = new CountDownLatch(1);new Thread(() -> {try {//模拟其他应用访问
                tcpMem();} catch (Exception e) {e.printStackTrace();}countDownLatch.countDown();}).start();countDownLatch.await();server.stop();}@Testpublic void pg2() throws Exception {//如果数据库不存在,该方式默认不允许创建数据库,使用 -ifNotExists 参数允许创建数据库;该方式还需要指定数据库文件目录Server server = Server.createPgServer("-baseDir", "d:/temp", "-ifNotExists").start();CountDownLatch countDownLatch = new CountDownLatch(1);new Thread(() -> {try {//模拟其他应用访问
                pg();} catch (Exception e) {e.printStackTrace();}countDownLatch.countDown();}).start();countDownLatch.await();server.stop();}private void business(Connection con, String dbName) throws SQLException {String tableName = "a_student";Statement st = con.createStatement();String sql = "select 1 from INFORMATION_SCHEMA.TABLES where upper(table_catalog)=? and upper(table_schema)=? and upper(table_name)=?";PreparedStatement pst = con.prepareStatement(sql);pst.setString(1, dbName.toUpperCase());pst.setString(2, "PUBLIC");pst.setString(3, tableName.toUpperCase());ResultSet rs = pst.executeQuery();if (!rs.next()) {//表不存在则创建并初始化数据,这里根据业务需要进行操作st.executeUpdate("create table " + tableName + "(id int, name varchar(32))");st.executeUpdate("insert into " + tableName + "(id,name) values (1,'李白')");st.executeUpdate("insert into " + tableName + "(id,name) values (2,'杜甫')");}rs = st.executeQuery("select * from " + tableName);while (rs.next()) {log.info("id={},name={}", rs.getInt("id"), rs.getString("name"));}}
}
H2Case.java
package com.abc.demo.db;import lombok.extern.slf4j.Slf4j;import java.sql.*;@Slf4j
public class JdbcUtil {private JdbcUtil() {}public static Connection getConnection(String driver, String url, String username, String password) {Connection con = null;try {Class.forName(driver);con = DriverManager.getConnection(url, username, password);} catch (ClassNotFoundException | SQLException e) {log.warn("url={},username={},password={}", url, username, password);e.printStackTrace();}return con;}
}
JdbcUtil.java

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/708642.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

利用Burpsuite爆破带有验证码web登录接口

工具下载地址 https://github.com/f0ng/captcha-killer-modified 该工具下的验证码识别python脚本要求python环境小于3.10.0 安装验证码识别python脚本引用的库 pip install -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com ddddocr aiohttp 加载…

整理C语言预处理过程语法的实用方法与技巧

预处理 目录预处理一、宏定义数值宏常量字符串宏常量用define宏定义注释符号?程序的编译过程预处理中宏替换和去注释谁先谁后?如何写一个不会出现问题的宏函数do-while-zero结构do-while-zero的评价宏定义中的空格宏只能在main函数上面定义吗?宏的作用范围#undef宏替换是在函…

如何把多个文件(夹)平均复制到多个文件夹中

首先,需要用到的这个工具:度娘网盘 提取码:qwu2 蓝奏云 提取码:2r1z 假定的情况是,共有20个兔兔的图片,想要平均的复制4个文件夹里,那么每个文件夹里面就有5个图片(如果是5个,那每个自然是4个,具体除数是多少,根据实际情况即可)打开工具,切换到 文件批量复制 版块…

任意文件上传漏洞详解

当文件上传接口可以上传任意文件,但是不解析,文件上传后的路径可控。这种情况下有两种方法1、上传.htaccess和.user.ini配置文件。2、当知道网站根路径的情况下,可以上传到其他目录下。3、当不知道网站根路径的情况下,可以通过上传计划任务的方式实现命令执行。 文件上传漏…

ray tracing in one weekend - 5

dielectric 水、玻璃、钻石等透明材料都是电介质。当光线照射到它们身上时,它会分裂成反射光线和折射(透射)光线。我们将通过在反射和折射之间随机选择来处理这个问题,每次相互作用只产生一个散射射线。 折射程度 : 是根据两个介质折射率的差值决定的。 Refraction Snells L…

如何把多个文件(夹)随机复制到多个文件夹中

首先,需要用到的这个工具:度娘网盘 提取码:qwu2 蓝奏云 提取码:2r1z 先看文件的情况一共20个兔兔的图片,4个文件夹,把全部的图片随机的复制这些地方去打开工具,切换到 文件批量复制 版块找到右下角的 设置,点击打开勾选“随机复制”,把文件进行随机的复制选中全部的兔…

php 异步并行后续--兼容FPM使用的组件

上次给人推荐了这篇文章,关于PHP异步并行的文章,之后有人评论问这个组件能不能给fpm用,我测试了一下发现不行,于是又找到一个可以给fpm用的http请求组件. 安装很简单,就这样 composer require guzzlehttp/guzzle 进行安装一下. 然后代码示例如下: 我们先建一个文件作为一个长时…

DeepSparse: 通过剪枝和稀疏预训练,在不损失精度的情况下减少70%的模型大小,提升三倍速度

这篇论文提出了一种高稀疏性基础大型语言模型(LLMs)的新方法,通过有效的预训练和部署,实现了模型在保持高准确度的同时,显著提升了处理速度。https://avoid.overfit.cn/post/06961c02a12b48a6a3e1436b527fd2b7

从开发到部署,搭建离线私有大模型知识库

背景介绍 最近一段时间搭建了一套完整的私有大模型知识库,目前完整的服务已经完成测试部署上线。基本之前的实践过程,从工程角度整理技术方案以及中间碰到的一些问题,方便后续对这个方向有需求的研发同学们。 为什么做离线私有化部署 在大模型火热起来之后,很多企业都有尝试…

自媒体基础

自媒体:个人或者个人组织进行专业化,持续化的内容创作,并以此为盈利的方式 做自媒体的原因:盈利,个人品牌打造,进行企业品牌宣传 自媒体盈利: 1.平台分成

AJ-Report开源数据大屏存在远程命令执行漏洞

漏洞描述: 该平台可以通过post方式在validationRules参数对应值中进行命令执行,可以获得服务器权限,登陆管理后台接管大屏。如果被不法分子利用,书写反动标语,危害后果十分严重 Fofa: title="AJ-Report"POC: POST /dataSetParam/verification;swagger-ui/ HTTP/…

pde复习 第一章波动方程 第四节 高维波动方程的Cauchy问题

2024-05-18 16:14:50 星期六 知识点梳理 本节讨论的是高维波动方程,主要是计算\(\star\)公式为\(\star\)公式一定要记清,下面给出一些例题,动手计算。 例题 阅读顺序从左到右再下一行。评注:上面的两个例题的所有解法都值得认真看,还有里面的技巧(三角函数的周期性和正交…