postgresql jdbc 鏈接到postgresql 數據庫時,postgresql數據庫會返回一些參數來設置jdbc。postgresql 是經過發送類型爲S的數據包給客戶端的。本文主要講解jdbc中針對哪些參數進行了使用。java
經過搜索jdbc的源碼,能夠找到只有三個函數中針對參數進行了處理,這三個函數分別爲:readStartupMessages,processCopyResults,processResults。第一個函數是處理創建鏈接時的數據包的。第二個參數從名字看應該是處理copy功能時的函數。第三個參數處理的大部分操做的數據包。sql
在這三個函數中,readStartupMessages函數處理的參數分別爲:server_version_num,client_encoding,standard_conforming_strings,integer_datetimes。processCopyResults和processResults函數中只處理了client_encoding,DateStyle,standard_conforming_strings這三個參數,其餘的參數都被忽略掉了。數據庫
可是從9.4的postgresql數據庫的通訊看,傳遞了不少參數給客戶端,下面是經過jdbc的調試功能獲得的數據庫端設置jdbc端的參數狀況:session
<=BE ParameterStatus(application_name = ) <=BE ParameterStatus(client_encoding = UTF8) <=BE ParameterStatus(DateStyle = ISO, YMD) <=BE ParameterStatus(integer_datetimes = on) <=BE ParameterStatus(IntervalStyle = postgres) <=BE ParameterStatus(is_superuser = on) <=BE ParameterStatus(server_encoding = UTF8) <=BE ParameterStatus(server_version = 9.4.4) <=BE ParameterStatus(session_authorization = db_user) <=BE ParameterStatus(standard_conforming_strings = on) <=BE ParameterStatus(TimeZone = Asia/Shanghai) <=BE BackendKeyData(pid=22833,ckey=1140395019)
上面參數中integer_datetimes若是爲on,則表明日期能夠使用double類型來進行通訊。standard_conforming_strings則是針對字符串的處理的設置。若是爲on,則不把\當作轉義。app
下面是上述三個函數的詳細代碼:函數
readStartupMessagespost
case 'S': // ParameterStatus int l_len = pgStream.ReceiveInteger4(); String name = pgStream.ReceiveString(); String value = pgStream.ReceiveString(); if (logger.logDebug()) logger.debug(" <=BE ParameterStatus(" + name + " = " + value + ")"); if (name.equals("server_version_num")) protoConnection.setServerVersionNum(Integer.parseInt(value)); if (name.equals("server_version")) protoConnection.setServerVersion(value); else if (name.equals("client_encoding")) { if (!value.equals("UTF8")) throw new PSQLException(GT.tr("Protocol error. Session setup failed."), PSQLState.PROTOCOL_VIOLATION); pgStream.setEncoding(Encoding.getDatabaseEncoding("UTF8")); } else if (name.equals("standard_conforming_strings")) { if (value.equals("on")) protoConnection.setStandardConformingStrings(true); else if (value.equals("off")) protoConnection.setStandardConformingStrings(false); else throw new PSQLException(GT.tr("Protocol error. Session setup failed."), PSQLState.PROTOCOL_VIOLATION); } else if (name.equals("integer_datetimes")) { if (value.equals("on")) protoConnection.setIntegerDateTimes(true); else if (value.equals("off")) protoConnection.setIntegerDateTimes(false); else throw new PSQLException(GT.tr("Protocol error. Session setup failed."), PSQLState.PROTOCOL_VIOLATION); } break;
processCopyResults:ui
case 'S': // Parameter Status { int l_len = pgStream.ReceiveInteger4(); String name = pgStream.ReceiveString(); String value = pgStream.ReceiveString(); if (logger.logDebug()) logger.debug(" <=BE ParameterStatus(" + name + " = " + value + ")"); if (name.equals("client_encoding") && !value.equalsIgnoreCase("UTF8") && !allowEncodingChanges) { protoConnection.close(); // we're screwed now; we can't trust any subsequent string. error = new PSQLException(GT.tr("The server''s client_encoding parameter was changed to {0}. The JDBC driver requires client_encoding to be UTF8 for correct operation.", value), PSQLState.CONNECTION_FAILURE); endReceiving = true; } if (name.equals("DateStyle") && !value.startsWith("ISO,")) { protoConnection.close(); // we're screwed now; we can't trust any subsequent date. error = new PSQLException(GT.tr("The server''s DateStyle parameter was changed to {0}. The JDBC driver requires DateStyle to begin with ISO for correct operation.", value), PSQLState.CONNECTION_FAILURE); endReceiving = true; } if (name.equals("standard_conforming_strings")) { if (value.equals("on")) protoConnection.setStandardConformingStrings(true); else if (value.equals("off")) protoConnection.setStandardConformingStrings(false); else { protoConnection.close(); // we're screwed now; we don't know how to escape string literals error = new PSQLException(GT.tr("The server''s standard_conforming_strings parameter was reported as {0}. The JDBC driver expected on or off.", value), PSQLState.CONNECTION_FAILURE); endReceiving = true; } } }
processResultsdebug
case 'S': // Parameter Status { int l_len = pgStream.ReceiveInteger4(); String name = pgStream.ReceiveString(); String value = pgStream.ReceiveString(); if (logger.logDebug()) logger.debug(" <=BE ParameterStatus(" + name + " = " + value + ")"); if (name.equals("client_encoding") && !value.equalsIgnoreCase("UTF8") && !allowEncodingChanges) { protoConnection.close(); // we're screwed now; we can't trust any subsequent string. handler.handleError(new PSQLException(GT.tr("The server''s client_encoding parameter was changed to {0}. The JDBC driver requires client_encoding to be UTF8 for correct operation.", value), PSQLState.CONNECTION_FAILURE)); endQuery = true; } if (name.equals("DateStyle") && !value.startsWith("ISO,")) { protoConnection.close(); // we're screwed now; we can't trust any subsequent date. handler.handleError(new PSQLException(GT.tr("The server''s DateStyle parameter was changed to {0}. The JDBC driver requires DateStyle to begin with ISO for correct operation.", value), PSQLState.CONNECTION_FAILURE)); endQuery = true; } if (name.equals("standard_conforming_strings")) { if (value.equals("on")) protoConnection.setStandardConformingStrings(true); else if (value.equals("off")) protoConnection.setStandardConformingStrings(false); else { protoConnection.close(); // we're screwed now; we don't know how to escape string literals handler.handleError(new PSQLException(GT.tr("The server''s standard_conforming_strings parameter was reported as {0}. The JDBC driver expected on or off.", value), PSQLState.CONNECTION_FAILURE)); endQuery = true; } } }