从驱动检查、连接配置到 SQL 查询的完整验证
摘要: 本文介绍 Java JDBC 和 Linux ODBC 两种方式连接 DM8 数据库的配置与验证流程。JDBC 部分使用 DM JDBC 驱动和 Java 测试程序完成驱动加载、数据库连接、元数据读取及 SQL 查询;ODBC 部分使用 unixODBC、DM ODBC 驱动、驱动注册文件和数据源配置文件完成 DSN 配置,并通过 isql 执行实际查询。文章同时总结权限不足、动态库加载失败和配置名称不一致等常见问题的处理方法。
关键词: DM8、JDBC、ODBC、unixODBC、DSN、SQL 查询、数据库连接
JDBC 是 Java 程序访问关系型数据库的一套标准接口。Java 程序通过 JDBC API 调用数据库厂商提供的驱动,完成连接建立、SQL 执行、结果读取和事务处理。
连接 DM8 时,通常需要准备以下内容:
ODBC 是一种通用数据库访问接口。应用程序通过 ODBC 驱动管理器查找数据源,再调用对应的数据库驱动完成连接。
Linux 环境通常使用 unixODBC 作为驱动管理器:
odbcinst.ini 注册数据库驱动;odbc.ini 配置数据源名称 DSN;isql 验证连接和 SQL 查询。| 对比项 | JDBC | ODBC |
|---|---|---|
| 主要用途 | 供 Java 应用程序访问数据库 | 供支持 ODBC 的通用应用和工具访问数据库 |
| 核心依赖 | JDBC JAR、驱动类和 JDBC URL | ODBC 驱动、驱动管理器和 DSN |
| 本次驱动 | DmJdbcDriver8.jar |
libdodbc.so |
| 本次验证 | Java 程序编译、连接并执行 SQL | isql 通过 DM8_TEST 连接并执行 SQL |
本文在同一台 Linux 主机上,分别使用 Java JDBC 和 unixODBC 连接 DM8,并查询 HOTEL.PERSON_INFO 表。
DmJdbcDriver8.jar;libdodbc.so 和系统 unixODBC;| 项目 | JDBC | ODBC |
|---|---|---|
| 客户端 | Java 1.8.0_452 | unixODBC 2.3.7 / isql |
| 驱动 | /home/dmdba/dmdbms/drivers/jdbc/DmJdbcDriver8.jar |
/home/dmdba/dmdbms/bin/libdodbc.so |
| 数据库 | 192.168.80.**:5236 |
DSN:DM8_TEST → 192.168.80.**:5236 |
| 账号 | SYSDBA |
SYSDBA |
| 验证 SQL | COUNT(*) 与明细查询 |
COUNT(*) 与明细查询 |
检查点: 本次
DmJdbcDriver8.jar已与 Java 8 实测通过。其他环境应以 DM 安装目录中的实际驱动文件和 JDK 版本为准,不建议直接复制文件名或路径。
首先检查 Java 版本和 DM JDBC 驱动文件是否存在:
java -version
find /home/dmdba/dmdbms/drivers/jdbc \
-maxdepth 1 -type f -name '*.jar' -ls
ls -lh /home/dmdba/dmdbms/drivers/jdbc/DmJdbcDriver8.jar
[图 1:Java 版本和 DM JDBC 驱动文件检查]
创建独立目录保存源码和编译结果:
mkdir -p /home/dmdba/jdbc_test
cd /home/dmdba/jdbc_test
vi /home/dmdba/jdbc_test/DMJdbcTest.java
测试程序先加载 dm.jdbc.driver.DmDriver,再使用 jdbc:dm://主机:端口 建立连接,读取数据库元数据,并执行记录数统计和明细查询。
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class DMJdbcTest {
private static final String DRIVER = "dm.jdbc.driver.DmDriver";
private static final String URL = "jdbc:dm://192.168.80.**:5236";
private static final String USER = "SYSDBA";
private static final String PASSWORD = "你的密码";
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
System.out.println("========== DM8 JDBC Connection Test ==========");
Class.forName(DRIVER);
System.out.println("[1] JDBC driver loaded successfully.");
System.out.println(" Driver class : " + DRIVER);
conn = DriverManager.getConnection(URL, USER, PASSWORD);
System.out.println("[2] DM8 connection established successfully.");
DatabaseMetaData meta = conn.getMetaData();
System.out.println(" JDBC URL : " + meta.getURL());
System.out.println(" DB User : " + meta.getUserName());
System.out.println(" DB Product : " + meta.getDatabaseProductName());
System.out.println(" DB Version : " + meta.getDatabaseProductVersion());
System.out.println(" JDBC Driver : " + meta.getDriverName());
System.out.println(" Driver Ver : " + meta.getDriverVersion());
stmt = conn.createStatement();
rs = stmt.executeQuery(
"SELECT COUNT(*) FROM HOTEL.PERSON_INFO"
);
if (rs.next()) {
System.out.println("[3] SQL query executed successfully.");
System.out.println(
" HOTEL.PERSON_INFO row count = " + rs.getInt(1)
);
}
rs.close();
rs = stmt.executeQuery(
"SELECT ID, NAME, AGE, GENDER " +
"FROM HOTEL.PERSON_INFO ORDER BY ID"
);
System.out.println();
System.out.println("========== Query Result ==========");
System.out.printf(
"%-20s %-12s %-8s %-10s%n",
"ID", "NAME", "AGE", "GENDER"
);
while (rs.next()) {
System.out.printf(
"%-20s %-12s %-8d %-10s%n",
rs.getString("ID"),
rs.getString("NAME"),
rs.getInt("AGE"),
rs.getString("GENDER")
);
}
System.out.println("==================================");
System.out.println("[4] JDBC test completed successfully.");
} catch (Exception e) {
System.out.println("[ERROR] JDBC test failed.");
e.printStackTrace();
} finally {
try {
if (rs != null) rs.close();
} catch (Exception e) {
}
try {
if (stmt != null) stmt.close();
} catch (Exception e) {
}
try {
if (conn != null) {
conn.close();
System.out.println("[5] Database connection closed.");
}
} catch (Exception e) {
}
}
}
}
[图 2:DMJdbcTest.java 中的驱动、URL 和账号配置]
编译和运行时都要把同一个 JDBC JAR 放入 classpath。Linux 下 classpath 分隔符为冒号;运行时还要包含当前目录 .,否则 Java 找不到已编译的 DMJdbcTest 类。
cd /home/dmdba/jdbc_test
/home/dmdba/dmdbms/jdk/bin/javac \
-encoding UTF-8 \
-cp /home/dmdba/dmdbms/drivers/jdbc/DmJdbcDriver8.jar \
/home/dmdba/jdbc_test/DMJdbcTest.java
/home/dmdba/dmdbms/jdk/bin/java \
-cp .:/home/dmdba/dmdbms/drivers/jdbc/DmJdbcDriver8.jar \
DMJdbcTest
[图 3:JDBC 编译、连接、元数据和 SQL 查询结果]
JDBC 验收标准: 输出应同时包含驱动加载成功、DM8 连接成功、SQL 查询成功、实际数据行和连接关闭。只有“连接成功”不足以证明 SQL 权限和字段读取正常。
DM Linux ODBC 驱动通常位于 DM 安装目录的 bin 目录下。先确认 libdodbc.so、isql 和 odbcinst,再通过 odbcinst -j 确认系统实际读取的驱动配置和数据源配置路径。
find /home/dmdba/dmdbms \
-type f -name 'libdodbc.so' -print
command -v isql
command -v odbcinst
odbcinst -j
[图 4:DM ODBC 驱动、unixODBC 及配置路径检查]
检查点: 本次
odbcinst -j显示驱动配置文件为/etc/odbcinst.ini,系统数据源配置文件为/etc/odbc.ini。实际环境应以命令输出为准,不能只凭经验假定路径。
系统级 ODBC 配置位于 /etc,普通 dmdba 用户没有写权限。配置前先切换到 root 并备份现有文件,再分别注册驱动和数据源。
需要注意:odbc.ini 中的 Driver 值必须与 odbcinst.ini 中的节名完全一致。
su - root
cp -a /etc/odbcinst.ini /etc/odbcinst.ini.bak_20260804
cp -a /etc/odbc.ini /etc/odbc.ini.bak_20260804
cat >> /etc/odbcinst.ini <<'EOF'
[DM8 ODBC DRIVER]
Description = DM ODBC DRIVER FOR DM8
Driver = /home/dmdba/dmdbms/bin/libdodbc.so
EOF
cat >> /etc/odbc.ini <<'EOF'
[DM8_TEST]
Description = DM8 ODBC DSN
Driver = DM8 ODBC DRIVER
SERVER = 192.168.80.**
UID = SYSDBA
PWD = 你的密码
TCP_PORT = 5236
EOF
完成配置后进行检查:
odbcinst -q -d
odbcinst -q -s
ls -lh /home/dmdba/dmdbms/bin/libdodbc.so
ldd /home/dmdba/dmdbms/bin/libdodbc.so | grep 'not found'
[图 5:root 写入 DM8 驱动和 DM8_TEST 数据源配置]
注意: 如果
/etc/odbc.ini原本不存在,备份命令会提示文件不存在,此时直接创建即可。追加配置前应先查询同名节,避免重复定义。
配置完成后切回 dmdba,将 DM 的 bin 目录加入 LD_LIBRARY_PATH,再通过 isql -v DM8_TEST 连接数据库。
su - dmdba
export LD_LIBRARY_PATH=/home/dmdba/dmdbms/bin:$LD_LIBRARY_PATH
isql -v DM8_TEST
进入 SQL 提示符后执行统计和明细查询:
SELECT COUNT(*) FROM HOTEL.PERSON_INFO;
SELECT ID, NAME, AGE, GENDER
FROM HOTEL.PERSON_INFO
ORDER BY ID;
quit
[图 6:isql 连接 DM8 并执行实际 SQL 查询]
ODBC 验收时应同时确认以下内容:
isql -v DM8_TEST 能够正常连接;SQL> 提示符;COUNT(*) 查询能够返回结果;isql 后连接能够正常关闭。/etc/odbcinst.ini 提示 Permission denied| 项目 | 处理记录 |
|---|---|
| 现象 | dmdba 执行 cat >> /etc/odbcinst.ini 时提示 Permission denied。 |
| 原因 | /etc 下的系统级配置文件需要 root 权限,普通数据库用户不能写入。 |
| 验证 | 执行 whoami 和 ls -l /etc/odbcinst.ini,确认当前用户及文件属主权限。 |
| 解决 | 执行 su - root 后重新备份和写入;配置完成后再切回 dmdba 连接。 |
| 风险 | 使用 2>/dev/null || true 会隐藏备份失败,可能误以为已经存在可恢复副本。 |
| 复盘 | 系统配置修改前先确认用户身份;备份命令不要吞掉关键错误。 |
isql 无法加载驱动| 检查项 | 验证命令 | 处理方向 |
|---|---|---|
| 驱动路径 | ls -lh /home/dmdba/dmdbms/bin/libdodbc.so |
修正 odbcinst.ini 中的 Driver 路径。 |
| 动态库依赖 | ldd libdodbc.so \| grep 'not found' |
补齐依赖或设置正确的库路径。 |
| DSN 名称 | odbcinst -q -s |
确认 isql 使用 DM8_TEST。 |
| 驱动节名 | odbcinst -q -d |
确保 Driver=DM8 ODBC DRIVER 完全一致。 |
| 网络端口 | 结合 192.168.80.21:5236 检查连接报错 |
确认 DM8 服务状态和防火墙策略。 |
JDBC 和 ODBC 都可以用于访问 DM8,但二者的配置链路不同:JDBC 重点检查 JAR、驱动类、JDBC URL 和 classpath;ODBC 重点检查驱动文件、unixODBC、驱动注册、DSN 和动态库路径。
实际验收时,不应只验证“连接成功”,还应继续执行真实 SQL,确认数据库权限、字段读取、字符显示和结果返回均正常。对于 ODBC 配置,还要特别注意 root 权限、驱动节名与 DSN 名称的一致性,以及 LD_LIBRARY_PATH 是否包含 DM 驱动依赖目录。
THE END
达梦社区地址:https://eco.dameng.com
文章
阅读量
获赞
