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

前言

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

一、JDBC驱动

1.1 基本介绍

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

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

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

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

84a45e5d-cd00-439d-89d4-17c2615633d8.png

1.2 标准接口

JDBC定义了一组标准的接口用于访问数据库,它们分别是数据库连接对象(Connection), 语句(Statement)以及结果集(ResultSet)。注意JDBC所有对象都必须显式的关闭,否则将造成资源泄露。它们之间的关系如下图示:连接创建语句,语句执行返回结果集。
d2b951c3-910c-447f-88fa-ac21ecd50bd3.png

1.3 openGauss驱动简介

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

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

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

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

b0b9f010-1b59-4811-a5f8-4bbec523a73d.png

注意版本号的差别:自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 子协议

  • 批量插入子协议

921b3faf-5aac-443c-99b0-a68793619c58.png

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

2.2 认证协议介绍

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

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

ef2d286c-5ead-4428-9bae-6b23d4b42ba2.png

startup阶段认证过程如下:

3f3dac84-0839-4402-a8ae-cfbfa7d2f9d9.png
  • 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会将请求过程分为若干个步骤,以加快数据库的处理速度。

3f3bfbfe-11cf-4305-bcc1-48b1ae343d45.png

2.4 copy协议

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

copy 子协议对应三种模式:

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

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

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

以copy-in处理流程举例

50c204f7-b833-4c1f-bae9-3d49ff7e3ef3.png

2.5 代码结构

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

4ed4b4bc-a4f2-46d6-91c4-d2e44483b006.png

核心入口来源于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核心流程

186ba342-dcce-415b-8bb8-7f3fd8f15456.png

2.8 编译

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

e9f83b05-6718-49e5-8987-1ccf89a857ef.png

2.9 调试

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

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

b2dc7df8-5b1f-4d81-8678-d2737865d7fd.png

第二步:添加测试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

13d619ad-1989-48f3-9431-246be4ca1823.png

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

5f2e164a-19fd-40df-80d1-69f06c9404a2.png

三、最终原因分析结果为错误的将含有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”)实现驱动的加载。 a17e6514-7270-4cec-a9f5-04c92b3d17de.png

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

1d329cf0-0b58-451e-b266-e0c3a1047d97.png

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

3.2 标准应用开发

665327cb-f117-4810-83cb-2998df472c47.png

注意


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

007312b9-62ce-44bd-b6ef-118da2785ee6.png

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

8e2137ca-71ab-409d-afe0-bafe0d7d5294.png

4.2 连接池

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

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

3268ff64-d701-4300-a508-940aa009c7fd.png

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

4.3 小结

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


本文分享自微信公众号 - openGauss(openGauss)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“ OSC源创计划 ”,欢迎正在阅读的你也加入,一起分享。

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

openGauss社区

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值