JDBC 接口

JDBC (Java Database Connectivity) 是 Java 应用程序与数据库的接口规范,旨在让各数据库开发商为 Java 程序员提供标准的数据库应用程序编程接口 (API)。JDBC 定义了一个跨数据库、跨平台的通用 SQL 数据库 API。

DM JDBC 数据库驱动程序是一个能够支持基本 SQL 功能的通用应用程序编程接口,支持一般的 SQL 数据库访问。通过 JDBC 驱动程序,用户可以在应用程序中实现对 DM 数据库的连接与访问,JDBC 驱动程序的主要功能包括:

  • 建立与 DM 数据库的连接。
  • 转接发送 SQL 语句到数据库。
  • 处理并返回语句执行结果。

开发环境搭建

软件 版本
DM 数据库 DM 8.0 及以上版本
JDK JDK 8
Eclipse 2018-12 (4.10.0)

安装 DM 数据库

请参考 DM 数据库快速上手指南

数据库安装过程中,请勾选创建 BOOKSHOPDMHR 示例库,作为数据库模拟环境,如下图所示:

DMHR 示例库

安装 Java 开发工具包--JDK

双击安装包进行安装,安装步骤简单,点击【下一步】安装即可。以安装目录 D:\java\jdk1.8.0_111 为例,安装完成如下图所示:

安装成功

安装成功后需要配置 JDK 环境变量,即将 JDK 安装路径的 bin 路径复制到环境变量 path 里,如下图所示:

环境变量配置

环境变量配置成功后,可使用 win+R 打开命令提示符,输入 java -version 命令,可以正常出现 JDK 版本号,即环境变量配置成功,如下图所示:

JDK 版本号

注意

JDK 安装完成后还需配置环境变量,环境变量配置不正确会导致项目启动报错。

因环境变量配置错误导致的常见错误代码如下:

Unable to find a javac compiler;
Perhaps JAVA_HOME does not point to the JDK;

安装集成开发环境 eclipse

正确配置 Java 环境变量后,eclipse 可正常打开。

数据库连接

准备 DM-JDBC 驱动包

DM JDBC 驱动 jar 包在 DM 安装目录 /dmdbms/drivers/jdbc,如下图所示:

JDBC 驱动程序安装目录

注意

DmJdbcDriver16.jar 对应 JDK 6 使用 DmJdbcDriver17.jar 对应 JDK 7 使用 DmJdbcDriver18.jar 对应 JDK 8 使用 请根据开发环境选择合适的 DM JDBC 驱动包

数据库连接示例

DM 数据库扩展连接串的使用

DM JDBC 数据库连接驱动具体位置是 dm.jdbc.driver.DmDriver

连接串的书写格式有以下两种:

  1. host、port 不作为连接属性,此时只需输入值即可:
