Pgjdbc之CopyManager(一)

引入

CopyManager主要用于远程执行数据库的copy命令,主要分为In和Out两方面。
从常见的**public long copyIn(final String sql, Reader from)**方法开始:

此处传入了默认的参数:

实际执行

参数

三个参数的含义分别为:

  • sql 参数: 该参数是一个 COPY FROM STDIN 语句,用于指定复制操作的目标表以及复制的格式。COPY FROM STDIN 语句通常包括表名、列名、CSV 格式的选项(如分隔符、NULL 值的表示等)。
  • from 参数: 这个参数代表数据的来源,通常是一个 CSV 文件或类似的文本数据流。它用于读取数据并发送给数据库服务器进行复制操作。
  • bufferSize 参数: 这个参数指定了缓冲区的大小,单位是字符数。它用于暂存从 Reader 中读取的数据,然后将这些数据一次性发送到数据库服务器。
流程

流程很清晰:使用该sql新建一个CopyIn,每次写入bufferSize个char(最后一次除外),直到写完,执行cp.endCopy(),结束copy(cp.cancelCopy()可以大致理解为close,作用大概就是清缓存,未放入流程)。

内部实现
CopyIn cp = copyIn(sql)


看一下这行

queryExecutor.startCopy(sql, connection.getAutoCommit()); // 注意,该处的connection.getAutoCommit()是获取是否原子操作,该处的auto不是自动

实际实现如下:

不先关注事务内部和外部实现那一部分,只关注具体实现:

由发送的消息格式可以看出,这部分将该sql以简单查询的格式发出了。

接下来看看返回了什么:

processCopyResults(null, true)

该部分源码比较长,简单概括一下:我们之前向数据库发送了一条消息,这部分就是接收它返回的消息,然后做处理。
查阅官方文档可知,CopyInResponse的消息以’G’标识,查找到对应处理位置:

显而易见,新建了一个CopyDualImpl对象,并对其初始化,设置了结束接收消息标志,最后将该CopyDualImpl对象返回。

实际上,发送过来的消息肯定不止一个字符’Q’,还有一部分指示发送行格式和列数量和格式的部分,其它的部分在初始化接收并处理,最终设置为CopyDualImpl对象的属性,最终实现部分如下:

cp.writeToCopy

追踪到底层:

'd’代表着:Identifies the message as data.COPY,即告诉后端,之后我要发送的消息理解为’COPY’的数据。之后告诉后端要发送的消息大小。

cp.endCopy

显而易见,向后端发送copyIn结束指令,底层如下:

‘c’:Identifies the message as a -complete indicator.COPY,结束该copyIn

之后会收到后端发来的’Z’开头的消息,表明已经准备好接收下一条命令,并解锁:

cp.cancelCopy

浅提一下,该部分向后端发送以’f’开始的消息,并等待接收’Z’开头的消息:

‘f’:Identifies the message as a -failure indicator.COPY

总结

本质上就是约定好了消息格式,在该基础上进行socket通信。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值