我是靠谱客的博主 文艺绿草,这篇文章主要介绍postgresql jdbc prepared 的通信过程的分析,现在分享给大家,希望可以做个参考。

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

    通过postgresql的官方文档,可以了解到与prepared整个过程相关的包大概包含parse, bind, describe , execute ,sync,这5个包是从客户端向服务端发送的。当服务端处理完毕这些包后会返回对应的parseComplete, bindComplete,rowDescription, rowdata, nodata 等等数据包作为回应。

    本文想讲解的重点是bind包中关于结果字段格式的问题。从官方文档可以知道字段格式有两种:文本(0)和二进制(1)。那么哪些字段是文本格式,哪些字段是二进制格式呢。prepared中什么时候使用文本格式,什么时候使用二进制格式呢?

一,使用二进制格式的数据类型

    从postgresql jdbc 9.4源码的AbstractJdbc2Connection.java文件的163行左右(代码段如下)来看。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
if (binaryTransfer && protoConnection.getProtocolVersion() >= 3) { binaryOids.add(Oid.BYTEA); binaryOids.add(Oid.INT2); binaryOids.add(Oid.INT4); binaryOids.add(Oid.INT8); binaryOids.add(Oid.FLOAT4); binaryOids.add(Oid.FLOAT8); binaryOids.add(Oid.TIME); binaryOids.add(Oid.DATE); binaryOids.add(Oid.TIMETZ); binaryOids.add(Oid.TIMESTAMP); binaryOids.add(Oid.TIMESTAMPTZ); binaryOids.add(Oid.INT2_ARRAY); binaryOids.add(Oid.INT4_ARRAY); binaryOids.add(Oid.INT8_ARRAY); binaryOids.add(Oid.FLOAT4_ARRAY); binaryOids.add(Oid.FLOAT8_ARRAY); binaryOids.add(Oid.FLOAT8_ARRAY); binaryOids.add(Oid.VARCHAR_ARRAY); binaryOids.add(Oid.TEXT_ARRAY); binaryOids.add(Oid.POINT); binaryOids.add(Oid.BOX); binaryOids.add(Oid.UUID); } // the pre 8.0 servers do not disclose their internal encoding for // time fields so do not try to use them. if (!haveMinimumCompatibleVersion(ServerVersion.v8_0)) { binaryOids.remove(Oid.TIME); binaryOids.remove(Oid.TIMETZ); binaryOids.remove(Oid.TIMESTAMP); binaryOids.remove(Oid.TIMESTAMPTZ); } // driver supports only null-compatible arrays if (!haveMinimumCompatibleVersion(ServerVersion.v8_3)) { binaryOids.remove(Oid.INT2_ARRAY); binaryOids.remove(Oid.INT4_ARRAY); binaryOids.remove(Oid.INT8_ARRAY); binaryOids.remove(Oid.FLOAT4_ARRAY); binaryOids.remove(Oid.FLOAT8_ARRAY); binaryOids.remove(Oid.FLOAT8_ARRAY); binaryOids.remove(Oid.VARCHAR_ARRAY); binaryOids.remove(Oid.TEXT_ARRAY); } binaryOids.addAll(getOidSet(PGProperty.BINARY_TRANSFER_ENABLE.get(info))); binaryOids.removeAll(getOidSet(PGProperty.BINARY_TRANSFER_DISABLE.get(info)));

只有协议版本在3及以上才会出现二进制的类型。并且在postgresql 小于8.0, 小于8.3 以及大于等于8.3的版本之间有一定的差异。

 有时候为了不让某些类型通过二进制通信,则可以通过PGProperty来DISABLE这些类型即可。相反则ENABLE这些类型。

需要注意的是所有 版本中都不支持Oid.DATE进行二进制通信。(不管用户ENABLE与否)

排除以上 出现的类型外,其他的类型都使用文本进行通信。

二,prepared中使用二进制的时机

   只有当针对同一个语句进行多次bind时,才会进行二进制的格式进行通信。第一次通信都是以文本的形式得到结果数据的。只有第二次及以后的调用对应的类型的字段的值才以二进制的格式进行通信。可以通过postgresql jdbc打开debug来观察。

    从理论上面来讲,第一次发送parse和bind包时,根本就不知道表中字段的类型。故bind无法要求服务端以特定的格式返回数据。第二次发送bind时,由于已经存在第一次调用返回的字段信息,故可以知道要求返回特定格式的数据。

转载于:https://my.oschina.net/u/918218/blog/691373

最后

以上就是文艺绿草最近收集整理的关于postgresql jdbc prepared 的通信过程的分析的全部内容,更多相关postgresql内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(52)

评论列表共有 0 条评论

立即
投稿
返回
顶部