美文网首页JavaEE
H2(Java嵌入式数据库)

H2(Java嵌入式数据库)

作者: 平安喜乐698 | 来源:发表于2022-11-04 16:35 被阅读0次
    目录
      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:][<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=密码
    
    测试

    相关文章

      网友评论

        本文标题:H2(Java嵌入式数据库)

        本文链接:https://www.haomeiwen.com/subject/pkbytdtx.html