H2(Java嵌入式数据库)

目录
  1. 下载H2数据库
  2. 在JavaWeb项目中使用H2
  3. 在JavaWeb项目中嵌入H2
  4. 向H2数据库注册自定义的数据库函数

简介

优势:
  1. H2采用纯Java编写,因此不受平台的限制。
  2. H2只有一个jar文件,非常适合作为嵌入式数据库(不需要安装独立的客户端和服务器端)。
  3. H2提供了一个十分方便的web控制台用于操作和管理数据库内容。

1. 下载H2数据库

  1. 下载H2数据库

下载最新版本的H2数据库(选择Platform-IndependentZip),并解压到指定目录(如:/Users/cx/H2Database)

H2数据库的目录结构

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构建脚本
  1. 启动H2数据库服务
在终端执行:
  cd /Users/cx/H2Database/h2/bin 
  sh h2.sh

在浏览器中访问H2数据库的WebConsole:http://localhost:8082
H2数据库的Web控制台
  1. 创建并连接数据库、创建表
点击顶部的绿色小图标,选择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:][]
    例:
      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://[:]/[]
  例:
    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文件中添加
    
    
        com.sst.cx.web.listener.H2DBServerStartListener
    
    
    
        H2Console
        org.h2.server.web.WebServlet
        
            webAllowOthers
            
        
        
            trace
            
        
        1
    
    
    
        H2Console
        /console/*
    
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文件中,添加
    
        注册H2数据库的扩展函数
        RegisterH2DBExtFunction
        com.sst.cx.RegisterH2ExtFuncServlet
    
        1
    

===》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=密码
测试

你可能感兴趣的:(H2(Java嵌入式数据库))