openGauss驱动应用程序开发流程操作指南

2024年 5月 20日 72.5k 0

前言

本篇文章主要介绍JDBC的基本原理、驱动开发方法,了解原理后可以更进一步基于JDBC去访问数据库,实现应用程序开发。期望大家通过本文能够对JDBC驱动有一定的了解,并能够参与openGauss社区开发实践活动,积极探索openGauss社区、贡献openGauss社区。

一、JDBC驱动

1.1 基本介绍

JDBC( Java DataBase Connectivity ) 称为Java数据库连接,是一种访问数据库访问的标准应用程序API 。

为什么需要JDBC:不同的数据库通常会有不同的通信协议, 当一个程序使用不同的数据库时,就不得不按照厂商API写出几套连接程序;而厂商API可能在依赖操作系统功能,这将带来严重的跨平台依赖和重复代码问题。

JDBC的出现解决了这个问题,它提供了一致的编码规范,无论是哪一种数据库,在应用程序层面,都是通过一致的API去访问。

当然由于各个数据库的实现差异较大,不同的数据库驱动程序各不相同,JDBC通常由数据库厂商提供:

openGauss驱动应用程序开发流程操作指南-1

1.2 标准接口

JDBC定义了一组标准的接口用于访问数据库,它们分别是数据库连接对象(Connection), 语句(Statement)以及结果集(ResultSet)。注意JDBC所有对象都必须显式的关闭,否则将造成资源泄露。它们之间的关系如下图示:连接创建语句,语句执行返回结果集。
openGauss驱动应用程序开发流程操作指南-2

1.3 openGauss驱动简介

openGauss驱动是由openGauss开源社区提供的,使用Java语言编写的专用于访问openGauss数据库的驱动程序。

下载地址:https://opengauss.org/zh/download/

jdbc提供一键式编译脚本“sh build.sh”即可完成编译打包。

openGauss-jdbc已发布在maven中心仓,访问坐标如下:

openGauss驱动应用程序开发流程操作指南-3

注意版本号的差别:自3.1.0版本开始,均会提供带"-og"后缀的版本,它们的功能完全一致,差别点是否与pg驱动共存,如:

"3.1.0"的版本中,jar包内的包名为org.postgresql,它可以完全替换pg驱动类,但是它不可与pg驱动共存。

"3.1.0-og"版本中,jar包内的包名为org.opengauss,它可以与pg数据库驱动包共存。

1.4 小结

以上内容是关于JDBC的介绍,让大家了解了JDBC的作用,同时也可以掌握openGauss社区的jdbc开源地址、发布包等内容,为下一步的驱动开发做好准备。

二、openGauss驱动原理

2.1 基本介绍

openGauss-jdbc在是TCP/IP 协议之上实现了一套基于消息的通信协议。主要包括以下内容:

  • 建立和取消连接的消息流

  • 通信协议中使用的消息格式和类型

  • 处理请求的消息流

  • Copy 子协议

  • 批量插入子协议

openGauss驱动应用程序开发流程操作指南-4

openGauss 是多线程架构,守护线程 Postmaster 为每个连接分配一个后台线程(backend),后台线程的分配是在协议处理之前进行的,每个后台进程自行负责协议的处理。在 openGauss 源码或者文档中,通常认为 ‘backend’ 和 ‘server’ 是等价的,表示服务端;同样,‘frontend’ 和 ‘client’ 是等价的,表示客户端(应用程序)。

2.2 认证协议介绍

openGauss-jdbc通信协议包括两个阶段:startup和normal。startup阶段主要完成客户端与数据库认证连接,正常则连接成功进入normal阶段。normal阶段客户端完成SQL命令的请求和数据库的响应。

startup是非通用消息,会将协议版本号和客户端连接的用户名、数据库和GUC参数发送给数据库,而normal阶段则使用通用的消息格式:

openGauss驱动应用程序开发流程操作指南-5

startup阶段认证过程如下:

openGauss驱动应用程序开发流程操作指南-6

  • auth request消息(13字节):R 4字节(长度) 4字节(认证协议) 4字节(随机盐值)

  • PasswordMesage消息: p 4字节(长度) 36字节(35字节md5密码+\0)

  • ParameterStatus消息(包括server_version,client_edcoding和DataStyle): S 4字节(长度) key\0value\0

  • BackendKeyData消息(13字节): K 4字节(长度) 4字节(pid码) 4字节(ckey)

  • ReadyForQuery消息(6字节): Z 4字节(长度) 1字节(状态码I->idle, T->事务中, E->出现错误)

2.3 查询过程协议

normal阶段有两种“子协议”来发送请求,分别是simple query和extended query。使用simple query时,客户端直接发送请求,数据库立即处理并返回结果;而extended query会将请求过程分为若干个步骤,以加快数据库的处理速度。

openGauss驱动应用程序开发流程操作指南-7

2.4 copy协议

为了高效导入/导出数据,openGauss支持copy命令,copy命令会使数据库的连接处于不同的数据处理模式下。

copy 子协议对应三种模式:

  • copy-in 导入数据,对应命令 COPY FROM STDIN

  • copy-out 导出数据,对应命令 COPY TO STDOUT

  • copy-both 用于 walsender,在主备间批量传输数据

以copy-in处理流程举例

openGauss驱动应用程序开发流程操作指南-8

2.5 代码结构

源码地址: https://gitee.com/opengauss/openGauss-connector-jdbc.git

openGauss驱动应用程序开发流程操作指南-9

核心入口来源于Driver类,由它来完成所有JDBC接口类的调用;

openGauss驱动也提供了负载均衡、逻辑复制、copy等特有实现内容。

2.6 属性配置

连接数据库时使用Driver.connect函数实现,属性配置既可以通过url传递也可以通过properties传递。

