对于初学者来说,先理解什么是接口?由浅入深学习。
接口(Interface):一套预先定义好的函数 / 方法规范,规定了 怎么发请求、怎么拿结果,是应用程序 和 数据库(或者其他系统)之间的约定。
不用关心数据库底层磁盘怎么存数据、内存怎么处理,只要按照接口规定好的格式调用函数,就能完成连接、发 SQL、拿结果。
JDK 自带,源码公开,简化示例:
// JDK自带的接口【只是定义规范,没有实现】
public interface Driver
{
// 规定:必须有一个getConnection方法,接收url、账号密码,返回连接
Connection getConnection(String url, String user, String pwd) throws SQLException;
}
这就是 JDBC 接口标准,只定义方法签名,里面没有代码逻辑。
也是一模一样的逻辑: sql.h 头文件里只是函数声明:
// ODBC标准:函数原型声明,没有实现
SQLRETURN SQLAllocHandle( SQLSMALLINT HandleType,SQLHANDLE InputHandle,SQLHANDLE *OutputHandlePtr );
前面简单了解了下,接口的定义。那么ODBC和JDBC接口有什么区别?
简单来说,JDBC = 给 Java 量身定做的数据库接口,Java 程序首选,简单方便,只能 Java 用;ODBC = 通用 C 语言接口标准,不分数据库,C 语言程序用,配置繁琐,多语言都能对接。
顾名思义,JDBC:Java Database Connectivity,翻译为 Java 数据库连接。
从以下几个维度介绍:
1、定位:Java 语言专属的接口规范,只给 Java 程序用。
2、语言:只能在 Java 代码中调用。你写Main.java、jdbc_insert.java,就是用 JDBC 接口。
3、架构:
Java应用程序 → JDBC接口(Java标准api)→ 达梦JDBC驱动jar → TCP网络 → 达梦数据库
4、核心对象:
DriverManager:驱动管理器,建立数据库连接
Connection:数据库连接句柄
Statement/PreparedStatement:执行 SQL
ResultSet:查询结果集
5、特点:
✅ 跨平台:一套 Java 代码,Windows/Linux 都能跑,只要带上对应 jar 包
✅ 面向 Java 生态:Java 项目、IDEA 开发、Spring 框架全部用 JDBC
✅ 驱动形式:.jar包(Java 归档文件)
❌ 只能 Java 使用,C/C++ 程序不能直接调用 JDBC
同样的,ODBC:Open Database Connectivity,可翻译为开放数据库互连。
也同样从以下几个维度介绍:
1、定位:C 语言的通用标准接口,跨编程语言、跨数据库。
2、语言:原生是 C 语言 API,C/C++ 可以直接调用;Python/PHP 等语言也可以包装 ODBC 使用。
3、架构(两层)
C应用程序 → ODBC标准接口(sql.h等头文件)→ unixODBC驱动管理器 → 达梦ODBC驱动libdodbc.so → TCP → 达梦数据库
unixODBC:Linux 下的 ODBC 驱动管理器,相当于 ODBC 的中间层,读取
odbc.ini/odbcinst.ini配置。Windows 上自带 ODBC 管理器。
4、核心句柄:
HENV:环境句柄
HDBC:连接句柄
HSTMT:语句句柄
SQLAllocHandle、SQLExecDirect、SQLFetch 都是 ODBC 标准接口函数
5、特点 :
✅ 异构数据库通用:同一套 ODBC 代码,改驱动配置,就能连达梦、MySQL、Oracle。
✅ 多语言可用:C/C++、Python、PHP 都可以调用 ODBC 接口
✅ 驱动形式:Linux 是.so动态库,Windows 是.dll
❌ 配置麻烦:需要配置 odbc.ini、odbcinst.ini,Linux 还要安装 unixODBC 组件 ❌ 没有 Java 原生支持:Java 想用 ODBC 要靠桥接(JDBC-ODBC 桥,不推荐)
在学习接口和驱动之前,搭建了一套主备集群,在理解接口和驱动的同时,也对主备集群的读写分离有深入的理解。
测试环境如下:
| 项目 | 信息 |
|---|---|
| 操作系统 | Centos7 |
| 数据库版本 | dm V8 |
| 主库IP/端口 | 192.168.229.181/5236 |
| 备库IP/端口 | 192.168.229.180/5236 |
| 测试用户 | SYSDBA |
| 测试密码 | SYSDBA |
| 测试模式/表 | PRODUCTION/PRODUCT_CATEGORY |
| JDBC驱动路径 | /home/dmdba/dm/dmdbms/drivers/jdbc/DmJdbcDriver8.jar |
| ODBC驱动路径 | /home/dmdba/dm/dmdbms/drivers/odbc/libdodbc.so |
准备好安装包 jdk-8u111-windows-x64.exe 文件
双击.exe文件,一直点击下一步。在这期间会选择安装路径,如果不自主选择的话,默认装在C盘,我装在了D:\JAVA\jdk1.8.0_111路径下。
右键桌面上的此电脑,选择属性,点击高级系统设置,在弹窗中选择环境变量,在系统变量里点新建,变量名填JAVA_HOME,填写上一步JDK的安装路径:D:\JAVA\jdk1.8.0_111:
在系统变量里找到Path变量,选中它,点下方的编辑
在弹出的窗口中,选择新建,输入:%JAVA_HOME%\bin、%JAVA_HOME%\jre\bin
检验是否安装成功,按win + R,输入cmd,然后回车,如果输出有下面的内容,说明JAVA环境安装成功:
安装包使用的是ideaIU-2024.2.exe,安装路径为D:\IDEA2024.2,如果对步骤有疑惑,安装步骤请参看csdn上有详细的保姆级教程,这里主要讲接口相关内容。
在下图中可以看到DM自带JDBC的驱动包:
使用SCP指令在本地将驱动包传入:
scp root@192.168.229.181:/home/dmdba/dm/dmdbms/drivers/jdbc/DmJdbcDriver8.jar D:\IDEA2024.2
传输成功:
新建模式PRODUCTION,并在模式下新建表PRODUCT_CATEGORY
# 创建模式 PRODUCTION
CREATE SCHEMA PRODUCTION;
# 创建表 PRODUCT_CATEGORY
# ID 自增主键,NAME 存储课程名称
CREATE TABLE PRODUCTION.PRODUCT_CATEGORY(
ID INT IDENTITY(1,1) PRIMARY KEY,
NAME VARCHAR(50)
);
# 插入测试数据
INSERT INTO PRODUCTION.PRODUCT_CATEGORY(NAME) VALUES
('小说'),
('文学'),
('计算机'),
('英语'),
('管理')
('少儿'),
('金融');
# 查询验证
SELECT * FROM PRODUCTION.PRODUCT_CATEGORY;
将驱动加至项目目录下:
注意下图中需要修改的内容,主要是 url 和 pwd :
测试连接成功!这里连接的是主库。
下方写入了连接数据库,并对数据库中的测试表进行增删改查的语句:
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://192.168.229.181:5236";
// 定义连接用户名
static String userName = "SYSDBA";
// 定义连接用户口令
static String password = "Sysdba%_025";
// 定义连接对象
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);
System.out.println("数据库连接成功");
//3.通过连接对象创建 java.sql.Statement 对象
state = conn.createStatement();
//增加
String sql_insert = "insert into PRODUCTION.PRODUCT_CATEGORY(name)values('厨艺')";
state.execute(sql_insert);
//删除,想看新增数据就注释下面这一行
String sql_delete = "delete from PRODUCTION.PRODUCT_CATEGORY where name = '厨艺'";
state.execute(sql_delete);
//修改:文学 -> 国学
String sql_update = "update PRODUCTION.PRODUCT_CATEGORY set name = '国学' where name = '文学'";
int affectRows = state.executeUpdate(sql_update);
// 查询放在增删改最后!查看最终表里的数据
String sql_selectAll = "select * from PRODUCTION.PRODUCT_CATEGORY";
rs = state.executeQuery(sql_selectAll);
displayResultSet(rs);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
// 增加判空,防止空指针
if(rs != null) rs.close();
if(state != null) state.close();
if(conn != null) conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
//显示结果集
public static void displayResultSet(ResultSet rs) throws SQLException{
while (rs.next()) {
Object id = rs.getObject(1);
Object name = rs.getObject(2);
System.out.println(id + "\t" + name);
}
}
}
对表修改前查询如下:
在工程中对表修改后输出如下:
在数据库中查询如下:
可以看到对表中的数据成功进行了修改!
需要下载unixODBC 和 unixODBC-devel
Centos7环境下自带 ODBC 安装包,可以直接下载:
[root@localhost ~]# yum install -y unixODBC unixODBC-devel
已加载插件:fastestmirror, langpacks
Loading mirror speeds from cached hostfile
* base: mirrors.aliyun.com
* extras: mirrors.aliyun.com
* updates: mirrors.aliyun.com
正在解决依赖关系
--> 正在检查事务
---> 软件包 unixODBC.x86_64.0.2.3.1-14.el7 将被 安装
---> 软件包 unixODBC-devel.x86_64.0.2.3.1-14.el7 将被 安装
--> 解决依赖关系完成
依赖关系解决
==========================================================================================================================
Package 架构 版本 源 大小
==========================================================================================================================
正在安装:
unixODBC x86_64 2.3.1-14.el7 base 413 k
unixODBC-devel x86_64 2.3.1-14.el7 base 55 k
事务概要
==========================================================================================================================
安装 2 软件包
总下载量:468 k
安装大小:1.4 M
Downloading packages:
(1/2): unixODBC-devel-2.3.1-14.el7.x86_64.rpm | 55 kB 00:00:00
(2/2): unixODBC-2.3.1-14.el7.x86_64.rpm | 413 kB 00:00:01
--------------------------------------------------------------------------------------------------------------------------
总计 282 kB/s | 468 kB 00:00:01
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
正在安装 : unixODBC-2.3.1-14.el7.x86_64 1/2
正在安装 : unixODBC-devel-2.3.1-14.el7.x86_64 2/2
验证中 : unixODBC-devel-2.3.1-14.el7.x86_64 1/2
验证中 : unixODBC-2.3.1-14.el7.x86_64 2/2
已安装:
unixODBC.x86_64 0:2.3.1-14.el7 unixODBC-devel.x86_64 0:2.3.1-14.el7
完毕!
查看安装结果:
[root@localhost ~]# odbcinst -j
unixODBC 2.3.1
DRIVERS............: /etc/odbcinst.ini
SYSTEM DATA SOURCES: /etc/odbc.ini
FILE DATA SOURCES..: /etc/ODBCDataSources
USER DATA SOURCES..: /root/.odbc.ini
SQLULEN Size.......: 8
SQLLEN Size........: 8
SQLSETPOSIROW Size.: 8
[DM] DRIVER = DM8 ODBC DRIVER SERVER = 192.168.229.181 UID = SYSDBA PWD = Sysdba%_025 TCP_PORT = 5236
验证ODBC是否配置正常:
[root@localhost ~]# isql -n dm
+---------------------------------------+
| Connected! |
| |
| sql-statement(s)[;] |
| go |
| \noac |
| \ac |
| \commit |
| \rollback |
| \tables |
| \columns <table-name> |
| \quit |
| |
+---------------------------------------+
SQL>
运行结果如下:
通过 ODBC 数据源 dm 连接达梦数据库,启用多行 SQL 输入模式,用来验证 ODBC 配置是否正常、跑 SQL 测试。
[root@localhost etc]# gcc --version
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44)
Copyright © 2015 Free Software Foundation, Inc.
在/home/dmdba/dm/dmdbms/路径下创建一个新的文件夹odbc_test_code,里面需包含makefile脚本、odbc_conn.c文件、odbc_dml.c文件,分别用来编译c文件、连接数据库、执行增删改查命令。
制作makefile脚本:
[dmdba@localhost ~/dmdbms/odbc_test_code]$cat makefile
CC=gcc
includepath=$(DM_HOME)/include
libpath=$(DM_HOME)/bin
vpath=./
CFLAGS=-I$(includepath) -DDM64 -Wall
LINKFLAGS=-L$(libpath) -ldodbc -Wall -Wl,-rpath $(libpath)
%.o:%.c
$(CC) -g -c $(CFLAGS) $< -o $@
object_file1=odbc_conn.o
object_file2=odbc_dml.o
object_files=odbc_conn.o odbc_dml.o
final_objects=odbc_conn odbc_dml
all : $(final_objects)
.PHONY : all clean rebuild
odbc_conn : $(object_file1)
$(CC) -o $@ $(object_file1) -g $(LINKFLAGS)
@echo make ok.
odbc_dml : $(object_file2)
$(CC) -o $@ $(object_file2) -g $(LINKFLAGS)
@echo make ok.
clean :
@rm -rf $(object_files)
@rm -rf $(final_objects)
rebuild : clean all
odbc_conn.c文件如下:
[dmdba@localhost ~/dmdbms/odbc_test_code]$cat odbc_conn.c
#include <stdio.h>
#include <stdlib.h>
#include <sql.h>
#include <sqltypes.h>
#include <sqlext.h>
/* 检测返回代码是否为成功标志,当为成功标志返回 TRUE,否则返回 FALSE */
#define RC_SUCCESSFUL(rc) ((rc) == SQL_SUCCESS || (rc) == SQL_SUCCESS_WITH_INFO)
/* 检测返回代码是否为失败标志,当为失败标志返回 TRUE,否则返回 FALSE */
#define RC_NOTSUCCESSFUL(rc) (!(RC_SUCCESSFUL(rc)))
HENV henv;/* 环境句柄 */
HDBC hdbc;/* 连接句柄 */
HSTMT hsmt;/* 语句句柄 */
SQLRETURN sret; /* 返回代码 */
int main(void)
{
/* 申请一个环境句柄 */
SQLAllocHandle(SQL_HANDLE_ENV, NULL, &henv);
/* 设置环境句柄的 ODBC 版本 */
SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3,
SQL_IS_INTEGER);
/* 申请一个连接句柄 */
SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
sret = SQLConnect(hdbc, (SQLCHAR *)"DM", SQL_NTS, (SQLCHAR *)"SYSDBA", SQL_NTS, (SQLCHAR *)"Sysdba%_025", SQL_NTS);
if (RC_NOTSUCCESSFUL(sret)) {
/* 连接数据源失败! */
printf("odbc: fail to connect to server!\n");
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
SQLFreeHandle(SQL_HANDLE_ENV, henv);
exit(0);
}
printf("odbc: connect to server success!\n");
/* 断开与数据源之间的连接 */
SQLDisconnect(hdbc);
/* 释放连接句柄 */
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
/* 释放环境句柄 */
SQLFreeHandle(SQL_HANDLE_ENV, henv);
return 0;
}
odbc_dml.c文件如下:
[dmdba@localhost ~/dmdbms/odbc_test_code]$cat odbc_dml.c
#include <stdio.h>
#include <stdlib.h>
#include <sql.h>
#include <sqltypes.h>
#include <sqlext.h>
#define RC_SUCCESSFUL(rc) ((rc) == SQL_SUCCESS || (rc) == SQL_SUCCESS_WITH_INFO)
#define RC_NOTSUCCESSFUL(rc) (!(RC_SUCCESSFUL(rc)))
// 新增:ODBC错误打印函数,获取详细报错信息
void PrintODBCError(SQLHANDLE hHandle, SQLSMALLINT hType)
{
SQLCHAR state[6], errMsg[256];
SQLINTEGER nativeErr;
SQLSMALLINT msgLen;
SQLGetDiagRec(hType, hHandle, 1, state, &nativeErr, errMsg, sizeof(errMsg), &msgLen);
printf("SQLSTATE=%s, 达梦错误码:%d, 错误信息:%s\n", state, (int)nativeErr, errMsg);
}
HENV henv;
HDBC hdbc;
HSTMT hstmt;
SQLRETURN sret;
int main(void)
{
int out_c1 = 0;
SQLCHAR out_c2[20]= { 0 };
SQLLEN out_c1_ind = 0;
SQLLEN out_c2_ind = 0;
/* 申请环境句柄 */
SQLAllocHandle(SQL_HANDLE_ENV, NULL, &henv);
SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, SQL_IS_INTEGER);
SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
// DSN名称:odbc.ini中的[DM]段,按需修改
sret = SQLConnect(hdbc, (SQLCHAR *)"DM", SQL_NTS,
(SQLCHAR *)"SYSDBA", SQL_NTS,
(SQLCHAR *)"Sysdba%_025", SQL_NTS);
if (RC_NOTSUCCESSFUL(sret)) {
printf("odbc: fail to connect to server!\n");
PrintODBCError(hdbc, SQL_HANDLE_DBC);
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
SQLFreeHandle(SQL_HANDLE_ENV, henv);
exit(EXIT_FAILURE);
}
printf("odbc: connect to server success!\n");
SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
// ========== 1.清空表,增加返回值判断 ==========
printf("\n---执行DELETE清空表---\n");
sret = SQLExecDirect(hstmt, (SQLCHAR *) "delete from PRODUCTION.PRODUCT_CATEGORY", SQL_NTS);
if (RC_NOTSUCCESSFUL(sret)) {
printf("odbc: delete table fail\n");
PrintODBCError(hstmt, SQL_HANDLE_STMT);
goto EXIT;
}
printf("odbc: clear table success\n");
// ========== 2.插入数据 ==========
printf("\n---执行INSERT插入---\n");
sret = SQLExecDirect(hstmt, (SQLCHAR *) "insert into PRODUCTION.PRODUCT_CATEGORY(NAME) values('语文'), ('数学'), ('英语'), ('体育') ", SQL_NTS);
if (RC_NOTSUCCESSFUL(sret)) {
printf("odbc: insert fail\n");
PrintODBCError(hstmt, SQL_HANDLE_STMT);
goto EXIT;
}
printf("odbc: insert success\n");
printf("\n---执行DELETE删除数学---\n");
sret = SQLExecDirect(hstmt, (SQLCHAR *) "delete from PRODUCTION.PRODUCT_CATEGORY where name='数学' ", SQL_NTS);
if (RC_NOTSUCCESSFUL(sret)) {
printf("odbc: delete fail\n");
PrintODBCError(hstmt, SQL_HANDLE_STMT);
goto EXIT;
}
printf("odbc: delete success\n");
printf("\n---执行UPDATE更新英语---\n");
sret = SQLExecDirect(hstmt, (SQLCHAR *) "update PRODUCTION.PRODUCT_CATEGORY set name = '英语-新课标' where name='英语' ", SQL_NTS);
if (RC_NOTSUCCESSFUL(sret)) {
printf("odbc: update fail\n");
PrintODBCError(hstmt, SQL_HANDLE_STMT);
goto EXIT;
}
printf("odbc: update success\n");
printf("\n---执行SELECT查询结果---\n");
sret = SQLExecDirect(hstmt, (SQLCHAR *) "select * from PRODUCTION.PRODUCT_CATEGORY", SQL_NTS);
if (RC_NOTSUCCESSFUL(sret)) {
printf("odbc: select fail\n");
PrintODBCError(hstmt, SQL_HANDLE_STMT);
goto EXIT;
}
SQLBindCol(hstmt, 1, SQL_C_SLONG, &out_c1, sizeof(out_c1), &out_c1_ind);
SQLBindCol(hstmt, 2, SQL_C_CHAR, out_c2, sizeof(out_c2), &out_c2_ind);
while( (sret = SQLFetch(hstmt)) != SQL_NO_DATA )
{
if(RC_NOTSUCCESSFUL(sret))
{
PrintODBCError(hstmt, SQL_HANDLE_STMT);
break;
}
printf("id = %d, name = %s\n", out_c1, out_c2);
}
printf("odbc: select finish\n");
EXIT:
SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
SQLDisconnect(hdbc);
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
SQLFreeHandle(SQL_HANDLE_ENV, henv);
return 0;
}
makefile编译过程如下,里面涉及到odbc_conn.c和odbc_dml.c,需要在编译前写入,不然报错:
[dmdba@localhost ~/dmdbms/odbc_test_code]$make -f makefile
gcc -g -c -I/home/dmdba/dm/dmdbms/include -DDM64 -Wall odbc_conn.c -o odbc_conn.o
gcc -o odbc_conn odbc_conn.o -g -L/home/dmdba/dm/dmdbms/bin -ldodbc -Wall -Wl,-rpath /home/dmdba/dm/dmdbms/bin
make ok.
gcc -g -c -I/home/dmdba/dm/dmdbms/include -DDM64 -Wall odbc_dml.c -o odbc_dml.o
gcc -o odbc_dml odbc_dml.o -g -L/home/dmdba/dm/dmdbms/bin -ldodbc -Wall -Wl,-rpath /home/dmdba/dm/dmdbms/bin
make ok.
[dmdba@localhost ~/dmdbms/odbc_test_code]$ll
总用量 60
-rwxr-xr-x 1 dmdba dinstall 638 9月 20 17:18 makefile
-rwxr-xr-x 1 dmdba dinstall 10192 9月 20 18:45 odbc_conn
-rwxr-xr-x 1 dmdba dinstall 1518 9月 20 18:45 odbc_conn.c
-rw-r--r-- 1 dmdba dinstall 5520 9月 20 18:45 odbc_conn.o
-rwxr-xr-x 1 dmdba dinstall 14696 9月 20 18:45 odbc_dml
-rwxr-xr-x 1 dmdba dinstall 2931 9月 20 17:14 odbc_dml.c
-rw-r--r-- 1 dmdba dinstall 8376 9月 20 18:45 odbc_dml.o
写入并编译上面的odbc_conn.c文件,进行连接测试:
[root@localhost ~]# su - dmdba
上一次登录:日 9月 20 18:42:53 CST 2026pts/0 上
[dmdba@localhost ~]$cd /home/dmdba/dm/dmdbms/
[dmdba@localhost ~/dmdbms]$ls
bin desktop drivers jar license_chs.txt license_en.txt odbc_test_code script uninstall
bin2 doc include jdk license_cht.txt log samples tool uninstall.sh
[dmdba@localhost ~/dmdbms]$cd odbc_test_code/
[dmdba@localhost ~/dmdbms/odbc_test_code]$ls
makefile odbc_conn odbc_conn.c odbc_conn.o odbc_dml odbc_dml.c odbc_dml.o
[dmdba@localhost ~/dmdbms/odbc_test_code]$./odbc_conn
odbc: connect to server success!
写入并编译上面的odbc_dml.c文件,进行增删改查测试,运行结果如下:
在管理工具中查询如下:
刚才所有的ddl、dml操作都是在主库中进行,验证主库可以读+写入数据,接下来对备库进行测试。
下图为尝试写入数据的示例,结果为失败:
下图为读数据的示例,可以正常查询表中的数据:
结论:
1、备库能查到最新数据,不是备库自己写入的,是主库产生 REDO 日志同步过来、备库后台自动重演出来的。
2、备库的修改来源只有 REDO 日志重演,不接收任何用户提交的 DML/DDL。
dblink连接同类数据库的方式有三种,接下来我们使用最为好用的一种方式DPI-DBLINK去测试集群。
如下图所示,可以看到在右侧的公共外部链接处有新建的LINK_DPI_180:
LINK_DPI_180为主库连接备库的外部链接,下面主要只针对备库的功能进行测试:
下图为在主库连接备库去读数据的示例,可以正常查询表中的数据:
下图为在主库连接备库去尝试写入数据的示例,结果为失败:
上面所有的实验都在验证主库和备库的读写分离功能,主库既可以读又可以写入数据,但备库只可以读数据,无法写入。
文章
阅读量
获赞
