目录
1. 下载H2数据库
2. 在JavaWeb项目中使用H2
3. 在JavaWeb项目中嵌入H2
4. 向H2数据库注册自定义的数据库函数
简介
优势:
1. H2采用纯Java编写,因此不受平台的限制。
2. H2只有一个jar文件,非常适合作为嵌入式数据库(不需要安装独立的客户端和服务器端)。
3. H2提供了一个十分方便的web控制台用于操作和管理数据库内容。
1. 下载H2数据库
- 下载H2数据库
下载最新版本的H2数据库(选择Platform-IndependentZip),并解压到指定目录(如:/Users/cx/H2Database)
H2数据库的目录结构说明
h2
|---bin
| |---h2-2.1.214.jar // H2数据库的jar包(驱动也在里面)
| |---h2.bat // Windows控制台启动脚本
| |---h2.sh // Linux/MAC控制台启动脚本
| |---h2w.bat // Windows控制台启动脚本(不带黑屏窗口)
|---docs // H2数据库的帮助文档(内有H2数据库的使用手册)
|---service // 通过wrapper包装成服务。
|---src // H2数据库的源代码
|---build.bat // Windows构建脚本
|---build.sh // Linux构建脚本
- 启动H2数据库服务
在终端执行:
cd /Users/cx/H2Database/h2/bin
sh h2.sh
在浏览器中访问H2数据库的WebConsole:http://localhost:8082
H2数据库的Web控制台
点击顶部的绿色小图标,选择Create a new database
- 创建并连接数据库、创建表
创建数据库,会在h2/bin目录下创建test.mv.db数据库文件
测试连接
点击连接,登录到test数据库的WebConsole,执行创建表SQL,在左侧可以看到创建的users表
2. 在JavaWeb项目中使用H2
1. 创建Web项目(Dynamic Web Project)
2. 导入H2依赖包
将h2-xxx.jar复制到WEB-INF/lib目录下
3. 以嵌入式(本地)连接方式连接H2数据库(方式1)
默认情况下只允许有一个客户端连接到H2数据库(有客户端连接到H2数据库之后,此时数据库文件就会被锁定,其他客户端无法再连接)。
连接语法:jdbc:h2:[file:][<path>]<databaseName>
例:
jdbc:h2:~/test // 连接位于用户目录下的test数据库
jdbc:h2:file:/data/sample
jdbc:h2:file:E:/H2/test(Windows系统下)
===》Test.java
package com.sst.cx;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class Test {
// 数据库连接URL
private static final String JDBC_URL = "jdbc:h2:~/H2Database/h2/bin/test";
// 连接数据库的用户名
private static final String USER = "sa";
// 连接数据库的密码
private static final String PASSWORD = "密码";
// 连接数据库的驱动类(H2数据库提供)
private static final String DRIVER_CLASS="org.h2.Driver";
public static void main(String[] args) throws Exception {
// 加载H2数据库驱动
Class.forName(DRIVER_CLASS);
// 根据连接URL,用户名,密码获取数据库连接
Connection conn = DriverManager.getConnection(JDBC_URL, USER, PASSWORD);
Statement stmt = conn.createStatement();
// 如果存在USERS表就先删除USERS表
stmt.execute("DROP TABLE IF EXISTS USERS");
// 创建users表
stmt.execute("create table users("
+ " id int primary key,"
+ " name varchar(40),"
+ " password varchar(40))");
// 新增
stmt.executeUpdate("INSERT INTO users VALUES(1,'张三','12')");
stmt.executeUpdate("INSERT INTO users VALUES(2,'李四','34')");
stmt.executeUpdate("INSERT INTO users VALUES(3,'王五','56')");
stmt.executeUpdate("INSERT INTO users VALUES(4,'麻六','78')");
stmt.executeUpdate("INSERT INTO users VALUES(5,'邹七','90')");
// 删除
stmt.executeUpdate("DELETE FROM users WHERE name='张三'");
// 修改
stmt.executeUpdate("UPDATE users SET name='李二' WHERE name='李四'");
// 查询
ResultSet rs = stmt.executeQuery("SELECT * FROM users");
// 遍历结果集
while (rs.next()) {
System.out.println(rs.getString("id") + "," + rs.getString("name")+ "," + rs.getString("password"));
}
// 释放资源
stmt.close();
// 关闭连接
conn.close();
}
}
项目结构
查询结果
3. 使用TCP/IP的服务器模式(远程连接)方式连接H2数据库(方式2 推荐)
连接方式和其他数据库类似(基于Service的形式进行连接),因此允许多个客户端同时连接到H2数据库。
连接语法:jdbc:h2:tcp://<server>[:<port>]/[<path>]<databaseName>
例:
jdbc:h2:tcp://localhost/~/test
===》Test2.java
package com.sst.cx;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class Test2 {
// 数据库连接URL
private static final String JDBC_URL = "jdbc:h2:tcp://127.0.0.1/~/H2Database/h2/bin/test";
// 连接数据库的用户名
private static final String USER = "sa";
// 连接数据库的密码
private static final String PASSWORD = "密码";
// 连接数据库的驱动类(由H2数据库提供)
private static final String DRIVER_CLASS="org.h2.Driver";
public static void main(String[] args) throws Exception {
// 加载H2数据库驱动
Class.forName(DRIVER_CLASS);
// 根据连接URL,用户名,密码获取数据库连接
Connection conn = DriverManager.getConnection(JDBC_URL, USER, PASSWORD);
Statement stmt = conn.createStatement();
//如果存在users表就先删除users表
stmt.execute("DROP TABLE IF EXISTS USERS");
// 创建users表
stmt.execute("create table users("
+ " id int primary key,"
+ " name varchar(40),"
+ " password varchar(40))");
// 新增
stmt.executeUpdate("INSERT INTO users VALUES(1,'张三','12')");
stmt.executeUpdate("INSERT INTO users VALUES(2,'李四','34')");
stmt.executeUpdate("INSERT INTO users VALUES(3,'王五','56')");
stmt.executeUpdate("INSERT INTO users VALUES(4,'麻六','78')");
stmt.executeUpdate("INSERT INTO users VALUES(5,'邹七','90')");
// 删除
stmt.executeUpdate("DELETE FROM users WHERE name='张三'");
// 修改
stmt.executeUpdate("UPDATE users SET name='李二' WHERE name='李四'");
// 查询
ResultSet rs = stmt.executeQuery("SELECT * FROM users");
// 遍历结果集
while (rs.next()) {
System.out.println(rs.getString("id") + "," + rs.getString("name")+ "," + rs.getString("password"));
}
// 释放资源
stmt.close();
// 关闭连接
conn.close();
}
}
3. 在JavaWeb项目中嵌入H2
1. 创建Web项目(Dynamic Web Project)
2. 导入依赖包
将h2-xxx.jar、servlet-api.jar复制到WEB-INF/lib目录下
3. 创建一个专门用于启动H2数据库服务的监听器
===》H2DBServerStartListener.java
package com.sst.cx.web.listener;
import java.sql.SQLException;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.h2.tools.Server;
// 用于启动H2数据库服务的Listener
public class H2DBServerStartListener implements ServletContextListener {
// H2数据库服务器启动实例
private Server server;
// Web应用初始化时启动H2数据库
public void contextInitialized(ServletContextEvent sce) {
try {
System.out.println("正在启动h2数据库...");
// 使用org.h2.tools.Server这个类创建一个H2数据库的服务并启动服务,由于没有指定任何参数,那么H2数据库启动时默认占用的端口就是8082
server = Server.createTcpServer().start();
System.out.println("h2数据库启动成功...");
} catch (SQLException e) {
System.out.println("启动h2数据库出错:" + e.toString());
e.printStackTrace();
throw new RuntimeException(e);
}
}
// Web应用销毁时停止H2数据库
public void contextDestroyed(ServletContextEvent sce) {
if (this.server != null) {
// 停止H2数据库
this.server.stop();
this.server = null;
}
}
}
4. 在web.xml文件中添加
<!-- 配置监听器:启动和停止H2数据库服务 -->
<listener>
<listener-class>com.sst.cx.web.listener.H2DBServerStartListener</listener-class>
</listener>
<!-- 配置用于访问H2数据库Console的Servlet -->
<servlet>
<servlet-name>H2Console</servlet-name>
<servlet-class>org.h2.server.web.WebServlet</servlet-class>
<init-param>
<param-name>webAllowOthers</param-name>
<param-value></param-value>
</init-param>
<init-param>
<param-name>trace</param-name>
<param-value></param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- 映射H2控制台的访问路径 -->
<servlet-mapping>
<servlet-name>H2Console</servlet-name>
<url-pattern>/console/*</url-pattern>
</servlet-mapping>
5. 测试
部署到Tomcat,并启动Tomcat。
在浏览器中输入http://localhost:8080/hello/console/ 可访问H2的Web控制台。
4. 向H2数据库注册自定义的数据库函数
1. 实现自定义数据库函数
创建一个普通类,创建一个public static修饰的方法并实现。
例:
public class Hello{
public static String hi(){
return "hello"; // 根据自身需求,编写功能
}
}
2. 注册到H2数据库中(在H2的Web控制台中执行)
CREATE ALIAS [IF NOT EXISTS] newFunctionAliasName [DETERMINISTIC] FOR classAndMethodName
例:
CREATE ALIAS hello FOR "com.sst.cx.Hello.hi"
3. 测试
select hello()
注册到H2数据库
测试
例(一次性向H2数据库注册多个函数)
===》1. H2DBFunctionExt.java(定义数据库函数)
package com.sst.cx;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;
public class Hello {
public static String hi(){
return "hello";
}
public static String my_uuid(){
return "com.sst.cx"+UUID.randomUUID().toString();
}
public static String now(){
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = new Date();
String dateStr = simpleDateFormat.format(date);
return dateStr;
}
public static String getIp(){
try {
InetAddress addr = InetAddress.getLocalHost();
// 获得本机IP
return addr.getHostAddress();
} catch (UnknownHostException e) {
e.printStackTrace();
return "未知的IP地址";
}
}
public static String date_format(String date,String pattern){
if (date != null) {
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
try {
Date temp = sdf.parse(date);
return sdf.format(temp);
} catch (ParseException e) {
e.printStackTrace();
}
}
return "";
}
}
===》2. RegisterH2ExtFuncServlet.java(注册数据库函数)
package com.sst.cx;
import java.sql.Connection;
import java.sql.Statement;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
public class RegisterH2ExtFuncServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public void init() throws ServletException {
// 0、注册hi函数的SQL语句
String sql0 = "CREATE ALIAS IF NOT EXISTS hello FOR \"com.sst.cx.H2DBFunctionExt.hi\"";
// 1、注册uuid函数的SQL语句
String sql1 = "CREATE ALIAS IF NOT EXISTS my_uuid FOR \"com.sst.cx.H2DBFunctionExt.my_uuid\"";
// 2、注册currentTime函数的SQL语句
String sql2 = "CREATE ALIAS IF NOT EXISTS currentTime FOR \"com.sst.cx.H2DBFunctionExt.now\"";
// 3、注册IP函数的SQL语句
String sql3 = "CREATE ALIAS IF NOT EXISTS IP FOR \"com.sst.cx.H2DBFunctionExt.getIp\"";
// 4、注册date_format函数的SQL语句
String sql4 = "CREATE ALIAS IF NOT EXISTS date_format FOR \"com.sst.cx.H2DBFunctionExt.date_format\"";
Connection connection = null;
Statement stmt = null;
try {
// 获取数据库连接
connection = JdbcUtil.getConnection();
// 获取Statement对象
stmt = connection.createStatement();
// 添加要执行的SQL
stmt.addBatch(sql0);
stmt.addBatch(sql1);
stmt.addBatch(sql2);
stmt.addBatch(sql3);
stmt.addBatch(sql4);
// 批量执行
stmt.executeBatch();
System.out.println("H2数据库扩展函数注册成功!");
stmt.clearBatch();
} catch (Exception e) {
System.out.println("H2数据库扩展函数注册失败!");
e.printStackTrace();
}finally{
try {
stmt.close();
connection.close();
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
}
===》3. 在web.xml文件中,添加
<servlet>
<description>注册H2数据库的扩展函数</description>
<servlet-name>RegisterH2DBExtFunction</servlet-name>
<servlet-class>com.sst.cx.RegisterH2ExtFuncServlet</servlet-class>
<!--
1、load-on-startup元素标记容器是否在启动的时候就加载这个servlet(实例化并调用其init()方法)。
2、它的值必须是一个整数,表示servlet应该被载入的顺序
3、当值为0或者大于0时,表示容器在应用启动时就加载并初始化这个servlet;
4、当值小于0或者没有指定时,则表示容器在该servlet被选择时才会去加载。
5、正数的值越小,该servlet的优先级越高,应用启动时就越先加载。
6、当值相同时,容器就会自己选择顺序来加载。
所以,<load-on-startup>x</load-on-startup>,中x的取值1,2,3,4,5代表的是优先级,而非启动延迟时间。
-->
<load-on-startup>1</load-on-startup>
</servlet>
===》4. JdbcUtil.java(提供JDBC连接)
package com.sst.cx;
import java.io.InputStream;
import java.sql.Connection;
import java.util.Properties;
import org.h2.jdbcx.JdbcConnectionPool;
public class JdbcUtil {
private static JdbcConnectionPool cp = null;
static{
try {
// 加载src目录下的h2config.properties
InputStream in = JdbcUtil.class.getClassLoader().getResourceAsStream("h2config.properties");
Properties prop = new Properties();
prop.load(in);
// 创建数据库连接池
cp = JdbcConnectionPool.create(prop.getProperty("JDBC_URL"), prop.getProperty("USER"), prop.getProperty("PASSWORD"));
} catch (Exception e) {
System.out.println("连接池初始化异常");
e.printStackTrace();
}
}
public static Connection getConnection() throws Exception{
return cp.getConnection();
}
public static JdbcConnectionPool getCp() {
return cp;
}
}
===》5. 创建h2config.properties文件(src目录下)
JDBC_URL=jdbc:h2:tcp://127.0.0.1/~/H2Database/h2/bin/test
USER=sa
PASSWORD=密码
测试
网友评论