注意:properties仅接收字符串的value参数,同时传递时properties的参数优先级更高。

参考官方文档:https://docs-opengauss.osinfra.cn/zh/docs/latest/docs/DeveloperGuide/JDBC%E5%B8%B8%E7%94%A8%E5%8F%82%E6%95%B0%E5%8F%82%E8%80%83.html

更多配置参数可以从PGProperty.java中获得。

常见参数:PGDBNAME、PGHOST、PGPORT、user、password、loggerLevel、prepareThreshold、preparedStatementCacheQueries等。

常见的url串编写如下:

jdbc:opengauss://$PGHOST:$ PGPORT/$ PGDBNAME?key=value&key1=value1...

实例:

jdbc:opengauss://127.0.0.1:5432/postgres?allowEncodingChanges=true&characterEncoding=UTF-8

2.7 PBE核心流程

openGauss驱动应用程序开发流程操作指南-10

2.8 编译

openGauss的编译提供一键式编译脚本build.sh,代码仓中有详细的编译说明:

openGauss驱动应用程序开发流程操作指南-11

2.9 调试

openGauss代码仓中已经提供了全套的juin4测试用例,最快捷的调试方法就是在工程下面添加新的测试用例验证。

第一步:更新测试数据库的配置信息(build.properties),也可以使用build.local.properties文件。

openGauss驱动应用程序开发流程操作指南-12

第二步:添加测试case,进行驱动验证。

参考org.postgresql.v511. SelectFunctionTest进行纯jdbc测试case验证。或者参考org.postgresql.jdbc.DeepBatchedInsertStatementTest继承自BaseTest4进行标准case验证。

2.10 问题实战

以问题单:https://gitee.com/opengauss/openGauss-connector-jdbc/issues/I84URC为例讲解实战分析过程:

一、添加测试case验证问题是否复现:

主动添加org.postgresql.v511.SelectFunctionTest类,增加testFunctionQuery测试方法,同时增加loggerLevel=TRACE

openGauss驱动应用程序开发流程操作指南-13

二、通过日志可以看出来是因为SQL被截断所致,而SQL截断是否Parser. parseJdbcSql处理,可以继续跟进调试。

openGauss驱动应用程序开发流程操作指南-14

三、最终原因分析结果为错误的将含有function的字符串识别成了函数体创建,引起分割问题

参考解决PR:https://gitee.com/opengauss/openGauss-connector-jdbc/pulls/172

2.11 小结

在本部分中,大家应该了解openGauss jdbc驱动的协议、实现原理,掌握jdbc代码的编译、调试能力,可以参与到jdbc的社区问题实战活动。

三、纯JDBC应用程序开发

3.1 驱动加载原理

在jdk1.6以前,通常编写jdbc程序前需主动调用Class.formName(“org.opengauss.Driver”)实现驱动的加载。openGauss驱动应用程序开发流程操作指南-15

在jdk1.6及以后,java支持SPI机制实现驱动自发现,不需要再额外的操作。

openGauss驱动应用程序开发流程操作指南-16

常见的驱动未发现异常(“No suitable driver found”),请仔细排查驱动包是否被加载。

3.2 标准应用开发

openGauss驱动应用程序开发流程操作指南-17

    注意

JDBC的Connection/Statement/ResultSet都是不受JVM管理的资源,必须显式的申请和释放,否则会造成资源泄露!

3.3 逻辑复制

openGauss提供逻辑复制功能以实现同构/异构数据库间的数据同步。

代码参考: https://docs-opengauss.osinfra.cn/zh/docs/2.0.1/docs/Developerguide/%E7%A4%BA%E4%BE%8B-%E9%80%BB%E8%BE%91%E5%A4%8D%E5%88%B6%E4%BB%A3%E7%A0%81%E7%A4%BA%E4%BE%8B.html

openGauss驱动应用程序开发流程操作指南-18

3.4 小结

在本部分中,大家应该了解了openGauss jdbc的加载过程和基本的jdbc应用程序编写。

四、使用ORM框架和连接池的应用程序开发

4.1 ORM框架

ORM(Object Relational Mapping)框架采用元数据来描述对象与关系映射的细节,元数据一般采用XML格式,并且存放在专门的对象一映射文件中。简单理解为一种框架的格式,可以大大减少数据库的保存、删除、读取等重复性代码。

本次以MyBatis为例:https://mybatis.org/mybatis-3/zh_CN/index.html

完整示例代码参考: https://gitee.com/justbk/jdbc_test/blob/master/src/test/java/BlobTest.java

openGauss驱动应用程序开发流程操作指南-19

4.2 连接池

数据库连接池(Connection Pooling)是将数据库的多个连接统一管理起来的程序,它可以动态地进行连接的申请、使用、释放管理。由于数据库创建连接是非常大的开销,所以连接复用是其核心思想。本文以druid为例进行讲解。

源代码地址: https://gitee.com/justbk/jdbc_test/blob/master/src/test/java/DruidTest.java

openGauss驱动应用程序开发流程操作指南-20

由于连接池本身也是围绕JDBC规范而设计的,所以对ORM/连接池来说,使用用法基本一致,与数据库关系较小。

4.3 小结

在本部分中,大家应该了解了与驱动密切相关的ORM和连接池概念,以及掌握mybatis和druid的使用。

相关文章

Oracle如何使用授予和撤销权限的语法和示例
Awesome Project: 探索 MatrixOrigin 云原生分布式数据库
下载丨66页PDF,云和恩墨技术通讯(2024年7月刊)
社区版oceanbase安装
Oracle 导出CSV工具-sqluldr2
ETL数据集成丨快速将MySQL数据迁移至Doris数据库

发布评论