jdbc:dm [: //host][:port][?propName1=propValue1][& propName2=propValue2]...
注意
  • 若 host 不设置,则默认为‘localhost’。
  • 若 port 不设置,则默认为‘5236’。
  • 若 host 不设置,则 port 一定不能设。
  • 若 user、password 没有单独作为参数传入,则必须在连接属性中传入。
  • 若 host 为 ipv6 地址,则应包含在[]中。

示例如下:

jdbc:dm://192.168.0.96:5236?LobMode=1
  1. host、port 作为连接属性,此时必须按照下表中说明进行设置,且属性名称大小写敏感。
属性名称 说明 是否必须设置
“host” 主库地址,包括 IP、localhost 或者配置文件中主库地址,
列表对应的变量名,如 dm_svc.conf 中的“o2000”
“port” 端口号,服务器登录端口号

连接串格式格式如下:

jdbc:dm:// [?propName1=propValue1] [ & propName2=propValue2] [&…]…
注意

host、port 设置与否,以及在属性串中的位置没有限制。 若 user、password 没有单独作为参数传入,则必须在连接属性中传入。

示例如下:

jdbc:dm:// ?host=192.168.0.96&port=5236
建议

更多连接串属性的使用请参考《DM 程序员手册》-DM 扩展连接属性的使用,手册位于数据库安装路径 /dmdbms/doc 文件夹下。

示例代码

package java_jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class jdbc_conn {
    static Connection con = null;
    static String cname = "dm.jdbc.driver.DmDriver";
    static String url = "jdbc:dm://localhost:5236";
    static String userid = "SYSDBA";
    static String pwd = "SYSDBA";
    public static void main(String[] args) {
        try {
            Class.forName(cname);
            con = DriverManager.getConnection(url, userid, pwd);
            con.setAutoCommit(true);
            System.out.println("[SUCCESS]conn database");
        } catch (Exception e) {
            System.out.println("[FAIL]conn database:" + e.getMessage());
        }
    }
    public void disConn(Connection con) throws SQLException {
        if (con != null) {
            con.close();
        }
    }
}

运行结果如下图所示:

连接示例运行成功截图

开发示例

基本操作示例

基础增删改查示例代码

package java_jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class jdbc_insert {
// 定义 DM JDBC 驱动串
static String jdbcString = "dm.jdbc.driver.DmDriver";
// 定义 DM URL 连接串
static String urlString = "jdbc:dm://localhost:5236";
// 定义连接用户名
static String userName = "SYSDBA";
// 定义连接用户口令
static String password = "SYSDBA";
// 定义连接对象
static Connection conn = null;
// 定义 SQL 语句执行对象
static Statement state = null;
// 定义结果集对象
static ResultSet rs = null;
public static void main(String[] args) {
    try {
        //1.加载 JDBC 驱动程序
        System.out.println("Loading JDBC Driver...");
        Class.forName(jdbcString);
        //2.连接 DM 数据库
        System.out.println("Connecting to DM Server...");
        conn = DriverManager.getConnection(urlString, userName, password);
        //3.通过连接对象创建 java.sql.Statement 对象
        state = conn.createStatement();
//------------------------------------------------------------------------------
        //基础操作:此处对应的操作代码为示例库中 PRODUCTION 模式中的
        //PRODUCT_CATEGORY 表
        //增加
            //定义增加的 SQL 这里由于此表中的结构为主键,自增,只需插入 name 列的值
            String sql_insert = "insert into PRODUCTION.PRODUCT_CATEGORY"+
            "(name)values('厨艺')";
            //执行添加的 SQL 语句
            state.execute(sql_insert);
        //删除
            //定义删除的 SQL 语句
            String sql_delete = "delete from PRODUCTION.PRODUCT_CATEGORY "+
            "where name = '厨艺'";
            //执行删除的 SQL 语句
            state.execute(sql_delete);
        //修改
            String sql_update = "update PRODUCTION.PRODUCT_CATEGORY set "+
            "name = '国学' where name = '文学'";
        //查询表中数据
            //定义查询 SQL
            String sql_selectAll = "select * from PRODUCTION.PRODUCT_CATEGORY";
            //执行查询的 SQL 语句
            rs = state.executeQuery(sql_selectAll);
            displayResultSet(rs);
//----------------------------------------------------------------------------
                state.executeUpdate(sql_update);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                //关闭资源
                rs.close();
                state.close();
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    //显示结果集
    public static void displayResultSet(ResultSet rs) throws SQLException{
        while (rs.next()) {
            int i=1;
            Object id = rs.getObject(i++);
            Object name = rs.getObject(i++);
            System.out.println(id+"  "+name);
        }
    }
}

运行示例截图

运行前数据库数据如下图所示:

运行前数据库数据

运行后控制台输出结果如下图所示:

运行后控制台输出结果

运行后数据库数据如下图所示:

运行后数据库数据

绑定变量示例

绑定参数示例代码

package java_jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class jdbc_prepareStatement{
    // 定义 DM JDBC 驱动串
    static String jdbcString = "dm.jdbc.driver.DmDriver";
    // 定义 DM URL 连接串
    static String urlString = "jdbc:dm://localhost:5236";
    // 定义连接用户名
    static String userName = "SYSDBA";
    // 定义连接用户口令
    static String password = "SYSDBA";
    // 定义连接对象
    static Connection conn = null;
    // 定义 SQL 语句执行对象
    static PreparedStatement pstate = null;
    public static void main(String[] args) {
        try {
            //1.加载 JDBC 驱动程序
            System.out.println("Loading JDBC Driver...");
            Class.forName(jdbcString);
            //2.连接 DM 数据库
            System.out.println("Connecting to DM Server...");
            conn = DriverManager.getConnection(urlString, userName, password);
//----------------------------------------------------------------------------
            //绑定操作:此处操作对应的数据库,为示例库中的 PRODUCTION 模式中的
            //PRODUCT_CATEGORY 表
            //根据指定 id 修改 PRODUCT_CATEGORY 表中的 name 的值
            //这里 name 和 id 不确认用?代替
            String sql_updateNameById = "update PRODUCTION.PRODUCT_CATEGORY "+
            "set name = ? where PRODUCT_CATEGORYID = ? ";
            //3.通过连接对象和修改语句的模板,创建 java.sql.PreparedStatement 对象
            pstate = conn.prepareStatement(sql_updateNameById);
            //4.绑定?对应的参数:理论上有多少个?就要绑定多少个值;
            //把 id 为 3 所对应的 name 值修改为 "魔幻"
            pstate.setString(1, "魔幻");
            pstate.setInt(2, 3);
            //5. 执行 SQL 语句
            pstate.executeUpdate();
//----------------------------------------------------------------------------
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                pstate.close();
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

运行示例截图

运行后控制台输出如下图所示:

运行后控制台输出图

运行后数据库截图如下图所示:

运行后数据库截图图

大字段操作示例

大字段操作示例代码

  1. 创建需要操作的含大字段类型的数据表。
CREATE TABLE "PRODUCTION"."TEST_BIG_DATA"
(
"id" INT IDENTITY(1, 1) NOT NULL,
"photo" IMAGE,
"describe" BLOB,
"txt" CLOB);
  1. 在 D 盘根目录下,创建 DM8 特点.jpg达梦产品简介.txt 两个文件,作为大字段存储,如下图所示:

准备大字段存储文件

  1. 插入大字段关键代码。
//1.插入大字段信息:  
    package java_jdbc;
    import java.io.BufferedInputStream;
    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.UnsupportedEncodingException;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
    public class jdbc_operate_bigData{
        // 定义 DM JDBC 驱动串
        static String jdbcString = "dm.jdbc.driver.DmDriver";
        // 定义 DM URL 连接串
        static String urlString = "jdbc:dm://localhost:5236";
        // 定义连接用户名
        static String userName = "SYSDBA";
        // 定义连接用户口令
        static String password = "SYSDBA";
        // 定义连接对象
        static Connection conn = null;
        // 定义 SQL 语句执行对象
        static PreparedStatement pstate = null;
        public static void main(String[] args) {
            try {
                //1.加载 JDBC 驱动程序
                System.out.println("Loading JDBC Driver...");
                Class.forName(jdbcString);
                //2.连接 DM 数据库
                System.out.println("Connecting to DM Server...");
                conn = DriverManager.getConnection(urlString, userName, password);
    //------------------------------------------------------------------------------------------
                //1.插入大字段信息:  
                String sql_insert = "INSERT INTO production.TEST_BIG_DATA (\"photo\","
                    + "\"describe\",\"txt\")VALUES(?,?,?);";
                pstate = conn.prepareStatement(sql_insert);
                //加载图片为输入流
                String filePath = "D:\\DM8特点.jpg";
                File file = new File(filePath);
                String filePath2 = "D:\\达梦产品简介.txt";
                File file2 = new File(filePath2);
                InputStream in = new BufferedInputStream(new FileInputStream(file));
                InputStream in2 = new BufferedInputStream(new FileInputStream(file));
                BufferedReader reader = new BufferedReader(
                    new InputStreamReader(new FileInputStream(file2),"UTF-8"));
                //1.绑定 stream 流信息到第一个?
                pstate.setBinaryStream(1, in);
                //2.绑定 Inputstream 对象到第二个?这里
                pstate.setBlob(2, in2);
                //3.绑定 Reader 对象到第三个?
                pstate.setClob(3, reader);
                pstate.executeUpdate();
    //-------------------------------------------------------------------------------------------
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (SQLException e) {
                e.printStackTrace();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            } finally {
                try {
                    pstate.close();
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
  1. 插入数据后,数据库数据如下所示:
  • stream 以字节输入流的形式,插入 Image 类型的字段,数据库保存的是图片信息。
  • Clob 以字节输入流的形式,插入 Clob 类型的字段,数据库保存的是图片信息。
  • Blob 以字符输入流的形式,插入 Blob 类型的字段,数据库表中保存的是文本信息。

Image 类型字段数据库保存的是图片信息 Blob 类型字段数据库保存的是文本信息

  1. 查询大字段关键代码。
package java_jdbc;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class jdbc_operate_bigData2{
    // 定义 DM JDBC 驱动串
    static String jdbcString = "dm.jdbc.driver.DmDriver";
    // 定义 DM URL 连接串
    static String urlString = "jdbc:dm://localhost:5236";
    // 定义连接用户名
    static String userName = "SYSDBA";
    // 定义连接用户口令
    static String password = "SYSDBA";
    // 定义连接对象
    static Connection conn = null;
    // 定义 SQL 语句执行对象
    static PreparedStatement pstate = null;
    // 定义保存结果集的对象
    static ResultSet rs = null;
    // 定义输入流对象
    static InputStream in = null;
    // 定义输出流对象
    static FileOutputStream fos = null;
    // 定义输出流对象
    static FileOutputStream fos2 = null;
    // 定义高效字符流对象
    static BufferedReader reader = null;
    public static void main(String[] args) {
        try {
            //1.加载 JDBC 驱动程序
            System.out.println("Loading JDBC Driver...");
            Class.forName(jdbcString);
            //2.连接 DM 数据库
            System.out.println("Connecting to DM Server...");
            conn = DriverManager.getConnection(urlString, userName, password);
//-----------------------------------------------------------------------------------------------
            //3.查询大字段信息 SQL 语句
            String sql_insert = "SELECT * FROM production.TEST_BIG_DATA ;";
            pstate = conn.prepareStatement(sql_insert);
            //4.创建 ResultSet 对象保存查询结果集
            rs = pstate.executeQuery();
            //5.解析结果集
            while(rs.next()) {
                //获取第一列 id 信息
                int id = rs.getInt("id");
                //获取第二列 photo 图片信息,并把该图片直接写入到 D:/id_DM8特点.jpg;
                in = rs.getBinaryStream("photo");
                fos = new FileOutputStream("D:/"+id+"_DM8特点.jpg");
                int num = 0;
                //每次从输入流中读取一个字节数据,如果没读到最后指针向下继续循环
                while((num=in.read())!=-1) {
                    //将每次读取的字节数据,写入到输出流中
                    fos.write(num);
                }
                //获取第三列的 Blob 大字段信息
                //Blob 对象处理的是字节型大字段信息例如图片、视频文件等
                Blob blob = rs.getBlob("describe");
                in = blob.getBinaryStream();
                fos2 = new FileOutputStream("D:/"+id+"_Blob_DM8特点.jpg");
                //每次从输入流中读取一个字节数据,如果没读到最后指针向下继续循环
                while((num=in.read())!=-1) {
                    //将每次读取的字节数据,写入到输出流中
                    fos.write(num);
                }
                //获取第四列的 Clob 大字段信息
                //Clob 大字段处理的是字符型大字段信息,文本等数据
                Clob clob = rs.getClob("txt");
                reader = new BufferedReader(clob.getCharacterStream());
                String str = null;
                while((str=reader.readLine())!=null) {
                    //将每次读取的字节数据
                    System.out.println(str.toString());
                }
            }
//-----------------------------------------------------------------------------------------
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                //关闭资源
                fos.close();
                in.close();
                rs.close();
                pstate.close();
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

运行示例截图

运行前如下图所示:

运行前

运行后控制台输出 Clob 里保存的大字段文本信息,如下图所示:

输出 Clob 里保存的大字段文本信息

运行后读取处理 Image 大字段和 Blob 大字段后的信息,如下图所示:

读取处理 Image 大字段和 Blob 大字段后的信息

微信扫码
分享文档
扫一扫
联系客服