第26章:連接器

目錄

26.1. MySQL Connector/ODBC
26.1.1. MyODBC介紹
26.1.2. 關於ODBC和MyODBC的一般訊息
26.1.3. 如何安裝MyODBC
26.1.4. 在Windows平台上從二進製版本安裝MyODBC
26.1.5. I在Unix平台上從二進製版本安裝MyODBC
26.1.6. 在Windows平台上從原始碼版本安裝MyODBC
26.1.7. 在Unix平台上從原始碼版本安裝MyODBC
26.1.8. 從BitKeeper開發原始碼樹安裝MyODBC
26.1.9. MyODBC配置
26.1.10. 與MyODBC連接相關的事宜
26.1.11. MyODBC和Microsoft Access
26.1.12. MyODBC和Microsoft VBA及ASP
26.1.13. MyODBC和第三方ODBC工具
26.1.14. MyODBC通用功能
26.1.15. 基本的MyODBC應用步驟
26.1.16. MyODBC API引用
26.1.17. MyODBC數據類型
26.1.18. MyODBC錯誤代碼
26.1.19. MyODBC與VB:ADO、DAO和RDO
26.1.20. MyODBC與Microsoft.NET
26.1.21. 感謝
26.2. MySQL Connector/NET
26.2.1. 前言
26.2.2. 下載並安裝MySQL Connector/NET
26.2.3. Connector/NET體系結構
26.2.4. 使用MySQL Connector/NET
26.2.5. MySQL Connector/NET變更史
26.3. MySQL Connector/J
26.3.1. 基本的JDBC概念
26.3.2. 安裝 Connector/J
26.3.3. JDBC引用
26.3.4. 與J2EE和其他Java框架一起使用 Connector/J
26.3.5. 診斷 Connector/J方面的問題
26.3.6. Changelog
26.4. MySQL Connector/MXJ
26.4.1. 前言
26.4.2. 支援平台:
26.4.3. Junit測試要求
26.4.4. 運行Junit測試
26.4.5. 作為JDBC驅動程式的一部分運行
26.4.6. 在Java對像中運行
26.4.7. MysqldResource API
26.4.8. 在JMX代理(custom)中運行
26.4.9. 部署在標準的JMX代理環境下 (JBoss)
26.4.10. 安裝
在本章中,介紹了MySQL連接器,所謂連接器,是為客戶端程式提供與MySQL伺服器連接性的驅動程式。

26.1. MySQL Connector/ODBC

通過MySQL Connector/ODBC(MyODBC驅動程式系列),MySQL為ODBC提供了支援。這是針對MyODBC驅動程式中Connector/ODBC產品系列的參考,它提供了對MySQL資料庫系統的ODBC 3.5x兼容訪問。介紹了安裝MyODBC和使用MyODBC的方式。此外,在本章中還介紹了能夠與MyODBC一起工作的公用程式訊息,並回答了一些關於MyODBC的常見問題。

本參考適用於MyODBC 3.51。對於相應的版本,您可以找到舊的二進製版或原始碼版MyODBC手冊。

這是關於MySQL ODBC驅動程式的參考手冊,而不是通用ODBC參考。關於ODBC的更多訊息,請參閱http://www.microsoft.com/data/

對於本參考的應用程式開發部分,假定用戶在C語言方面有著良好的實踐知識,對DBMS有一般瞭解,最後,還應熟悉MySQL。關於MySQL功能及其語法的更多訊息,請參閱http://dev.mysql.com/doc/

如果您的問題未能在本文檔中得到解答,請發送電子郵件至myodbc@lists.mysql.com

26.1.1. MyODBC介紹

26.1.1.1. 什麼是ODBC?

ODBC(開放式資料庫連接性)為客戶端程式提供了訪問眾多資料庫或數據源的一種方式。ODBC是標準化的API,允許與SQL資料庫伺服器進行連接。它是根據SQL Access Group的規範開發的,它定義了一套函數使用、錯誤代碼和數據類型,可將其用於開發獨立於資料庫的應用程式。通常情況下,當需要資料庫獨立或需要同時訪問不同的數據源時,將用到ODBC。

關於ODBC的更多訊息,請參閱http://www.microsoft.com/data/

26.1.1.2. 什麼是Connector/ODBC?

Connector/ODBC是描述MySQL ODBC驅動程式MySQL AB產品系列的名稱。它們也稱為MyODBC驅動程式。

26.1.1.3. 什麼是MyODBC 2.50?

MyODBC 2.50是MySQL AB的32位ODBC驅動程式,它基於ODBC 2.50規範層次0(具有層次1和層次2的特性)。這是開放原始碼市場最流行的ODBC驅動程式之一,很多用戶都使用它來訪問MySQL提供的功能。

26.1.1.4. 什麼是MyODBC 2.50?

MyODBC 3.51是一種32位ODBC驅動程式,也稱為MySQL ODBC 3.51驅動程式。與已有的MyODBC 2.50驅動程式相比,該版本有所增強。它支援ODBC 3.5x規範層次1(全部核心API +層次2特性),以便能夠為訪問MySQL提供所有的ODBC功能。

26.1.1.5. 從哪獲取MyODBC

MySQL AB依GPL(通用公共授權)發佈其所有產品。您可以從MySQL AB的網站獲取最新的MyODBC二進製版和原始碼版:http://dev.mysql.com/downloads/

關於MyODBC的更多訊息,請訪問http://www.mysql.com/products/myodbc/

關於授權的更多訊息,請訪問http://www.mysql.com/company/legal/licensing/

26.1.1.6. 支援的平台

MyODBC可用於MySQL支援的所有主要平台,如:

·         Windows 95, 98, Me, NT, 2000, XP和2003

·         所有Unix作業系統

o        AIX

o        Amiga

o        BSDI

o        DEC

o        FreeBSD

o        HP-UX 10, 11

o        Linux

o        Mac OS X Server

o        Mac OS X

o        NetBSD

o        OpenBSD

o        OS/2

o        SGI Irix

o        Solaris

o        SunOS

o        SCO OpenServer

o        SCO UnixWare

o        Tru64 Unix

對於特定平台,如果無法下載二進製版本,可通過下載驅動程式原始碼自行建立驅動程式。您也可以為MySQL貢獻二進制代碼,方式是發送郵件至myodbc@lists.mysql.com,這樣其他用戶就能使用您貢獻的內容。

26.1.1.7. MyODBC郵件列資料表

MySQL AB通過其郵件列資料表為用戶社區提供幫助。對於與MyODBC有關的事宜,可使用myodbc@lists.mysql.com郵件列資料表,從有經驗的用戶處獲得幫助。

關於訂閱MySQL郵件列資料表或瀏覽列資料表檔案的更多訊息,請訪問http://lists.mysql.com/

其中,關注程度最高的是論壇MySQL連接器部分的ODBC論壇。

26.1.1.8. MyODBC論壇

通過MySQL論壇(位於http://forums.mysql.com),可獲得有經驗用戶的支援和幫助。

26.1.1.9. 如何通報MyODBC問題或問題

如果遇到與MyODBC有關的困難或問題,首先應使用ODBC管理器和MyODBC生成一份日誌檔案(請求來自ODBC ADMIN的日誌時獲得的日誌檔案)。關於完成該步驟的方式,請參見26.1.9.7節,「獲取ODBC跟蹤檔案」

檢查MyODBC跟蹤檔案,找出可能出錯的地方。通過在myodbc.log檔案中搜索字串>mysql_real_query,可確定已執行的語句。

此外,您還應嘗試從mysql客戶端程式或admndemo執行語句。這樣,就能幫助您確定錯誤的出處,MyODBC或MySQL。

如果您發現了不正確的事項,請將相關行(最多40行)發送給MyODBC郵件列資料表。請參見1.7.1.1節,「MySQL郵件列資料表」。請勿發送整個MyODBC或ODBC日誌檔案!

如果您無法找出錯誤之所在,最後的選擇是,以tar或zip格式建立包含MyODBC跟蹤檔案、ODBC日誌檔案和README檔案(闡明問題)的檔案。您可以將該檔案檔案發送至ftp://ftp.mysql.com/pub/mysql/upload/。只有位於MySQL AB的我們才能訪問您上傳的檔案,而且我們會十分謹慎地對待這類數據。

如果您建立了仍出現問題的程式,請將該程式也包含在檔案檔案中。

如果程式能夠與某些其他SQL伺服器一起工作,檔案中還應包含在這類其他SQL伺服器下工作的ODBC日誌檔案。

請記住,您提供給我們的訊息越多,我們更正問題的機會就越大。

26.1.1.10. 如何提交MyODBC補丁

您可以通過電子郵件,就已有代碼或問題發送補丁或提出更好的解決方案:myodbc@lists.mysql.com

26.1.2. 關於ODBC和MyODBC的一般訊息

26.1.2.1. ODBC介紹

開放式資料庫連接性(ODBC)是廣泛接受的用於資料庫訪問的應用程式編程接口(API)。它基於針對資料庫API的CLI(使用層接口)規範(來自X/Open和ISO/IEC),並採用了結構化查詢語言(SQL)作為其資料庫訪問語言。

26.1.16節,「MyODBC API引用」中,概要介紹了MyODBC支援的ODBC功能。關於ODBC的更多訊息,請參閱http://www.microsoft.com/data/

26.1.2.2. MyODBC體系結構

MyODBC體系結構建立在5個組件上,如下圖所示:

MyODBC Architecture

·         應用程式:

應用程式指的是通過使用ODBC API來訪問MySQL伺服器上數據的程式。應用程式使用標準的ODBC使用與驅動管理器進行通信。應用程式不關心數據的儲存位置,儲存方式,甚至不關心為訪問數據而進行的系統配置方式。它僅需要知道數據源名(DSN)。

對於所有的應用程式,無論它們使用OBDC的方式是什麼,很多任務是共同的。這些任務包括:

o        選擇MySQL伺服器,並與之連接。

o        提交將要執行的SQL語句。

o        檢索結果(如果有的話)。

o        處理錯誤。

o        提交或回滾包含SQL語句的事務。

o        中斷與MySQL伺服器的連接。

由於大多數數據訪問工作是使用SQL完成,對於使用OBDC的應用程式來說,其主要任務是提交SQL語句,並檢索由這些語句生成的結果。

·         驅動管理器:

驅動管理器是用於管理應用程式和驅動程式間通信的庫。它負責執行下述任務:

o        解析數據源名(DSN)。

o        加載和卸載驅動程式。

o        處理ODBC使用,或將其傳遞給驅動程式。

·         MyODBC驅動程式:

MyODBC驅動程式是用於實施ODBC API所提供功能的庫。它負責處理ODBC函數使用,將SQL請求提交給MySQL伺服器,並將結果返回給應用程式。如有必要,驅動程式會更改應用程式的請求,以便該請求符合MySQL支援的語法。

·         ODBC.INI:

ODBC.INI是ODBC配置檔案,其中保存了連接到伺服器所需的驅動訊息和資料庫訊息。驅動管理器將使用它來確定加載哪個驅動程式(使用數據源名)。驅動程式將根據指定的DSN使用它來讀取連接參數。更多訊息,請參見26.1.9節,「MyODBC配置」

·         MySQL伺服器:

MySQL伺服器是數據源。MySQL是:

o        一種資料庫管理系統(DBMS)

o        一種關聯資料庫管理系統(RDBMS)

o        開放原始碼軟件

26.1.2.3. ODBC驅動管理器

ODBC驅動管理器是用於管理ODBC應用程式和驅動程式間通信的庫。其主要功能包括:

·         解析數據源名(DSN)。

·         加載和卸載驅動程式。

·         處理ODBC函數使用,或將其傳遞給驅動程式。

下面給出了一些常用的驅動程式:

·         Microsoft Windows ODBC驅動管理器(odbc32.dll),http://www.microsoft.com/data/

·         unixODBC Unix驅動管理器(libodbc.so),http://www.unixodbc.org

·         iODBC ODBC Unix驅動管理器(libiodbc.so),http://www.iodbc.org

從2.1.2版開始,UnixODBC也提供MyODBC 3.51。

26.1.2.4. MySQL ODBC驅動程式的類型

MySQL AB支援兩種通過ODBC API訪問MySQL功能的開放原始碼ODBC驅動程式: MyODBC (MyODBC 2.50)和MySQL ODBC 3.51驅動(MyODBC 3.51)。

註釋: 從本節起,我們將這兩類驅動程式統稱為MyODBC。但當存在差異時,我們將使用它們的本名。

26.1.3. 如何安裝MyODBC

MyODBC能夠工作在Windows 9x, Me, NT, 2000, XP和2003,以及大多數Unix平台上。

MyODBC是開放原始碼軟件。您可以在網站http://dev.mysql.com/downloads/connector/odbc/上找到它的最新版本。請注意,2.50.x版採用的是LGPL授權,而3.51.x版採用的是GPL授權。

如果使用MyODBC時出現了問題,而且您的程式還能與OLEDB一起工作,應嘗試使用OLEDB驅動程式。

正常情況下,在Windows機器上僅需安裝MyODBC。僅當您擁有運行在Unix機器上的程式(如ColdFusion),而且該程式將使用ODBC來訪問資料庫時,才需安裝用於Unix的MyODBC。

如果您打算在Unix機器上安裝MyODBC,還需要1個ODBC管理器。MyODBC能夠與大多數Unix ODBC管理器一起工作。

·         要想使用ODBC應用程式(不支援MySQL的應用程式),建立從Windows平台到Unix平台的連接,首先必須在Windows機器上安裝MyODBC。

·         用戶和Windows機器必須具有訪問位於Unix機器上的MySQL伺服器的權限。這可通過GRANT命令設置。請參見13.5.1.3節,「GRANT和REVOKE語法」

·         必須建立ODBC DSN條目,方式如下:

1.    打開Windows機器上的控制面板。

2.    雙擊ODBC數據源32位圖標。

3.    點擊選項卡「用戶DSN」。

4.    點擊「新增」按鈕。

5.    在「建立新數據源」屏幕上選擇MySQL,並點擊「完成」按鈕。

6.    顯示MySQL驅動程式的預設配置屏幕。請參見26.1.9.2節,「在Windows上配置MyODBC DSN」

·         啟動應用程式,並使用在ODBC管理器中指定的DSN選擇ODBC驅動程式。

注意,在MySQL屏幕上還顯示了其他選項,如果遇到問題,可嘗試這些選項(如跟蹤、連接時不提示等)。

26.1.4. 在Windows平台上從二進製版本安裝MyODBC

要想在Windows平台上安裝MyODBC,應從下述站點下載恰當的分發檔案,http://dev.mysql.com/downloads/connector/odbc/,解壓該檔案,並執行MyODBC-VERSION.exe檔案。

在Windows平台上,安裝較舊的MyODBC 2.50驅動時,可能會遇到下述錯誤:

拷貝C:\WINDOWS\SYSTEM\MFC30.DLL時出現錯誤。

 
重啟Windows,並再次安裝(在運行任何使用ODBC的應用程式之前)。

問題在於其他程式正使用ODBC。由於Windows的設計方式,在這種情況下,您可能無法使用Microsoft的ODBC設置程式安裝新的ODBC驅動。在大多數情況下,可以通過連續按「忽略」鍵拷貝剩餘的MyODBC檔案,最終安裝應仍能工作。如不然,解決方案是在「安全模式」下重新啟動計算機。在重啟的過程中,在機器啟動Windows前按F8,選擇「安全模式」,安裝MyODBC,然後在正常模式下重新啟動計算機。

26.1.5. I在Unix平台上從二進製版本安裝MyODBC

26.1.5.1. 從RPM分發版安裝MyODBC

要想使用RPM分發版在Linux平台上安裝或升級MyODBC,可簡單地下載最新MyODBC的RPM分發版,並按照下面介紹的方式操作。使用su root成為根用戶,然後安裝RPM檔案。

如果是首次安裝:

shell> su root
shell> rpm -ivh MyODBC-3.51.01.i386-1.rpm

如果驅動程式已存在,可按照下述方式升級它:

shell> su root
shell> rpm -Uvh MyODBC-3.51.01.i386-1.rpm

如果存在關於MySQL客戶端庫libmysqlclient的任何依存錯誤,可使用-nodeps選項簡單地忽略它,然後確保MySQL客戶端共享庫位於路徑中或通過LD_LIBRARY_PATH進行了設置。

這樣,就會將驅動程式庫和相關檔案分別安裝到/usr/local/lib/usr/share/doc/MyODBC目錄下。請轉至26.1.9.3節,「在Unix平台上配置MyODBC DSN」

要想卸載驅動程式,請首先成為根用戶,然後執行rpm命令:

shell> su root
shell> rpm -e MyODBC

26.1.5.2. 從二進制Tarball分發版安裝MyODBC

要想從tarball分發版(.tar.gz檔案)安裝驅動程式,請下載針對您所使用作業系統的最新版驅動程式,然後按照下述步驟操作:

shell> su root
shell> gunzip MyODBC-3.51.01-i686-pc-linux.tar.gz
shell> tar xvf MyODBC-3.51.01-i686-pc-linux.tar
shell> cd MyODBC-3.51.01-i686-pc-linux

請閱讀INSTALL-BINARY檔案中的安裝說明,並執行下述命令:

shell> cp libmyodbc* /usr/local/lib
shell> cp odbc.ini /usr/local/etc
shell> export ODBCINI=/usr/local/etc/odbc.ini

然後,請跳至26.1.9.3節,「在Unix平台上配置MyODBC DSN」為MyODBC配置DSN。更多訊息,請參見與發佈版一起提供的INSTALL-BINARY檔案。

26.1.6. 在Windows平台上從原始碼版本安裝MyODBC

26.1.6.1. 要求

·         MDAC, Microsoft Data Access SDK:http://www.microsoft.com/data/

·         MySQL客戶端庫以及MySQL 4.0.0或更高版本的包含檔案。(最好是MySQL 4.0.16或更高版本)。應滿足上述要求,這是因為MyODBC需要用到該版本以上的庫才提供的新使用和結構。要想獲得客戶端庫和包含檔案,請訪問http://dev.mysql.com/downloads/

26.1.6.2. 構建MyODBC 3.51

MyODBC 3.51原始碼分發版包括使用nmakeMakefiles。在分發版中,您可以找到用於建立發佈版的Makefile,以及用於建立驅動庫和DLL調試版的Makefile_debug

要想建立驅動程式,請採取下述步驟:

1.    下載並將原始碼展開到檔案夾,然後將位置切換到該檔案夾。在下述命令中,假定檔案夾為myodbc3-src:

2.           C:\> cd myodbc3-src

3.    編輯Makefile,為MySQL客戶端庫和頭檔案指定正確的路徑。然後使用下述命令建立並安裝發佈版。

4.           C:\> nmake -f Makefile
5.           C:\> nmake -f Makefile install

nmake -f Makefile用於建立驅動程式的發佈版並將二進制碼放入名為Release的子目錄下。

nmake -f Makefile install用於將驅動程式DLL和庫(myodbc3.dll, myodbc3.lib)安裝(拷貝)到系統目錄下。

6.    要想建立調試版,請使用Makefile_Debug而不是Makefile,如下所示:

7.           C:\> nmake -f Makefile_debug
8.           C:\> nmake -f Makefile_debug install

9.    使用下述命令,可清除並重新建立驅動程式:

10.       C:\> nmake -f Makefile clean
11.       C:\> nmake -f Makefile install

註釋:

·         確保在Makefiles中指定了正確的MySQL客戶端庫和頭檔案路徑(設置MYSQL_LIB_PATHMYSQL_INCLUDE_PATH變數)。預設的頭檔案路徑是C:\mysql\include。對於發佈版DLL,預設的庫路徑是C:\mysql\lib\opt,對於調試版,預設路徑是C:\mysql\lib\debug。

·         關於nmake的完整用法,請參見http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dv_vcce4/html/evgrfRunningNMAKE.asp

·         如果您正在使用BitKeeper樹來進行編譯,所有的針對Windows的Makefiles均將被命名為Win_Makefile*

26.1.6.3. 測試

將驅動程式庫拷貝/安裝到系統目錄後,可使用示範子目錄下提供的示範測試這些庫是否已正確建立:
C:\> cd samples
C:\> nmake -f Makefile all

26.1.6.4. 構建MyODBC 2.50

MyODBC 2.50原始碼分發版包含VC工作空間檔案。通過在Microsoft Visual Studio 6.0中加載這些檔案(.dsp.dsw),可使用它們直接建立驅動程式。

26.1.7. 在Unix平台上從原始碼版本安裝MyODBC

26.1.7.1. 要求

·         MySQL客戶端庫以及MySQL 4.0.0或更高版本的包含檔案。(最好是MySQL 4.0.16或更高版本)。應滿足上述要求,這是因為MyODBC需要用到該版本以上的庫才提供的新使用和結構。要想獲得客戶端庫和包含檔案,請訪問http://dev.mysql.com/downloads/

·         必須使用「--enable-thread-safe-client」選項配置MySQL庫。Libmysqlclient是作為共享庫安裝的。

·         必須安裝下述Unix ODBC驅動管理器之一:

o        iodbc 3.0或更高版本(http://www.iodbc.org

o        unixodbc Alpha 3或更高版本(http://www.unixodbc.org

·         如果使用了未編譯在MySQL客戶端庫中的字元編碼(預設字元編碼為: latin1 big5 czech euc_kr gb2312 gbk sjis tis620 ujis),就需要從字元編碼目錄下將mysql字元定義安裝到SHAREDIR中(預設情況下位於/usr/local/mysql/share/mysql/charsets)。如果在相同機器上安裝了MySQL,它們應位於恰當位置。

一旦完成了所有所需檔案的安裝,將原始碼檔案解包到單獨目錄下,並按照下面給出的說明進行操作。

26.1.7.2. 典型配置選項

使用configure指令,能夠對您所建立MyODBC的配置方式進行多種控制。典型情況下,可在「configure」命令行使用選項完成該配置操作。也可以使用環境變數來影響配置。要想瞭解「configure」命令支援的選項列資料表和環境變數,可運行下述命令:
shell> ./configure --help

下面介紹了一些常用的「configure」選項。

1.    要想編譯MyODBC,須使用「--with-mysql-path=DIR」選項來提供MySQL客戶端庫檔案和包含檔案路徑,其中,「DIR」是MySQL的安裝目錄。

可通過運行「DIR/bin/mysql_config」來確定MySQL編譯選項。

2.    為ODBC驅動管理器(iodbcunixobc)提供標準的頭檔案和庫檔案路徑。

·         如果您正在使用iodbc,而且iodbc未安裝在其預設位置/usr/local),可能需要使用--with-iodbc=DIR」選項,其中,「DIR」是iodbc的安裝目錄。

如果iodbc頭檔案未位於DIR/include目錄下,可使用--with-iodbc-includes=INCDIR選項指定它們的位置。

上面所述也適用於庫檔案。如果庫檔案未位於DIR/lib目錄下,可使用「--with-iodbc-libs=LIBDIR」選項。

·         如果您正在使用unixODBC,可使用--with-unixODBC=DIR」選項(區分大小寫),讓configure尋找unixODBC而不是預設的iodbc,其中,「DIR」是unixODBC的安裝目錄。

如果unixODBC頭檔案和庫檔案未位於目錄DIR/includeDIR/lib下,可使用--with-unixODBC-includes=INCDIR」和「--with-unixODBC-libs=LIBDIR」選項。

3.    或許您也希望指定不同於「/usr/local」的安裝前綴。例如,要想將MyODBC驅動安裝到「/usr/local/odbc/lib」目錄下,可使用「--prefix=/usr/local/odbc」選項。

最終的配置命令應與下面給出的相似:

shell> ./configure --prefix=/usr/local \
         --with-iodbc=/usr/local \
         --with-mysql-path=/usr/local/mysql

26.1.7.3. 線程安全客戶端

為了將驅動程式與MySQL線程安全客戶端庫libmysqlclient_r.solibmysqlclient_r.a連結起來,必須指定下述configure選項:
--enable-thread-safe

也可以使用下述選項禁止它:

--disable-thread-safe

使用該選項,能夠通過mysql線程安全客戶端庫libmysqlclient_r.so(延伸名與作業系統有關)的連結,建立驅動程式線程安全庫libmyodbc3_r.so。

在配置線程安全選項時,如果出現了配置錯誤,應檢查config.log,檢查錯誤是否是因系統中缺少線程庫而導致的,如果是,使用LIBS選項提供一個,即

LIBS="-lpthread" ./configure ..

26.1.7.4. 共享或靜態選項

可以使用下述選項啟用或禁止共享和靜態選項:

--enable-shared[=yes/no]
--disable-shared
--enable-static[=yes/no]
--disable-static

26.1.7.5. 啟用調試訊息

預設情況下,所有的二進制分發版均會被建立為非調試版(採用「--without-debug」進行配置)。

要想啟用調試訊息,請使用原始碼分發版建立驅動程式,並在運行「configure」時使用「--with-debug選項

26.1.7.6. 允許文檔功能

該選項僅能用於BK克隆樹,而不是一般的原始碼分發版。

預設情況下,驅動程式是使用「--without-docs建立的。如果希望在正常建立過程中觀察文檔訊息,可使用下述選項進行配置:

--with-docs

26.1.7.7. 建立和編譯

要想建立驅動程式庫,僅需執行「make」,該命令能完成所有事項。
shell> make

如果出現錯誤,更正後,繼續執行建立程序。如果無法建立,請發送詳細的電子郵件至myodbc@lists.mysql.com,以獲取進一步幫助。

26.1.7.8. 建立共享庫

在大多數平台上,預設情況下,MySQL不會建立或支援「.so(共享)客戶端庫,這是因為,建立共享庫在過去造成過很多問題。

在這種情況下,您可以下載MySQL分發版,並使用以下選項進行配置:

--without-server --enable-shared

要想建立共享驅動程式庫,必須為「configure」指定「--enable-shared選項。預設情況下,「configure」不啟用該選項。

如果使用「--disable-shared」選項進行了配置操作,可使用下述命令,從靜態庫建立「.so」檔案。

shell> cd MyODBC-3.51.01
shell> make
shell> cd driver
shell> CC=/usr/bin/gcc \
     $CC -bundle -flat_namespace -undefined error \
         -o .libs/libmyodbc3-3.51.01.so \
         catalog.o connect.o cursor.o dll.o error.o execute.o \
         handle.o info.o misc.o myodbc3.o options.o prepare.o \
         results.o transact.o utility.o \
         -L/usr/local/mysql/lib/mysql/ \
         -L/usr/local/iodbc/lib/ \
         -lz -lc -lmysqlclient -liodbcinst

如果您正在使用unixODBC而不是iODBC,務必將「-liodbcinst更改為-lodbcinst,並相應地配置庫路徑。

這樣,就建立了libmyodbc3-3.51.01.so檔案,並將其放在.libs目錄下。將該檔案拷貝到MyODBC庫目錄下(/usr/local/lib,或使用--prefix提供的安裝目錄下的lib目錄)。

shell> cd .libs
shell> cp libmyodbc3-3.51.01.so /usr/local/lib
shell> cd /usr/local/lib
shell> ln -s libmyodbc3-3.51.01.so libmyodbc3.so

要想建立線程安全驅動程式庫:

shell> CC=/usr/bin/gcc \
     $CC -bundle -flat_namespace -undefined error
      -o .libs/libmyodbc3_r-3.51.01.so
      catalog.o connect.o cursor.o dll.o error.o execute.o
      handle.o info.o misc.o myodbc3.o options.o prepare.o
      results.o transact.o utility.o
      -L/usr/local/mysql/lib/mysql/
      -L/usr/local/iodbc/lib/
      -lz -lc -lmysqlclient_r -liodbcinst

26.1.7.9. 安裝驅動庫

要想安裝驅動程式庫,請執行下述命令:
shell> make install

該命令將安裝下述庫集合之一:

對於MyODBC 3.51:

·         libmyodbc3.so

·         libmyodbc3-3.51.01.so,其中,3.51.01是驅動程式的版本

·         libmyodbc3.a

對於線程安全MyODBC 3.51:

·         libmyodbc3_r.so

·         libmyodbc3-3_r.51.01.so

·         libmyodbc3_r.a

對於MyODBC 2.5.0:

·         libmyodbc.so

·         libmyodbc-2.50.39.so,其中,2.50.39是驅動程式的版本

·         libmyodbc.a

關於建立程序的更多訊息,請參閱與原始碼分發版一起提供的INSTALL檔案。注意,如果您試圖使用Sun的「make」,可能會以錯誤結束。從另一方面來說,GNU gmake在所有平台上均能良好工作。

26.1.7.10. 在Unix平台上測試MyODBC

要想與您建立的庫一起運行分發版中提供的示範,可執行:
shell> make test

首先,務必在odbc.ini中配置DSN 'myodbc3',並將環境變數ODBCINI指向正確的odbc.ini檔案;同時MySQL伺服器應處於運行狀態。在驅動分發版中,可找到一個示範用odbc.ini檔案。

您甚至可以更改示範/運行示範指令,以命令行參數的形式將所需的DSN、UID和PASSWORD值傳遞給示範。

26.1.7.11. Mac OS X注意事項

要想在Mac OS X (Darwin)環境下建立驅動程式,可使用下述configure示範:
shell> ./configure --prefix=/usr/local
           --with-unixODBC=/usr/local
           --with-mysql-path=/usr/local/mysql
           --disable-shared
           --enable-gui=no
           --host=powerpc-apple

該命令假定unixODBC和MySQL均安裝在預設位置。如不然,請進行相應配置。

在 Mac OS X環境下,「--enable-shared選項將預設建立.dylib檔案。您也可以採用下述方式建立「.so」檔案:

shell> make
shell> cd driver
shell> CC=/usr/bin/gcc \
     $CC -bundle -flat_namespace -undefined error
         -o .libs/libmyodbc3-3.51.01.so *.o
         -L/usr/local/mysql/lib/
         -L/usr/local/iodbc/lib
         -liodbcinst -lmysqlclient -lz -lc

要想建立線程安全驅動程式庫:

shell> CC=/usr/bin/gcc \
     $CC -bundle -flat_namespace -undefined error
     -o .libs/libmyodbc3-3.51.01.so *.o
     -L/usr/local/mysql/lib/
     -L/usr/local/iodbc/lib
     -liodbcinst -lmysqlclienti_r -lz -lc -lpthread

如果您正在使用unixODBC而不是iODBC,務必將「-liodbcinst更改為-lodbcinst,並相應地配置庫路徑。

在Apple的GCC版本中,ccgcc實際上均是gcc3的符號連結。

將該庫拷貝到$prefix/lib目錄下,並將symlink拷貝到libmyodbc3.so

可以使用下述命令交叉檢驗輸出的共享庫屬性:

shell> otool -LD .libs/libmyodbc3-3.51.01.so

26.1.7.12. HP-UX注意事項

要想在HP-UX 10.x或11.x環境下建立驅動程式,可使用下述configure示範:

如果使用cc

shell> CC="cc" \
     CFLAGS="+z" \
     LDFLAGS="-Wl,+b:-Wl,+s" \
     ./configure --prefix=/usr/local
           --with-unixodbc=/usr/local
           --with-mysql-path=/usr/local/mysql/lib/mysql
           --enable-shared
           --enable-thread-safe

如果使用gcc

shell> CC="gcc" \
     LDFLAGS="-Wl,+b:-Wl,+s" \
     ./configure --prefix=/usr/local
           --with-unixodbc=/usr/local
           --with-mysql-path=/usr/local/mysql
           --enable-shared
           --enable-thread-safe

一旦建立了驅動程式,使用「chatr .libs/libmyodbc3.sl」交叉檢查其屬性,查看是否需要使用SHLIB_PATH環境變數的MySQL客戶端庫。對於靜態版,忽略所有的共享庫選項,並使用「--disable-shared」選項運行「configure」。

26.1.7.13. AIX注意事項

要想在AIX環境下建立驅動程式,可使用下述configure示範:

shell> ./configure --prefix=/usr/local
           --with-unixodbc=/usr/local
           --with-mysql-path=/usr/local/mysql
           --disable-shared
           --enable-thread-safe
註釋: 關於在不同平台上建立和設置靜態和共享庫方式的更多訊息,請參見跨平台使用靜態和共享庫

26.1.8. 從BitKeeper開發原始碼樹安裝MyODBC

註釋: 如果您對協助我們測試新的代碼感興趣,應閱讀本節的內容。

要想獲得我方的最新開發原始碼樹,請:

1.    參見2.8.3節,「從開發原始碼樹安裝」,關於如何下載和安裝BitKeeper的說明。

2.    安裝完BitKeeper後,首先進入打算在其中工作的目錄,然後,如果打算克隆MyODBC 3.51分支,請使用該命令:

3.           shell> bk clone bk://mysql.bkbits.net/myodbc3 myodbc-3.51

在前面的示範中,原始碼樹是在myodbc-3.51/中設置的,或在當前目錄的myodbc3/子目錄下設置的(預設)。如果您位於防火牆後,而且僅能啟動HTTP連接,也可以通過HTTP使用BitKeeper。如果要求使用代理伺服器,可簡單地設置環境變數http_proxy,使之指向代理伺服器:

shell> export http_proxy="http://your.proxy.server:8080/"

執行克隆操作時,用http://替換bk://。例如:

shell> bk clone http://mysql.bkbits.net/myodbc3 myodbc-3.51

首次下載原始碼樹時需要一段時間,具體情況取決於連接速度,請耐心等候。

4.    要想運行下一組命令,需要GNU autoconf 2.52(或更新版本)automake 1.4libtool 1.4,以及m4

5.           shell> cd myodbc-3.51
6.           shell> bk -r edit
7.           shell> aclocal; autoheader; autoconf;  automake;
8.           shell> ./configure  # Add your favorite options here
9.           shell> make

關於如何建立的更多訊息,請參閱位於相同目錄下的INSTALL檔案。在Windows平台下,建立驅動程式時,請使用Windows Makefiles WIN-MakefileWIN-Makefile_debug,更多訊息,請參見26.1.6節,「在Windows平台上從原始碼版本安裝MyODBC」

10.完成建立後,運行make install,將MyODBC 3.51驅動程式安裝到您的系統上。

11.如果進入了make階段,但並未編譯分發版本,請將其通報給myodbc@lists.mysql.com

12.啟動了bk clone操作獲得原始碼樹後,應定期運行bk pull進行更新。

13.可以使用「bk sccstool」檢查樹的變更史。如果您發現了有趣的差異,並對代碼存在一問,請立刻發送電子郵件至myodbc@lists.mysql.com

此外,如果您認為有更好的主意,請發送電子郵件至相同的地址並附上補丁。更改了原始碼後,使用「bk diffs」可生成補丁。如果您沒有時間就您的觀點編寫代碼,可發送描述性訊息。

14.BitKeeper具有一個可通過bk helptool訪問的幫助工具。

通過瀏覽http://mysql.bkbits.net:8080/myodbc3,也能線上瀏覽變化集、註釋和源代碼。

26.1.9. MyODBC配置

本節介紹了配置MyODBC的方法,包括DSN建立,以及驅動程式在連接字串中作為輸入參數的不同參數。此外,還介紹了建立ODBC跟蹤檔案的方法。

26.1.9.1. 什麼是數據源名?

「數據源」是提供數據的地點。數據源必須有穩定的標識符,即數據源名。使用數據源名,MySQL可訪問初始化訊息。通過初始化訊息,MySQL能夠瞭解去哪裡訪問資料庫,以及在開始訪問時使用什麼設置。

事實上,數據源就是數據的路徑。在不同的情況下,它可能有著不同的內容,但是在典型情況下,它指明了正在運行的MySQL伺服器(例如,通過網絡地址或伺服器名),連接時該伺服器的預設資料庫,以及必要的連接訊息(如端口)。MySQL驅動程式(以及Windows系統上的ODBC驅動管理器)將使用數據源進行連接。對於該目的,名為Microsoft ODBC數據源管理器的管理工具可能十分有用。

有兩處可能保存初始化訊息的位置: Windows註冊資料表(Windows系統),或DSN檔案(任何系統)。

如果訊息位於Windows註冊資料表中,它稱為「機器數據源」。它可以是「用戶數據源」,在這種情況下,只有一位用戶能看到它。它也可以是「系統數據源」,在這種情況下,計算機上的所有用戶均能訪問它,如果用戶是通過Microsoft Windows NT服務連接在一起的話,與該計算機相連的所有用戶均能訪問它。運行ODBC數據管理程式時,可以選擇是否使用「用戶」或「系統」,它們位於不同的選項卡上。

如果訊息位於DSN檔案中,它稱為「檔案數據源」。這是一種文本檔案。其優點在於: (a)它適合於任何類型的計算機,而不僅僅是使用Windows作業系統的計算機;(b)其內容的拷貝或傳輸相對容易。

26.1.9.2. 在Windows上配置MyODBC DSN

要想在Windows平台上新增和配置新的MyODBC數據源,請使用ODBC數據源管理器。ODBC管理器能夠更新數據源連接訊息。新增了數據源時,ODBC管理器能夠更新註冊訊息。

要想從控制面板打開ODBC管理器:

1.    點擊「開始」,將指針指向「設置」,然後點擊「控制面板」。

2.    在運行Microsoft Windows 2000或更新版本的計算機上,雙擊「管理工具」,然後雙擊「數據源」(ODBC)。在運行舊版本Windows的計算機上,雙擊32位ODBCODBC

ODBC Data Sources
              Icon

打開ODBC數據源管理器對話框,如下圖所示:

ODBC Data Source
              Administrator Dialog

點擊「幫助」以瞭解ODBC數據源管理器對話框各選項卡的詳細訊息。

要想在Windows平台上新增數據源:

1.    打開ODBC數據源管理器。

2.    在ODBC數據源管理器對話框中,點擊「新增」。打開「建立新數據源」對話框。

3.    選擇MySQL ODBC 3.51驅動程式,然後點擊完成打開「MySQL ODBC 3.51驅動程式-DSN配置對話框,如下圖所示:

MySQL ODBC DSN
              Configuration Dialog

4.    在「數據源名」框中,輸入打算訪問的數據源的名稱。它可以是您選擇的任何有效名稱。

5.    在「描述」框中,輸入DSn所需的描述訊息。

6.    在「主機」或「伺服器名」(或IP)框中,輸入準備訪問的MySQL伺服器主機的名稱。預設情況下為localhost(本地主機)。

7.    在「資料庫名」框中,輸入準備用作預設資料庫的MySQL資料庫名稱。

8.    在「用戶」框中,輸入您的MySQL帳號(資料庫用戶ID)。

9.    在「密碼」框中輸入密碼。

10.在「端口」框中,如果端口不是預設端口,輸入端口號。

11.在「SQL命令」框中,可輸入建立連接後自動執行的SQL語句。

最後,對話框與下圖顯示的類似:

Filled-In MySQL ODBC DSN
              Configuration Dialog

點擊「OK」新增該數據源。

註釋: 點擊「OK」後,將打開「數據源」對話框,ODBC管理器將更新註冊訊息。連接到該數據源時,您所輸入的帳號和連接字串將成為該數據源的預設連接值。

您也可以使用「測試數據源」按鈕,測試您的設置是否適合於連接到伺服器。該特性僅對MyODBC 3.51驅動程式有效。成功完成測試後,將顯示下述窗口:

MyODBC Successful Connection
          Message

如果測試失敗,將顯示錯誤消息。

MyODBC Failed Connection Message

DNS配置對話框也有一個「選項」按鈕。如果選擇了它,將打開下述選項對話框,顯示控制驅動程式的行為。關於這些選項的含義,請參見26.1.9.4節,「連接參數」

MyODBC Options Dialog

註釋: 在「驅動程式跟蹤」選項下列出的選項已被禁止(灰色),除非您使用的是驅動DLL的調試版本。

要想在Windows平台上更改數據源:

1.    打開ODBC數據源管理器。點擊恰當的選項卡「DSN」。

2.    選擇打算更改的MySQL數據源,然後點擊「配置」。打開「MySQL ODBC 3.51驅動程式-DSN配置對話框。

3.    更改適用的數據源字段,然後點擊「OK」。

更改完該對話框中的訊息後,ODBC管理器將更新註冊訊息。

26.1.9.3. 在Unix平台上配置MyODBC DSN

Unix平台上,可以直接在odbc.ini檔案中配置DSN條目。這裡給出了1個典型的odbc.ini檔案,在該檔案中,分別將myodbc和myodbc3配置為MyODBC 2.50和MyODBC 3.51的DSN名稱:

;
;  odbc.ini對MyODBC和MyODBC 3.51驅動程式的配置
;

[ODBC Data Sources]
myodbc      = MyODBC 2.50 Driver DSN
myodbc3     = MyODBC 3.51 Driver DSN

[myodbc]
Driver       = /usr/local/lib/libmyodbc.so
Description  = MyODBC 2.50 Driver DSN
SERVER       = localhost
PORT         =
USER         = root
Password     =
Database     = test
OPTION       = 3
SOCKET       =

[myodbc3]
Driver       = /usr/local/lib/libmyodbc3.so
Description  = MyODBC 3.51 Driver DSN
SERVER       = localhost
PORT         =
USER         = root
Password     =
Database     = test
OPTION       = 3
SOCKET       =

[Default]
Driver       = /usr/local/lib/libmyodbc3.so
Description  = MyODBC 3.51 Driver DSN
SERVER       = localhost
PORT         =
USER         = root
Password     =
Database     = test
OPTION       = 3
SOCKET       =

關於可提供連接參數的清單,請參見26.1.9.4節,「連接參數」

註釋: 如果您正在使用unixODBC,可使用下述工具設置DSN:

·         ODBCConfig GUI tool(HOWTO: ODBCConfig)

·         odbcinst

在某些情況下使用unixODBC,可能會出現下述錯誤:

Data source name not found and no default driver specified(數據源名不存在,未指定預設驅動程式)

如果出現該情況,請確認ODBCINIODBCSYSINI環境變數指向正確的odbc.ini檔案。例如,如果您的odbc.ini檔案位於目錄「/usr/local/etc下,可將環境變數設為:

export ODBCINI=/usr/local/etc/odbc.ini
export ODBCSYSINI=/usr/local/etc

26.1.9.4. 連接參數

您可以在ODBC.INI檔案的[Data Source Name](數據源名)部分、或通過SQLDriverConnect() call的InConnectionString參量為MyODBC指定下述參數

參數

預設值

註釋

user

ODBC (on Windows)

用於連結至MySQL的帳號。

server

localhost

MySQL伺服器的主機名。

database

 

預設資料庫。

option

0

指定MyODBC工作方式的選項。參見下面。

port

3306

如果伺服器不是本地主機將要使用的TCP/IP端口。

stmt

 

連接至MySQL時將要執行的語句。

password

 

伺服器上用戶帳號的密碼。

socket

 

當伺服器是本地主機是將要連接的Unix套接字檔案或Windows命名管道。

選項參量用於通知MyODBC:客戶端不是100% ODBC兼容的。在Windows平台下,正常情況下,應通過切換連接屏幕上的復選框選擇選項,但也能在選項參量中選擇它們。下述選項是按照它們在MyODBC連接屏幕上顯示的順序排列的:

描述

1

客戶端無法處理,MyODBC返回列的實際寬度。

2

客戶端無法處理,MyODBC返回受影響行的真值。如果設置了該標誌,MySQL將返回「發現的行」取而代之。MySQL的版本必須是3.21.14或更高版本,該功能才能生效。

4

c:\myodbc.log中生成調試日誌。它與將MYSQL_DEBUG=d:t:O,c::\myodbc.log放到AUTOEXEC.BAT中的效果相同(在Unix平台下,該檔案是/tmp/myodbc.log)。

8

不為結果和參數設置任何訊息報限制。

16

即使驅動程式可能會給出提示,對出現的問題不予提示。

32

允許或禁止動態光標支援。(在MyODBC 2.50中不允許)。

64

db_name.tbl_name.col_name中忽略資料庫名的使用。

128

強制使用ODBC管理器光標(實驗性)。

256

禁止使用延伸取數據(實驗性)。

512

CHAR列填充為全列寬。

1024

SQLDescribeCol()返回完全合格的列名。

2048

使用壓縮客戶端/伺服器協議。

4096

通知伺服器忽略函數名之後和「(」之前的空格(PowerBuilder要求這樣)。這會使所有的函數名成為關鍵字。

8192

用命名管道連結至運行在NT環境下的mysqld伺服器。

16384

LONGLONG列更改為INT列(某些應用程式不能處理LONGLONG列)

32768

SQLTables返回作為Table_qualifierTable_owner的用戶(實驗性)。

65536

my.cnf的[client][odbc]組讀取參數。

131072

增加一些額外檢查(不應需要之,但)。

262144

禁止事務。

524288

允許將查詢記錄到c:\myodbc.sql(/tmp/myodbc.sql)檔案。(僅在調試模式下才能啟用)。

1048576

不要驅動中的結果進行緩衝處理,而應從伺服器讀取「mysql_use_result()」。僅對正向光標才能起作用。當您不希望緩衝處理整個結果集時,對於大資料表處理,該選項十分重要。

2097152

強制使用正向光標類型。在應用程式設置了預設靜態/動態光標類型的情況下,如果希望驅動程式使用非緩衝結果集,那麼該選項能夠保證正向光標的行為。

要想選擇多個選項,可將它們的值加在一起。例如,將選項設置為12(4+8),就能獲得調試功能,但沒有訊息包限制。

預設的myodbc3.dll是為最佳化性能而編譯的。如果希望調試MyODBC 3.51(例如,啟用跟蹤功能),應使用myodbc3d.dll。要想安裝該檔案,請拷貝myodbc3d.dll,使之覆蓋已安裝的myodbc3.dll檔案。一旦完成了調試操作,務必恢復至驅動DLL的發佈版本,這是因為調試版本可能會導致性能問題。注意,在MyODBC 3.51.07至3.51.11中未包含myodbc3d.dll。如果您正在使用這些版本中的一個,應從之前的版本(例如3.51.06)拷貝該DLL檔案。

對於MyODBC 2.50,採用了myodbc.dll和myodbcd.dll取而代之。

在下面的資料表各中,給出了針對各種配置的推薦選項值:

配置

選項值

Microsoft Access

3

Microsoft Visual Basic

3

具有很多行的大資料表

2049

驅動跟蹤生成(調試模式)

4

查詢日誌生成(調試模式)

524288

生成驅動跟蹤和查詢日誌(調試模式)

524292

具有非緩衝結果的大資料表

3145731

26.1.9.5. 沒有預定義DSN下的連接

是。通過指定DRIVER名稱字段,可使用SQLDriverConnect連接到MySQL伺服器。下面給出了使用DSN-Less連接的MyODBC連接字串:

對於MyODBC 2.50:

ConnectionString = "DRIVER={MySQL};\
                  SERVER=localhost;\
                  DATABASE=test;\
                  USER=venu;\
                  PASSWORD=venu;\
                  OPTION=3;"

對於MyODBC 3.51:

ConnectionString = "DRIVER={MySQL ODBC 3.51 Driver};\
                  SERVER=localhost;\
                  DATABASE=test;\
                  USER=venu;\
                  PASSWORD=venu;\
                  OPTION=3;"

如果您使用的編程語言會將後跟空格的反斜槓轉換為空格,最好將連接字串指定為單個長字串,或使用不會在其中新增空格的多個字串串接。例如:

ConnectionString = "DRIVER={MySQL ODBC 3.51 Driver};"
                  "SERVER=localhost;"
                  "DATABASE=test;"
                  "USER=venu;"
                  "PASSWORD=venu;"
                  "OPTION=3;"

關於可提供連接參數的清單,請參見26.1.9.4節,「連接參數」

26.1.9.6. 建立從系統A到系統B的遠程連接

如果您打算使用myusermypassword作為帳號和密碼從系統B連接到系統A,可參考下面給出的簡單步驟。

在系統A上,執行下述步驟:

1.    啟動MySQL伺服器。

2.    使用GRANT建立帳號為myuser的帳號,該帳號可使用密碼myuser從系統B建立連接。

3.             GRANT ALL ON *.* to 'myuser'@'B' IDENTIFIED BY 'mypassword';

4.    GRANT語句為用戶myuser授予了使用密碼mypassword從系統B進行連接的所有權限。要想執行該語句,必須在系統A上擁有根用戶權限,或是具有恰當權限的另一用戶。關於MySQL權限的更多訊息,請參見5.8節,「MySQL用戶帳號管理」

在系統B上,執行下述步驟:

1.    使用下述連接參數配置MyODBC DSN:

2.           DSN            = remote_test
3.           SERVER or HOST = A (or IP address of system A)
4.           DATABASE       = test (The default database or an appropriate one)
5.           USER           = myuser
6.           PASSWORD       = mypassword

關於建立DSN-less連接的更多訊息,請參見26.1.9.5節,「沒有預定義DSN下的連接」

7.    使用Ping命令或其它方式檢查是否能從系統B訪問系統A。如果無法訪問系統A,請檢查網絡或Internet連接,或與您的系統管理員聯繫。

8.    嘗試使用DSN=remote_test進行連接。如果失敗,請跟蹤查詢MyODBC日誌,並根據日誌給出的錯誤訊息採取進一步的步驟。如果需要進一步幫助,請發送詳細的電子郵件至myodbc@lists.mysql.com

在下述站點,您可以找到關於如何完成該操作的簡單示範:http://www.phphelp.com/tutorial/using-myodbc-to-connect-to-a-remote-database.html.

26.1.9.7. 獲取ODBC跟蹤檔案

如果遇到與MyODBC有關的困難或問題,首先應使用ODBC管理器和MyODBC生成一份日誌檔案(請求來自ODBC ADMIN的日誌時獲得的日誌檔案)。

要想通過驅動管理器獲得ODBC跟蹤檔案,可採取下述步驟:

·         打開ODBC數據源管理器:

1.    點擊「開始」,將指針指向「設置」,然後點擊「控制面板」。

2.    在運行Microsoft Windows 2000、XP或2003的計算機上,雙擊「管理工具」,然後雙擊「數據源」(ODBC),如下圖所示。

ODBC Data Sources
                  Icon

在運行早期Microsoft Windows版本的計算機上,雙擊「控制面板」中的32位ODBC或ODBC。

3.    打開ODBC數據源管理器對話框,如下圖所示:

ODBC Data Source
                  Administrator Dialog

4.    點擊「幫助」以瞭解ODBC數據源管理器對話框各選項卡的詳細訊息。

·         啟用跟蹤選項 對於Windows和Unix平台,該步驟不同。

要想在Windows平台上啟用跟蹤選項:

1.    通過「ODBC數據源管理器」對話框的「跟蹤」選項卡,可對跟蹤ODBC函數的方式進行配置。

2.    從「跟蹤」選項卡激活了跟蹤功能後,驅動管理器會對後續運行的所有應用程式的ODBC函數使用進行跟蹤。

3.    激活跟蹤功能前所運行應用程式的ODBC函數使用不會被記錄。ODBC函數使用將被記錄在您指定的日誌檔案中。

4.    點擊「現在停止跟蹤」後,跟蹤功能將停止。請記住,啟動跟蹤功能後,日誌檔案將不斷增大,而且跟蹤功能會影響所有ODBC應用程式的性能。

ODBC Tracing
                  Tab

要想在Unix平台上啟用跟蹤選項:

5.    在Unix平台上,需要在ODBC.INI檔案中明確設置跟蹤選項。

使用TraceFile和odbc.ini中的Trace(跟蹤)參數打開或關閉跟蹤功能,如下所示:

TraceFile  = /tmp/odbc.trace
Trace      = 1

TraceFile指明了跟蹤檔案的名稱和完整路徑,將Trace(跟蹤)設為ONOFF。也可以使用「1」或「Yes」資料表示ON,以及「0」或「No」資料表示OFF。如果正在使用unixODBC的ODBCConfig,然後遵照HOWTO-ODBCConfig中介紹的關於跟蹤unixODBC使用的指示說明。

要想生成MyODBC日誌,可採取下述步驟:

6.    確保您所使用的是驅動程式調試DLL(對於MyODBC 3.51,它是myodbc3d.dll而不是myodbc3.dll,對於MyODBC 2.50,它是myodbcd.dll)。

最簡單的方法是從MyODBC 3.51分發版找到myodbc3d.dll(或myodbcd.dll),並用其覆蓋myodbc3.dll(或myodbc.dll),該檔案通常位於C:\windows\system32C:\winnt\system32目錄下。注意,完成測試後,您或許希望恢復舊的myodbc.dll檔案,這是因為它比myodbc3d.dll(或myodbcd.dll)快很多,因此,請保存原始DLL的備份。

7.      在「MyODBC連接/配置」屏幕上啟用「跟蹤MyODBC」選項。日誌將被寫入檔案C:\myodbc.log。當您返回上述屏幕時,如果您設置的跟蹤選項未被記住,表明您正在使用的是myodbcd.dll驅動(參見前面的介紹)。在Linux平台上,或您使用的是DSN-Less連接,需在連接字串中提供「OPTION=4

8.    啟動應用程式,並嘗試著使其出現問題。然後檢查MyODBC跟蹤檔案,找出可能出錯的地方。

如果發現某些事項出錯,請發送電子郵件至myodbc@lists.mysql.com(或support@mysql.com,如果有與MySQL AB簽訂的支援合同),簡要描述出現的問題,並提供下述額外訊息:

o        MyODBC版本

o        ODBC驅動管理器的類型和版本

o        MySQL伺服器的版本

o        驅動管理器的ODBC跟蹤

o        來自MyODBC驅動的MyODBC日誌檔案

o        簡單的可複製示範

請記住,您提供給我們的訊息越多,我們更正問題的機會就越大。

此外,在提供問題訊息前,請檢查MyODBC郵件列資料表(http://lists.mysql.com/)。

26.1.9.8. 用MyODBC測試的應用程式

使用下述應用程式測試了MyODBC:

如果您知道能夠與MyODBC一起工作的其他應用程式,請以電子郵件的方式指明它:myodbc@lists.mysql.com

26.1.9.9. 已知的能與MyODBC一起工作的程式

大多數程式均能與MyODBC一起工作,對上面所列的每一程式,我們自己進行了測試,或得到用戶的確認。很多介紹中均給出了您可能會遇到問題的描述。

·         程式

註釋

·         Access

要想使Access工作:

o        如果您正在使用Access 2000,應從下述地址獲取並安裝最新的(2.6版或更高)Microsoft MDAC(Microsoft數據訪問組件),http://www.microsoft.com/data/。它更正了Access在將數據導出至MySQL時存在的一個問題,未指定資料表名和列名。另一種解決該問題的方法是,升級到MyODBC 2.50.33和MySQL 3.23.x, 它們共同提供了避免該問題的一種方式。

此外,您還應獲取並應用Microsoft Jet 4.0 Service Pack 5 (SP5),可在下述地址找到它:http://support.microsoft.com/default.aspx?scid=kb;EN-US;q239114。它修正了某些情況下在Access中列被標注為「#DELETED#的問題。

註釋: 如果您正使用MySQL 3.22,必須安裝MDAC補丁,並使用MyODBC 2.50.32或2.50.34或更高版本以解決該問題。

o        對於所有版本的Access,應啟用「MyODBC返回匹配行」選項。對於Access 2.0,還應額外啟用「模擬ODBC 1.0選項

o        在希望能夠更新的所有資料表中,均應有時間戳。為了獲得最大的可移植性,在列聲明中不要使用長度規範。也就是說,應使用TIMESTAMP,而不是TIMESTAMP(n), n < 14。

o        在資料表中應有1個主鍵。如不然,新的或更新的行可能會顯示為「#DELETED#」。

o        僅應使用DOUBLE浮點字段。與單精度浮點進行比較時,Access將失敗。其徵兆是新的或更新的行可能會顯示為「#DELETED#」,或無法找到或更新行。

o        如果您正使用MyODBC來連結到有BIGINT列的資料表,結果會顯示為「#DELETED」。排除它的解決方案是:

§         有1個以TIMESTAMP作為數據類型的虛擬列。

§         在「ODBC DSN管理器」的連接對話框中選擇「將BIGINT列更改為INT」選項。

§         刪除與Access的資料表連結,並重新建立它。

舊記錄仍將顯示為「#DELETED#」,但新增/更新的記錄會恰當顯示。

o        新增了TIMESTAMP列後,另一位用戶更改了數據,如果錯誤依舊出現,下述技巧或許有所幫助:

不要使用資料表數據資料表視圖。取而代之的是,從您希望使用的資料表建立一個資料表單,並使用資料表單數據資料表視圖。應將TIMESTAM列的DefaultValue屬性設置為NOW()。在視圖中隱藏TIMESTAMP列或許是個好主意,這樣就不會使您的用戶感到迷惑。

o        在某些情況下,Access可能會生成MySQL無法理解的SQL語句。可通過在Access菜單中選擇「Query|SQLSpecific|Pass-Through」來更正該問題。

o        在NT平台上,Access會將BLOB列通報為OLE OBJECTS(OLE對像)。如果您打算用MEMO列取而代之,應使用ALTER TABLE將BLOB列更改為TEXT。

o        Access無法在任何時候均恰當處理DATE列。如果遇到這類問題,請將列更改為DATETIME

o        如果在Access中存在定義為BYTE的列,Access會視圖將其導出為TINYINT而不是TINYINT UNSIGNED。如果列中的值大於127,將出現問題。

·         ADO

使用ADO API和MyODBC進行編碼時,需要注意某些不被MySQL伺服器支援的預設屬性。例如,對於RecordCount屬性,如果將CursorLocation屬性用作adUseServer,將返回結果-1要想獲得正確的值,需要將該屬性設置為adUseClient,如下面給出的VB代碼示範所示:

Dim myconn As New ADODB.Connection
Dim myrs As New Recordset
Dim mySQL As String
Dim myrows As Long
 
myconn.Open "DSN=MyODBCsample"
mySQL = "SELECT * from user"
myrs.Source = mySQL
Set myrs.ActiveConnection = myconn
myrs.CursorLocation = adUseClient
myrs.Open
myrows = myrs.RecordCount
 
myrs.Close
myconn.Close

另一種處理方式是,對類似查詢使用SELECT COUNT(*)語句以獲取正確的行計數。

·         主動伺服器頁(ASP)

應選擇「返回匹配行」選項。

·         BDE應用程式

要想使這類應用程式工作,應選擇「不最佳化列寬度並返回匹配行」選項。

·         Borland Builder 4

開始查詢時,可使用Active屬性或Open方法。注意,Active將通過自動發出SELECT * FROM ...查詢開始。如果資料表很大,這不是什麼好事。

·         ColdFusion(在Unix平台上)

下述訊息取自ColdFusion文檔:

使用下述訊息來配置用於Linux的ColdFusion伺服器,以便使用針對MySQL數據源的unixODBC驅動和MyODBC。Allaire已證明,MyODBC 2.50.26能夠與MySQL 3.22.27以及用於Linux的ColdFusion一起工作。(任何較新的版本也應能正確工作)。您可以在網站http://dev.mysql.com/downloads/connector/odbc/上下載MyODBC。

通過ColdFusion 4.5.1版,可以使用「ColdFusion管理器」來新增MySQL數據源。但是,驅動程式未包含在ColdFusion 4.5.1版中。在MySQL驅動程式出現在ODBC數據源下拉列資料表之前,必須建立MyODBC驅動程式,並將其拷貝到/opt/coldfusion/lib/libmyodbc.so

在Contrib目錄下包含程式mydsn-xxx.zip,使用它,對於Coldfusion應用程式,可建立並刪除用於MyODBC驅動的DSN註冊檔案。

·         DataJunction

應對其進行更改,使之輸出VARCHAR而不是ENUM,因為其導出ENUM的方式會造成MySQL問題。

·         Excel

工作。一些提示:

o        如果遇到日期方面的問題,請使用CONCAT()函數,將其選擇為字串。例如:

o                     SELECT CONCAT(rise_time), CONCAT(set_time)
o                       FROM sunrise_sunset;

採用該方式以字串提取的值應能被Excel97正確識別為時間值。

在本例中,CONCAT()的目的是讓ODBC認為列是字串類型如果沒有CONCAT(),ODBC會將列視為時間類型,Excel無法理解它。

注意,Excel存在1個問題,這是因為它會自動將字串轉換為時間。如果源是文本檔案,不存在問題,但當源是通報各列準確類型的ODBC連接時,將出現問題。

·         Word

要想將數據從MySQL提取到Word/Excel文檔,需要使用MyODBC驅動程式以及「Microsoft查詢幫助」插件。

例如,用含有兩列文本的資料表建立1個資料庫:

o        使用mysql客戶端命令行工具插入行。

o        使用ODBC管理器建立1個DSN檔案,例如,針對剛建立資料庫的「my」。

o        打開Word應用程式。

o        建立1個新的空白文檔。

o        在資料庫工具欄上,按「插入資料庫」按鈕。

o        按「獲取數據」按鈕。

o        在「獲取數據」屏幕右側,按「Ms Query」按鈕。

o        在「Ms Query」中使用「my DSN」檔案建立1個新數據源。

o        選擇新查詢。

o        選擇打算使用的列。

o        如果願意,建立1個過濾器。

o        如果願意,建立1個分類。

o        選擇「將數據返回到Microsoft Word」。

o        點擊「完成」。

o        點擊「插入數據」並選擇記錄。

o        點擊OK,在您的Word文檔中將看到插入的行。

·         odbcadmin

ODBC的測試程式。

·         Delphi

必須使用BDE 3.2版或更新的版本。連接到MySQL時,選擇「不最佳化列寬度」選項。

此外,這裡給出了一些可能有用的Delphi代碼,這些代碼可設置為MyODBC設置ODBC條目和BDE條目。BDE條目要求用到「BDE別名編輯器」,它位於靠近您的「Delphi Super Page」上,可自由拖動。(下述內容由Bryan Brunton <bryan@flesherfab.com>提供):

fReg:= TRegistry.Create;
fReg.OpenKey('\Software\ODBC\ODBC.INI\DocumentsFab', True);
fReg.WriteString('Database', 'Documents');
fReg.WriteString('Description', ' ');
fReg.WriteString('Driver', 'C:\WINNT\System32\myodbc.dll');
fReg.WriteString('Flag', '1');
fReg.WriteString('Password', '');
fReg.WriteString('Port', ' ');
fReg.WriteString('Server', 'xmark');
fReg.WriteString('User', 'winuser');
fReg.OpenKey('\Software\ODBC\ODBC.INI\ODBC Data Sources', True);
fReg.WriteString('DocumentsFab', 'MySQL');
fReg.CloseKey;
fReg.Free;
 
Memo1.Lines.Add('DATABASE NAME=');
Memo1.Lines.Add('USER NAME=');
Memo1.Lines.Add('ODBC DSN=DocumentsFab');
Memo1.Lines.Add('OPEN MODE=READ/WRITE');
Memo1.Lines.Add('BATCH COUNT=200');
Memo1.Lines.Add('LANGDRIVER=');
Memo1.Lines.Add('MAX ROWS=-1');
Memo1.Lines.Add('SCHEMA CACHE DIR=');
Memo1.Lines.Add('SCHEMA CACHE SIZE=8');
Memo1.Lines.Add('SCHEMA CACHE TIME=-1');
Memo1.Lines.Add('SQLPASSTHRU MODE=SHARED AUTOCOMMIT');
Memo1.Lines.Add('SQLQRYMODE=');
Memo1.Lines.Add('ENABLE SCHEMA CACHE=FALSE');
Memo1.Lines.Add('ENABLE BCD=FALSE');
Memo1.Lines.Add('ROWSET SIZE=20');
Memo1.Lines.Add('BLOBS TO CACHE=64');
Memo1.Lines.Add('BLOB SIZE=32');
 
AliasEditor.Add('DocumentsFab','MySQL',Memo1.Lines);

·         C++ Builder

用BDE 3.0版進行了測試。目前已知的唯一問題是,更改資料表方案時,查詢字段不更新。然而,BDE看上去不會識別主鍵,它僅是名為PRIMARY的索引,儘管這談不上是問題。

·         Vision

應選擇「返回匹配行」選項。

·         Visual Basic

要想更新資料表,必須為資料表定義主鍵。

帶有ADO的Visual Basic不能處理大整數。這意味著某些查詢(如SHOW PROCESSLIST等)不會正確工作。更正方法是,在ODBC連接字串中使用OPTION=16384,或在MyODBC連接屏幕上選擇「將BIGINT列更改為INT」選項。或許,您也希望選擇「返回匹配行」選項。

·         VisualInterDev

如果在結果中有BIGINT,可能會出現錯誤[Microsoft][ODBC Driver Manager]驅動程式不支持該參數。請MyODBC連接屏幕上選擇「將BIGINT列更改為INT」選項。

·         Visual Objects

應選擇「不最佳化列寬度」選項。

·         MS Visio Enterprise 2000

通過MyODBC(2.50.37或更高版本),通過連接MS Vision Enterprise 2000和MySQL,並使用Visio的逆向工程師功能,我們建立了資料庫模型,使用它來檢索關於DB的訊息(Visio顯示了所有的列定義、主鍵、索引等)。此外,我們還通過指定Visio中的新資料表進行了測試,並通過MyODBC將其導出至MySQL。

26.1.10. 與MyODBC連接相關的事宜

在本節中,回答了與MyODBC連接有關的問題。

26.1.10.1. 配置MyODBC DSN時,出現不能加載翻譯器或設置庫錯誤

更多訊息,請參見MS知識庫文章(Q260558)。此外,請確認在您的系統目錄下有最新的有效ctl3d32.dll檔案。

26.1.10.2. 連接時,出現拒絕訪問錯誤

請參見5.7.8節,「拒絕訪問錯誤的原因

26.1.10.3. INFO:關於ODBC連接池

關於連接池方面的訊息,請參閱下述文檔: http://support.microsoft.com/default.aspx?scid=kb;EN-US;q169470

26.1.11. MyODBC和Microsoft Access

在本節中,回答了與MyODBC和Microsoft Access有關的問題。

26.1.11.1. 如何設置Microsoft Access,使之能夠與使用MyODBC的MySQL一起工作?

要想使Microsoft Access能夠與MyODBC一起工作,在您的客戶端PC上必須完成下述操作。

1.    如果您正在使用Access 2000,應從下述地址獲取並安裝最新的(2.6版或更高)Microsoft MDAC(Microsoft數據訪問組件),http://www.microsoft.com/data/。它更正了Access在將數據導出至MySQL時存在的一個問題,未指定資料表名和列名。另一種解決該問題的方法是,升級到MyODBC 2.50.33和MySQL 3.23.x, 它們共同提供了避免該問題的一種方式。

此外,您還應獲取並應用Microsoft Jet 4.0 Service Pack 5 (SP5),可在下述地址找到它:http://support.microsoft.com/default.aspx?scid=kb;EN-US;q239114。它修正了某些情況下在Access中列被標注為「#DELETED#的問題。

註釋: 如果您正使用MySQL 3.22,必須安裝MDAC補丁,並使用MyODBC 2.50.32或2.50.34或更高版本以解決該問題。

2.    安裝最新版MySQL,http://dev.mysql.com/downloads/

3.    安裝最新版MyODBC 3.51或2.50,http://dev.mysql.com/downloads/connector/odbc/

4.    對於所有版本的Access,應啟用「MyODBC返回匹配行」選項。

5.    通過MyODBC,將Access用作MySQL伺服器的前端程式。

26.1.11.2. 如何將資料表或查詢從Access導出到MySQL?

除非已安裝了MyODBC,否則不能將資料表或查詢導出到MySQL。

要想將資料表從Access導入MySQL,請遵循下述說明:

1.    打開Access資料庫或Access項目時,出現「資料庫」窗口。其中顯示了用於建立新資料庫對像和打開已有對象的快捷方式。

Access Database

2.    點擊打算導出的資料表名或查詢名,然後在「檔案」菜單中選擇「導出」。

3.    在「導出對像類型對像名」對話框中,在「另存為類型」框中,選擇ODBC資料庫(),如下圖所示

Selecting an ODBC Database

4.    在「導出」對話框中,輸入檔案名(或使用建議的檔案名),然後選擇OK。

5.    顯示「選擇數據源」對話框,其中列出了為計算機上已安裝的各ODBC驅動定義的數據源。點擊「檔案數據源」或「機器數據源」選項卡,然後雙擊打算導出至的MyODBC或MyODBC 3.51數據源。關於為MyODBC定義新數據源的方法,請參見26.1.9.2節,「在Windows上配置MyODBC DSN」

Microsoft Access通過該數據源連接至MySQL伺服器,並導出新的資料表和/或數據。

26.1.11.3. 如何導入MySQL資料庫資料表或將其連結到Access?

除非已安裝了MyODBC,否則不能將資料表或查詢導出到MySQL資料庫。

要想將資料表從MySQL導入或連結到Access,請採取下述步驟:

1.    打開資料庫,或切換到「資料庫」窗口以打開資料庫。

2.    要想導入資料表,在「檔案」菜單上,將鼠標指針指向「獲取外部數據」,然後點擊「導入」。要想連結資料表,在「檔案」菜單上,將鼠標指針指向「獲取外部數據」,然後點擊「連結資料表」。

3.    在「導入」(或「連結」)對話框中,在「檔案類型」框中選擇「ODBC Databases ()」。在「選擇數據源」對話框中,列出了定義的數據源。顯示「選擇數據源」對話框,其中列出了為安裝在計算機上的任何ODBC驅動定義的數據源。點擊「檔案數據源」或「機器數據源」選項卡,然後雙擊打算導出至的MyODBC或MyODBC 3.51數據源。關於為MyODBC或MyODBC 3.51驅動定義新數據源的方法,請參見26.1.9.2節,「在Windows上配置MyODBC DSN」

4.    如果所選的數據源要求登錄,請輸入登錄ID和密碼(可能還需要額外訊息),然後點擊OK。

5.    Microsoft Access通過ODBC數據源連接到MySQL伺服器,並顯示可導入或連結的資料表清單。

6.    點擊希望導入或連結的每個資料表,然後點擊OK。如果您正在連結1個資料表,但它沒有唯一識別各條記錄的索引,Microsoft Access將顯示連結資料表中的字段列資料表。點擊能唯一標識各記錄的字段或字段組合,然後點擊OK。

26.1.11.4. 連結資料表的結構或位置已改變,我能看到連結資料表中的這些變化嗎?

是。當連結資料表的結構或位置發生變化時,可採取下述步驟查看或刷新連結。「連結資料表管理器」列出了當前連結的所有資料表的路徑。

要想查看或刷新連結:

1.    打開包含資料表連結的資料庫。

2.    在「工具」菜單上,指向「加載項」(在Access 2000或更新版本中為「資料庫實用工具」),然後點擊「連結資料表管理器」。

3.    選中打算刷新連結的資料表的復選框。

4.    點擊OK,刷新連結。

Microsoft Access將確認成功的刷新操作,或者,如果未找到資料表,將顯示「選擇<table name>新位置」對話框,在該對話框中,可指定資料表的新位置。如果您所選擇的數個資料表已被移至您所指定的新位置,連結資料表管理器將針對所有所選的資料表搜索該位置,並一次性地更新所有連結。

要想更改連結資料表集合的路徑:

1.    打開包含資料表連結的資料庫。

2.    在「工具」菜單上,指向「加載項」(在Access 2000或更新版本中為「資料庫實用工具」),然後點擊「連結資料表管理器」。

3.    選中「對新位置始終提示」復選框。

4.    選中打算更改連結的資料表的復選框,然後點擊OK。

5.    在「選擇<table name>新位置」對話框中,指定新位置,點擊「打開」,然後點擊OK。

26.1.11.5. 當我在連結資料表中插入記錄或更新其中的記錄時,遇到「#DELETED#」

如果在Access中插入或更新的記錄顯示為「#DELETED#」:

·         如果您正在使用Access 2000,應從下述地址獲取並安裝最新的(2.6版或更高)Microsoft MDAC(Microsoft數據訪問組件),http://www.microsoft.com/data/。它更正了Access在將數據導出至MySQL時存在的一個問題,未指定資料表名和列名。另一種解決該問題的方法是,升級到MyODBC 2.50.33和MySQL 3.23.x, 它們共同提供了避免該問題的一種方式。

此外,您還應獲取並應用Microsoft Jet 4.0 Service Pack 5 (SP5),可在下述地址找到它:http://support.microsoft.com/default.aspx?scid=kb;EN-US;q239114。它修正了某些情況下在Access中列被標注為「#DELETED#的問題。

註釋: 如果您正使用MySQL 3.22,必須安裝MDAC補丁,並使用MyODBC 2.50.32或2.50.34或更高版本以解決該問題。

·         對於所有版本的Access,應啟用「MyODBC返回匹配行」選項。對於Access 2.0,還應額外啟用「模擬ODBC 1.0選項

·         在希望能夠更新的所有資料表中,均應有時間戳。為了獲得最大的可移植性,在列聲明中不要使用長度規範。也就是說,應使用TIMESTAMP,而不是TIMESTAMP(n), n < 14。

·         在資料表中應有1個主鍵。如不然,新的或更新的行可能會顯示為「#DELETED#」。

·         僅應使用DOUBLE浮點字段。與單精度浮點進行比較時,Access將失敗。其徵兆是新的或更新的行可能會顯示為「#DELETED#」,或無法找到或更新行。

·         如果您正使用MyODBC來連結到有BIGINT列的資料表,結果會顯示為「#DELETED」。排除它的解決方案是:

o        有1個以TIMESTAMP作為數據類型的虛擬列。

o        在「ODBC DSN管理器」的連接對話框中選擇「將BIGINT列更改為INT」選項。

o        刪除與Access的資料表連結,並重新建立它。

舊記錄仍將顯示為「#DELETED#」,但新增/更新的記錄會恰當顯示。

26.1.11.6. 如何處理寫衝突或行位置錯誤?

如果看到下述錯誤,請在「DSN配置」對話框中選擇「返回匹配行」選項,或將連接參數指定為「OPTION=2
寫衝突。另一用戶更改了您的數據。
 
無法找到需更新行的位置。自上次讀取操作以來,某些值可能已被改變。

26.1.11.7. 無論何時,當我從Access 97導出資料表時,出現陌生的語法錯誤

對於Access 97,這是件奇怪的事宜,但在Access 2000或2002中並未出現。將MyODBC升級至MyODBC 3.51.02或以上,可以克服該問題。

26.1.11.8. 編輯記錄時,Access返回「另一用戶更改了您修改的記錄」

對於某些程式,可能會出現該錯誤: 另一用戶更改了您所修改的記錄。在大多數情況下,可通過下述措施解決該問題:

·         如果主鍵不存在,為資料表新增1個主鍵。

·         如果時間戳不存在,新增1個時間戳列。

·         僅應使用DOUBLE浮點字段。與單精度浮點值比較時,某些程式會出錯。

如果這些措施未能解決問題,首先應從ODBC管理器生成1個日誌檔案(請求來自ODBC ADMIN的日誌時獲得的日誌檔案),以及1個MyODBC日誌,使用它們找出出錯的原因。具體介紹,請參見26.1.9.7節,「獲取ODBC跟蹤檔案」

26.1.11.9. 如何在Access中俘獲ODBC登錄錯誤消息?

請閱讀「如何在Access中俘獲ODBC登錄錯誤消息」,http://support.microsoft.com/support/kb/articles/Q124/9/01.asp?LN=EN-US&SD=gn&FR=0%3CP%3E

26.1.11.10. 如何最佳化Access與MyODBC一起工作的性能?

26.1.11.11. 我有很長的資料表,MyODBC訪問這些Access資料表的最佳配置是什麼?

如果在Access中有很大(長)的資料表,可能需要相當長的時間才能打開。或者,也可能是虛擬內存較低的情況下運行,最終導致ODBC查詢失敗錯誤,並無法打開資料表。為了解決該問題,可選擇下述選項:

·         返回匹配行(2)

·         允許BIG結果(8)

這樣可將值增加到10(OPTION=10)。

26.1.11.12. 如何為ODBC連接設置QueryTimeout值?

請參閱「為ODBC連接設置QueryTimeout值」,http://support.microsoft.com/default.aspx?scid=kb%3Ben-us%3B153756

26.1.11.13. INFO:用於Access和MySQL間導入/導出的工具

關於可用工具列資料表,請參閱轉換器一節。

26.1.12. MyODBC和Microsoft VBA及ASP

在本節中,回答了與Microsoft Visual Basic(ADO, DAO & RDO)和ASP一起使用MyODBC有關的問題。

26.1.12.1. 為什麼SELECT COUNT(*) FROM tbl_name返回錯誤?

這是因為COUNT(*)資料表達式返回了1個BIGINT,ADO不理解這個大值的含義。選擇「將BIGINT列更改為INT選項(選項值16384)。

26.1.12.2. 無論何時,當我使用AppendChunk()或GetChunk() ADO方法時,遇到錯誤「多步操作導致錯誤,請檢查每個狀態值」

將光標位置指定為adUseServer時,ADO的GetChunk()AppendChunk()方法不能按預期的方式工作。從另一方面上講,可使用adUseClient克服該問題。

http://www.dwam.net/iishelp/ado/docs/adomth02_4.htm上給出了一個簡單示範。

26.1.12.3. 在ADO中如何發現受特定SQL語句影響的總行數?

在ADO執行方法中使用RecordsAffected屬性。關於使用執行方法的更多訊息,請參見http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ado270/htm/mdmthcnnexecute.asp

26.1.12.4. 在Visual Basic中如何處理Blob數據?

下面給出了Mike Hillyer(m.hillyer@telusplanet.net)寫的一篇好文章,其中解釋了如何在ADO中通過MyODBC插入數據和/或從Blob列獲取數據的方法。MySQL BLOB列和Visual Basic 6

26.1.12.5. 如何將Visual Basic的數據類型映射到MySQL類型?

下面給出了Mike Hillyer(m.hillyer@telusplanet.net)的另一篇好文章。如何將Visual basic數據類型映射為MySQL類型

26.1.12.6. 示範:VB與ADO、DAO和RDO

下面給出了ADO、DAO和RDO與VB一起使用的用法示範:

·         ADO示範: 26.1.19節,「MyODBC與VB:ADO、DAO和RDO」

·         DAO示範: 26.1.19節,「MyODBC與VB:ADO、DAO和RDO」

·         RDO示範: 26.1.19節,「MyODBC與VB:ADO、DAO和RDO」

如果您有其他好的例子,或關於ADO/DAO/RDO的基本知識,請將詳情發送至myodbc@lists.mysql.com

26.1.12.7. ASP和MySQL以及MyODBC

關於如何使用MyODBC通過ASP訪問MySQL的更多訊息,請參閱下述文章:

·         使用MyODBC通過ASP訪問您的MySQL資料庫

·         ASP and MySQL at DWAM.NT

http://support.microsoft.com/default.aspx?scid=/Support/ActiveServer/faq/data/adofaq.asp中,給出了關於ASP的常見問題清單。

26.1.12.8. INFO:關於ActiveX數據對像(ADO)的常見問題

更多訊息,請參見ActiveX數據對像(ADO)常見問題

26.1.13. MyODBC和第三方ODBC工具

在本節中,回答了與MyODBC和各種ODBC相關工具有關的問題,如Microsoft Word、Excel和ColdFusion。

26.1.13.1. 如何將數據從MySQL提取到MS-Word/Excel文檔?

要想將數據從MySQL提取到Word/Excel文檔,需要使用MyODBC驅動程式以及「Microsoft查詢幫助」插件。

例如,用含有兩列文本的資料表建立1個資料庫:

·         使用mysql客戶端命令行工具插入行。

·         使用ODBC管理器建立1個DSN檔案,例如,針對剛建立資料庫的「my」。

·         打開Word應用程式。

·         建立1個新的空白文檔。

·         在資料庫工具欄上,按「插入資料庫」按鈕。

·         按「獲取數據」按鈕。

·         在「獲取數據」屏幕右側,按「Ms Query」按鈕。

·         在「Ms Query」中使用「my DSN」檔案建立1個新數據源。

·         選擇新查詢。

·         選擇打算使用的列。

·         如果願意,建立1個過濾器。

·         如果願意,建立1個分類。

·         選擇「將數據返回到Microsoft Word」。

·         點擊「完成」。

·         點擊「插入數據」並選擇記錄。

·         點擊OK,在您的Word文檔中將看到插入的行。

26.1.13.2. 使用MyODBC將資料表從MS DTS導出到MySQL時出現語法錯誤

這與當資料表由TEXT或VARCHAR數據類型構成時Access 97遇到的問題類似。通過將MyODBC驅動升級到3.51.02或更高版本,即可排除該錯誤。

26.1.13.3. 如何在Solaris平台上配置MySQL+MyODBC+unixODBC+ColdFusion

請參見MySQL ColdFusion unixODBC MyODBC和Solaris:如何成功

26.1.14. MyODBC通用功能

在本節中,回答了與MyODBC一般功能有關的問題。

26.1.14.1. 如何在ODBC中獲取AUTO_INCREMENT列的值

一個常見問題是,如何獲取從INSERT語句自動生成的ID的值。使用ODBC,您可以作與以下示範類似的任何事(假定「auto」為AUTO_INCREMENT字段):

INSERT INTO tbl (auto,text) VALUES(NULL,'text');
SELECT LAST_INSERT_ID();

或者,如果您僅打算將ID插入到另一資料表中,您可以:

INSERT INTO tbl (auto,text) VALUES(NULL,'text');
INSERT INTO tbl2 (id,text) VALUES(LAST_INSERT_ID(),'text');

請參見25.2.13.3節,「如何獲得上次插入行的唯一ID」

為了使某些ODBC應用程式(至少是Delphi和Access)獲得更好的性能,可使用下述查詢來找到新插入的行:

SELECT * FROM tbl WHERE auto IS NULL;

26.1.14.2. MyODBC支援動態光標類型嗎?

是。MyODBC 3.51支援動態光標類型以及正向和靜態特性。

由於性能方面的原因,在預設情況下,驅動程式不支援該特性。您可以啟用該特性,方法是,將連接選項標誌指定為「OPTION=32,或在DSN配置中選中「啟用動態光標」選項。

26.1.14.3. 導致事務無法啟用錯誤的原因是什麼?

當應用程式發出事務使用,但底層MySQL伺服器不支援事務或禁止事務時,驅動程式將返回該錯誤。

為了避免該問題,必須使用啟用了InnoDBBDB儲存引擎(或兩者)的伺服器,並使用這類資料表。從4.0版以後,預設情況下,MySQL伺服器均支援InnoDB。在BDB可用的平台上,MySQL-Max伺服器也支援BDB

此外,如果您的伺服器支援事務資料表類型(InnoDB和BDB),請確保在DSN配置中未設置「禁止事務」選項。

26.1.14.4. 導致無法找到光標錯誤的原因是什麼?

這是因為應用程式正在使用舊的MyODBC 2.50版本,不能通過SQLSetCursorName明確設置光標名稱。更正它的方法是升級到MyODBC 3.51版。

26.1.14.5. 我能與MyODBC 3.51一起使用MyODBC 2.50應用程式嗎?

是。如果您發現不能與MyODBC 3.51一起工作,但能與MyODBC 2.50一起工作的任何事項,請發送電子郵件至myodbc@lists.mysql.com

26.1.14.6. 我能使用MyODBC從.NET環境訪問MySQL嗎?

是。您可以使用odbc.net,通過MyODBC連接到MySQL。這裡給出了一些從VC.NET和VB.NET連接到MySQL的基本示範。

·         請參見26.1.20.1節,「ODBC.NET: CSHARP(C#)」

·         請參見26.1.20.2節,「ODBC.NET: VB」

這裡給出了Venu(MyODBC開發人員)撰寫的另一篇好文章研究.NET環境下的MySQL,其中,給出了所有的MySQL .NET接口以及一些有用的例子。

注意: 在與MyODBC一起使用ODBC.NET的過程中,在獲取空字串的同時(長度為0),將給出SQL_NO_DATA異常。從站點http://support.microsoft.com/default.aspx?scid=kb;EN-US;q319243,可獲取針對它的補丁。

26.1.14.7. MyODBC的性能為什麼很差,對於相對較小的查詢也會導致大量的磁盤動作?

MyODBC比其他ODBC驅動程式快很多。緩慢可能是因未使用下述選項造成的:

·         打開「ODBC跟蹤」選項。遵循這裡給出的指示說明,交叉檢查是否未啟用該選項。

ODBC Tracing
              Tab

如上圖所示,「ODBC數據源管理器」「跟蹤」選項卡的「何時跟蹤」選項應始終指向「現在開始跟蹤」,而不是「現在停止跟蹤」。

·         使用了驅動程式的調試版本。如果您正在使用驅動DLL的調試版本,也會使查詢處理變慢。您可以執行交叉檢查,通過驅動DLL屬性(在系統目錄下,右擊驅動DLL並點擊「屬性」)的「註釋」區,檢查DLL是否是調試版或發佈版,如下圖所示:

DLL Properties Dialog

·         啟用了「驅動跟蹤和查詢日誌」。即使您打算使用驅動程式的調試版(在生產環境下總應使用發佈版),也應確保禁止了「驅動跟蹤和查詢日誌」選項(OPTION=4,524288),如下圖所示:

MyODBC Options Dialog

26.1.15. 基本的MyODBC應用步驟

從MyODBC應用程式執行的與MySQL伺服器的交互包含以下操作:

·         配置MyODBC DSN。

·         連接到MySQL伺服器。

·         初始化操作。

·         執行SQL語句。

·         檢索結果。

·         執行事務。

·         中斷與伺服器的連接。

大多數應用程式均使用了這些步驟的某些變體。在下圖中,給出了基本的應用步驟:

MyODBC Programming Flowchart

26.1.16. MyODBC API引用

在本節中,概要介紹了按功能分類的ODBC子程式。

關於全部ODBC API參考,請參見ODBC程式員參考,http://msdn.microsoft.com/library/en-us/odbc/htm/odbcabout_this_manual.asp

應用程式可以使用SQLGetInfo函數來獲得關於MyODBC的一致性訊息。為了獲得驅動程式對特定函數的支援訊息,應用程式可使用SQLGetFunctions

註釋: 為了向後兼容,MyODBC 3.51驅動程式支援所有已不使用的函數。

在下面的資料表各中,按任務分組列出了MyODBC API使用:

連接到數據源:

函數名

MyODBC

MyODBC

一致性

目的

 

2.50

3.51

 

 

SQLAllocHandle

No

Yes

ISO 92

獲取環境、連接、語句或描述符句柄。

SQLConnect

Yes

Yes

ISO 92

按數據源名、用戶ID和密碼連接到特定驅動程式。

SQLDriverConnect

Yes

Yes

ODBC

通過連接字串,或驅動管理器和驅動顯示對話框發出的請求,連接到特定驅動程式。

SQLAllocEnv

Yes

Yes

Deprecated

獲得驅動程式分配的環境句柄。

SQLAllocConnect

Yes

Yes

Deprecated

獲取連接句柄。

獲取關於驅動程式和數據源的訊息:

函數名

MyODBC

MyODBC

一致性

目的

 

2.50

3.51

 

 

SQLDataSources

No

No

ISO 92

返回可用數據源的列資料表,由驅動管理器處理。

SQLDrivers

No

No

ODBC

返回已安裝驅動程式和器屬性的列資料表,由驅動管理器處理。

SQLGetInfo

Yes

Yes

ISO 92

返回關於特定驅動程式和數據源的訊息。

SQLGetFunctions

Yes

Yes

ISO 92

返回支援的驅動函數。

SQLGetTypeInfo

Yes

Yes

ISO 92

返回關於所支援數據類型的訊息。

設置並檢索驅動屬性:

函數名

MyODBC

MyODBC

一致性

目的

 

2.50

3.51

 

 

SQLSetConnectAttr

No

Yes

ISO 92

設置連接屬性。

SQLGetConnectAttr

No

Yes

ISO 92

返回連接屬性的值。

SQLSetConnectOption

Yes

Yes

Deprecated

設置連接選項。

SQLGetConnectOption

Yes

Yes

Deprecated

返回連接選項的值。

SQLSetEnvAttr

No

Yes

ISO 92

設置環境屬性。

SQLGetEnvAttr

No

Yes

ISO 92

返迴環境屬性的值。

SQLSetStmtAttr

No

Yes

ISO 92

設置語句屬性。

SQLGetStmtAttr

No

Yes

ISO 92

返回語句屬性的值。

SQLSetStmtOption

Yes

Yes

Deprecated

設置語句選項。

SQLGetStmtOption

Yes

Yes

Deprecated

返回語句選項的值。

準備SQL請求:

函數名

MyODBC

MyODBC

一致性

目的

 

2.50

3.51

 

 

SQLAllocStmt

Yes

Yes

Deprecated

分配語句句柄。

SQLPrepare

Yes

Yes

ISO 92

準備隨後執行的SQL語句。

SQLBindParameter

Yes

Yes

ODBC

為SQL語句中的參數分配儲存器。

SQLGetCursorName

Yes

Yes

ISO 92

返回與語句句柄相關的光標名。

SQLSetCursorName

Yes

Yes

ISO 92

指定光標名。

SQLSetScrollOptions

Yes

Yes

ODBC

設置控制光標行為的選項。

提交請求:

函數名

MyODBC

MyODBC

一致性

目的

 

2.50

3.51

 

 

SQLExecute

Yes

Yes

ISO 92

執行準備好的語句。

SQLExecDirect

Yes

Yes

ISO 92

執行語句。

SQLNativeSql

Yes

Yes

ODBC

返回由驅動程式翻譯的SQL語句的文本。

SQLDescribeParam

Yes

Yes

ODBC

返回語句中特定參數的描述。

SQLNumParams

Yes

Yes

ISO 92

返回語句中的參數數目。

SQLParamData

Yes

Yes

ISO 92

SQLPutData一起使用,以便在執行時提供參數。(對於長數據值很有用)。

SQLPutData

Yes

Yes

ISO 92

發送某一參數數據值的部分或全部。(對於長數據值很有用)。

檢索結果以及關於結果的訊息:

函數名

MyODBC

MyODBC

一致性

目的

 

2.50

3.51

 

 

SQLRowCount

Yes

Yes

ISO 92

返回插入、更新或刪除請求影響的行數。

SQLNumResultCols

Yes

Yes

ISO 92

返回結果集中的列數。

SQLDescribeCol

Yes

Yes

ISO 92

描述結果集中的列。

SQLColAttribute

No

Yes

ISO 92

描述結果集中的某1列的屬性。

SQLColAttributes

Yes

Yes

Deprecated

描述結果集中的某1列的多個屬性。

SQLFetch

Yes

Yes

ISO 92

返回多個結果行。

SQLFetchScroll

No

Yes

ISO 92

返回可滾動結果行。

SQLExtendedFetch

Yes

Yes

Deprecated

返回可滾動結果行。

SQLSetPos

Yes

Yes

ODBC

將光標定為在獲取的數據塊中,允許應用程式更新行集合中的數據,或更新或刪除結果集中的數據。

SQLBulkOperations

No

Yes

ODBC

執行批量插入和批量書籤操作,包括更新、刪除和按書籤獲取。

檢索錯誤和診斷訊息:

函數名

MyODBC

MyODBC

一致性

目的

 

2.50

3.51

 

 

SQLError

Yes

Yes

Deprecated

返回額外的錯誤或狀態訊息。

SQLGetDiagField

Yes

Yes

ISO 92

返回額外的診斷訊息(診斷性數據結構的單個字段)。

SQLGetDiagRec

Yes

Yes

ISO 92

返回額外的診斷訊息(診斷性數據結構的多個字段)。

獲取關於數據源的系統資料表(目錄函數)條目的訊息:

函數名

MyODBC

MyODBC

一致性

目的

 

2.50

3.51

 

 

SQLColumnPrivileges

Yes

Yes

ODBC

返回關於一個或多個資料表的列和相關屬性的列資料表。

SQLColumns

Yes

Yes

X/Open

返回指定資料表中列名的列資料表。

SQLForeignKeys

Yes

Yes

ODBC

在指定資料表中如果存在外部鍵,返回構成外部鍵的列名列資料表。

SQLPrimaryKeys

Yes

Yes

ODBC

返回構成某1資料表的主鍵的列名列資料表。

SQLSpecialColumns

Yes

Yes

X/Open

返回關於最佳列集合的訊息,該列集合唯一地指明了指定資料表中的行,或當某1事務更新了行中的任何值時自動更新的列。

SQLStatistics

Yes

Yes

ISO 92

返回關於單個資料表的統計訊息,以及與資料表相關的索引列資料表。

SQLTablePrivileges

Yes

Yes

ODBC

返回資料表列資料表,以及與各資料表相關的權限。

SQLTables

Yes

Yes

X/Open

返回儲存在特定數據源內的資料表名列資料表。

執行事務:

函數名

MyODBC

MyODBC

一致性

目的

 

2.50

3.51

 

 

SQLTransact

Yes

Yes

Deprecated

提交或回滾事務。

SQLEndTran

No

Yes

ISO 92

提交或回滾事務。

中止語句:

函數名

MyODBC

MyODBC

一致性

目的

 

2.50

3.51

 

 

SQLFreeStmt

Yes

Yes

ISO 92

結束語句處理,捨棄未決結果,並釋放與語句句柄相關的所有資源(可選)。

SQLCloseCursor

Yes

Yes

ISO 92

關閉在語句句柄上打開的指針。

SQLCancel

Yes

Yes

ISO 92

取消SQL語句。

中止連接:

函數名

MyODBC

MyODBC

一致性

目的

 

2.50

3.51

 

 

SQLDisconnect

Yes

Yes

ISO 92

關閉連接。

SQLFreeHandle

No

Yes

ISO 92

釋放環境、連接、語句或描述符句柄。

SQLFreeConnect

Yes

Yes

Deprecated

釋放連接句柄。

SQLFreeEnv

Yes

Yes

Deprecated

釋放連接句柄。

26.1.17. MyODBC數據類型

在下資料表中,介紹了驅動程式將伺服器數據類型映射為預設SQL和C數據類型的方法:

SQL類型

C類型

bit

SQL_BIT

SQL_C_BIT

tinyint

SQL_TINYINT

SQL_C_STINYINT

tinyint unsigned

SQL_TINYINT

SQL_C_UTINYINT

bigint

SQL_BIGINT

SQL_C_SBIGINT

bigint unsigned

SQL_BIGINT

SQL_C_UBIGINT

long varbinary

SQL_LONGVARBINARY

SQL_C_BINARY

blob

SQL_LONGVARBINARY

SQL_C_BINARY

longblob

SQL_LONGVARBINARY

SQL_C_BINARY

tinyblob

SQL_LONGVARBINARY

SQL_C_BINARY

mediumblob

SQL_LONGVARBINARY

SQL_C_BINARY

long varchar

SQL_LONGVARCHAR

SQL_C_CHAR

text

SQL_LONGVARCHAR

SQL_C_CHAR

mediumtext

SQL_LONGVARCHAR

SQL_C_CHAR

char

SQL_CHAR

SQL_C_CHAR

numeric

SQL_NUMERIC

SQL_C_CHAR

decimal

SQL_DECIMAL

SQL_C_CHAR

integer

SQL_INTEGER

SQL_C_SLONG

integer unsigned

SQL_INTEGER

SQL_C_ULONG

int

SQL_INTEGER

SQL_C_SLONG

int unsigned

SQL_INTEGER

SQL_C_ULONG

mediumint

SQL_INTEGER

SQL_C_SLONG

mediumint unsigned

SQL_INTEGER

SQL_C_ULONG

smallint

SQL_SMALLINT

SQL_C_SSHORT

smallint unsigned

SQL_SMALLINT

SQL_C_USHORT

real

SQL_FLOAT

SQL_C_DOUBLE

double

SQL_FLOAT

SQL_C_DOUBLE

float

SQL_REAL

SQL_C_FLOAT

double precision

SQL_DOUBLE

SQL_C_DOUBLE

date

SQL_DATE

SQL_C_DATE

time

SQL_TIME

SQL_C_TIME

year

SQL_SMALLINT

SQL_C_SHORT

datetime

SQL_TIMESTAMP

SQL_C_TIMESTAMP

timestamp

SQL_TIMESTAMP

SQL_C_TIMESTAMP

text

SQL_VARCHAR

SQL_C_CHAR

varchar

SQL_VARCHAR

SQL_C_CHAR

enum

SQL_VARCHAR

SQL_C_CHAR

set

SQL_VARCHAR

SQL_C_CHAR

bit

SQL_CHAR

SQL_C_CHAR

bool

SQL_CHAR

SQL_C_CHAR

26.1.18. MyODBC錯誤代碼

在下資料表中,列出了驅動程式返回的除伺服器錯誤之外的錯誤代碼列資料表:

本機代碼

SQLSTATE 2

SQLSTATE 3

錯誤消息

500

01000

01000

一般警告

501

01004

01004

字串數據,右截

502

01S02

01S02

選項值被更改

503

01S03

01S03

未更新/刪除行

504

01S04

01S04

更新/刪除了1個以上的行

505

01S06

01S06

在結果集合返回第1個行集合之前視圖獲取數據。

506

07001

07002

對於所有參數,未使用SQLBindParameter

507

07005

07005

精製語句不符合光標規範

508

07009

07009

無效的描述符索引。

509

08002

08002

連接名正在使用。

510

08003

08003

連接不存在。

511

24000

24000

無效的光標狀態。

512

25000

25000

無效的事務狀態。

513

25S01

25S01

事務狀態未知。

514

34000

34000

無效光標名。

515

S1000

HY000

一般的驅動程式定義錯誤。

516

S1001

HY001

內存分配錯誤。

517

S1002

HY002

無效的列編號。

518

S1003

HY003

無效的應用緩衝類型。

519

S1004

HY004

無效的SQL數據類型。

520

S1009

HY009

空指針的無效使用。

521

S1010

HY010

函數順序錯誤。

522

S1011

HY011

現在無法設置屬性。

523

S1012

HY012

無效的事務操作碼。

524

S1013

HY013

內存管理錯誤。

525

S1015

HY015

無可用的光標名。

526

S1024

HY024

無效的屬性值。

527

S1090

HY090

無效字串或緩衝長度。

528

S1091

HY091

無效的描述符字段標識符。

529

S1092

HY092

無效的屬性/選項標識符。

530

S1093

HY093

無效的參數編號。

531

S1095

HY095

函數類型超出範圍。

532

S1106

HY106

獲取類型超出範圍。

533

S1117

HY117

行值超出範圍。

534

S1109

HY109

無效的光標位置。

535

S1C00

HYC00

可選特性未實施。

0

21S01

21S01

列計數與值計數不匹配。

0

23000

23000

完整性約束違反。

0

42000

42000

語法錯誤或訪問衝突。

0

42S02

42S02

未發現基本資料表或視圖。

0

42S12

42S12

未發現索引。

0

42S21

42S21

列已存在。

0

42S22

42S22

未發現列。

0

08S01

08S01

通信連結失敗。

26.1.19. MyODBC與VB:ADO、DAO和RDO

在本節中,給出了MySQL ODBC 3.51驅動程式與ADO、DAO和RDO一起使用的一些簡單示範。

26.1.19.1. ADO: rs.addNew, rs.delete和rs.update

在下面的ADO(ActiveX數據對像)示範中,建立了資料表my_ado,並演示了rs.addNewrs.deleters.update的用法。

Private Sub myodbc_ado_Click()
 
Dim conn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim fld As ADODB.Field
Dim sql As String
 
'connect to MySQL server using MySQL ODBC 3.51 Driver(使用MySQL ODBC 3.51驅動程式連接到MySQL伺服器)
Set conn = New ADODB.Connection
conn.ConnectionString = "DRIVER={MySQL ODBC 3.51 Driver};"_
                      & "SERVER=localhost;"_
                      & " DATABASE=test;"_
                      & "UID=venu;PWD=venu; OPTION=3"
 
conn.Open
 
'create table(建立資料表)
conn.Execute "DROP TABLE IF EXISTS my_ado"
conn.Execute "CREATE TABLE my_ado(id int not null primary key, name varchar(20)," _
                               & "txt text, dt date, tm time, ts timestamp)"
 
'direct insert(直接插入)
conn.Execute "INSERT INTO my_ado(id,name,txt) values(1,100,'venu')"
conn.Execute "INSERT INTO my_ado(id,name,txt) values(2,200,'MySQL')"
conn.Execute "INSERT INTO my_ado(id,name,txt) values(3,300,'Delete')"
 
Set rs = New ADODB.Recordset
rs.CursorLocation = adUseServer
 
'fetch the initial table ..(獲取初始資料表…)
rs.Open "SELECT * FROM my_ado", conn
  Debug.Print rs.RecordCount
  rs.MoveFirst
  Debug.Print String(50, "-") & "Initial my_ado Result Set " & String(50, "-")
  For Each fld In rs.Fields
    Debug.Print fld.Name,
    Next
    Debug.Print
 
    Do Until rs.EOF
    For Each fld In rs.Fields
    Debug.Print fld.Value,
    Next
    rs.MoveNext
    Debug.Print
  Loop
rs.Close
 
'rs insertrs插入)
rs.Open "select * from my_ado", conn, adOpenDynamic, adLockOptimistic
rs.AddNew
rs!Name = "Monty"
rs!txt = "Insert row"
rs.Update
rs.Close
 
'rs updaters更新)
rs.Open "SELECT * FROM my_ado"
rs!Name = "update"
rs!txt = "updated-row"
rs.Update
rs.Close
 
'rs update second time..rs更新第2次…)
rs.Open "SELECT * FROM my_ado"
rs!Name = "update"
rs!txt = "updated-second-time"
rs.Update
rs.Close
 
'rs deleters刪除)
rs.Open "SELECT * FROM my_ado"
rs.MoveNext
rs.MoveNext
rs.Delete
rs.Close
 
'fetch the updated table ..(獲取更新的資料表…)
rs.Open "SELECT * FROM my_ado", conn
  Debug.Print rs.RecordCount
  rs.MoveFirst
  Debug.Print String(50, "-") & "Updated my_ado Result Set " & String(50, "-")
  For Each fld In rs.Fields
    Debug.Print fld.Name,
    Next
    Debug.Print
 
    Do Until rs.EOF
    For Each fld In rs.Fields
    Debug.Print fld.Value,
    Next
    rs.MoveNext
    Debug.Print
  Loop
rs.Close
conn.Close
End Sub

26.1.19.2. DAO: rs.addNew, rs.update和滾動

在下面的DAO(數據訪問對像)示範中,建立了資料表my_dao,並演示了rs.addNewrs.update、以及結果集滾動的用法。
Private Sub myodbc_dao_Click()
 
Dim ws As Workspace
Dim conn As Connection
Dim queryDef As queryDef
Dim str As String
 
'connect to MySQL server using MySQL ODBC 3.51 Driver(使用MySQL ODBC 3.51驅動程式連接到MySQL)
Set ws = DBEngine.CreateWorkspace("", "venu", "venu", dbUseODBC)
str = "odbc;DRIVER={MySQL ODBC 3.51 Driver};"_
                      & "SERVER=localhost;"_
                      & " DATABASE=test;"_
                      & "UID=venu;PWD=venu; OPTION=3"
Set conn = ws.OpenConnection("test", dbDriverNoPrompt, False, str)
 
'Create table my_dao(建立資料表my_dao
Set queryDef = conn.CreateQueryDef("", "drop table if exists my_dao")
queryDef.Execute
 
Set queryDef = conn.CreateQueryDef("", "create table my_dao(Id INT AUTO_INCREMENT PRIMARY KEY, " _
                                                         & "Ts TIMESTAMP(14) NOT NULL, Name varchar(20), Id2 INT)")
queryDef.Execute
 
'Insert new records using rs.addNew(使用rs.addNew插入新記錄)
Set rs = conn.OpenRecordset("my_dao")
Dim i As Integer
 
  For i = 10 To 15
  rs.AddNew
  rs!Name = "insert record" & i
  rs!Id2 = i
  rs.Update
  Next i
           rs.Close
 
'rs update..rs更新)
Set rs = conn.OpenRecordset("my_dao")
rs.Edit
rs!Name = "updated-string"
rs.Update
rs.Close
 
'fetch the table back...(向後獲取資料表…)
Set rs = conn.OpenRecordset("my_dao", dbOpenDynamic)
str = "Results:"
rs.MoveFirst
While Not rs.EOF
str = " " & rs!Id & " , " & rs!Name & ", " & rs!Ts & ", " & rs!Id2
Debug.Print "DATA:" & str
rs.MoveNext
Wend
 
'rs Scrollingrs滾動)
rs.MoveFirst
str = " FIRST ROW: " & rs!Id & " , " & rs!Name & ", " & rs!Ts & ", " & rs!Id2
Debug.Print str
 
rs.MoveLast
str = " LAST ROW: " & rs!Id & " , " & rs!Name & ", " & rs!Ts & ", " & rs!Id2
Debug.Print str
 
rs.MovePrevious
str = " LAST-1 ROW: " & rs!Id & " , " & rs!Name & ", " & rs!Ts & ", " & rs!Id2
Debug.Print str
 
'free all resources(釋放所有資源)
rs.Close
queryDef.Close
conn.Close
ws.Close
 
End Sub

26.1.19.3. RDO: rs.addNew和rs.update

在下面的RDO(遠程數據對像)示範中,建立了資料表my_rdo,並演示了rs.addNewrs.update的用法。
Dim rs As rdoResultset
  Dim cn As New rdoConnection
  Dim cl As rdoColumn
  Dim SQL As String
 
  'cn.Connect = "DSN=test;"
  cn.Connect = "DRIVER={MySQL ODBC 3.51 Driver};"_
                      & "SERVER=localhost;"_
                      & " DATABASE=test;"_
                      & "UID=venu;PWD=venu; OPTION=3"
 
  cn.CursorDriver = rdUseOdbc
  cn.EstablishConnection rdDriverPrompt
 
 
  'drop table my_rdo(捨棄資料表my_rdo
  SQL = "drop table if exists my_rdo"
  cn.Execute SQL, rdExecDirect
 
  'create table my_rdo(建立資料表my_rdo
  SQL = "create table my_rdo(id int, name varchar(20))"
  cn.Execute SQL, rdExecDirect
 
  'insert  direct(插入,直接)
  SQL = "insert into my_rdo values (100,'venu')"
  cn.Execute SQL, rdExecDirect
 
  SQL = "insert into my_rdo values (200,'MySQL')"
  cn.Execute SQL, rdExecDirect
 
  'rs insertrs插入)
  SQL = "select * from my_rdo"
  Set rs = cn.OpenResultset(SQL, rdOpenStatic, rdConcurRowVer, rdExecDirect)
  rs.AddNew
  rs!id = 300
  rs!Name = "Insert1"
  rs.Update
  rs.Close
 
  'rs insertrs插入)
  SQL = "select * from my_rdo"
  Set rs = cn.OpenResultset(SQL, rdOpenStatic, rdConcurRowVer, rdExecDirect)
  rs.AddNew
  rs!id = 400
  rs!Name = "Insert 2"
  rs.Update
  rs.Close
 
  'rs updaters更新)
  SQL = "select * from my_rdo"
  Set rs = cn.OpenResultset(SQL, rdOpenStatic, rdConcurRowVer, rdExecDirect)
  rs.Edit
  rs!id = 999
  rs!Name = "updated"
  rs.Update
  rs.Close
 
  'fetch back...
  SQL = "select * from my_rdo"
  Set rs = cn.OpenResultset(SQL, rdOpenStatic, rdConcurRowVer, rdExecDirect)
  Do Until rs.EOF
  For Each cl In rs.rdoColumns
              Debug.Print cl.Value,
    Next
    rs.MoveNext
    Debug.Print
             Loop
  Debug.Print "Row count="; rs.RowCount
 
  'close(關閉)
  rs.Close
  cn.Close
 
End Sub

26.1.20. MyODBC與Microsoft.NET

本節包含一些簡單示範,介紹了MyODBC驅動程式與ODBC.NET一起使用的用法。

26.1.20.1. ODBC.NET: CSHARP(C#)

在下面的簡單示範中建立了資料表my_odbc_net,並介紹了它在C#中的使用。

/**
* @sample    : mycon.cs
* @purpose   : Demo sample for ODBC.NET using MyODBC
* @author    : Venu, <venu@mysql.com>
*
* (C) Copyright MySQL AB, 1995-2004
*
**/

/* build command
*
*  csc /t:exe
*      /out:mycon.exe mycon.cs
*      /r:Microsoft.Data.Odbc.dll
*/

using Console = System.Console;
using Microsoft.Data.Odbc;

namespace myodbc3
{
class mycon
{
  static void Main(string[] args)
  {
    try
    {
      //Connection string for MyODBC 2.50
      /*string MyConString = "DRIVER={MySQL};" +
                           "SERVER=localhost;" +
                           "DATABASE=test;" +
                           "UID=venu;" +
                           "PASSWORD=venu;" +
                           "OPTION=3";
      */
      //Connection string for MyODBC 3.51
      string MyConString = "DRIVER={MySQL ODBC 3.51 Driver};" +
                           "SERVER=localhost;" +
                           "DATABASE=test;" +
                           "UID=venu;" +
                           "PASSWORD=venu;" +
                           "OPTION=3";

      //Connect to MySQL using MyODBC
      OdbcConnection MyConnection = new OdbcConnection(MyConString);
      MyConnection.Open();

      Console.WriteLine("\n !!! success, connected successfully !!!\n");

      //Display connection information
      Console.WriteLine("Connection Information:");
      Console.WriteLine("\tConnection String:" + MyConnection.ConnectionString);
      Console.WriteLine("\tConnection Timeout:" + MyConnection.ConnectionTimeout);
      Console.WriteLine("\tDatabase:" + MyConnection.Database);
      Console.WriteLine("\tDataSource:" + MyConnection.DataSource);
      Console.WriteLine("\tDriver:" + MyConnection.Driver);
      Console.WriteLine("\tServerVersion:" + MyConnection.ServerVersion);

      //Create a sample table
      OdbcCommand MyCommand = new OdbcCommand("DROP TABLE IF EXISTS my_odbc_net",MyConnection);
      MyCommand.ExecuteNonQuery();
      MyCommand.CommandText = "CREATE TABLE my_odbc_net(id int, name varchar(20), idb bigint)";
      MyCommand.ExecuteNonQuery();

      //Insert
      MyCommand.CommandText = "INSERT INTO my_odbc_net VALUES(10,'venu', 300)";
      Console.WriteLine("INSERT, Total rows affected:" + MyCommand.ExecuteNonQuery());;

      //Insert
      MyCommand.CommandText = "INSERT INTO my_odbc_net VALUES(20,'mysql',400)";
      Console.WriteLine("INSERT, Total rows affected:" + MyCommand.ExecuteNonQuery());

      //Insert
      MyCommand.CommandText = "INSERT INTO my_odbc_net VALUES(20,'mysql',500)";
      Console.WriteLine("INSERT, Total rows affected:" + MyCommand.ExecuteNonQuery());

      //Update
      MyCommand.CommandText = "UPDATE my_odbc_net SET id=999 WHERE id=20";
      Console.WriteLine("Update, Total rows affected:" + MyCommand.ExecuteNonQuery());

      //COUNT(*)
      MyCommand.CommandText = "SELECT COUNT(*) as TRows FROM my_odbc_net";
      Console.WriteLine("Total Rows:" + MyCommand.ExecuteScalar());

      //Fetch
      MyCommand.CommandText = "SELECT * FROM my_odbc_net";
      OdbcDataReader MyDataReader;
      MyDataReader =  MyCommand.ExecuteReader();
      while (MyDataReader.Read())
      {
       if(string.Compare(MyConnection.Driver,"myodbc3.dll") == 0) {
         Console.WriteLine("Data:" + MyDataReader.GetInt32(0) + " " +
                                     MyDataReader.GetString(1) + " " +
                                     MyDataReader.GetInt64(2)); //Supported only by MyODBC 3.51
       }
       else {
         Console.WriteLine("Data:" + MyDataReader.GetInt32(0) + " " +
                                     MyDataReader.GetString(1) + " " +
                                     MyDataReader.GetInt32(2)); //BIGINTs not supported by MyODBC
       }
      }

      //Close all resources
      MyDataReader.Close();
      MyConnection.Close();
    }
    catch (OdbcException MyOdbcException)//Catch any ODBC exception ..
    {
      for (int i=0; i < MyOdbcException.Errors.Count; i++)
      {
        Console.Write("ERROR #" + i + "\n" +
          "Message: " + MyOdbcException.Errors[i].Message + "\n" +
          "Native: " + MyOdbcException.Errors[i].NativeError.ToString() + "\n" +
          "Source: " + MyOdbcException.Errors[i].Source + "\n" +
          "SQL: " + MyOdbcException.Errors[i].SQLState + "\n");
      }
    }
  }
}
}

26.1.20.2. ODBC.NET: VB

在下面的簡單示範中建立了資料表my_vb_net,並介紹了它在VB中的用法。

' @sample    : myvb.vb
' @purpose   : Demo sample for ODBC.NET using MyODBC
' @author    : Venu, <venu@mysql.com>
'
' (C) Copyright MySQL AB, 1995-2004
'
'

'
' build command
'
' vbc /target:exe
'     /out:myvb.exe
'     /r:Microsoft.Data.Odbc.dll
'     /r:System.dll
'     /r:System.Data.dll
'

Imports Microsoft.Data.Odbc
Imports System

Module myvb
  Sub Main()
      Try

          'MyODBC 3.51 connection string
          Dim MyConString As String = "DRIVER={MySQL ODBC 3.51 Driver};" & _
                         "SERVER=localhost;" & _
                         "DATABASE=test;" & _
                         "UID=venu;" & _
                         "PASSWORD=venu;" & _
                         "OPTION=3;"

          'Connection
          Dim MyConnection As New OdbcConnection(MyConString)
          MyConnection.Open()

          Console.WriteLine ("Connection State::" & MyConnection.State.ToString)

          'Drop
          Console.WriteLine ("Dropping table")
          Dim MyCommand As New OdbcCommand()
          MyCommand.Connection = MyConnection
          MyCommand.CommandText = "DROP TABLE IF EXISTS my_vb_net"
          MyCommand.ExecuteNonQuery()

          'Create
          Console.WriteLine ("Creating....")
          MyCommand.CommandText = "CREATE TABLE my_vb_net(id int, name varchar(30))"
          MyCommand.ExecuteNonQuery()

          'Insert
          MyCommand.CommandText = "INSERT INTO my_vb_net VALUES(10,'venu')"
          Console.WriteLine("INSERT, Total rows affected:" & MyCommand.ExecuteNonQuery())

          'Insert
          MyCommand.CommandText = "INSERT INTO my_vb_net VALUES(20,'mysql')"
          Console.WriteLine("INSERT, Total rows affected:" & MyCommand.ExecuteNonQuery())

          'Insert
          MyCommand.CommandText = "INSERT INTO my_vb_net VALUES(20,'mysql')"
          Console.WriteLine("INSERT, Total rows affected:" & MyCommand.ExecuteNonQuery())

          'Insert
          MyCommand.CommandText = "INSERT INTO my_vb_net(id) VALUES(30)"
          Console.WriteLine("INSERT, Total rows affected:" & MyCommand.ExecuteNonQuery())

          'Update
          MyCommand.CommandText = "UPDATE my_vb_net SET id=999 WHERE id=20"
          Console.WriteLine("Update, Total rows affected:" & MyCommand.ExecuteNonQuery())

          'COUNT(*)
          MyCommand.CommandText = "SELECT COUNT(*) as TRows FROM my_vb_net"
          Console.WriteLine("Total Rows:" & MyCommand.ExecuteScalar())

          'Select
          Console.WriteLine ("Select * FROM my_vb_net")
          MyCommand.CommandText = "SELECT * FROM my_vb_net"
          Dim MyDataReader As OdbcDataReader
          MyDataReader = MyCommand.ExecuteReader
          While MyDataReader.Read
              If MyDataReader("name") Is DBNull.Value Then
                  Console.WriteLine ("id = " & CStr(MyDataReader("id")) & "  name = " & _
                    "NULL")
              Else
                  Console.WriteLine ("id = " & CStr(MyDataReader("id")) & "  name = " & _
                                        CStr(MyDataReader("name")))
              End If
          End While

      'Catch ODBC Exception
      Catch MyOdbcException As OdbcException
          Dim i As Integer
          Console.WriteLine (MyOdbcException.ToString)

      'Catch program exception
      Catch MyException As Exception
          Console.WriteLine (MyException.ToString)
  End Try
  End Sub
End Module

26.1.21. 感謝

下面列出了一些MySQL AB公司負責MyODBC和MyODBC 3.51驅動程式開發的人員。

  • Micheal (Monty) Widenius

  • Venu Anuganti

  • Peter Harvey

26.2. MySQL Connector/NET

26.2.1. 前言

使用MySQL Connector/NET,開發人員能夠方便地建立需要安全和高性能數據連接(與MySQL)的.NET應用程式。它實施了所需的ADO.NET接口,並將其集成到了ADO.NET aware工具中。開發人員能夠使用他們選擇的.NET語言建立應用程式。MySQL Connector/NET是用100%純C#語言編寫的可完全管理的ADO.NET驅動程式。

MySQL Connector/NET包括對下述事宜的完整支援:

·         MySQL 5.0特性(儲存程式等)。

·         MySQL 4.1特性(伺服器端的精製語句、Unicode、以及共享內存訪問等)。

·         大訊息包支援,可發送和接收高達2GB的行和BLOB。

·         協議壓縮,允許壓縮客戶端和伺服器之間的數據流。

·         支援使用CP/IP套接字、命名管道、以及Windows共享內存的連接。

·         支援使用CP/IP套接字、或Unix套接字的連接。

·         支援由Novell開發的開放原始碼Mono框架。

·         可完全管理,不利用MySQL客戶端庫。

MySQL Connector/NET的開發人員高度尊重用戶在軟件開發過程中提供的幫助。如果您發現MySQL Connector/NET缺少對您來說很重要的某些特性,或者如果您發現了問題,請使用我們的MySQL問題系統請求該特性或通報問題。

通過http://forums.mysql.com上的論壇以及http://lists.mysql.com上的郵件列資料表,可找到針對MySQL Connector/NET的社區支援訊息。MySQL AB公司提供付費支援,更多訊息請參見http://www.mysql.com/support/

本文檔的目的是作為MySQL Connector/NET的用戶指南,而不是語法參考。如果您打算瞭解詳細的語法訊息,請閱讀MySQL Connector/NET分發版中提供的Documentation.chm檔案。

26.2.2. 下載並安裝MySQL Connector/NET

MySQL Connector/NET能夠運行在任何支援.NET框架的平台上。.NET框架主要被最近的Microsoft Windows版本支援,通過由Novell開發的Mono框架,在Linux上也支援它(請參見http://www.mono-project.com)。

MySQL Connector/NET可通過使用Windows Installer (.msi)安裝軟件包進行安裝,使用該軟件包,可在任何Windows作業系統上安裝MySQL Connector/NET。MSI軟件包包含在名為mysql-connector-net-version.zip的壓縮檔案中,其中,version(版本)指明了MySQL Connector/NET的版本。

可從下述網站下載MySQL Connector/NET:http://dev.mysql.com/downloads/connector/net/1.0.html

隨著Windows XP的發佈,Windows Installer(安裝器)引擎也予以了更新,對於使用舊版本的用戶,可參閱該Microsoft知識庫文章以瞭解升級至最新版本的更多訊息。

要想安裝MySQL Connector/NET,請右擊MSI檔案並選擇「安裝」。在安裝器提示您完成安裝參數選擇後,安裝將自動開始。對於大多數用戶,建議採用典型安裝。

如果在運行安裝器時遇到問題,可下載不帶安裝器的ZIP檔案。該檔案名為mysql-connector-net-version-noinstall.zip。使用ZIP程式,將其解壓至您所選擇的目錄。

除非作了其他選擇,否則MySQL Connector/NET將被安裝到「C:\Program Files\MySQL\MySQL Connector Net X.X.X」,其中,「X.X.X」是您所安裝的MySQL Connector/NET的版本號。新安裝不會覆蓋已有的MySQL Connector/NET版本。

26.2.3. Connector/NET體系結構

MySQL Connector/NET包含數個類,這些類可用於連接到資料庫,執行查詢和語句,並管理查詢結果。

下面介紹了MySQL Connector/NET的主要類:

·         MySqlCommand:代資料表對MySQL資料庫進行執行操作的SQL語句。

·         MySqlCommandBuilder:自動生成單個資料表的命令,用於協調對DataSet所作的更改和相關的MySQL資料庫。

·         MySqlConnection:代資料表與MySQL伺服器資料庫的開放式連接。

·         MySqlDataAdapter:代資料表一組數據命令和資料庫連接,用於填充資料庫和更新MySQL資料庫。

·         MySqlDataReader:提供了從MySQL資料庫讀取行的「僅正向」流的一種方式。

·         MySqlException:當MySQL返回錯誤時拋出的異常。

·         MySqlHelper:助手類,能使工作變的更簡單。

·         MySqlTransaction:代資料表將在MySQL資料庫中進行的SQL事務。

在後續段落中,將分別介紹這些對象。這些章節的目的是概要介紹MySQL Connector/NET的主要類,而不是語法參考。如果您打算瞭解詳細的語法訊息,請閱讀MySQL Connector/NET分發版中提供的Documentation.chm檔案。

26.2.3.1. MySqlCommand類

MySqlCommand類代資料表對MySQL資料庫進行執行操作的SQL語句。

註釋:在以前的版本中,採用符號「@」來標識SQL中的參數。它與MySQL用戶變數不兼容,因此,現採用符號「?」來定位SQL中的參數。為了支援早期代碼,也可以在連接字串中設置「old syntax=yes」。如果進行了這類設置,請注意,如果無法定義希望在SQL中使用的參數(定義失敗),不會給出異常提示。

26.2.3.1.1. 屬性
可用屬性如下:

·         CommandText:獲取或設置將在數據源上執行的SQL語句。

·         CommandTimeout:獲取或設置中止執行命令並生成錯誤之前應等待的時間。

·         CommandType:獲取或設置值,該值指明了解釋CommandText的方式。可能的值包括StoredProcedureTableDirectText

·         Connection:獲取或設置該MySqlCommand實例使用的MySqlConnection。

·         IsPrepared:如果該命令已準備好,為「真」,否則為「假」。

·         Parameters:獲取MySqlParameterCollection。

·         Transaction:獲取或設置MySqlTransaction,MySqlCommand將在其中執行。

·         UpdatedRowSource:當DbDataAdapter的Update方法使用它時,用於獲取或設置命令結果作用在DataRow上的方式。

26.2.3.1.2. 方法
可用方法如下:

·         Cancel:嘗試取消MySqlCommand的執行。不支援該操作。

·         Clone:建立該MySqlCommand對象的克隆對象。包括CommandText、Connection和Transaction屬性,以及整個參數列資料表。

·         CreateParameter:建立MySqlParameter對象的新實例。

·         Dispose:處理該MySqlCommand實例。

·         ExecuteNonQuery:根據連接情況執行SQL語句,並返回受影響的行數。

·         ExecuteReader:將CommandText發送給Connection,並建立MySqlDataReader。

·         ExecuteScalar:執行查詢,並返回查詢操作所返回的結果集中第1行的第1列。多餘的列或行將被忽略。

·         Prepare:在MySQL伺服器的1個實例上建立命令的預製版本。

26.2.3.1.3. 用法
在下面的示範中,建立了1個MySqlCommand和1個MySqlConnection。打開了MySqlConnection,並將其設置為用於MySqlCommand的連接。隨後,使用ExecuteNonQuery,並關閉連接。為了完成該任務,為ExecuteNonQuery傳遞了1個連接字串和1個查詢字串(查詢字串是1條SQL INSERT語句)。
26.2.3.1.3.1. VB.NET

在下例中,介紹了在VB.NET中使用MySqlCommand類的方法:

Public Sub InsertRow(myConnectionString As String)
    ' If the connection string is null, use a default.
    If myConnectionString = "" Then
        myConnectionString = "Database=Test;Data Source=localhost;User Id=username;Password=pass"
    End If
    Dim myConnection As New MySqlConnection(myConnectionString)
    Dim myInsertQuery As String = "INSERT INTO Orders (id, customerId, amount) Values(1001, 23, 30.66)"
    Dim myCommand As New MySqlCommand(myInsertQuery)
    myCommand.Connection = myConnection
    myConnection.Open()
    myCommand.ExecuteNonQuery()
    myCommand.Connection.Close()
End Sub
26.2.3.1.3.2. C#

在下例中,介紹了在C#中使用MySqlCommand類的方法:

public void InsertRow(string myConnectionString) 
{
    // If the connection string is null, use a default.
    if(myConnectionString == "") 
    {
        myConnectionString = "Database=Test;Data Source=localhost;User Id=username;Password=pass";
    }
    MySqlConnection myConnection = new MySqlConnection(myConnectionString);
    string myInsertQuery = "INSERT INTO Orders (id, customerId, amount) Values(1001, 23, 30.66)";
    MySqlCommand myCommand = new MySqlCommand(myInsertQuery);
    myCommand.Connection = myConnection;
    myConnection.Open();
    myCommand.ExecuteNonQuery();
    myCommand.Connection.Close();
}

26.2.3.2. MySqlCommandBuilder類

MySqlDataAdapter不會自動生成所需的SQL語句(用於協調對DataSet所作的更改和相關的MySQL實例)。但是,如果設置了MySqlDataAdapter的SelectCommand屬性,可以建立MySqlCommandBuilder對像來自動生成針對單個資料表更新的SQL語句。隨後,MySqlCommandBuilder將生成您未設置的任何附加的SQL語句。

一旦您設置了DataAdapter屬性,MySqlCommandBuilder會將自己註冊為針對OnRowUpdating事件的監聽程式。一次只能將1個MySqlDataAdapter或MySqlCommandBuilder對像關聯起來。

為了生成INSERT、UPDATE或DELETE語句,MySqlCommandBuilder使用了SelectCommand屬性來自動檢索所需的元數據集合。如果在檢索完元數據後更改了SelectCommand(例如首次更新後),應使用RefreshSchema方法來更新元數據。

SelectCommand也必須返回至少1個主鍵或唯一列。如果未顯示任何返回訊息,將生成InvalidOperation異常,而且不會生成命令。

MySqlCommandBuilder還會使用SelectCommand引用的Connection、CommandTimeout和Transaction屬性。如果更改了這些屬性中的任何1個,或者,如果替換了SelectCommand本身,用戶應使用RefreshSchema。如不然,InsertCommand、UpdateCommand和DeleteCommand屬性將保持它們以前的值。

如果使用了Dispose,MySqlCommandBuilder將解除與MySqlDataAdapter的關聯,已生成的命令將不再使用。

26.2.3.2.1. 屬性

可用屬性如下:

·         DataAdapter:MySqlCommandBuilder將自己註冊為針對RowUpdating事件的監聽程式,RowUpdating事件是由在該屬性中指定的MySqlDataAdapter生成的。建立了新的MySqlCommandBuilder實例時,將釋放任何已有的與MySqlDataAdapter關聯的MySqlCommandBuilder。

·         QuotePrefix, QuoteSuffix:MySQL中的資料庫對像能夠包含特殊字元,如空格等,這會使得正常的SQL字串無法解析。使用QuotePrefix和QuoteSuffix屬性,MySqlCommandBuilder能夠建立處理該問題的SQL命令。

26.2.3.2.2. 方法

可用方法如下:

·         DeriveParameters:從MySqlCommand指定的儲存程式中檢索參數訊息,並填充所指定MySqlCommand對象的參數集。目前不支援該方法,這是因為MySQL中未提供儲存程式。

·         GetDeleteCommand:獲取用於在資料庫上執行刪除操作所需的、自動生成的MySqlCommand對象。

·         GetInsertCommand:獲取用於在資料庫上執行插入操作所需的、自動生成的MySqlCommand對象。

·         GetUpdateCommand:獲取用於在資料庫上執行更新操作所需的、自動生成的MySqlCommand對象。

·         RefreshSchema:刷新用於生成INSERT、UPDATE或DELETE語句的資料庫方案訊息。

26.2.3.2.3. 用法
在下面給出的示範中,使用了MySqlCommand、MySqlDataAdapter和MySqlConnection,用於從數據源選擇行。為該示範傳遞了1個初始化的DataSet、1個連接字串、1個查詢字串(是SQL SELECT語句)、以及1個作為資料庫資料表名稱的字串。隨後,該示範建立了1個MySqlCommandBuilder。
26.2.3.2.3.1. VB.NET

在下例中,介紹了在VB.NET中使用MySqlCommandBuilder類的方法:

  Public Shared Function SelectRows(myConnection As String, mySelectQuery As String, myTableName As String) As DataSet
        Dim myConn As New MySqlConnection(myConnection)
        Dim myDataAdapter As New MySqlDataAdapter()
        myDataAdapter.SelectCommand = New MySqlCommand(mySelectQuery, myConn)
        Dim cb As SqlCommandBuilder = New MySqlCommandBuilder(myDataAdapter)

        myConn.Open()

        Dim ds As DataSet = New DataSet
        myDataAdapter.Fill(ds, myTableName)

        ' Code to modify data in DataSet here 

        ' Without the MySqlCommandBuilder this line would fail.
        myDataAdapter.Update(ds, myTableName)

        myConn.Close()
    End Function 'SelectRows
    
26.2.3.2.3.2. C#

在下例中,介紹了在C#中使用MySqlCommandBuilder類的方法:

    public static DataSet SelectRows(string myConnection, string mySelectQuery, string myTableName)
    {
      MySqlConnection myConn = new MySqlConnection(myConnection);
      MySqlDataAdapter myDataAdapter = new MySqlDataAdapter();
      myDataAdapter.SelectCommand = new MySqlCommand(mySelectQuery, myConn);
      MySqlCommandBuilder cb = new MySqlCommandBuilder(myDataAdapter);

      myConn.Open();

      DataSet ds = new DataSet();
      myDataAdapter.Fill(ds, myTableName);

      //code to modify data in DataSet here

      //Without the MySqlCommandBuilder this line would fail
      myDataAdapter.Update(ds, myTableName);

      myConn.Close();

      return ds;
    }  
    

26.2.3.3. MySqlConnection類

MySqlConnection對像代資料表與MySQL伺服器數據源的會話。建立MySqlConnection實例時,所有屬性均將被設置為它們的初始值。關於這些值的列資料表,請參見MySqlConnection構造函數。

如果MySqlConnection超出範圍,不會被關閉。因此,必須通過使用Close或Dispose明確地關閉連接。

26.2.3.3.1. 屬性
可用屬性如下:

·         ConnectionString:設置或獲取用於連接至MySQL伺服器資料庫的字串。

·         ConnectionTimeout:獲取在中止嘗試並生成錯誤之前為建立連接所需的等待時間。

·         Database:獲取當前資料庫的名稱或打開連接後將使用的資料庫的名稱。

·         DataSource:獲取將要連接的MySQL伺服器的名稱。

·         ServerThread:返回該連接所使用的伺服器線程的ID。

·         ServerVersion:獲取包含客戶端與之相連的MySQL伺服器版本的字串。

·         State:獲取連接的當前連接的狀態。

·         UseConnection:與伺服器進行通信時,指明該連接是否將使用壓縮特性。

26.2.3.3.2. 方法
可用方法如下:

·         BeginTransaction:開始資料庫事務。

·         ChangeDatabase:針對打開的MySqlConnection,更改當前資料庫。

·         Close:關閉與資料庫的連接。這是關閉任何打開連接的首選方法。

·         CreateCommand:建立並返回與MySqlConnection相關的MySqlCommand對象。

·         Dispose:釋放MySqlConnection使用的資源。

·         Open:用ConnectionString指定的屬性設置打開資料庫連接。

·         Ping:對MySQL伺服器執行Ping操作。

26.2.3.3.3. 用法
在下面的示範中,建立了1個MySqlCommand和1個MySqlConnection。打開了MySqlConnection,並將其設置為用於MySqlCommand的連接。隨後,使用ExecuteNonQuery,並關閉連接。為了完成該任務,為ExecuteNonQuery傳遞了1個連接字串和1個查詢字串(查詢字串是1條SQL INSERT語句)。
26.2.3.3.3.1. VB.NET

在下例中,介紹了在VB.NET中使用MySqlConnection類的方法:

Public Sub InsertRow(myConnectionString As String)
    ' If the connection string is null, use a default.
    If myConnectionString = "" Then
        myConnectionString = "Database=Test;Data Source=localhost;User Id=username;Password=pass"
    End If
    Dim myConnection As New MySqlConnection(myConnectionString)
    Dim myInsertQuery As String = "INSERT INTO Orders (id, customerId, amount) Values(1001, 23, 30.66)"
    Dim myCommand As New MySqlCommand(myInsertQuery)
    myCommand.Connection = myConnection
    myConnection.Open()
    myCommand.ExecuteNonQuery()
    myCommand.Connection.Close()
End Sub
      
26.2.3.3.3.2. C#

在下例中,介紹了在C#中使用MySqlConnection類的方法:

public void InsertRow(string myConnectionString) 
{
    // If the connection string is null, use a default.
    if(myConnectionString == "") 
    {
        myConnectionString = "Database=Test;Data Source=localhost;User Id=username;Password=pass";
    }
    MySqlConnection myConnection = new MySqlConnection(myConnectionString);
    string myInsertQuery = "INSERT INTO Orders (id, customerId, amount) Values(1001, 23, 30.66)";
    MySqlCommand myCommand = new MySqlCommand(myInsertQuery);
    myCommand.Connection = myConnection;
    myConnection.Open();
    myCommand.ExecuteNonQuery();
    myCommand.Connection.Close();
}

      

26.2.3.4. MySqlDataAdapter類

MySQLDataAdapter起著DataSet和MySQL之間橋樑的作用,用於檢索和保存數據。MySQLDataAdapter通過映射Fill(填充)和Update(更新)提供了該橋,Fill能改變DataSet中的數據以便與數據源中的數據匹配,Update能改變數據源中的數據以便與DataSet中的數據匹配(通過對數據源使用恰當的SQL語句)。

當MySQLDataAdapter填充DataSet時,如果資料表或列不存在,它將為返回的數據建立必要的資料表和列。但是,在隱式建立的方案中不包括主鍵訊息,除非將MissingSchemaAction屬性設為AddWithKey。在使用FillSchema用數據填充它之前,也能讓MySQLDataAdapter建立DataSet方案,包含主鍵訊息。

MySQLDataAdapter用於MySqlConnection和MySqlCommand的連接,用以提升連接至MySQL資料庫時的性能。

MySQLDataAdapter還包括SelectCommand、InsertCommand、DeleteCommand、UpdateCommand和TableMappings屬性,用於簡化數據的加載和更新操作。

26.2.3.4.1. 屬性

可用屬性如下:

·         AcceptChangesDuringFill:獲取或設置值,該值指明了在任何填充操作過程中,在將DataRow新增到DataTable後,是否要在DataRow上使用AcceptChanges。

·         ContinueUpdateOnError:獲取或設置值,該值指定了在行更新過程中出現錯誤時是否要生成異常項。

·         DeleteCommand:獲取或設置用於將記錄從數據集中刪除的SQL語句或儲存程式。

·         InsertCommand:獲取或設置用於在數據集中插入記錄的SQL語句或儲存程式。

·         MissingMappingAction:確定當進入的數據不含匹配資料表或列時需要採取的動作。

·         MissingSchemaAction:確定當已有的DataSet方案與進入數據不匹配時需要採取的動作。

·         SelectCommand:獲取或設置用於在數據源中選擇記錄的SQL語句或儲存程式。

·         TableMappings:獲取提供了源資料表和DataTable之間主映射的集合。

·         UpdateCommand:獲取或設置用於在數據源中更新記錄的SQL語句或儲存程式。

26.2.3.4.2. 方法
可用方法如下:

·         Fill:使用DataSet名稱新增或刷新DataSet中的行,以便與數據源中的行匹配,並建立名為「Table」的DataTable。

·         FillSchema:將名為「Table」的DataTable新增到指定的DataSet,並配置方案,以便與基於指定SchemaType的數據源中的資料表匹配。

·         GetFillParameters:執行SQL SELECT語句時,按用戶獲取參數集。

·         Update:為指定DataSet中的各插入行、更新行或刪除行分別使用INSERT、UPDATE或DELETE語句。

26.2.3.4.3. 用法
在下面的示範中,建立了1個MySqlCommand和1個MySqlConnection。打開MySqlConnection,並將其設置為用於MySqlCommand的連接。隨後,使用ExecuteNonQuery,並關閉連接。為了完成該任務,為ExecuteNonQuery傳遞了1個連接字串和1個查詢字串(查詢字串是1條SQL INSERT語句)。
26.2.3.4.3.1. VB.NET

在下例中,介紹了在VB.NET中使用MySqlDataAdapter類的方法:

Public Function SelectRows(dataSet As DataSet, connection As String, query As String) As DataSet
    Dim conn As New MySqlConnection(connection)
    Dim adapter As New MySqlDataAdapter()
    adapter.SelectCommand = new MySqlCommand(query, conn)
    adapter.Fill(dataset)
    Return dataset
End Function 
26.2.3.4.3.2. C#

在下例中,介紹了在C#中使用MySqlDataAdapter類的方法:

public DataSet SelectRows(DataSet dataset,string connection,string query) 
{
    MySqlConnection conn = new MySqlConnection(connection);
    MySqlDataAdapter adapter = new MySqlDataAdapter();
    adapter.SelectCommand = new MySqlCommand(query, conn);
    adapter.Fill(dataset);
    return dataset;
}   
  

26.2.3.5. MySqlDataReader類

MySqlDataReader類提供了從MySQL資料庫讀取行的「僅正向」流的一種方式。

要想建立MySQLDataReader,必須使用MySqlCommand對象的ExecuteReader方法,而不是直接使用構造函數。

使用MySqlDataReader的同時,相關的MySqlConnection將忙於MySqlDataReader。除了關閉它之外,不能在MySqlConnection上執行任何操作。該情況將一直持續到使用了MySqlDataReader的「Close」方法為止。

關閉了MySqlDataReader後,您只能使用IsClosed和RecordsAffected屬性。儘管在MySqlDataReader存在同時能夠訪問RecordsAffected屬性,但在返回RecordsAffected的值之前總應使用「Close」,以確保準確的返回值。

為了獲得最佳性能,MySqlDataReader將避免建立不必要的對象或執行不必要的數據拷貝。其結果是,對諸如GetValue等方法的多個使用會返回對相同對象的引用。如果您準備更改由諸如GetValue等方法返回的對象的基本值,請仔細小心。

26.2.3.5.1. 屬性
可用屬性如下:

·         Depth:獲取指明當前行嵌套深度的值。目前並不支援方法,總會返回0。

·         FieldCount:獲取當前行中的列數。

·         HasRows:獲取值,該值指明了MySqlDataReader是否包含1行或多行。

·         IsClosed:獲取值,該值指明了和蘇劇閱讀器是否已關閉。

·         Item:以固有格式獲取列的值。在C#,該屬性是MySqlDataReader類的索引屬性。

·         RecordsAffected:獲取隱執行SQL語句而更改、插入、或刪除的行數。

26.2.3.5.2. 方法
可用方法如下:

·         Close:關閉MySqlDataReader對象。

·         GetBoolean:獲取指定列的布爾值。

·         GetByte:以字節形式獲取指定列的值。

·         GetBytes:讀取從指定列偏移至緩衝的字節流,數組從給定的緩衝偏移位置開始。

·         GetChar:以單字元形式獲取指定列的值。

·         GetChars:讀取從指定列偏移至緩衝的字元流,數組從給定的緩衝偏移位置開始。

·         GetDataTypeName:獲取源數據類型的名稱。

·         GetDateTime:以DateTime對像形式獲取指定列的值。

·         GetDecimal:以DateTime對像形式獲取指定列的值。

·         GetDouble:以雙精度浮點數的形式獲取指定列的值。

·         GetFieldType:獲取作為對像數據類型的類型。

·         GetFloat:以單精度浮點數的形式獲取指定列的值。

·         GetGuid:以GUID的形式獲取指定列的值。

·         GetInt16:以16位帶符號整數的形式獲取指定列的值。

·         GetInt32:以32位帶符號整數的形式獲取指定列的值。

·         GetInt64:以64位帶符號整數的形式獲取指定列的值。

·         GetMySqlDateTime:以MySqlDateTime對象的形式獲取指定列的值。

·         GetName:獲取指定列的名稱。

·         GetOrdinal:給定列名,獲取列的順序。

·         GetSchemaTable:返回描述了MySqlDataReader的列元數據的DataTable。

·         GetString:以String對象的形式獲取指定列的值。

·         GetTimeSpan:以TimeSpan對象的形式獲取指定列的值。

·         GetUInt16:以16位無符號整數的形式獲取指定列的值。

·         GetUInt32:以32位無符號整數的形式獲取指定列的值。

·         GetUInt64:以64位無符號整數的形式獲取指定列的值。

·         GetValue:以固有格式獲取指定列的值。

·         GetValues:獲取當前行集合中的所有屬性列。

·         IsDBNull:獲取值,該值指明了列中是否包含不存在或丟失的值。

·         NextResult:讀取批SQL語句的結果時,使數據閱讀器跳到下一個結果。

·         Read:使MySqlDataReader跳到下一條記錄。

26.2.3.5.3. 用法
在下面的示範中,建立了1個MySqlConnection,1個MySqlCommand和1個MySqlDataReader。該示範讀取數據,並將數據輸出到控制台。最後,本例關閉了MySqlDataReader,然後關閉了MySqlConnection。
26.2.3.5.3.1. VB.NET

在下例中,介紹了在VB.NET中使用MySqlDataReader類的方法:

Public Sub ReadMyData(myConnString As String)
    Dim mySelectQuery As String = "SELECT OrderID, CustomerID FROM Orders"
    Dim myConnection As New MySqlConnection(myConnString)
    Dim myCommand As New MySqlCommand(mySelectQuery, myConnection)
    myConnection.Open()
    Dim myReader As MySqlDataReader
    myReader = myCommand.ExecuteReader()
    ' Always call Read before accessing data.
    While myReader.Read()
        Console.WriteLine((myReader.GetInt32(0) & ", " & myReader.GetString(1)))
    End While
    ' always call Close when done reading.
    myReader.Close()
    ' Close the connection when done with it.
    myConnection.Close()
End Sub 'ReadMyData       
      
26.2.3.5.3.2. C#

在下例中,介紹了在C#中使用MySqlDataReader類的方法:

public void ReadMyData(string myConnString) {
    string mySelectQuery = "SELECT OrderID, CustomerID FROM Orders";
    MySqlConnection myConnection = new MySqlConnection(myConnString);
    MySqlCommand myCommand = new MySqlCommand(mySelectQuery,myConnection);
    myConnection.Open();
    MySqlDataReader myReader;
    myReader = myCommand.ExecuteReader();
    // Always call Read before accessing data.
    while (myReader.Read()) {
       Console.WriteLine(myReader.GetInt32(0) + ", " + myReader.GetString(1));
    }
    // always call Close when done reading.
    myReader.Close();
    // Close the connection when done with it.
    myConnection.Close();
 }     
      

26.2.3.6. MySqlException類

當MySql數據提供方遇到伺服器生成的錯誤時將建立該類。

拋出異常時,打開的連接不會自動關閉。如果客戶端應用程式判定該異常是致命的,應關閉任何打開的MySqlDataReader對像或MySqlConnection對象。

26.2.3.6.1. 屬性
可用屬性如下:

·         HelpLink:獲取或設置指向與該異常相關的幫助檔案的連結。

·         InnerException:獲取導致當前異常的異常實例。

·         IsFatal:如果該異常是致命的,為「真」,並關閉連接,如果不是致命的,為「假」。

·         Message:獲取描述當前異常的消息。

·         Number:獲取指明錯誤類型的編號。

·         Source:獲取或設置導致錯誤的應用程式或對象的名稱。

·         StackTrace:獲取拋出當前異常時在使用堆棧上幀的字串表徵。

·         TargetSite:獲取拋出當前異常的方法。

26.2.3.6.2. 方法
MySqlException類沒有相應的方法。
26.2.3.6.3. 用法
在下述示範中,因丟失了伺服器而生成了MySqlException,然後顯示異常。
26.2.3.6.3.1. VB.NET

該示範介紹在VB.NET下使用MySqlException類的方法。

Public Sub ShowException()
     Dim mySelectQuery As String = "SELECT column1 FROM table1"
     Dim myConnection As New MySqlConnection ("Data Source=localhost;Database=Sample;")
     Dim myCommand As New MySqlCommand(mySelectQuery, myConnection)

     Try
         myCommand.Connection.Open()
     Catch e As MySqlException
        MessageBox.Show( e.Message )
     End Try
 End Sub       
      
26.2.3.6.3.2. C#

該示範介紹在C#下使用MySqlException類的方法。

public void ShowException() 
{
   string mySelectQuery = "SELECT column1 FROM table1";
   MySqlConnection myConnection =
      new MySqlConnection("Data Source=localhost;Database=Sample;");
   MySqlCommand myCommand = new MySqlCommand(mySelectQuery,myConnection);

   try 
   {
      myCommand.Connection.Open();
   }
   catch (MySqlException e) 
   {
        MessageBox.Show( e.Message );
   }
}
    

26.2.3.7. MySqlHelper類

助手類,能使與提供方(Provider)一起進行的工作變的更簡單。開發人員可以使用該類提供的方法自動執行共同任務。
26.2.3.7.1. 屬性
MySqlHelper類沒有相應的屬性。
26.2.3.7.2. 方法
可用方法如下:

·         ExecuteDataRow:執行單個SQL語句並返回結果集的第1行。在該方法的執行過程中,將建立、打開並關閉1個新的MySqlConnection對象。

·         ExecuteDataset:執行單個SQL命令並返回DataSet中的結果集。在該方法的執行過程中,將建立、打開並關閉1個新的MySqlConnection對象。

·         ExecuteNonQuery:在MySQL資料庫上執行單個命令。使用該方法時,將認為MySqlConnection已打開,方法執行完後,MySqlConnection仍保持打開狀態。

·         ExecuteReader:Overloaded:在MySQL資料庫上執行單個命令。

·         ExecuteScalar:在MySQL資料庫上執行單個命令。

·         UpdateDataSet:用來自給定DataSet的數據更新給定資料表。

26.2.3.8. MySqlTransaction類

代資料表將在MySQL資料庫中進行的SQL事務。
26.2.3.8.1. 屬性
可用屬性如下:

·         Connection:獲取與事務相關的MySqlConnection對象,如果事務不再有效,獲取空引用(在Visual Basic中為Nothing)。

·         IsolationLevel:為該事務指定IsolationLevel。

26.2.3.8.2. 方法
可用方法如下:

·         Commit:提交資料庫事務。

·         Rollback:從掛起狀態回滾事務。

26.2.3.8.3. 用法
在下面的示範中,建立了1個MySqlConnection和1個MySqlTransaction。此外,在示範中還介紹了如何使用BeginTransaction、Commit和Rollback方法。
26.2.3.8.3.1. VB.NET

在下例中,介紹了在VB.NET中使用MySqlTransaction類的方法:

Public Sub RunTransaction(myConnString As String)
    Dim myConnection As New MySqlConnection(myConnString)
    myConnection.Open()
    
    Dim myCommand As MySqlCommand = myConnection.CreateCommand()
    Dim myTrans As MySqlTransaction
    
    ' Start a local transaction
    myTrans = myConnection.BeginTransaction()
    ' Must assign both transaction object and connection
    ' to Command object for a pending local transaction
    myCommand.Connection = myConnection
    myCommand.Transaction = myTrans
    
    Try
      myCommand.CommandText = "Insert into Region (RegionID, RegionDescription) VALUES (100, 'Description')"
      myCommand.ExecuteNonQuery()
      myCommand.CommandText = "Insert into Region (RegionID, RegionDescription) VALUES (101, 'Description')"
      myCommand.ExecuteNonQuery()
      myTrans.Commit()
      Console.WriteLine("Both records are written to database.")
    Catch e As Exception
      Try
        myTrans.Rollback()
      Catch ex As MySqlException
        If Not myTrans.Connection Is Nothing Then
          Console.WriteLine("An exception of type " & ex.GetType().ToString() & _
                            " was encountered while attempting to roll back the transaction.")
        End If
      End Try
    
      Console.WriteLine("An exception of type " & e.GetType().ToString() & _
                      "was encountered while inserting the data.")
      Console.WriteLine("Neither record was written to database.")
    Finally
      myConnection.Close()
    End Try
End Sub 'RunTransaction       
      
26.2.3.8.3.2. C#

在下例中,介紹了在C#中使用MySqlTransaction類的方法:

public void RunTransaction(string myConnString) 
 {
    MySqlConnection myConnection = new MySqlConnection(myConnString);
    myConnection.Open();

    MySqlCommand myCommand = myConnection.CreateCommand();
    MySqlTransaction myTrans;

    // Start a local transaction
    myTrans = myConnection.BeginTransaction();
    // Must assign both transaction object and connection
    // to Command object for a pending local transaction
    myCommand.Connection = myConnection;
    myCommand.Transaction = myTrans;

    try
    {
      myCommand.CommandText = "Insert into Region (RegionID, RegionDescription) VALUES (100, 'Description')";
      myCommand.ExecuteNonQuery();
      myCommand.CommandText = "Insert into Region (RegionID, RegionDescription) VALUES (101, 'Description')";
      myCommand.ExecuteNonQuery();
      myTrans.Commit();
      Console.WriteLine("Both records are written to database.");
    }
    catch(Exception e)
    {
      try
      {
        myTrans.Rollback();
      }
      catch (MySqlException ex)
      {
        if (myTrans.Connection != null)
        {
          Console.WriteLine("An exception of type " + ex.GetType() +
                            " was encountered while attempting to roll back the transaction.");
        }
      }
    
      Console.WriteLine("An exception of type " + e.GetType() +
                        " was encountered while inserting the data.");
      Console.WriteLine("Neither record was written to database.");
    }
    finally 
    {
      myConnection.Close();
    }
}       
      

26.2.4. 使用MySQL Connector/NET

26.2.4.1. 前言

在本節中,介紹的Connector/NET的一些常用方式,包括BLOB處理,日期處理,以及與諸如Crystal Reports等常見工具一起使用Connector/NET的方法。

26.2.4.2. 使用MySQL Connector/NET連接到MySQL

26.2.4.2.1. 前言
.NET應用程式和MySQL伺服器之間的所有交互均是通過MySqlConnection對像傳送的。在應用程式能夠與伺服器進行交互之前,必須獲取、配置、並打開MySqlConnection對象。

即使在使用MySqlHelper類時,MySqlConnection對象也會被Helper類建立。

在本節中,介紹了使用MySqlConnection對像連接到MySQL的方法。

26.2.4.2.2. 建立連接字串

MySqlConnection對象是使用連接字串配置的。1個連接字串包含伺服器鍵/值對,由分號隔開。每個鍵/值對由等號連接。

下面給出了1個簡單的連接字串示範:

    Server=127.0.0.1;Uid=root;Pwd=12345;Database=test;
    

在本例中,對MySqlConnection對像進行了配置,使用帳號root和密碼12345與位於127.0.0.1的MySQL伺服器相連。所有語句的預設資料庫為測試資料庫。

典型的選項如下(關於選項的完整清單,請參見API文檔):

·         Server:將要連接的MySQL實例的名稱或網絡地址。預設為本地主機。別名包括Host, Data Source, DataSource, Address, AddrNetwork Address。

·         Uid:連接時使用的MySQL用戶帳號。別名包括User Id, UsernameUser name。

·         Pwd:MySQL帳號的密碼。也可以使用別名密碼。

·         Database:所有語句作用於的預設資料庫。預設為mysql。也可以使用別名Initial Catalog

·         Port:MySQL用於監聽連接的端口。預設為3306。將該值指定為「-1將使用命名管道連接。

26.2.4.2.3. 打開連接

一旦建立了連接字串,可使用它打開與MySQL伺服器的連接。

下述代碼用於建立MySqlConnection對象,指定連接字串,並打開連接。

[VB]

Dim conn As New MySql.Data.MySqlClient.MySqlConnection
Dim myConnectionString as String

myConnectionString = "server=127.0.0.1;" _
            & "uid=root;" _
            & "pwd=12345;" _
            & "database=test;"

Try
  conn.ConnectionString = myConnectionString
  conn.Open()

Catch ex As MySql.Data.MySqlClient.MySqlException
  MessageBox.Show(ex.Message)
End Try
  

[C#]

MySql.Data.MySqlClient.MySqlConnection conn;
string myConnectionString;
    
myConnectionString = "server=127.0.0.1;uid=root;" +
    "pwd=12345;database=test;";
  
try
{
    conn = new MySql.Data.MySqlClient.MySqlConnection();
    conn.ConnectionString = myConnectionString;
    conn.Open();
}
catch (MySql.Data.MySqlClient.MySqlException ex)
{
    MessageBox.Show(ex.Message);
}

您也可以將連接字串傳遞給MySqlConnection類的構造函數:

[VB]

Dim myConnectionString as String

myConnectionString = "server=127.0.0.1;" _
              & "uid=root;" _
              & "pwd=12345;" _
              & "database=test;" 

Try
    Dim conn As New MySql.Data.MySqlClient.MySqlConnection(myConnectionString)
    conn.Open()
Catch ex As MySql.Data.MySqlClient.MySqlException
   MessageBox.Show(ex.Message)
End Try
  

[C#]

MySql.Data.MySqlClient.MySqlConnection conn;
string myConnectionString;

myConnectionString = "server=127.0.0.1;uid=root;" +
    "pwd=12345;database=test;";

try
{
    conn = new MySql.Data.MySqlClient.MySqlConnection(myConnectionString);
    conn.Open();
}
catch (MySql.Data.MySqlClient.MySqlException ex)
{
    MessageBox.Show(ex.Message);
}
一旦打開了連接,其他MySQL Connector/NET類也能使用該連接與MySQL伺服器進行通信。
26.2.4.2.4. 處理連接錯誤

由於與外部伺服器的連接不可預測,應為您的.NET應用程式新增錯誤處理功能,這點很重要。出現連接錯誤時,MySqlConnection類將返回1個MySqlException對象。該對像有兩個在處理錯誤時十分有用的屬性:

·         Message:描述當前異常的消息。

·         Number:MySQL錯誤編號。

處理錯誤時,可根據錯誤編號瞭解應用程式的響應。進行連接時最常見的兩個錯誤編號如下:

·         0: 無法連接到伺服器。

·         1045: 無效的帳號和/或密碼。

在下面的代碼中,介紹了根據實際錯誤改編應用程式的方法:

[VB]

Dim myConnectionString as String

myConnectionString = "server=127.0.0.1;" _
          & "uid=root;" _
          & "pwd=12345;" _
          & "database=test;" 

Try
    Dim conn As New MySql.Data.MySqlClient.MySqlConnection(myConnectionString)
    conn.Open()
Catch ex As MySql.Data.MySqlClient.MySqlException
    Select Case ex.Number
        Case 0
            MessageBox.Show("Cannot connect to server. Contact administrator")
        Case 1045
            MessageBox.Show("Invalid username/password, please try again")
    End Select
End Try
  

[C#]

MySql.Data.MySqlClient.MySqlConnection conn;
string myConnectionString;

myConnectionString = "server=127.0.0.1;uid=root;" +  
    "pwd=12345;database=test;";

try
{
    conn = new MySql.Data.MySqlClient.MySqlConnection(myConnectionString);
    conn.Open();
}
    catch (MySql.Data.MySqlClient.MySqlException ex)
{
    switch (ex.Number)
    {
        case 0:
            MessageBox.Show("Cannot connect to server.  Contact administrator");
        case 1045:
            MessageBox.Show("Invalid username/password, please try again");
    }
}
  

26.2.4.3. 與預處理語句一起使用MySQL Connector/NET

26.2.4.3.1. 前言
從MySQL 4.1開始,能夠與MySQL Connector/NET一起使用預處理語句。使用預處理語句能夠現住改善多次執行的查詢的性能。

對於多次執行的語句,預處理執行的速度快於直接執行,這是因為只需進行1次解析操作。在直接執行的情況下,每次執行時均將進行解析操作。預處理執行還能降低網絡通信量,這是因為對於預處理語句的每次執行,僅需發送用於參數的數據。

預處理語句的另一優點是,它能使用二進制協議,這使得客戶端和伺服器間的數據傳輸更有效率。

26.2.4.3.2. 在MySQL Connector/NET中準備語句
為了準備好語句,需建立1個命令對象,並為查詢設置.CommandText屬性。

輸入語句後,使用MySqlCommand對象的.Prepare方法。完成語句的準備後,為查詢中的每個元素新增參數。

輸入查詢並輸入參數後,使用.ExecuteNonQuery().ExecuteScalar()、或.ExecuteReader方法執行語句。

對於後續的執行操作,僅需更改參數值並再次使用執行方法,無需設置.CommandText屬性或重新定義參數。

[VB]

Dim conn As New MySqlConnection
Dim cmd As New MySqlCommand
  
conn.ConnectionString = strConnection
 
Try
   conn.Open()
   cmd.Connection = conn
 
   cmd.CommandText = "INSERT INTO myTable VALUES(NULL, ?number, ?text)"
   cmd.Prepare()
 
   cmd.Parameters.Add("?number", 1)
   cmd.Parameters.Add("?text", "One")
 
   For i = 1 To 1000
       cmd.Parameters("?number").Value = i
       cmd.Parameters("?text").Value = "A string value"
 
       cmd.ExecuteNonQuery()
     Next 
Catch ex As MySqlException
    MessageBox.Show("Error " & ex.Number & " has occurred: " & ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
  

[C#]

MySql.Data.MySqlClient.MySqlConnection conn;
MySql.Data.MySqlClient.MySqlCommand cmd;
  
conn = new MySql.Data.MySqlClient.MySqlConnection();
cmd = new MySql.Data.MySqlClient.MySqlCommand();
 
conn.ConnectionString = strConnection;
 
try
{
    conn.Open();
    cmd.Connection = conn;
 
    cmd.CommandText = "INSERT INTO myTable VALUES(NULL, ?number, ?text)";
    cmd.Prepare();
 
    cmd.Parameters.Add("?number", 1);
    cmd.Parameters.Add("?text", "One");
 
    for (int i=1; i <= 1000; i++)
    {
        cmd.Parameters["?number"].Value = i;
        cmd.Parameters["?text"].Value = "A string value";
 
        cmd.ExecuteNonQuery();
    }
}
catch (MySql.Data.MySqlClient.MySqlException ex)
{
    MessageBox.Show("Error " + ex.Number + " has occurred: " + ex.Message,
        "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}

26.2.4.4. 用MySQL Connector/NET訪問儲存程式

26.2.4.4.1. 前言

隨著MySQL版本5的發佈,MySQL伺服器目前支援儲存程式,它採用了SQL 2003儲存程式的語法。

 

儲存程式指的是能夠保存在伺服器上的一組SQL語句。 一旦完成了該操作,客戶端無需再次發出單獨語句,而僅需引用儲存程式取而代之。

在下述情況下,儲存程式尤其有用:

·         多個客戶端應用程式是採用不同語言編寫的或工作在不同平台上,但需執行相同的資料庫操作。

·         安全性極其重要時。例如,對於所有共同操作,銀行採用了儲存程式。這樣,就能提供一致且安全的環境,而且這類儲存程式能夠保證每次操作均具有恰當登錄。在這類設置下,應用程式和用戶無法直接訪問資料庫資料表,但能執行特定的儲存程式。

MySQL Connector/NET支援通過MySqlCommand對象的儲存程式使用。使用MySqlCommand.Parameters集,能夠將數據傳入和傳出MySQL儲存程式。

在本節中,未深度介紹建立儲存程式方面的訊息,要想瞭解這類訊息,請參見MySQL參考手冊的儲存程式

在MySQL Connector/NET安裝的Samples目錄下,可找到1個相應的示範,該示範演示了與MySQL Connector/NET一起使用儲存程式的方法。

26.2.4.4.2. 從MySQL Connector/NET建立儲存程式

可使用多種工具建立MySQL中的儲存程式。首先,可使用mysql命令行客戶端建立儲存程式。其次,可使用MySQL Query Browser GUI客戶端建立儲存程式。最後,可使用MySqlCommand對象的.ExecuteNonQuery方法建立儲存程式。

[VB]

Dim conn As New MySqlConnection
Dim cmd As New MySqlCommand

conn.ConnectionString = "server=127.0.0.1;" _
    & "uid=root;" _
    & "pwd=12345;" _
    & "database=test"

Try
    conn.Open()
    cmd.Connection = conn

    cmd.CommandText = "CREATE PROCEDURE add_emp(" _
        & "IN fname VARCHAR(20), IN lname VARCHAR(20), IN bday DATETIME, OUT empno INT) " _
        & "BEGIN INSERT INTO emp(first_name, last_name, birthdate) " _
        & "VALUES(fname, lname, DATE(bday)); SET empno = LAST_INSERT_ID(); END"
 
    cmd.ExecuteNonQuery()
Catch ex As MySqlException
    MessageBox.Show("Error " & ex.Number & " has occurred: " & ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try

[C#]

MySql.Data.MySqlClient.MySqlConnection conn;
MySql.Data.MySqlClient.MySqlCommand cmd;

conn = new MySql.Data.MySqlClient.MySqlConnection();
cmd = new MySql.Data.MySqlClient.MySqlCommand();

conn.ConnectionString = "server=127.0.0.1;uid=root;" +
    "pwd=12345;database=test;";

try
{
    conn.Open();
    cmd.Connection = conn;

    cmd.CommandText = "CREATE PROCEDURE add_emp(" +
        "IN fname VARCHAR(20), IN lname VARCHAR(20), IN bday DATETIME, OUT empno INT) " +
        "BEGIN INSERT INTO emp(first_name, last_name, birthdate) " +
        "VALUES(fname, lname, DATE(bday)); SET empno = LAST_INSERT_ID(); END";

    cmd.ExecuteNonQuery();
}
catch (MySql.Data.MySqlClient.MySqlException ex)
{
MessageBox.Show("Error " + ex.Number + " has occurred: " + ex.Message,
    "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
請注意,不同於命令行和GUI客戶端,在MySQL Connector/NET中建立儲存程式時不需要指定特殊的定界符。
26.2.4.4.3. 從MySQL Connector/NET使用儲存程式

要想使用MySQL Connector/NET來使用儲存程式,應建立1個MySqlCommand對象,並將儲存程式名作為.CommandText屬性傳遞。.CommandType屬性設置為CommandType.StoredProcedure。

命名了儲存程式後,為儲存程式中的每個參數建立1個MySqlCommand參數。用參數名和包含值的對象定義IN參數,用參數名和預計將返回的數據類型定義OUT參數。對於所有參數,均需定義參數方向。

定義完參數後,使用MySqlCommand.ExecuteNonQuery()方法使用儲存程式。

[VB]

Dim conn As New MySqlConnection
Dim cmd As New MySqlCommand

conn.ConnectionString = "server=127.0.0.1;" _
    & "uid=root;" _
    & "pwd=12345;" _
    & "database=test"

Try
    conn.Open()
    cmd.Connection = conn

    cmd.CommandText = "add_emp"
    cmd.CommandType = CommandType.StoredProcedure

    cmd.Parameters.Add("?lname", 'Jones')
    cmd.Parameters("?lname").Direction = ParameterDirection.Input

    cmd.Parameters.Add("?fname", 'Tom')
    cmd.Parameters("?fname").Direction = ParameterDirection.Input

    cmd.Parameters.Add("?bday", #12/13/1977 2:17:36 PM#)
    cmd.Parameters("?bday").Direction = ParameterDirection.Input

    cmd.Parameters.Add("?empno", MySqlDbType.Int32)
    cmd.Parameters("?empno").Direction = ParameterDirection.Output

    cmd.ExecuteNonQuery()

    MessageBox.Show(cmd.Parameters("?empno").Value)
Catch ex As MySqlException
    MessageBox.Show("Error " & ex.Number & " has occurred: " & ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try

[C#]

MySql.Data.MySqlClient.MySqlConnection conn;
MySql.Data.MySqlClient.MySqlCommand cmd;

conn = new MySql.Data.MySqlClient.MySqlConnection();
cmd = new MySql.Data.MySqlClient.MySqlCommand();

conn.ConnectionString = "server=127.0.0.1;uid=root;" +
    "pwd=12345;database=test;";

try
{
    conn.Open();
    cmd.Connection = conn;

    cmd.CommandText = "add_emp";
    cmd.CommandType = CommandType.StoredProcedure;

    cmd.Parameters.Add("?lname", "Jones");
    cmd.Parameters("?lname").Direction = ParameterDirection.Input;

    cmd.Parameters.Add("?fname", "Tom");
    cmd.Parameters("?fname").Direction = ParameterDirection.Input;

    cmd.Parameters.Add("?bday", DateTime.Parse("12/13/1977 2:17:36 PM"));
    cmd.Parameters("?bday").Direction = ParameterDirection.Input;

    cmd.Parameters.Add("?empno", MySqlDbType.Int32);
    cmd.Parameters("?empno").Direction = ParameterDirection.Output;

    cmd.ExecuteNonQuery();

    MessageBox.Show(cmd.Parameters("?empno").Value);
}
catch (MySql.Data.MySqlClient.MySqlException ex)
{
    MessageBox.Show("Error " + ex.Number + " has occurred: " + ex.Message,
      "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
一旦使用了儲存程式,可使用MySqlConnector.Parameters集的.Value屬性檢索輸出參數的值。

26.2.4.5. 用Connector/NET處理BLOB數據

26.2.4.5.1. 前言
MySQL的1種用途是在BLOB列中保存二進制數據。MySQL支援4種不同的BLOB數據類型:TINYBLOB, BLOB, MEDIUMBLOBLONGBLOB

可使用Connector/NET訪問保存在BLOB列中的數據,並能使用客戶端代碼對這類數據進行操作。使用Connector/NET和BLOB數據時,無特殊要求。

在本節中,給出了數個簡單的代碼示範,在MySQL Connector/NET安裝的Samples目錄下,可找到1個完整的示範應用程式。

26.2.4.5.2. 準備MySQL伺服器
與BLOB數據一起使用MySQL的第1步是配置伺服器。首先,讓我們從建立要訪問的資料表開始。在我的檔案資料表中,通常有4列:1個具有恰當大小的AUTO_INCREMENT列(UNSIGNED SMALLINT),用於保存識別檔案的主鍵;1個VARCHAR列,用於保存檔案名;1個UNSIGNED MEDIUMINT列,用於保存檔案的大小;以及1個用於保存檔案本身的MEDIUMBLOB列。對於本例,我將使用下述資料表定義:
CREATE TABLE file(
file_id SMALLINT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
file_name VARCHAR(64) NOT NULL,
file_size MEDIUMINT UNSIGNED NOT NULL,
file MEDIUMBLOB NOT NULL);

完成資料表的建立後,或許需要更改max_allowed_packet系統變數。該變數決定了能夠發送給MySQL伺服器的訊息包(即單個行)大小。預設情況下,伺服器能夠接受來自客戶端應用程式的訊息包最大為1MB。如果不打算超過1MB,情況良好。如果打算在檔案傳輸中超出1MB,必須增加該數值。

可以使用「MySQL系統管理員的啟動變數」屏幕更改max_allowed_packet選項。在「聯網」選項卡的「內存」部分,恰當調整「允許的最大值」選項。完成值的調整後,點擊「應用更改」按鈕,並使用「MySQL管理員」的「服務控制」屏幕重新啟動伺服器。也可以在my.cnf檔案中直接調整該值(新增1行,max_allowed_packet=xxM),或在MySQL中使用SET max_allowed_packet=xxM。

設置max_allowed_packet時應保守些,這是因為傳輸BLOB數據需要一段時間。恰當地設置該值,使之與預期使用相符,並在必要時增大該值。

26.2.4.5.3. 將檔案寫入資料庫

要想將檔案寫入資料庫,需要將檔案轉換為字節數組,然後將字節數組用作INSERT查詢的參數。

在下述代碼中,使用FileStream對像打開了1個檔案,將其讀入至字節數組,然後將其插入到檔案資料表中:

[VB]

Dim conn As New MySqlConnection
Dim cmd As New MySqlCommand

Dim SQL As String

Dim FileSize As UInt32
Dim rawData() As Byte
Dim fs As FileStream

conn.ConnectionString = "server=127.0.0.1;" _
    & "uid=root;" _
    & "pwd=12345;" _
    & "database=test"

Try
    fs = New FileStream("c:\image.png", FileMode.Open, FileAccess.Read)
    FileSize = fs.Length
    
    rawData = New Byte(FileSize) {}
    fs.Read(rawData, 0, FileSize)
    fs.Close()
    
    conn.Open()
    
    SQL = "INSERT INTO file VALUES(NULL, ?FileName, ?FileSize, ?File)"
    
    cmd.Connection = conn
    cmd.CommandText = SQL
    cmd.Parameters.Add("?FileName", strFileName)
    cmd.Parameters.Add("?FileSize", FileSize)
    cmd.Parameters.Add("?File", rawData)
    
    cmd.ExecuteNonQuery()
    
    MessageBox.Show("File Inserted into database successfully!", _
    "Success!", MessageBoxButtons.OK, MessageBoxIcon.Asterisk)
    
    conn.Close()
Catch ex As Exception
    MessageBox.Show("There was an error: " & ex.Message, "Error", _
        MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
  

[C#]

MySql.Data.MySqlClient.MySqlConnection conn;
MySql.Data.MySqlClient.MySqlCommand cmd;

conn = new MySql.Data.MySqlClient.MySqlConnection();
cmd = new MySql.Data.MySqlClient.MySqlCommand();

string SQL;
UInt32 FileSize;
byte[] rawData;
FileStream fs;

conn.ConnectionString = "server=127.0.0.1;uid=root;" +
    "pwd=12345;database=test;";

try
{
    fs = new FileStream(@"c:\image.png", FileMode.Open, FileAccess.Read);
    FileSize = fs.Length;

    rawData = new byte[FileSize];
    fs.Read(rawData, 0, FileSize);
    fs.Close();

    conn.Open();

    SQL = "INSERT INTO file VALUES(NULL, ?FileName, ?FileSize, ?File)";

    cmd.Connection = conn;
    cmd.CommandText = SQL;
    cmd.Parameters.Add("?FileName", strFileName);
    cmd.Parameters.Add("?FileSize", FileSize);
    cmd.Parameters.Add("?File", rawData);

    cmd.ExecuteNonQuery();

    MessageBox.Show("File Inserted into database successfully!",
        "Success!", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);

    conn.Close();
}
catch (MySql.Data.MySqlClient.MySqlException ex)
{
    MessageBox.Show("Error " + ex.Number + " has occurred: " + ex.Message,
        "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
 
FileStream對象的Read方法可用於將檔案加載到字節數組中,該字節數組的大小是根據FileStream對象的Length屬性確定的。

將字節數組指定為MySqlCommand對象的參數後,使用ExecuteNonQuery方法,並將BLOB插入到檔案資料表中。

26.2.4.5.4. 將BLOB從資料庫讀取到磁盤上的檔案

一旦將檔案加載到了檔案資料表中,就能使用MySqlDataReader類來檢索它。

在下述代碼中,從檔案資料表提取了1行,然後將數據裝載到要寫入至磁盤的FileStream對象。

[VB]

Dim conn As New MySqlConnection
Dim cmd As New MySqlCommand
Dim myData As MySqlDataReader
Dim SQL As String
Dim rawData() As Byte
Dim FileSize As UInt32
Dim fs As FileStream

conn.ConnectionString = "server=127.0.0.1;" _
    & "uid=root;" _
    & "pwd=12345;" _
    & "database=test"

SQL = "SELECT file_name, file_size, file FROM file"

Try
    conn.Open()
    
    cmd.Connection = conn
    cmd.CommandText = SQL
    
    myData = cmd.ExecuteReader
    
    If Not myData.HasRows Then Throw New Exception("There are no BLOBs to save")
    
    myData.Read()
    
    FileSize = myData.GetUInt32(myData.GetOrdinal("file_size"))
    rawData = New Byte(FileSize) {}
    
    myData.GetBytes(myData.GetOrdinal("file"), 0, rawData, 0, FileSize)
    
    fs = New FileStream("C:\newfile.png", FileMode.OpenOrCreate, FileAccess.Write)
    fs.Write(rawData, 0, FileSize)
    fs.Close()
    
    MessageBox.Show("File successfully written to disk!", "Success!", MessageBoxButtons.OK, MessageBoxIcon.Asterisk)
    
    myData.Close()
    conn.Close()
Catch ex As Exception
    MessageBox.Show("There was an error: " & ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
  

[C#]

MySql.Data.MySqlClient.MySqlConnection conn;
MySql.Data.MySqlClient.MySqlCommand cmd;
MySql.Data.MySqlClient.MySqlDataReader myData;

conn = new MySql.Data.MySqlClient.MySqlConnection();
cmd = new MySql.Data.MySqlClient.MySqlCommand();

string SQL;
UInt32 FileSize;
byte[] rawData;
FileStream fs;

conn.ConnectionString = "server=127.0.0.1;uid=root;" +
    "pwd=12345;database=test;";

SQL = "SELECT file_name, file_size, file FROM file";

try
{
    conn.Open();

    cmd.Connection = conn;
    cmd.CommandText = SQL;

    myData = cmd.ExecuteReader();

    if (! myData.HasRows)
        throw new Exception("There are no BLOBs to save");

    myData.Read();

    FileSize = myData.GetUInt32(myData.GetOrdinal("file_size"));
    rawData = new byte[FileSize];

    myData.GetBytes(myData.GetOrdinal("file"), 0, rawData, 0, FileSize);

    fs = new FileStream(@"C:\newfile.png", FileMode.OpenOrCreate, FileAccess.Write);
    fs.Write(rawData, 0, FileSize);
    fs.Close();

    MessageBox.Show("File successfully written to disk!",
        "Success!", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);

    myData.Close();
    conn.Close();
}
catch (MySql.Data.MySqlClient.MySqlException ex)
{
    MessageBox.Show("Error " + ex.Number + " has occurred: " + ex.Message,
        "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
 
連接後,檔案資料表的內容將被加載到MySqlDataReader對像中。使用MySqlDataReader的GetBytes方法將BLOB加載到字節數組,然後使用FileStream對像將字節數據寫入磁盤。

MySqlDataReader的GetOrdinal方法可用於確定命名列的整數索引。如果SELECT查詢的列順序發生變化,使用GetOrdinal方法能夠防止錯誤。

26.2.4.6. 與Crystal Reports一起使用MySQL Connector/NET

26.2.4.6.1. 前言
Crystal Reports是Windows應用程式開發人員用於通報文檔生成的常用工具。在本節中,介紹了Crystal Reports XI與MySQL和Connector/NET一起使用的方法。

在MySQL Connector/NET安裝的Samples目錄的CrystalDemo子目錄下,可找到完整的示範應用程式。

26.2.4.6.2. 建立數據源

在Crystal Reports中建立報告時,在設計報告時,有兩個用於訪問MySQL數據的選項。

第1個選項是,設計報告時,使用Connector/ODBC作為ADO數據源。您能夠瀏覽資料庫,並使用拖放式操作選擇資料表和字段以建立報告。該方法的缺點是,必須在應用程式中執行額外操作以生成與報告預期的數據集匹配的數據集。

第2個選項是在VB.NET中建立數據集,並將其保存為XML格式。隨後,該XML檔案可被用於設計報告。在應用程式中顯示報告時,它的資料表現相當良好,但設計時的通用性較差,這是因為在建立數據集時,必須選擇所有的相關列。如果忘記選擇了某一列,在能夠將列新增到報告前,必須重新建立數據集。

使用下述代碼,可根據查詢操作建立數據集,並將其寫入磁盤。

[VB]

Dim myData As New DataSet
Dim conn As New MySqlConnection
Dim cmd As New MySqlCommand
Dim myAdapter As New MySqlDataAdapter

conn.ConnectionString = "server=127.0.0.1;" _
    & "uid=root;" _
    & "pwd=12345;" _
    & "database=world"

Try
    conn.Open()
    cmd.CommandText = "SELECT city.name AS cityName, city.population AS CityPopulation, " _ 
        & "country.name, country.population, country.continent " _
        & "FROM country, city ORDER BY country.continent, country.name"
    cmd.Connection = conn
    
    myAdapter.SelectCommand = cmd
    myAdapter.Fill(myData)
    
    myData.WriteXml("C:\dataset.xml", XmlWriteMode.WriteSchema)
Catch ex As Exception
    MessageBox.Show(ex.Message, "Report could not be created", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
 

[C#]

DataSet myData = new DataSet();
MySql.Data.MySqlClient.MySqlConnection conn;
MySql.Data.MySqlClient.MySqlCommand cmd;
MySql.Data.MySqlClient.MySqlDataAdapter myAdapter;

conn = new MySql.Data.MySqlClient.MySqlConnection();
cmd = new MySql.Data.MySqlClient.MySqlCommand();
myAdapter = new MySql.Data.MySqlClient.MySqlDataAdapter();

conn.ConnectionString = "server=127.0.0.1;uid=root;" +
  "pwd=12345;database=test;";
  
try
{
  cmd.CommandText = "SELECT city.name AS cityName, city.population AS CityPopulation, " +
  "country.name, country.population, country.continent " +
  "FROM country, city ORDER BY country.continent, country.name";
  cmd.Connection = conn;
  
  myAdapter.SelectCommand = cmd;
  myAdapter.Fill(myData);
  
  myData.WriteXml(@"C:\dataset.xml", XmlWriteMode.WriteSchema);
}
catch (MySql.Data.MySqlClient.MySqlException ex)
{
  MessageBox.Show(ex.Message, "Report could not be created",
  MessageBoxButtons.OK, MessageBoxIcon.Error);
}
設計報告時,可將該代碼生成的XML檔案用作ADO.NET XML數據源。

如果您選擇使用Connector/ODBC來設計報告,可從dev.mysql.com下載它。

26.2.4.6.3. 建立報告
對於大多數應用目的,標準的報告嚮導應能幫助您完成報告的最初建立。要想啟動嚮導,打開Crystal Reports並從「檔案」菜單選擇「New > Standard Report」選項。

嚮導首先要求您提供數據源。如果您正使用Connector/ODBC作為數據源,選擇數據源時,請使用OLE DB (ADO)樹的「用於ODBC的OLEDB provider」選項,,而不是來自ODBC (RDO)的對應選項。如果您使用的是已保存的數據集,請選擇ADO.NET (XML)選項,並瀏覽您保存的數據集。

在報告的建立過程中,剩餘部分將由嚮導自動完成。

建立完報告後,選擇「檔案」菜單中的「Report Options...」菜單項。取消對「Save Data With Report」(與報告一起保存數據)選項的選擇。這樣,就能防止保存的數據干擾應用程式中的數據加載操作。

26.2.4.6.4. 顯示報告

要想顯示報告,首先用報告所需的數據填充數據集,然後加載報告,並將其與綁定到數據集。最後,將報告傳遞給crViewer控制,以便向用戶顯示它。

在顯示報告的項目中,需要下述引用:

·         CrytalDecisions.CrystalReports.Engine

·         CrystalDecisions.ReportSource

·         CrystalDecisions.Shared

·         CrystalDecisions.Windows.Forms

在下述代碼中,假定您使用數據集(用建立數據源中給出的代碼保存的數據集)建立了報告,並在名為「myViewer」的資料表單上有1個crViewer控件。

[VB]

Imports CrystalDecisions.CrystalReports.Engine
Imports System.Data
Imports MySql.Data.MySqlClient

Dim myReport As New ReportDocument
Dim myData As New DataSet
Dim conn As New MySqlConnection
Dim cmd As New MySqlCommand
Dim myAdapter As New MySqlDataAdapter

conn.ConnectionString = _
    "server=127.0.0.1;" _
    & "uid=root;" _
    & "pwd=12345;" _
    & "database=test"

Try
    conn.Open()
    
    cmd.CommandText = "SELECT city.name AS cityName, city.population AS CityPopulation, " _ 
        & "country.name, country.population, country.continent " _
        & "FROM country, city ORDER BY country.continent, country.name"
    cmd.Connection = conn
    
    myAdapter.SelectCommand = cmd
    myAdapter.Fill(myData)
    
    myReport.Load(".\world_report.rpt")
    myReport.SetDataSource(myData)
    myViewer.ReportSource = myReport
Catch ex As Exception
    MessageBox.Show(ex.Message, "Report could not be created", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try

[C#]

using CrystalDecisions.CrystalReports.Engine;
using System.Data;
using MySql.Data.MySqlClient;

ReportDocument myReport = new ReportDocument();
DataSet myData = new DataSet();
MySql.Data.MySqlClient.MySqlConnection conn;
MySql.Data.MySqlClient.MySqlCommand cmd;
MySql.Data.MySqlClient.MySqlDataAdapter myAdapter;

conn = new MySql.Data.MySqlClient.MySqlConnection();
cmd = new MySql.Data.MySqlClient.MySqlCommand();
myAdapter = new MySql.Data.MySqlClient.MySqlDataAdapter();

conn.ConnectionString = "server=127.0.0.1;uid=root;" +
    "pwd=12345;database=test;";

try
{
    cmd.CommandText = "SELECT city.name AS cityName, city.population AS CityPopulation, " +
        "country.name, country.population, country.continent " +
        "FROM country, city ORDER BY country.continent, country.name";
    cmd.Connection = conn;

    myAdapter.SelectCommand = cmd;
    myAdapter.Fill(myData);

    myReport.Load(@".\world_report.rpt");
    myReport.SetDataSource(myData);
    myViewer.ReportSource = myReport;
}
catch (MySql.Data.MySqlClient.MySqlException ex)
{
    MessageBox.Show(ex.Message, "Report could not be created",
        MessageBoxButtons.OK, MessageBoxIcon.Error);
}

使用相同的查詢(用於生成前面保存的數據集),可生成新的數據集。一旦填充了數據集,可使用ReportDocument加載報告檔案,並將其與數據集綁定在一起。ReportDocument是作為crViewer的ReportSource而傳遞的。

使用Connector/ODBC從單個資料表建立報告時,採用了相同的方法。數據集替換報告中使用的資料表,並恰當顯示報告。

如果報告是使用Connector/ODBC從多個資料表建立的,在我們的應用程式中必須建立具有多個資料表的數據集。這樣,就能用數據集中的報告替換報告數據源中的各個資料表。

在我們的MySqlCommand對像中提供多條SELECT語句,通過該方式,用多個資料表填充數據集。這些SELECT語句基於SQL查詢,如資料庫菜單「Show SQL Query」選項中的「Crystal Reports」中顯示的那樣。假定有下述查詢:

SELECT `country`.`Name`, `country`.`Continent`, `country`.`Population`, `city`.`Name`, `city`.`Population`
FROM `world`.`country` `country` LEFT OUTER JOIN `world`.`city` `city` ON `country`.`Code`=`city`.`CountryCode`
ORDER BY `country`.`Continent`, `country`.`Name`, `city`.`Name`

該查詢將被轉換為兩條SELECT查詢,並以下述代碼顯示:

[VB]

Imports CrystalDecisions.CrystalReports.Engine
Imports System.Data
Imports MySql.Data.MySqlClient

Dim myReport As New ReportDocument
Dim myData As New DataSet
Dim conn As New MySqlConnection
Dim cmd As New MySqlCommand
Dim myAdapter As New MySqlDataAdapter

conn.ConnectionString = "server=127.0.0.1;" _
    & "uid=root;" _
    & "pwd=12345;" _
    & "database=world"

Try
    conn.Open()
    cmd.CommandText = "SELECT name, population, countrycode FROM city ORDER BY countrycode, name; " _
        & "SELECT name, population, code, continent FROM country ORDER BY continent, name"
    cmd.Connection = conn
    
    myAdapter.SelectCommand = cmd
    myAdapter.Fill(myData)
    
    myReport.Load(".\world_report.rpt")
    myReport.Database.Tables(0).SetDataSource(myData.Tables(0))
    myReport.Database.Tables(1).SetDataSource(myData.Tables(1))
    myViewer.ReportSource = myReport
Catch ex As Exception
    MessageBox.Show(ex.Message, "Report could not be created", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try

[C#]

using CrystalDecisions.CrystalReports.Engine;
using System.Data;
using MySql.Data.MySqlClient;

ReportDocument myReport = new ReportDocument();
DataSet myData = new DataSet();
MySql.Data.MySqlClient.MySqlConnection conn;
MySql.Data.MySqlClient.MySqlCommand cmd;
MySql.Data.MySqlClient.MySqlDataAdapter myAdapter;

conn = new MySql.Data.MySqlClient.MySqlConnection();
cmd = new MySql.Data.MySqlClient.MySqlCommand();
myAdapter = new MySql.Data.MySqlClient.MySqlDataAdapter();

conn.ConnectionString = "server=127.0.0.1;uid=root;" +
    "pwd=12345;database=test;";

try
{
    cmd.CommandText = "SELECT name, population, countrycode FROM city ORDER " +
        "BY countrycode, name; SELECT name, population, code, continent FROM " +
        "country ORDER BY continent, name";
    cmd.Connection = conn;

    myAdapter.SelectCommand = cmd;
    myAdapter.Fill(myData);

    myReport.Load(@".\world_report.rpt");
    myReport.Database.Tables(0).SetDataSource(myData.Tables(0));
    myReport.Database.Tables(1).SetDataSource(myData.Tables(1));
    myViewer.ReportSource = myReport;
}
catch (MySql.Data.MySqlClient.MySqlException ex)
{
    MessageBox.Show(ex.Message, "Report could not be created",
        MessageBoxButtons.OK, MessageBoxIcon.Error);
}  
 
應將SELECT語句按字母順序排列,這點很重要,原因在於,這是報告希望其源資料表所具有的順序。對於報告中的每個資料表,均需要一條SetDataSource語句。

該方法會導致性能問題,這是因為Crystal Reports必須在客戶端一側將資料表綁定在一起,與使用以前保存的數據集相比,速度較慢。

26.2.4.7. 在MySQL Connector/NET中處理日期和時間訊息

26.2.4.7.1. 前言
MySQL和.NET語言處理日期和時間訊息的方式是不同的,MySQL允許使用無法由.NET數據類型資料表示的日期,如「0000-00-00 00:00:00如果處理步當,該差異會導致問題。

在本節中,介紹了使用MySQL Connector/NET時恰當處理日期和時間訊息的方法。

26.2.4.7.2. 使用無效日期時的問題
對於使用無效日期的開發人員來說,數據處理方面的差異會導致問題。無效的MySQL日期無法被加載到.NET DateTime對像中,包括NULL日期。

由於該原因,不能用MySqlDataAdapter類的Fill方法填充.NET DataSet對象,這是因為無效日期會導致System.ArgumentOutOfRangeException異常。

26.2.4.7.3. 限制無效日期
對日期問題的最佳解決方案是,限制用戶輸入無效日期。這即可在客戶端上進行,也可在伺服器端進行。

在客戶端上限制無效日期十分簡單,即總使用.NET DateTime類來處理日期。DateTime類僅允許有效日期,從而確保了資料庫中的值也是有效的。該方法的缺點是,在使用.NET和非.NET代碼操作資料庫的混合環境下不能使用它,這是因為各應用程式必須執行自己的日期驗證。

MySQL 5.0.2和更高版本的用戶可使用新的傳統SQL模式來限制無效日期值。關於使用傳統SQL模式的更多訊息,請參見http://dev.mysql.com/doc/mysql/en/server-sql-mode.html

26.2.4.7.4. 處理無效日期
強烈建議在您的.NET應用程式中應避免使用無效日期,儘管如此,也能tongguo MySqlDateTime數據類型使用無效日期。

MySqlDateTime數據類型支援MySQL伺服器支援的相同日期值。MySQL Connector/NET的預設行為是,對有效的日期值返回1個.NET DateTime對象,對無效日期值返回錯誤。可以更改該預設方式,使MySQL Connector/NET為無效日期返回MySqlDateTime對象。

要想使MySQL Connector/NET為無效日期返回MySqlDateTime對象,可在連接字串中新增下行:

  Allow Zero Datetime=True
  

請注意,使用MySqlDateTime類仍會產生問題。下面介紹了一些已知問題:

1.    無效日期的數據綁定仍會導致錯誤(零日期0000-00-00看上去不存在該問題)。

2.    ToString方法返回按標準MySQL格式進行格式處理的日期(例如,2005-02-23 08:50:25)。這與.NET DateTime類的ToString行為不同。

3.    MySqlDateTime類支援NULL日期,但.NET DateTime類不支援NULL日期。如果未首先檢查NULL,在試圖將MySQLDateTime轉換為DateTime時,會導致錯誤。

由於存在上述已知事宜,最佳建議仍是,在您的應用程式中僅使用有效日期。

26.2.4.7.5. 處理NULL日期

.NET DateTime數據類型不能處理NULL值。同樣,在查詢中為DateTime變數賦值時,必須首先檢查值是否是NULL。

使用MySqlDataReader時,在賦值前,應使用.IsDBNull方法檢查值是否為NULL:

[VB]

If Not myReader.IsDBNull(myReader.GetOrdinal("mytime")) Then
    myTime = myReader.GetDateTime(myReader.GetOrdinal("mytime"))
Else
    myTime = DateTime.MinValue
End If
  

[C#]

if (! myReader.IsDBNull(myReader.GetOrdinal("mytime")))
    myTime = myReader.GetDateTime(myReader.GetOrdinal("mytime"));
else
    myTime = DateTime.MinValue;
  
NULL值能夠在數據集中使用,也能將其綁定以構成控件,無需特殊處理。

26.2.5. MySQL Connector/NET變更史

26.2.5.1. 版本2.0.0

·         更正了在未填充Connection.Database的情況下使用儲存程式時出現的異常 (Bug #11450) 。

·         特定的殘缺查詢將觸發「連接必須是有效和打開的」錯誤消息 (Bug #11490) 。

26.2.5.2. 版本1.0.7

·         使用其某一參數含有特殊字元(如「@」)的儲存程式將產生異常。注意,必須啟用ANSI_QUOTES才會使之成為可能 (Bug #13753) 。

·         如果語句包含對相同參數的多個引用,無法對其進行預處理 (Bug #13541) 。

·         Ping()方法不更新Connection對象的State屬性 (Bug #13658) 。

26.2.5.3. 版本1.0.6

·         Nant構建序列有問題(Bug #12978)

·         如果傳遞的第1個值是NULL,參數的串行化操作失敗 (Bug #13276) 。

·         含下述字元的字段名將導致錯誤:()%<>/ (Bug #13036) 。

·         MySQL Connector/NET 1.0.5安裝程式不能同時安裝MySQL Connector/NET 1.0.4. (Bug #12835)。

·         在Mono上MySQL Connector/NET 1.0.5不能連接 (Bug #13345) 。

26.2.5.4. 版本1.0.5

·         連接字串中有多個主機時,MySQL Connector/NET無法與列資料表中的1個主機相連 (Bug #12628) 。

·         MySQL Connector/NET將新的十進制數據類型解釋為字節數組 (Bug #11294) 。

·         不支援cp1250字元編碼 (Bug #11621) 。

·         當.NET線程池無可用的工作線程時,連接可能失敗 (Bug #10637) 。

·         十進制參數導致語法錯誤 (Bug #11550, Bug #10486, Bug #10152)。

·         如果儲存程式不含參數,使用儲存程式將導致異常 (Bug #11542) 。

·         特定的殘缺查詢將觸發「連接必須是有效和打開的」錯誤消息 (Bug #11490) 。

·         除了預設資料庫外,MySqlCommandBuilder類不能處理引用了其他資料庫中資料表的查詢 (Bug #8382) 。

·         MySQL Connector/NET無法特定的局部設置一起正常工作 (WL#8228)。

·         未填充Connection.Database時使用儲存程式導致異常 (Bug #11450) 。

·         讀取TIMESTAMP列時產生異常 (Bug #7951) 。

·         用換行符隔開參數時,無法識別參數 (Bug #9722) 。

·         在初始連接上未設置連接字串時,使用MySqlConnection.clone將導致錯誤 (Bug #10281) 。

·         增加了對從MySQL Connector/NET使用儲存函數的支援 (Bug #10644) 。

·         MySQL Connector/NET不能連接到MySQL 4.1.14. (Bug #12771)。

·         用設計器新增了MySqlConnection對像時,無法設置ConnectionString屬性 (Bug #12551, Bug #8724)。

26.2.5.5. 版本1.0.4 1-20-05

·         Bug #7243:使用準備導致異常[已更正]。

·         更正了與預處理語句有關的另一個小問題。

·         Bug #7258:MySqlCommand.Connection返回IDbConnection [已更正]。

·         Bug #7345:MySqlAdapter.Fill方法拋出錯誤消息:需要非負數值[已更正]。

·         Bug #7478:MySqlCommand中的克隆方法問題[已更正]。

·         Bug #7612:當字段為NULL時,MySqlDataReader.GetString(index)返回了非Null值[已更正]。

·         Bug #7755:如果列是無符號類型,MySqlReader.GetInt32拋出異常[已更正]。

·         Bug #7704:GetBytes不再工作[已更正]。

·         Bug #7724:引用字元「\222」在EscapeString中未被引用[已更正]。

·         更正了命名管道不能與某些Blob功能一起工作的問題。

·         更正了與共享內存連接有關的問題。

·         Bug #7436:與多個結果集有關的問題 [已更正]。

·         在API參考文檔中增加了多個主題。

26.2.5.6. 版本1.0.3-gamma 12-10-04

·         使MySQL成為預設的命名管道名稱。

·         現在,連接時SHOW COLLATION可用於檢索完整的字元編碼ID列資料表。

·         更正了無效字元編碼索引:200 (Bug #6547) 。

·         安裝器現在包含了多個選項,可安裝至GAC中,並建立「開始」菜單項。

·         Bug #6863:MySqlCommand參數中的Int64支援[已更正]。

·         對於連接,現在無需在連接字串上給出資料庫。

·         Bug #6770:MySqlDataReader.GetChar(int i)拋出IndexOutOfRange異常[已更正]。

·         更正了因具有不同行數的多個結果集而導致的問題。

·         Bug #6983:再次拋出異常時異常堆棧跟蹤丟失[已更正]。

·         更正了與使用預處理語句檢測Null值有關的主要問題。

·         Bug #6902:解析儲存程式參數時的錯誤[已更正]。

·         Bug #6668:儲存程式的整數輸出參數返回為字串[已更正]。

·         Bug #7032:按文本分類的數據資料表中的MySqlDateTime,無數據 [已更正]。

·         Bug #7133:使用inout參數時的無效查詢字串[已更正]。

·         Bug #6831:與MySQL 4.0一起時,測試失敗,原因在於資料表名的大小寫敏感性[已更正]。

·         Bug #7132:插入DateTime導致System.InvalidCastException的拋出[已更正]。

·         Bug #6879:使用DATE_ADD-function時的InvalidCast[已更正]。

·         Bug #6634:1個打開的連接被主機系統關閉[已更正]。

·         為MySqlConnection新增了ServerThread屬性以顯示伺服器線程ID。

·         為MySqlConnection增加了Ping方法。

·         將測試包的名稱更改為MySql.Data.Tests.dll。

26.2.5.7. 版本1.0.2-gamma 04-11-15

·         更正了與MySqlBinary有關的問題,其中,無法使用字串值更新延伸的文本列。

·         更正了使用定制安裝時忽略的安裝目錄問題(Bug #6329)。

·         更正了設置命令文本將命令留在預處理狀態的問題。

·         更正了MySqlParameter雙類型處理問題(字串parameterName,對像值)(Bug #6428)。

·         更正了填充數據集時返回零日期「0000-00-00」錯誤(Bug #6429)。

·         更正了使用儲存程式可能會導致「Illegal mix of collations」(非法校對組合)的問題。

·         增加了charset連接字串選項。

·         更正了#HY000「Illegal mix of collations」(非法校對組合)(latin1_swedish_ci,IMPLICIT)和(utf8_general_ (Bug #6322)問題。

·         增加了TableEditor CS和VB示範。

·         更正了關於UCS-2的Charset-map問題(Bug #6541)。

·         更新了安裝器,包含了新的示範。

·         更正規了Long插入耗時很長的問題(Bug #5453)。

·         更正了對象無法被處理的問題(Bug #6649)。

·         提供方正將伺服器指定的字元編碼用作預設字元編碼。

26.2.5.8. 版本1.0.1-beta2 04-10-27

·         更正了MySqlParameter(string, object)構造函數中的可能問題BUG #5602

·         更正了BUG #5458,在longtext列上使用GetChars將拋出異常。

·         更正了BUG #5474,無法運行儲存程式來填充mysqlcommand.parameters。

·         更正了BUG #5469,設置DbType時拋出NullReferenceException。

·         更正了在關閉套接字之前連接器無法發出CMD_QUIT的問題。

·         更正了BUG #5392,MySqlCommand在字串文本內容中發現作為參數的「?」。

·         更正了與ConnectionInternal有關的問題,其中,1個鍵可能會被新增多次。

·         當伺服器版本為4.1.2或更高時,CP1252僅用於Latin1。

·         更正了BUG #5388,如果1行為NULL,DataReader通報所有行均為NULL。

·         虛擬化了驅動子系統,以便未來版本能輕易地支援客戶端或嵌入式伺服器。

·         再次使用字段緩衝,以減少內存分配並增加速度。

·         更正了相應的問題,使用接口時使用舊語法將導致問題。

·         對於寫入流操作,使用PacketWriter取代Packet。

·         在CompressedStream中再分解壓縮代碼,以清理NativeDriver。

·         增加了用於在預處理命令上重置命令文本的測試範例。

·         更正了給定Null值時MySqlParameterCollection.Add()將拋出不明異常的問題(Bug #5621)。

·         更正了MySqlCommand()中的構造函數初始化問題(Bug #5613)。

·         更正瞭解析「;」字元的問題(Bug #5876)。

·         更正了在DbType設置器中丟失引用的問題(Bug #5897)。

·         更正了使用YEAR數據類型時的System.OverflowException問題(Bug #6036)。

·         增加了聚合函數測試(實際上不是問題)。

·         更正了浮點參數(double, numeric, single, decimal)的序列化問題(Bug #5900)。

·         IsNullable錯誤(Bug #5796)。

·         更正了不遵守連接字串上給出的連接壽命的問題。

·         更正了不遵守Min Pool Size(最小池大小)的問題。

·         更正了MySqlDataReader和「show tables from ...」(從顯示資料表)行為(Bug #5256)。

·         實施了SequentialAccess。

·         更正了發現第1個0後MySqlDateTime在所有subseq.records上設置IsZero屬性的問題(Bug #6006)。

·         更正了無法正確顯示中文字的問題(Bug #5288)。

·         還更正了俄文字元支援。

·         更正了Method TokenizeSql()僅將有限的有效字元用於參數的問題(Bug #6217)。

·         更正了丟失resx檔案的NET Connector源(Bug #6216)。

·         更正了與檢索/更新查詢一起使用是會導致問題的DBNull值 (Bug #5798) 。

·         更正了仍有另一個「未設置給對像實例的對象引用」(Bug #5496)。

·         更正了PacketReader中的問題,其中,會試圖在EnsureCapacity中分配錯誤的緩衝大小。

·         更正了GetBoolean返回錯誤值的問題(Bug #6227)。

·         更正了帶有GetString(index)的DataReader一起讀取BLOB時的IndexOutOfBounds問題(Bug #6230)。

26.2.5.9. 版本1.0.0 04-09-01

·         更正了BUG# 3889,不能正確支援Thai編碼。

·         更新了很多測試範例。

·         更正了與使用壓縮有關的問題。

·         將貝塔1版本的版本號擴充為1.0.0。

·         增加了用於安裝器的COPYING.rtf檔案。

·         刪除了所有的XML註釋警告(以後將更好地清理它們)。

·         刪除了一些對ByteFX的最近引用。

26.2.5.10. 版本0.9.0 04-08-30

·         為預處理語句增加了測試定位器。

·         目前,所有類型的類均實施了SerializeBinary方法,用於將其數據發送給PacketWriter。

·         增加了PacketWriter類,允許將來的低內存大對像處理。

·         更正了運行預處理語句和儲存程式中存在的很多小問題。

·         更改了多條命令,使得在執行帶有特定參數(採用舊語法模式)的儲存程式時不再拋出異常。

·         SingleRow現在工作正常,即使在存在限制的情況下也同樣。

·         GetBytes目前僅作用在二進制列上。

·         Logger現在能夠截短長的SQL命令,從而使得blob列不會「撐爆」日誌。

·         主機和資料庫目前的預設值為「」,除非作了其他設置。

·         更正了BUG# 5214,忽略了連接超時。

·         增加了測試範例,針對bug# 5051:GetSchema不能正確工作。

·         更正了當列為關鍵字時GetSchema為IsUnique返回「假」的問題。

·         MySqlDataReader GetXXX方法目前採用了字段級MySqlValue對象,不執行轉換。

·         更正了BUG# 5097:DataReader為時間列返回NULL。

·         A增減了針對LOAD DATA LOCAL INFILE的測試範例。

·         增加了replacetext custom nant任務。

·         增加了CommandBuilderTest定位器。

·         為CommandBuilder增加了Last One Wins(最後一個勝出)特性。

·         更正了持續性安全訊息問題。

·         更正了GetBool,使得1, true, "true"和"yes"均可資料表示trueWL# 2024,從而使得參數標誌成為可配置的。

·         增加了"old syntax"連接字串參數,允許使用「@」參數標記符。

·         更正了Bug #4658,MySqlCommandBuilder。

·         更正了Bug #4864,如果「Persist Security Info」(持續性安全訊息)為假,ByteFX.MySqlClient將對密碼進行緩衝處理。

·         在所有的源檔案中更新了授權標誌,以包含FLOSS異常。

·         針對目前所有的MySql類型,增加了新的.Types名稱空間和具體實施。

·         增加了作為MySqlField子類的MySqlField41。

·         更改了很多類,使之能夠使用新的.Types類型。

·         將enum int類型更改為Int32,將short類型更改為Int16,並將bigint類型更改為Int64。

·         增加了偽類型UInt16、UInt32和UInt64,允許建立無符號參數。

·         現在,從連接池拉出連接時,連接將被復位。

·         在驅動程式中再次分解了auth代碼,使得其即能用於auth,也能用於reset。

·         在PoolingTests.cs中增加了UserReset測試。

·         現在,使用COM_CHANGE_USER從池中拉出連接時,連接將被復位。

·         實現了SingleResultSet行為。

·         實現了對unicode的支援。

·         為utf-8和ucs-2增加了字元編碼映射。

·         更正了Bug #4520,使用bytefx .net mysql驅動時,時間字段溢出。

·         在數據類型測試定位器中修改了時間測試,以便能夠檢查「hours > 24」的時間跨度。

·         更正了Bug #4505,在ByteFx.Data.MySqlClient.MySqlParameter中帶有反斜槓轉義的錯誤字串。

·         為參數測試範例TestQuoting增加了代碼,以測試反斜線符號。

·         更正了Bug #4486,與multi-word列名一起工作時,mysqlcommandbuilder失敗。

·         更正了TokenizeSql中的問題,其中,下劃線將中止獲取參數名中的字元。

·         為列名空間增加了測試範例。

·         更正了bug# 4324,MySqlDataReader.GetBytes不能正確工作。

·         為DataReader測試定位器增加了GetBytes()測試範例。

·         現在,能夠將InternalConnection.Configure中的所有伺服器變數讀入到Hashtable。

·         目前使用字串[],用於CharSetMap中的索引映射。

·         為SQL中的carriage返回增加了CRInSQL測試範例。

·         在Driver.ctor中,將maxPacketSize設為預設值。

·         更正了bug #4442,在參數上設置MySqlDbType的操作不設置一般類型。

·         刪除了過時的列類型Long和LongLong。

·         更正了bug# 4071,在連接字串上使用「use pipe」時,拋出溢出異常。

·         將關鍵字「use pipe」更改為「pipe name」或「pipe」。

·         允許從單個查詢讀取多個結果集。

·         為ServerStatusFlags enum增加了標誌屬性。

·         將ServerStatus enum的名稱更改為ServerStatusFlags。

·         更正了BUG #4386,插入的數據行未正確更新。

·         更正了bug #4074,錯誤處理表明建立了資料表。

·         將Packet.ReadLenInteger更改為ReadPackedLong,並增加了packet.ReadPackedInteger,它總讀取用2、3、4組裝的整數。

·         增加了syntax.cs測試定位器,以測試各種SQL語法問題。

·         更正了bug# 4149,對時間值的不當處理。現在,值「00:00:00」不再被當作Null。

·         將所有的測試包檔案移到了TestSuite檔案夾。

·         更正了空列會將結果訊息包指針向後移的問題。

·         增加了新的nant建立指令。

·         更正了BUG #3917,清除資料表名,以便能在下一GenerateSchema執行期間恰當地重新生成它。

·         更正了bug #3915,GetValues總返回0,而且總是試圖複製所有字段,而不是根據所傳入數組的大小。

·         實施了共享內存訪問協議。

·         實施了針對的MySQL 4.1的預處理語句。

·         實施了針對MySQL 5.0的儲存程式。

·         將MySqlInternalConnection重新命名為InternalConnection。

·         SQL現在被解釋為字元,更正了與其他語言有關的問題。

·         增加了日誌功能,並允許批連接字串選項。

·         更正了bug #3888,設置DataAdapter屬性時未設置RowUpdating事件。

·         更正了字元編碼映射中存在的問題。

·         實施了4.1鑒定。

·         改善了驅動中的open/auth代碼。

·         改善了在連接過程中連接位的設置方式。

·         現在,在初始的握手階段,將資料庫名傳遞給了伺服器。

·         將客戶端的名稱空間更改為MySql.Data.MySqlClient。

·         將客戶端的裝配名稱更改為MySql.Data.dll。

·         將所有源檔案中的授權文本更改為了GPL。

·         增加了MySqlClient.build Nant檔案。

·         刪除了mono批處理檔案。

·         將一些未使用的檔案移到了notused檔案夾,從而使得nant建立檔案能夠使用通配符。

·         實施了共享內存訪問。

·         對代碼結構進行了較大修補。

·         現在,預處理語句能夠在MySql 4.1.1和更高版本中使用。

·         對4.0、4.1.0和4.1.1完成了auth實施。

·         將名稱空間從MySQL.Data.MySQLClient更改為MySql.Data.MySqlClient。

·         更正了CharSetMapping中存在的問題,其中,它試圖將文本名稱用作ints。

·         將名稱空間更改為MySQL.Data.MySQLClient。

·         集成了來自UC2004的auth變動。

·         更正了在讀取數據之前和值後、在datareader上使用任何GetXXX方法時不能拋出恰當異常的問題(感謝Luca Morelli morelli.luca@iol.it)。

·         在parameter.cs中增加了TimeSpan代碼,以便能恰當地將timespan對像處理為mysql時間格式(感謝Gianluca Colombo g.colombo@alfi.it)。

·         為參數序列化代碼增加了TimeStamp。防止DataAdatper不正常的更新(感謝MIchael King)。

·         更正了MySqlHelper.cs中的拼寫錯誤(感謝Patrick Kristiansen)。

26.2.5.11. 版本0.76

·         驅動程式現在能使用握手協議中給定的字元編碼編號建立編碼。

·         更改了命令編輯器,使之指向MySqlClient.Design。

·         更正了Version.isAtLeast中的問題。

·         更改了DBConnectionString,使之能夠支援對MySqlConnectionString所作的更改。

·         刪除了SqlCommandEditor和DataAdapterPreviewDialog。

·         在很多地方採用了新的Long返回值。

·         集成了新的CompressedStream類。

·         更改了ConnectionString並增加了多項屬性,從而使之能夠在MySqlClient.Design中使用。

·         更改了packet.cs,以支援ReadLenInteger中的較新長度。

·         更改了其他類,以使用MySqlConnectionString的新屬性和字段。

·         現在,ConnectionInternal能夠使用PING命令查看伺服器是否可用。

·         將工具箱位圖移到了resource/下。

·         更改field.cs,允許值直接來自行緩衝器。

·         進行了相應的更改,以使用新的driver.Send語法。

·         使用了新的訊息包排隊系統。

·         開始著手進行「損壞的」壓縮訊息包處理。

·         更正了StreamCreator中的問題,無法連接到主機將導致無限循環(感謝Kevin Casella)。

·         改善了connectstring處理。

·         將設計器移到了Pro產品中。

·         從command.cs刪除了一些舊的、被註釋掉的代碼。

·         更正了與壓縮有關的1個問題。

·         更正了連接對象,打開連接前拋出的異常不會使連接保持在連接狀態(感謝Chris Cline)。

·         增加了GUID支援。

·         更正了序列混亂問題(感謝Mark Reay)。

26.2.5.12. 版本0.75

·         現在,可將Enum值作為參數值加以支援(感謝Philipp Sumi)。

·         支援Year數據類型。

·         更正了壓縮問題。

·         更正了以TimeSpan作為值的參數無法恰當序列化的問題。

·         更正了預設ctor不能設置預設連接字串值的問題。

·         為一些新成員增加了一些XML註釋。

·         著手更正/改善壓縮處理事宜。

·         改善了ConnectionString處理功能,使之能夠與SqlClient設定的標準更好地匹配。

·         如果帳號未包含在連接字串中,將拋出MySqlException。

·         如果在連接字串中未指定,本地主機將用作預設主機。

·         如果在連接打開的同時試圖設置連接字串,將拋出異常。

·         對ConnectionString文檔進行了小的修改。

·         刪除了MultiHostStream和MySqlStream。採用Common/StreamCreator取而代之。

·         增加了對「Use Pipe」連接字串值的支援。

·         增加了Platform類,以便能更容易地訪問平台的實用工具功能。

·         更正了小的連接池問題,即,在IsAlive失敗後,不能建立新的連接。

·         增加了Platform.cs和StreamCreator.cs。

·         更正了Field.cs,以便能恰當處理4.1版分格的時間戳。

·         將Common.Version更改為Common.DBVersion,以避免名稱衝突。

·         更正了field.cs,從而使得文本列能返回正確的字段類型(感謝beni27@gmx.net)。

·         增加了MySqlError類,以提供對錯誤代碼的一些引用(感謝Geert Veenstra)。

26.2.5.13. 版本0.74

·         增加了Unix套接字支援(感謝Mohammad DAMT [md@mt.web.id])。

·         沒有可用數據時,僅使用Thread.Sleep。

·         該井了參數數據中引用字元的轉義特性。

·         刪除了parameter.cs中易造成誤解的註釋。

·         更正了連接池問題。

·         再次更正了相同的連接池問題!! ;-)

·         更正了ConnectionSTring編輯器對話框(感謝marco p (pomarc))。

·         現在,在連接字串中支援UserId(感謝Jeff Neeley)。

·         建立非輸入參數時拋出異常(感謝Ryan Gregg)。

·         增加了更多文檔。

·         提供了新的MultiHostStream能力。誠摯感謝Dan Guisinger對此的貢獻。是他首次提供了在連接字串上支援多台機器的代碼和觀念。

·         增加了大量文檔。仍有很多文檔需要增加。

·         更正了與0.73有關的速度事宜。

·         更改了MySqlDataStream中的Thread.Sleep(0),以便在不需要等待時最佳化性能(感謝Todd German)。

·         預先將idlepools填充到了MinPoolSize。

·         個高質量MySqlPool死鎖條件以及愚蠢的問題,其中,CreateNewPooledConnection從不為連接池新增新連接。此外,還更正了MySqlStream.ReadBytes和ReadByte,從而不再使用並非始終正確的TicksPerSecond。(感謝Matthew J. Peddlesden)。

·         修正了精度和標度(感謝Matthew J. Peddlesden)。

·         為流讀取方法增加了Thread.Sleep(1),使之對CPU更友好(感謝Sean McGinnis)。

·         更正了ExecuteReader有時會返回Null的問題(感謝Lloyd Dupont)。

·         更正了與Null字段處理有關的主要問題(感謝Naucki)。

·         封裝了針對max_allowed_packet的查詢,以及Try Catch中的字元編碼(並設置為預設)。

·         更正了套接字未能恰當關閉的問題(感謝Steve)。

·         更正了ExecuteNonQuery不能始終返回正確值的問題。

·         更正了InternalConnection,不使用@@session.max_allowed_packet,而是使用@@max_allowed_packet。(感謝Miguel)。

·         增加了很多新XML文檔行。

·         更正了SQL解析功能,不發送控查詢(感謝Rory)。

·         更正了閱讀器在關閉時不能unpeeking訊息包的問題。

·         更正了不能處理用戶變數的問題(感謝Sami Vaaraniemi)。

·         更正了MySqlPool中的循環檢查功能(感謝Steve M. Brown)。

·         更正了ParameterCollection.Add方法,以與SqlClient匹配(感謝Joshua Mouch)。

·         更正了ConnectionSTring解析功能,以處理布爾類型的NO和YES,以及非小寫值(感謝Naucki)。

·         增加了InternalConnection類,修改了連接池功能。

·         實現了Persist Security Info(持續性安全訊息)。

·         為項目增加了security.cs和version.cs。

·         更正了Parameter.cs中的DateTime處理功能(感謝Burkhard Perkens-Golomb)。

·         更正了某些類型拋出cast異常的參數序列化問題。

·         更正了DataReader,轉換所有的返回值以防止拋棄錯誤(感謝Keith Murray)。

·         為Command.ExecuteReader增加了代碼,如果初始SQL命令拋出異常,將返回Null(感謝Burkhard Perkens-Golomb)。

·         構造了與重組一起引入ExecuteScalar問題。

·         進行了重新構造,允許LOCAL DATA INFILE,以及更好的訊息包排序。

·         更正了與重組有關的數個問題。

·         完成了前期工作,支援Mysql 4.1中更安全的密碼。不再支援4.1版中的舊密碼。

·         正確處理系統參數後顯示參數(Adam M. (adammil))。

·         現在,可將字串直接賦給blob字段(Adam M.)。

·         更正了浮點參數(感謝Pent)。

·         改善了參數ctor和ParameterCollection.Add方法,以更好地匹配SqlClient(感謝Joshua Mouch)。

·         更正了Connection.CreateCommand以返回MySqlCommand類型。

·         更正了連接字串設計器的對話框問題(感謝Abraham Guyt)。

·         更正了與發送命令無法總是讀取響應訊息包有關的問題(感謝Joshua Mouch)。

·         更正了某些Blob類型無法被處理的參數序列化問題(感謝Sean McGinnis)。

·         從DataReader代碼中刪除了偽MessageBox.show(感謝Joshua Mouch)。

·         更正了split sql代碼中的醜陋問題(感謝所有人! :-) )

26.2.5.14. 版本0.71

·         更正了MySqlStream中的問題,即可能會讀取過多數據(感謝Peter Belbin)。

·         實現了HasRows(感謝Nash Pherson)。

·         更正了大於256列的資料表會導致異常的問題(感謝Joshua Kessler)。

·         更正了以「;」結束的SQL語句會導致問題的問題(感謝Shane Krueger)。

·         更正了驅動中的問題,即,錯誤消息被截去1個字元(感謝Shane Krueger)。

·         使得MySqlException成為可序列化的(感謝Mathias Hasselmann)。

26.2.5.15. 版本0.70

·         更新了一些字元代碼頁,使之更加準確。

·         更正了閱讀器能夠在已有打開閱讀器的連接上打開的問題。

·         發佈了0.70。

·         將測試移至單獨的MySqlClientTests下。

·         更正了驅動程式序列混亂的愚蠢問題(感謝Peter Belbin)。

·         增加了一些管道測試。

·         將預設最大池大小增加到50。

·         與Mono 0-24一起進行了編譯。

·         更正了連接和數據閱讀器處理問題。

·         為參數序列化增加了字串數據類型處理功能。

·         更正了拋出異常後在驅動程式中出現的順序問題(感謝Burkhard Perkens-Golomb)。

·         增加了對CommandBehavior.SingleRow到DataReader的支援。

·         更正了命令sql的處理功能,以便能更好地處理引用(感謝Theo Spears)。

·         更正了double、single和decimal值的解析問題,以解釋非英文分隔符。如果您正使用硬編碼sql,仍須使用正確的語法,但是,如果您使用參數,代碼將轉換浮點類型,以便在進出伺服器的過程中恰當地在內部使用「.」。[感謝匿名人]。

·         增加了MySqlStream類,以簡化超時和驅動編碼。

·         更正了DataReader,以便在相關連接關閉時恰當地關閉它。[感謝smishra]。

·         使得客戶端更兼容SqlClient,在連接能夠用於運行另一命令前關閉DataReaders。

·         改進了字段中的DBNull.Value處理功能。

·         增加了數個單元測試。

·         更正了MySqlException,以便能使用基本類:-o

·         改進了驅動編碼。

·         更正了NextResult在最後1個結果集上返回「假」的問題。

·         為MySQL增加了多個測試。

·         通過等化無符號32bit值和Int64,以及無符號16bit值和Int32等,改進了拋棄問題。

·         為MySqlParameter增加了新的ctor(名稱、類型、大小、srccol)。

·         更正了MySqlDataReader中存在的問題,即,在返回字段計數前,不能檢查空的字段列資料表。

·         開始增加了MySqlClient單元測試(增加了MySqlClient/Tests檔案夾以及一些測試範例)。

·         更正了連接字串處理中的一些問題。

·         將INIT_DB移到MySqlPool。可或許會在此移動它,這是在協商的準備過程中。

·         更正了CommandBuilder中存在的問題,該問題會阻止插入正確出現。

·         改寫了一些內部構件,從而使得Command的所有三種執行方法均能正確工作。

·         更正了在基準測試過程中發現的一些小問題。

·         CoonectionPooling的首次截除工作恰當。保留了「min pool size」和「max pool size」。

·         進行處理,允許返回多個結果集。

·         現在,字元編碼的處理更為智能化。啟動時,驅動程式查詢MySQL,尋找預設的字元編碼。隨後,如果能夠加載代碼頁,該字元編碼將用於轉換。如不然,將使用當前作業系統的預設代碼頁。

·         增加了代碼,以便將推斷的類型保存在名稱,以及參數的值ctor中。

·         此外,如果使用Value屬性更改了空參數的值,還能推斷類型。

·         轉換了所有的檔案以使用恰當的Camel範例。現在,在所有檔案中,MySQL是MySql。PgSQL現在是PgSql。

·         為PgSql代碼增加了屬性,以防止設計器顯示它。

·         為參數對像增加了MySQLDbType屬性,並為從DbType到MySQLDbType的轉換增加了恰當的轉換代碼。

·         從MySQLParameter.cs中刪除了從未使用的ObjectToString方法。

·         更正了ParameterCollection中的Add(..)方法,不必使用Add(name, value)取而代之。

·         更正了ParameterCollection中的IndexOf和Contains,使之清楚保存參數名時不需要@。

·         更正了Command.ConvertSQLToBytes,僅允許能夠構出現在MySQL變數名中的字元。

·         更正了DataReader和字段,從而使得Blob字段能夠從Field.cs讀取其數據,而且GetBytes工作正確。

·         為MySQLCommand的CommandText屬性增加了簡單的構造器編輯器。

·         更正了CommandBuilder和Parameter序列化,指明在參數名稱中不保存@。

·         從Field.cs刪除了MySQLFieldType enum,現使用MySQLDbType enum。

·         為數個類增加了Designer屬性,防止了使用VS.Net時的設計器視圖。

·         更正了ConnectionString設計器中的初始目錄類型。

·         刪除了與(名稱、類型、值)衝突的3種MySQLParameter參數ctor。

·         更改了MySQLParameter,現在能夠保存paramName而無需前導@(這修正了使用設計器是的Null插入問題)。

·         更改了用於MySQLParameter的TypeConverter,以便能夠與所有屬性一起使用ctor。

26.2.5.16. 版本0.68

·         更正了驅動程式中的順序問題。

·         增加了DbParametersEditor,使得參數編輯更像SqlClient。

·         更正了Command類,以便能夠使用設計器編輯參數。

·         更新了連接字串設計器,支援使用壓縮標誌。

·         更正了字串編碼功能,從而使得歐洲字元(如a)能夠正確工作。

·         建立了基本類,以幫助建立新的數據Provider。

·         在連接字串中增加了對UID關鍵字的支援。

·         字段、參數和命令現在都能使用DBNull.Value,而不是null。

·         使用DBNull.Value的CommandBuilder。

·         未出現auto_insert字段時,CommandBuilder現在能正確建立插入命令。

·         現在,字段使用typeof關鍵字來返回System.Types(性能)。

26.2.5.17. 版本0.65

·         目前實現了MySQLCommandBuilder。

·         目前實現了事務支援(並非所有的資料表類型均支援它)。

·         更正了GetSchemaTable,不再使用xsd(對於Mono)。

·         驅動程式先能兼容Mono!!

·         現在支援TIME數據類型。

·         需要更多工作以改善Timestamp數據類型處理。

·         更改了所有類的特徵以匹配對應的SqlClient類。

26.2.5.18. 版本0.60

·         採用SharpZipLib的協議壓縮(www.icsharpcode.net)。

·         Windows平台上的命名管道現工作正常。

·         完成了更多工作,改善了Timestamp數據類型處理。

·         在DataReader上實現了Ienumerable,以使DataGrid能恰當工作。

26.2.5.19. 版本0.50

·         通過刪除網絡同步代碼中的問題,大幅度提高了速度。

·         驅動程式不再對數據行進行緩衝處理(更兼容ADO.Net)。

·         更正了與TIMESTAMP和DATETIME字段有關的轉換問題。

26.3. MySQL Connector/J

通過JDBC驅動,MySQL提供了與使用Java編程語言開發的客戶端應用程式的連通性,該驅動稱為MySQL Connector/J。

MySQL Connector/J是一種JDBC-3.0「類型4」驅動,這意味著它是一種純Java程式,實施了3.0版JDBC規範,並能使用MySQL協議與MySQL伺服器直接通信。

本文檔是為初級JDBC開發人員準備和安排的。如果您已有了使用JDBC方面的經驗,可直接從安裝 Connector/J開始。

儘管JDBC本身很有用,但我們希望,如果您在閱讀完本手冊的前幾節後尚未熟悉JDBC,除了最平常的問題外應避免全面使用「裸」JDBC,應考慮使用流行的架構,如HibernateSpringJDBC模板Ibatis SQL Maps等,使用它們來完成大多數重複性工作,以及在某些時侯需要用到JDBC的繁重任務。

本節不是作為完整的JDBC教程而設計的。如果需要瞭解使用JDBC方面的更多訊息,或許會對下述線上教程感興趣,與這裡提供的訊息相比,它們介紹的更為詳細和更具深度。

·         JDBC基礎,Sun公司提供的教程,涵蓋了JDBC的基本主題。。

·         JDBC簡明課程,Sun和JGuru提供了更深的教程。

26.3.1. 基本的JDBC概念

在本節中,介紹一些一般性的JDBC背景知識。

26.3.1.1. 使用DriverManager接口連接到MySQL

在應用伺服器外使用JDBC時,DriverManager類將用於管理連接的建立。

需要告訴DriverManager應與哪個JDBC驅動建立連接。完成該任務的最簡單方法是:在實施了java.sql.Driver接口的類上使用Class.forName()。對於MySQL Connector/J,該類的名稱是com.mysql.jdbc.Driver。採用該方法,可使用外部配置檔案來提供連接到資料庫時將使用的驅動類名和驅動參數。

在下面的Java代碼中,介紹了在應用程式的main()方法中註冊MySQL Connector/J的方式:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
 
// Notice, do not import com.mysql.jdbc.*
// or you will have problems!(注意,不要導入com.mysql.jdbc.*,否則// 將出現問題!)
 
public class LoadDriver {
    public static void main(String[] args) {
        try {
            // The newInstance() call is a work around for some
            // broken Java implementations
 
            Class.forName("com.mysql.jdbc.Driver").newInstance();
        } catch (Exception ex) {
            // handle the error
        }
}

在DriverManager中註冊了驅動後,通過使用DriverManager.getConnection(),能夠獲得與特殊資料庫相連的連接實例。

示範26.1:從DriverManager獲得連接

在本示範中,介紹了從DriverManager獲得連接實例的方法。對於getConnection()方法,有一些不同的特性。關於如何使用它們的更多訊息,請參閱與JDK一起提供的API文檔。

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
 
    ... try {
            Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/test?user=monty&password=greatsqldb");
 
            // Do something with the Connection
 
           ....
        } catch (SQLException ex) {
            // handle any errors
            System.out.println("SQLException: " + ex.getMessage());
            System.out.println("SQLState: " + ex.getSQLState());
            System.out.println("VendorError: " + ex.getErrorCode());
        }

一旦建立了連接,它可被用於建立語句和PreparedStatements,並檢索關於資料庫的元數據。在下面數節內,給出了進一步的解釋。

26.3.1.2. 使用語句以執行SQL

使用語句,可執行基本的SQL查詢,並通過下面介紹的ResultSet類檢索結果。

要想建立語句實例,應通過前面介紹的DriverManager.getConnection()或DataSource.getConnection()方法之一,在檢索的連接對像上使用createStatement()方法。

一旦擁有了語句實例,可以與希望使用的SQL一起通過使用executeQuery(String)方法執行SELECT查詢。

要想更新資料庫中的數據,可使用executeUpdate(String SQL)方法。該方法將返回受更新語句影響的行數。

如果您事先不清楚SQL語句是SELECT或UPDATE/INSERT,應使用execute(String SQL)方法。如果SQL查詢是SELECT,本方法將返回「真」,如果SQL查詢是UPDATE/INSERT/DELETE,本方法將返回「假」。如果是SELECT查詢,能夠通過使用getResultSet()方法檢索結果。如果是UPDATE/INSERT/DELETE查詢,能夠通過在語句實例上使用getUpdateCount()檢索受影響的行計數。

示範26.2:使用java.sql.Statement執行SELECT查詢

// assume conn is an already created JDBC connection
Statement stmt = null;
ResultSet rs = null;

try {
    stmt = conn.createStatement();
    rs = stmt.executeQuery("SELECT foo FROM bar");

    // or alternatively, if you don't know ahead of time that
    // the query will be a SELECT...

    if (stmt.execute("SELECT foo FROM bar")) {
        rs = stmt.getResultSet();
    }

    // Now do something with the ResultSet ....
} finally {
    // it is a good idea to release
    // resources in a finally{} block
    // in reverse-order of their creation
    // if they are no-longer needed

    if (rs != null) {
        try {
            rs.close();
        } catch (SQLException sqlEx) { // ignore }

        rs = null;
    }

    if (stmt != null) {
        try {
            stmt.close();
        } catch (SQLException sqlEx) { // ignore }

        stmt = null;
    }
}

26.3.1.3. 使用CallableStatements以執行儲存程式

從MySQL伺服器5.0版開始,與Connector/J 3.1.1或更新版本一起使用時,可完全實現java.sql.CallableStatement接口,getParameterMetaData()方法例外。

在MySQL參考手冊的「儲存程式和函數」一節中,介紹了MySQL儲存程式的語法。

通過JDBC的CallableStatement接口,Connector/J指明了儲存程式的功能。

在下面的示範中,給出了1個儲存程式,它返回增量為1的inOutParam的值,並通過inputParam傳遞了作為ResultSet的字串。

示範26.3. 儲存程式示範

CREATE PROCEDURE demoSp(IN inputParam VARCHAR(255), INOUT inOutParam INT)
BEGIN
    DECLARE z INT;
    SET z = inOutParam + 1;
    SET inOutParam = z;
 
    SELECT inputParam;
 
    SELECT CONCAT('zyxw', inputParam);
END

要想與Connector/J一起使用demoSp,可採取下述步驟:

1.    使用Connection.prepareCall()準備可使用語句。

注意,必須使用JDBC轉義語法,而且必須使用包含佔位符的圓括號:

示範26.4. 使用Connection.prepareCall()

導入java.sql.CallableStatement
 
...
 
    //
    // Prepare a call to the stored procedure 'demoSp'
    // with two parameters
    //
    // Notice the use of JDBC-escape syntax ({call ...})
    //
 
    CallableStatement cStmt = conn.prepareCall("{call demoSp(?, ?)}");
 
 
 
    cStmt.setString(1, "abcdefg");

註釋:

Connection.prepareCall()是一種開銷很大的方法,原因在於驅動程式執行的支援輸出參數的元數據檢索。出於性能方面的原因,應在您的代碼中再次使用CallableStatement實例,通過該方式,使對Connection.prepareCall()的不必要使用降至最低。

2.      註冊輸出參數(如果有的話)

為了檢索輸出參數的值(建立儲存程式時指定為OUT或INOUT的參數),JDBC要求在CallableStatement接口中使用各種registerOutputParameter()方法來執行語句之前指定它們:

示範26.5. 註冊輸出參數

導入java.sql.Types
 
...
    //
    // Connector/J supports both named and indexed
    // output parameters. You can register output
    // parameters using either method, as well
    // as retrieve output parameters using either
    // method, regardless of what method was
    // used to register them.
    //
    // The following examples show how to use
    // the various methods of registering
    // output parameters (you should of course
    // use only one registration per parameter).
    //
 
    //
    // Registers the second parameter as output
    //
 
    cStmt.registerOutParameter(2);
 
    //
    // Registers the second parameter as output, and
    // uses the type 'INTEGER' for values returned from
    // getObject()
    //
 
    cStmt.registerOutParameter(2, Types.INTEGER);
 
    //
    // Registers the named parameter 'inOutParam'
    //
 
    cStmt.registerOutParameter("inOutParam");
 
    //
    // Registers the named parameter 'inOutParam', and
    // uses the type 'INTEGER' for values returned from
    // getObject()
    //
 
    cStmt.registerOutParameter("inOutParam", Types.INTEGER);
 
...

3.      設置輸入參數(如果有的話)

輸入以及輸入/輸出參數是作為PreparedStatement對像而設置的。但是,CallableStatement也支援按名稱設置參數:

示範26.6. 設置CallableStatement輸入參數

...
 
    //
    // Set a parameter by index
    //
 
    cStmt.setString(1, "abcdefg");
 
    //
    // Alternatively, set a parameter using
    // the parameter name
    //
 
    cStmt.setString("inputParameter", "abcdefg");
 
    //
    // Set the 'in/out' parameter using an index
    //
 
    cStmt.setInt(2, 1);
 
    //
    // Alternatively, set the 'in/out' parameter
    // by name
    //
 
    cStmt.setInt("inOutParam", 1);
 
...

4.    執行CallableStatement,並檢索任何結果集或輸出參數。

儘管CallableStatement支援使用任何語句執行方法(executeUpdate()executeQuery()execute()),最靈活的方法是使用execute(),這是因為,採用該方法,您無需事先知道儲存程式是否將返回結果集:

示範26.7. 檢索結果和輸出參數值

...
 
    boolean hadResults = cStmt.execute();
 
    //
    // Process all returned result sets
    //
 
    while (hadResults) {
        ResultSet rs = cStmt.getResultSet();
 
        // process result set
        ...
 
        hadResults = cStmt.getMoreResults();
    }
 
    //
    // Retrieve output parameters
    //
    // Connector/J supports both index-based and
    // name-based retrieval
    //
 
    int outputValue = cStmt.getInt(1); // index-based
 
    outputValue = cStmt.getInt("inOutParam"); // name-based
 
...

26.3.1.4. 檢索AUTO_INCREMENT列的值

在JDBC API 3.0版之前,沒有從支援「自動增量」或ID列的資料庫中檢索關鍵值的標準方法。對於針對MySQL的早期JDBC驅動,總是不得不在語句接口上使用特定的MySQL方法,或在向擁有AUTO_INCREMENT關鍵字的資料表發出「INSERT後」發出「SELECT LAST_INSERT_ID()」。特殊的MySQL方法使用是不可移植的,而且對於發出「SELECT」以獲取AUTO_INCREMENT關鍵字的值來說,需要對資料庫執行另一往返操作,其效率不高。在下面的代碼片段中,介紹了檢索AUTO_INCREMENT值的三種不同方式。首先,介紹了JDBC-3.0新方法「getGeneratedKeys()」的使用方式,當您需要檢索AUTO_INCREMENT關鍵字並訪問JDBC-3.0,它是目前的首選方法。在第2個示範中,介紹了使用標準「SELECT LAST_INSERT_ID()」查詢檢索相同值的方法。在最後一個示範中,介紹了使用「insertRow()」方法時,用可更新結果集檢索AUTO_INCREMENT值的方式。

示範26.8. 使用Statement.getGeneratedKeys()檢索AUTO_INCREMENT列的值

   Statement stmt = null;
   ResultSet rs = null;

   try {

    //
    // Create a Statement instance that we can use for
    // 'normal' result sets assuming you have a
    // Connection 'conn' to a MySQL database already
    // available

    stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,
                                java.sql.ResultSet.CONCUR_UPDATABLE);

    //
    // Issue the DDL queries for the table for this example
    //

    stmt.executeUpdate("DROP TABLE IF EXISTS autoIncTutorial");
    stmt.executeUpdate(
            "CREATE TABLE autoIncTutorial ("
            + "priKey INT NOT NULL AUTO_INCREMENT, "
            + "dataField VARCHAR(64), PRIMARY KEY (priKey))");

    //
    // Insert one row that will generate an AUTO INCREMENT
    // key in the 'priKey' field
    //

    stmt.executeUpdate(
            "INSERT INTO autoIncTutorial (dataField) "
            + "values ('Can I Get the Auto Increment Field?')",
            Statement.RETURN_GENERATED_KEYS);

    //
    // Example of using Statement.getGeneratedKeys()
    // to retrieve the value of an auto-increment
    // value
    //

    int autoIncKeyFromApi = -1;

    rs = stmt.getGeneratedKeys();

    if (rs.next()) {
        autoIncKeyFromApi = rs.getInt(1);
    } else {

        // throw an exception from here
    }

    rs.close();

    rs = null;

    System.out.println("Key returned from getGeneratedKeys():"
        + autoIncKeyFromApi);
} finally {

    if (rs != null) {
        try {
            rs.close();
        } catch (SQLException ex) {
            // ignore
        }
    }

    if (stmt != null) {
        try {
            stmt.close();
        } catch (SQLException ex) {
            // ignore
        }
    }
}

示範26.9. 使用SELECT LAST_INSERT_ID()檢索AUTO_INCREMENT列的值

   Statement stmt = null;
   ResultSet rs = null;

   try {

    //
    // Create a Statement instance that we can use for
    // 'normal' result sets.

    stmt = conn.createStatement();

    //
    // Issue the DDL queries for the table for this example
    //

    stmt.executeUpdate("DROP TABLE IF EXISTS autoIncTutorial");
    stmt.executeUpdate(
            "CREATE TABLE autoIncTutorial ("
            + "priKey INT NOT NULL AUTO_INCREMENT, "
            + "dataField VARCHAR(64), PRIMARY KEY (priKey))");

    //
    // Insert one row that will generate an AUTO INCREMENT
    // key in the 'priKey' field
    //

    stmt.executeUpdate(
            "INSERT INTO autoIncTutorial (dataField) "
            + "values ('Can I Get the Auto Increment Field?')");

    //
    // Use the MySQL LAST_INSERT_ID()
    // function to do the same thing as getGeneratedKeys()
    //

    int autoIncKeyFromFunc = -1;
    rs = stmt.executeQuery("SELECT LAST_INSERT_ID()");

    if (rs.next()) {
        autoIncKeyFromFunc = rs.getInt(1);
    } else {
        // throw an exception from here
    }

    rs.close();

    System.out.println("Key returned from " + "'SELECT LAST_INSERT_ID()': "
        + autoIncKeyFromFunc);

} finally {

    if (rs != null) {
        try {
            rs.close();
        } catch (SQLException ex) {
            // ignore
        }
    }

    if (stmt != null) {
        try {
            stmt.close();
        } catch (SQLException ex) {
            // ignore
        }
    }
}
   

示範26.10. 在可更新的ResultSets中檢索AUTO_INCREMENT列的值

   Statement stmt = null;
   ResultSet rs = null;

   try {

    //
    // Create a Statement instance that we can use for
    // 'normal' result sets as well as an 'updatable'
    // one, assuming you have a Connection 'conn' to
    // a MySQL database already available
    //

    stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,
                                java.sql.ResultSet.CONCUR_UPDATABLE);

    //
    // Issue the DDL queries for the table for this example
    //

    stmt.executeUpdate("DROP TABLE IF EXISTS autoIncTutorial");
    stmt.executeUpdate(
            "CREATE TABLE autoIncTutorial ("
            + "priKey INT NOT NULL AUTO_INCREMENT, "
            + "dataField VARCHAR(64), PRIMARY KEY (priKey))");

    //
    // Example of retrieving an AUTO INCREMENT key
    // from an updatable result set
    //

    rs = stmt.executeQuery("SELECT priKey, dataField "
       + "FROM autoIncTutorial");

    rs.moveToInsertRow();

    rs.updateString("dataField", "AUTO INCREMENT here?");
    rs.insertRow();

    //
    // the driver adds rows at the end
    //

    rs.last();

    //
    // We should now be on the row we just inserted
    //

    int autoIncKeyFromRS = rs.getInt("priKey");

    rs.close();

    rs = null;

    System.out.println("Key returned for inserted row: "
        + autoIncKeyFromRS);

} finally {

    if (rs != null) {
        try {
            rs.close();
        } catch (SQLException ex) {
            // ignore
        }
    }

    if (stmt != null) {
        try {
            stmt.close();
        } catch (SQLException ex) {
            // ignore
        }
    }
}


   
運行上面的示範代碼時,將獲得下述輸出:從getGeneratedKeys():返回的鍵, 從「SELECT LAST_INSERT_ID():」返回1個鍵, 從插入的行返回1個鍵。請注意,有些時候,使用「SELECT LAST_INSERT_ID()」查詢十分複雜,原因在於函數值與連接相關。因此,如果在相同連接上存在其他查詢,函數值將被覆蓋。另一方面,「getGeneratedKeys()」方法是由語句實例確定的,因此,即使在相同連接上存在其他查詢也能使用它,但在相同語句實例上存在其他查詢時則不能使用。

26.3.2. 安裝 Connector/J

請按照下述說明安裝Connector/J。

26.3.2.1. 所需的軟件版本

26.3.2.1.1. 支援的Java版本
MySQL Connector/J支援Java-2 JVMs,包括JDK-1.2.x、JDK-1.3.x、JDK-1.4.x和JDK-1.5.x,並需要JDK-1.4.x或更新的版本進行編譯(而不是運行)。MySQL Connector/J不支援JDK-1.1.x或JDK-1.0.x。

由於實現了java.sql.Savepoint,Connector/J 3.1.0和更新版本不會運行在早於1.4版的JDK上,除非關閉了類驗證器(-Xverify:none),這是因為,類驗證器將試圖加載用於java.sql.Savepoint的類定義,除非使用了savepoint功能,否則驅動程式不會訪問類驗證器。

早於1.4.x版的JVM上,不能使用Connector/J 3.1.0或更高版本提供的新緩衝功能,這是因為該功能依賴JDK-1.4.0中首次提供的java.util.LinkedHashMap。

26.3.2.1.2. MySQL伺服器版本指南
MySQL Connector/J支援所有著名的MySQL伺服器版本。某些特性(外部鍵,可更新結果集)需要更新的MySQL版本才能工作。

與MySQL伺服器4.1版或更高版本建立連接時,最好使用MySQL Connector/J 3.1版,這是因為它全面支援較新版本的伺服器提供的特性,包括Unicode字元、視圖、儲存程式和伺服器端預處理語句。

儘管3.0版Connector/J能夠與MySQL伺服器4.1或更高版本建立連接,但由於實現了Unicode字元和新的鑒定機制,將無法更新Connector/J 3.0以支援當前和未來伺服器版本中提供的新特性。

26.3.2.1.3. 安裝驅動程式並配置CLASSPATH
MySQL Connector/J是以.zip或.tar.gz形式分發的,其中包含原始碼、類檔案、以及僅為「二進制」.jar的類檔案(名為mysql-connector-java-[version]-bin.jar),從Connector/J 3.1.8開始,驅動程式的「調試版」位於名為「mysql-connector-java-[version]-bin-g.jar」的檔案中。

從Connector/J 3.1.9開始,我們不再單獨提供.class檔案,僅在與驅動程式一起提供的JAR檔案中提供它們。

不應使用驅動程式的「調試版」,除非是在向MySQL AB通報問題或問題時需要用到它,這是因為「調試版」不是為生產環境下的運行而設計的,如果使用它,會對性能造成負面影響。二進制代碼的調試取決於Aspect/J運行時庫,該庫位於與Connector/J分發版一起提供的src/lib/aspectjrt.jar檔案中。

需要使用恰當的GUI或命令行使用工具來解開分發檔案(例如,用於.zip檔案的WinZip,以及用於.tar.gz檔案的「tar」)。由於在分發版中可能存在長檔案名,我們採用了GNU tar檔案格式。需要使用GNU tar(或能理解GNU tar檔案格式的其他應用程式)來解開分發版的.tar.gz檔案。

一旦解包了分發版檔案檔案,可以將mysql-connector-java-[version]-bin.jar放在您的類路徑中,或是在您的CLASSPATH環境變數中新增它的完整路徑,或是在啟動JVM(Java虛擬機)時用命令行開關「-cp」直接指定它,通過該方式安裝驅動。

如果您打算用JDBC DriverManager來使用驅動,可使用「com.mysql.jdbc.Driver」,將其用作實施了「java.sql.Driver」類。

示範26.11. 設置Unix環境下的CLASSPATH

在Unix環境下,下述命令用於「csh」:

$ setenv CLASSPATH /path/to/mysql-connector-java-[version]-bin.jar:$CLASSPATH

可以將上述命令新增到恰當的、用於登錄shell的啟動檔案中,從而使得所有的Java應用程式均能使用MySQL Connector/J。

如果希望與諸如Tomcat或Jboss等應用伺服器一起使用MySQL Connector/J,應仔細閱讀供應商提供的文檔,以瞭解如何配置第三方類庫的更多訊息,這是因為大多數應用伺服器均會忽略CLASSPATH環境變數。在「與J2EE和其他Java框架一起使用 Connector/J」一節中,給出了針對一些J2EE應用伺服器的配置示範,但是,對於特定的應用伺服器,JDBC連接池配置訊息的權威資訊來源是該應用伺服器的文檔。

如果您準備開發小服務程式和/或JSP,而且您的應用伺服器是J2EE兼容的,可以將驅動的.jar檔案放到webapp的WEB-INF/lib子目錄下,在J2EE Web應用程式中,這是第三方類庫的標準位置。

如果您的J2EE應用伺服器支援或要求,也可以使用com.mysql.jdbc.jdbc2.optional可選軟件包中的MysqlDataSource或MysqlConnectionPoolDataSource類。多種MysqlDataSource類均支援下述參數(通過標準的「Set」存取器):

·         user

·         password

·         serverName(參見前面關於故障切換主機的章節)

·         databaseName

·         port

26.3.2.2. 升級舊版本

MySQL AB試圖使升級程序盡可能簡單,但是,對於任何軟件來說,某些時侯需要在新版本中進行一些更改才能支援新的特性,改進已有的功能,或與新標準相符。

在本節中,介紹了打算從Connector/J的一個版本升級到另一版本(或考慮到JDBC的功能,升級到MySQL伺服器的新版本)的用戶應瞭解的訊息。

26.3.2.2.1. 從MySQL Connector/J 3.0升級到3.1

設計Connector/J 3.1時,盡量使它能向後兼容Connector/J 3.0。大的變化被單獨作為MySQL-4.1和更新版中的新功能,包括Unicode字元編碼、伺服器端預處理語句、由伺服器返回的錯誤訊息中的SQLState代碼、以及各種性能增強特性(可通過配置屬性啟用或禁止)。

·         Unicode字元編碼:關於MySQL新特性的更多訊息,請參見下一節,以及伺服器手冊中的「字元編碼」一節。如果有些事項配置不當,通常會顯示錯誤,同時給出錯誤消息,如「非法校對組合」。

·         伺服器端預處理語句:Connector/J 3.1將自動檢測伺服器端預處理語句,並在可用時自動使用它們(MySQL伺服器4.1.0版或更新)。

從3.1.7版開始,驅動程式能通過各種Connection.prepareStatement()變體掃瞄SQL,以判斷它是否是能夠在伺服器端支援的語句類型,如果不被伺服器端支援,會將其作為客戶端的模擬預處理語句進行處理。也可以通過在JDBC URL中傳遞「emulateUnsupportedPstmts=false」禁止該特性。

如果應用程式遇到與伺服器端預處理語句有關的問題,可將其回復為舊的客戶端模擬預處理語句代碼,在早於4.1.0版的MySQL伺服器中仍使用該代碼,連接屬性如下:

useServerPrepStmts=false

·         具有全0組分的Datetimes(0000-00-00 ...):在Java中,無法可靠地資料表示這些值。從結果集讀取它們時,Connector/J 3.0.x總是會將其轉換為NULL。

預設情況下,遇到這類值時,Connector/J 3.1將拋出異常,這是因為,根據JDBC和SQL標準,這是最正確的行為方式。可以使用「zeroDateTimeBehavior」配置屬性改變該行為。允許的值包括:「exception」,(預設值),用代碼為「S1009」的SQLState拋出SQLException;「convertToNull」,返回NULL而不是數據;以及「round」,對日期進行捨入處理,使之成為最接近的值,即「0001-01-01」。

從Connector/J 3.1.7開始,能夠使用「noDatetimeStringSync=true」(預設值為「假」),將ResultSet.getString()與該行為分離開,從而能夠以字串的形式提取未被改變的全0值。請注意,這也會阻止使用任何時區轉換功能,因此,驅動程式將禁止同時啟用noDatetimeStringSyncuseTimezone。

·         新SQLState代碼:Connector/J 3.1採用MySQL返回的SQL:1999 SQLState代碼(如果支援的話),它不同於Connector/J 3.0使用的「傳統」X/Open狀態碼。如果連接到了版本低於MySQL-4.1.0(能夠將SQLStates作為錯誤代碼組成部分返回的最早版本)的MySQL伺服器,驅動程式將使用內置的映射功能。您也可以使用下述配置選項,採用舊的映射。

useSqlStateCodes=false

·         在BLOB列上使用ResultSet.getString()將返回代資料表它的字節[]數組的地址,而不是BLOB的字串形式。BLOB沒有字元編碼,因此,在不造成數據丟失或損壞的情況下,不能將它們轉換為java.lang.Strings。

要想以BLOB方式將字串保存在MySQL中,可使用一種TEXT類型,驅動程式會將其當作java.sql.Clob對待。

·         從Connector/J 3.1.8開始,驅動的「調試版」(在名為「mysql-connector-java-[version]-bin-g.jar的檔案中與正常的二進制jar檔案名為mysql-connector-java-[version]-bin.jar一起提供

從Connector/J 3.1.9開始,我們不再單獨提供.class檔案,僅在與驅動程式一起提供的JAR檔案中提供它們。

不應使用驅動程式的「調試版」,除非是在向MySQL AB通報問題或問題時需要用到它,這是因為「調試版」不是為生產環境下的運行而設計的,如果使用它,會對性能造成負面影響。二進制代碼的調試取決於Aspect/J運行時庫,該庫位於與Connector/J分發版一起提供的src/lib/aspectjrt.jar檔案中。

26.3.2.2.2. 升級到MySQL伺服器4.1版或更新版本時的JDBC事宜

·         使用UTF-8字元編碼:在4.1版MySQL伺服器之前,伺服器不支援UTF-8字元編碼,但JDBC驅動能使用它,從而允許在伺服器上的latin1中保存多個字元編碼。

從MySQL-4.1版開始,該功能被放棄。如果您有依賴該功能的應用程式,而且無法升級它們以使用MySQL伺服器4.1版或更高版本中支援的正是Unicode字元編碼,應在連接URL中增加下述屬性:

useOldUTF8Behavior=true

·         伺服器端預處理語句:Connector/J 3.1將自動檢測伺服器端預處理語句,並在可用時自動使用它們(MySQL伺服器4.1.0版或更新)。如果應用程式遇到與伺服器端預處理語句有關的問題,可將其回復為舊的客戶端模擬預處理語句代碼,在早於4.1.0版的MySQL伺服器中仍使用該代碼,連接屬性如下:

useServerPrepStmts=false

26.3.3. JDBC引用

26.3.3.1. Driver/Datasource類名,URL語法,以及Connector/J的配置屬性

在MySQL Connector/J中實現了java.sql.Driver的類名是「com.mysql.jdbc.Driver」。「org.gjt.mm.mysql.Driver」類名任是可用的,以保持與MM.MySQL的向後相容性。註冊驅動程式,或配置軟件以使用MySQL Connector/J時,應使用該類名。

用於MySQL Connector/J的JDBC URL格式如下,方括號「[, ]」的項為可選項:

jdbc:mysql://[host][,failoverhost...][:port]/[database][?propertyName1][=propertyValue1][&propertyName2][=propertyValue2]...

如果未指定主機名,預設為「127.0.0.1」。如果未指定端口,預設為「3306」,它是MySQL伺服器的預設端口號。

jdbc:mysql://[host:port],[host:port].../[database][?propertyName1][=propertyValue1][&propertyName2][=propertyValue2]...

如果未指定資料庫,將使用無「當前」資料庫進行連接。在這種情況下,需要在連接實例上使用「setCatalog()」方法,或在SQL中使用資料庫名指定完整的資料表名(即「SELECT dbname.tablename.colname FROM dbname.tablename...」)。不指定連接時使用的資料庫,該選項通常僅在建立用於處理多個資料庫的工具時才有用,例如GUI資料庫管理器。

MySQL Connector/J支援故障切換功能。這樣,就允許驅動程式切換至「從」主機上,並仍能執行只讀查詢。僅當連接處於autoCommit(true)狀態時,才會出現故障切換,這是因為當事務正在進行時,無法可靠地保證故障切換。在事務/連接結束後,大多數應用伺服器和連接池均會將autoCommit設置為「真」。

故障切換功能具有下述行為方式:

如果URL屬性「autoReconnect」為「假」:故障切換僅會在連接初始化過程中出現,當驅動程式判斷第1台主機再次可用時,將返回。

如果URL屬性「autoReconnect」為「真」:當驅動程式判斷連接失敗時(在任意查詢之前),將出現故障切換,而且當驅動程式判斷第1台主機再次可用時(發出queriesBeforeRetryMaster查詢之後),將返回第1台主機。

在任何一種情況下,當您連接到經過故障切換的伺服器時,會將連接設置為只讀狀態,因此,對於會更改數據的查詢來說,將拋出異常(MySQL伺服器不會處理該查詢)。

配置屬性定義了Connector/J與MySQL伺服器進行連接的方式。除非作了其他說明,否則可以為DataSource對像或Connection對像設置屬性。

可採用下述方式的一種設置Configuration(配置)屬性:

·         在java.sql.DataSource的MySQL實施實例上使用set*()方法(它是使用java.sql.DataSource實施實例時的首選方法):

o        com.mysql.jdbc.jdbc2.optional.MysqlDataSource

o        com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource

·         作為傳遞給DriverManager.getConnection()或Driver.connect()的java.util.Properties實例中的 鍵/值對。

·         作為URL中的JDBC URL參數,以傳遞給java.sql.DriverManager.getConnection()、java.sql.Driver.connect()、或javax.sql.DataSource的setURL()方法的MySQL實施實例。

註釋:

如果您用來配置JDBC URL的方法是基於XML的,需要使用XML字元「&amp;」來隔開配置參數,「&」是XML的保留字元。

在下面的資料表各中,列出了這些屬性:

資料表26.1. 連接屬性 

屬性名

定義

要求?

預設值

版本

Connection/Authentication(連接/鑒定)

user

連接的用戶

No

 

全部

password

連接時使用的密碼。

No

 

全部

socketFactory

驅動程式用於建立與伺服器套接字連接的類的名稱。該類必須實現了接口「com.mysql.jdbc.SocketFactory」,並有公共無參量構造函數。

No

com.mysql.jdbc.StandardSocketFactory

3.0.3

connectTimeout

套接字連接的超時(單位為毫秒),0資料表示無超時。僅對JDK-1.4或更新版本有效。預設值為「0」。

No

0

3.0.1

socketTimeout

網絡套接字連接的超時(預設值0資料表示無超時)。

No

0

3.0.1

useConfigs

在解析URL屬性或應用用戶指定的屬性之前,加載由逗號「,」分隔的配置屬性列資料表。在文檔的「配置」部分中解釋了這些配置。

No

 

3.1.5

interactiveClient

設置CLIENT_INTERACTIVE標誌,根據INTERACTIVE_TIMEOUT而不是WAIT_TIMEOUT向MySQL通報超時連接。

No

false

3.1.0

propertiesTransform

com.mysql.jdbc.ConnectionPropertiesTransform的1個實施實例,在嘗試連接之前,驅動程式將使用它來更改傳遞給驅動的URL屬性。

No

 

3.1.4

useCompression

與伺服器進行通信時採用zlib壓縮(真/假)? 預設值為「假」。

No

false

3.0.17

High Availability and Clustering(高可用性和叢集集)

autoReconnect

驅動程式是否應嘗試再次建立失效的和/或死連接? 如果允許,對於在失效或死連接上發出的查詢(屬於當前事務),驅動程式將拋出異常,但在新事務的連接上發出下一個查詢時,將嘗試再連接。不推薦使用該特性,這是因為,當應用程式不能恰當處理SQLExceptions時,它會造成與會話狀態和數據一致性有關的副作用,設計它的目的僅用於下述情況,即,當您無法配置應用程式來恰當處理因死連接和/或無效連接導致的SQLExceptions時。作為可選方式,可將MySQL伺服器變數「wait_timeout」設置為較高的值,而不是預設的8小時。

No

false

1.1

autoReconnectForPools

使用適合於連接池的再連接策略(預設值為「假」)。

No

false

3.1.3

failOverReadOnly

在autoReconnect模式下出現故障切換時,是否應將連接設置為「只讀」?

No

true

3.0.12

reconnectAtTxEnd

如果將autoReconnect設置為「真」,在每次事務結束後驅動程式是否應嘗試再連接?

No

false

3.0.10

roundRobinLoadBalance

啟用了autoReconnect而且failoverReadonly為「假」時,是否應按照循環方式挑選要連接的主機?

No

false

3.1.2

queriesBeforeRetryMaster

出現故障切換(使用多主機故障切換)並返回主機之前發出的查詢數。無論首先滿足了哪個條件,「queriesBeforeRetryMaster」或「secondsBeforeRetryMaster」,均會再次與主機進行連接。預設值為「50」。

No

50

3.0.2

secondsBeforeRetryMaster

出現故障切換後,在嘗試再次連接到主伺服器之前,驅動程式應等待的時間? 無論首先滿足了哪個條件,「queriesBeforeRetryMaster」或「secondsBeforeRetryMaster」,均會再次與主機進行連接。單位為秒,預設值為30。

No

30

3.0.2

enableDeprecatedAutoreconnect

自3.2版開始,自動再連接功能受到冷落,在3.3版中將刪除該功能。將該屬性設置為「真」可禁止檢查配置的特性。

No

false

3.2.1

Security(安全)

allowMultiQueries

在一條語句中,允許使用「;」來分隔多條查詢(真/假,預設值為「假」)。

No

false

3.1.1

useSSL

與伺服器進行通信時使用SSL(真/假),預設值為「假」。

No

false

3.0.2

requireSSL

要求SSL連接,useSSL=true? 預設值為「假」。

No

false

3.1.0

allowUrlInLocalInfile

驅動程式在是「LOAD DATA LOCAL INFILE」語句中否允許URL?

No

false

3.1.4

paranoid

採取措施,防止在錯誤訊息中洩漏敏感訊息,並可可能時清除保存敏感數據的數據結構? 預設值為「假」。

No

false

3.0.1

Performance Extensions(性能延伸)

metadataCacheSize

如果將cacheResultSetMetaData設置為「真」,對cacheResultSetMetadata的查詢次數(預設值為50)。

No

50

3.1.1

prepStmtCacheSize

如果允許預處理語句緩衝功能,應緩衝處理多少條預處理語句?

No

25

3.0.10

prepStmtCacheSqlLimit

如果允許預處理語句緩衝功能,驅動程式將執行解析緩衝處理的最大SQL是什麼?

No

256

3.0.10

maintainTimeStats

驅動程式是否應維持各種內部定時器,以允許空閒時間計算,以及與伺服器的連接失敗時允許提供更詳細的錯誤消息? 將該屬性設置為「假」,對於每次查詢,至少能減少兩次對System.getCurrentTimeMillis()的使用。

No

true

3.1.9

blobSendChunkSize

組塊,當通過ServerPreparedStatements發送BLOB/CLOB時使用。

No

1048576

3.1.9

cacheCallableStmts

驅動程式是否應對CallableStatements的解析過程執行緩衝處理。

No

false

3.1.2

cachePrepStmts

驅動程式是否應對客戶端預處理語句的PreparedStatements的解析過程執行緩衝處理,是否應檢查伺服器端預處理語句的適用性以及伺服器端預處理語句本身?

No

false

3.0.10

cacheResultSetMetadata

驅動程式是否應對用於Statements和PreparedStatements的ResultSetMetaData執行緩衝處理? 要求 JDK-1.4+,真/假,預設為「假」。

No

false

3.1.1

cacheServerConfiguration

驅動程式是否應根據每條URL對「HOW VARIABLES」和「SHOW COLLATION」的結果執行緩衝處理?

No

false

3.1.5

dontTrackOpenResources

JDBC規範要求驅動程式自動跟蹤和關閉資源,但是,如果您的應用程式不能明確使用作用在語句或結果集上的close(),可能會導致內存洩漏。將該屬性設置為「真」,可放寬該限制,對於某些應用程式,會提供更高的內存效率。

No

false

3.1.7

dynamicCalendars

需要時,驅動程式是否應檢索預設日曆,或根據連接/會話對其進行緩衝處理?

No

false

3.1.5

elideSetAutoCommits

如果使用MySQL-4.1或更高版本,當伺服器的狀態與Connection.setAutoCommit(boolean)請求的狀態不匹配時,驅動程式是否僅應發出「set autocommit=n」查詢?

No

false

3.1.3

holdResultsOpenOverStatementClose

驅動程式是否應按照JDBC規範的要求關閉Statement.close()上的結果集?

No

false

3.1.7

locatorFetchBufferSize

如果將「emulateLocators」配置為「真」,當獲取關於getBinaryInputStream的BLOB數據時,緩衝區的大小應是多少?

No

1048576

3.2.1

useFastIntParsing

是否使用內部「String->Integer」轉換子程式來避免建立過多對像?

No

true

3.1.4

useLocalSessionState

驅動程式是否應引用autocommit的內部值,以及由Connection.setAutoCommit()和Connection.setTransactionIsolation()設置的事務隔離,而不是查詢資料庫?

No

false

3.1.7

useNewIO

驅動程式是否應將java.nio.* interfaces用於網絡通信(真/假),預設為「假」。

No

false

3.1.0

useReadAheadInput

從伺服器讀取數據時,是否使用較新的、最佳化的非成組緩衝輸入流?

No

true

3.1.5

Debuging/Profiling(調試/仿形)

logger

實現了com.mysql.jdbc.log.Log的類的名稱,com.mysql.jdbc.log.Log用於記錄消息(預設為「com.mysql.jdbc.log.StandardLogger」,它會將日誌記錄到STDERR)。

No

com.mysql.jdbc.log.StandardLogger

3.1.1

profileSQL

跟蹤查詢以及它們對已配製記錄器的執行/獲取次數(真/假),預設為「假」。

No

false

3.1.0

reportMetricsIntervalMillis

如果允許「gatherPerfMetrics」,記錄它們的頻率是多少(單位毫秒)?

No

30000

3.1.2

maxQuerySizeToLog

調試或仿形時,控制將記錄的查詢的最大長度/大小。

No

2048

3.1.3

packetDebugBufferSize

當「enablePacketDebug」為「真」時,需要保留的最大訊息包數目。

No

20

3.1.3

slowQueryThresholdMillis

如果允許「logSlowQueries」,在將查詢記錄為「慢」之前的查詢時間是多少(毫秒)?

No

2000

3.1.2

useUsageAdvisor

驅動程式是否應發出「使用情況」警告,就DBC和MySQL Connector/J的恰當和高效使用給出建議(真/假,預設為「假」)?

No

false

3.1.1

autoGenerateTestcaseScript

驅動程式是否應將正在執行的SQL(包括伺服器端預處理語句)轉儲到STDERR?

No

false

3.1.9

dumpQueriesOnException

驅動程式是否應將發送至伺服器的查詢內容轉儲到SQLExceptions中?

No

false

3.1.3

enablePacketDebug

允許時,將保留「packetDebugBufferSize」訊息包的環形緩衝區,並當在驅動程式代碼的關鍵區域拋出異常時進行轉儲。

No

false

3.1.3

explainSlowQueries

如果允許了「logSlowQueries」,驅動程式是否應在伺服器上自動發出「EXPLAIN」,並以WARN級別將結果發送給配置好的日誌?

No

false

3.1.2

logSlowQueries

是否要記錄時間長於「slowQueryThresholdMillis」的查詢?

No

false

3.1.2

traceProtocol

是否應記錄跟蹤級網絡協議?

No

false

3.1.2

Miscellaneous(其他)

useUnicode

處理字串時,驅動程式是否應使用Unicode字元編碼? 僅應在驅動程式無法確定字元編碼映射,或您正在強制驅動程式使用MySQL不是固有支援的字元編碼時(如UTF-8)才應使用。真/假,預設為「真」。

No

false

1.1g

characterEncoding

如果「useUnicode」被設置為「真」,處理字串時,驅動程式應使用什麼字元編碼? 預設為「autodetect」。

No

 

1.1g

characterSetResults

字元編碼,用於通知伺服器以何種字元編碼返回結果。

No

 

3.0.13

connectionCollation

如果設置了它,將通知伺服器通過「set collation_connection」使用該校對。

No

 

3.0.13

sessionVariables

以逗號隔開的「名稱/值」對列資料表,當驅動程式建立了連接後,以「SET SESSION ...」的方式將其發送給伺服器。

No

 

3.1.8

allowNanAndInf

驅動程式是否應在PreparedStatement.setDouble()中允許NaN或+/- INF值?

No

false

3.1.5

autoDeserialize

驅動程式是否應自動檢測並串並轉換保存在BLOB字段中的對象?

No

false

3.1.5

capitalizeTypeNames

是否將DatabaseMetaData中的類型名轉換為大寫? 通常僅在使用WebObjects時有用,真/假。預設為「假」。

No

false

2.0.7

clobberStreamingResults

這會使「流式」結果集被自動關閉,如果在所有數據尚未從伺服器中讀取完之前,執行了另一查詢,正在從伺服器流出的任何未完成數據均將丟失。

No

false

3.0.9

continueBatchOnError

如果一條語句失敗,驅動程式是否應繼續處理批命令? JDBC規範允許任何一種方式(預設為「真」)。

No

true

3.0.3

createDatabaseIfNotExist

如果不存在,建立URL中給定的資料庫。假定用戶具有建立資料庫的權限。

No

false

3.1.9

emptyStringsConvertToZero

驅動程式是否應允許從空字串字段到數值「0」的轉換?

No

true

3.1.8

emulateLocators

N/A

No

false

3.1.0

emulateUnsupportedPstmts

驅動程式是否應檢測不被伺服器支援的預處理語句,並用客戶端模擬版替換它們?

No

true

3.1.7

ignoreNonTxTables

是否忽略關於回退的非事務資料表? 預設值為「假」。

No

false

3.0.9

jdbcCompliantTruncation

連接到支援告警的伺服器時(MySQL 4.1.0和更高版本),當按照JDBC的要求截短數據時,驅動程式是否應拋出java.sql.DataTruncation異常?

No

true

3.1.2

maxRows

返回的最大行數(0,預設值資料表示返回所有行)。

No

-1

all versions

noDatetimeStringSync

不保證ResultSet.getDatetimeType().toString().equals(ResultSet.getString()。

No

false

3.1.7

nullCatalogMeansCurrent

當DatabaseMetadataMethods請求「目錄」參數時,值「Null」是否意味著使用當前目錄? 它不兼容JDBC,但符合驅動程式早期版本的傳統行為。

No

true

3.1.8

nullNamePatternMatchesAll

接受*pattern參數的DatabaseMetaData方法是否應將null按對待「%」的相同方式處理(不兼容JDBC,但驅動程式的早期版本能接受與規範的這類偏離)。

No

true

3.1.8

pedantic

嚴格遵守JDBC規範。

No

false

3.0.0

relaxAutoCommit

如果驅動程式所連接的MySQL伺服器的版本不支援事務,仍允許使用commit()、rollback()和setAutoCommit()?真/假,預設為「假」。

No

false

2.0.13

retainStatementAfterResultSetClose

使用ResultSet.close()後,驅動程式是否應將語句引用保存在結果集中? 在JDBC-4.0後,與JDBC不兼容。

No

false

3.1.11

rollbackOnPooledClose

當連接池中的邏輯連接關閉時,驅動程式是否應發出rollback()?

No

true

3.0.15

runningCTS13

允許在Sun與JDBC兼容的testsuite 1.3版中處理問題。

No

false

3.1.7

serverTimezone

覆蓋時區的檢測/映射。當伺服器的時區為映射到Java時區時使用。

No

 

3.0.2

strictFloatingPoint

僅在相容性測試的早期版本中使用。

No

false

3.0.0

strictUpdates

驅動程式是否應對可更新結果集進行嚴格檢查(選擇所有的主鍵)?真/假,預設為「真」。

No

true

3.0.4

tinyInt1isBit

驅動程式是否應將數據類型TINYINT(1)當作BIT類型對待?建立資料表時,伺服器會執行BIT -> TINYINT(1)操作。

No

true

3.0.16

transformedBitIsBoolean

如果驅動程式將TINYINT(1)轉換為不同的類型,為了與MySQL-5.0兼容,驅動程式是否應使用BOOLEAN取代BIT?這是因為MySQL-5.0具有BIT類型。

No

false

3.1.9

ultraDevHack

由於UltraDev已損壞,並為所有語句發出了prepareCall(),需要時,是否要為prepareCall()建立PreparedStatements?

真/假,預設值為「假」。

No

false

2.0.3

useHostsInPrivileges

在DatabaseMetaData.getColumn/TablePrivileges()中為用戶新增「@hostname」。真/假,預設為「真」。

No

true

3.0.2

useOldUTF8Behavior

與4.0和更早版本的伺服器進行通信時,使用UTF-8。

No

false

3.1.6

useOnlyServerErrorMessages

對伺服器返回的錯誤消息,不事先設定「標準的」SQLState錯誤消息。

No

true

3.0.15

useServerPrepStmts

如果伺服器支援,是否使用伺服器端預處理語句? 預設值為「真」。

No

true

3.1.0

useSqlStateCodes

使用SQL標準狀態碼取代「傳統的」X/Open/SQL狀態碼,真/假,預設為「真」。

No

true

3.1.3

useStreamLengthsInPrepStmts

是否採用PreparedStatement/ResultSet.setXXXStream()方法使用中的流長度參數?真/假,預設為「真」。

No

true

3.0.2

useTimezone

是否在客戶端和伺服器時區間轉換時間/日期類型(真/假,預設為「假」)?

No

false

3.0.2

useUnbufferedInput

不使用BufferedInputStream來從伺服器讀取數據。

No

true

3.0.11

yearIsDateType

JDBC驅動程式是否應將MySQL類型「YEAR」當作java.sql.Date或SHORT對待?

No

true

3.1.9

zeroDateTimeBehavior

當驅動程式遇到全由0組成的DATETIME值時,應出現什麼?MySQL使用它來資料表示無效日期。有效值是「exception」、「round」和「convertToNull」。

No

exception

3.1.4

通過「socketFactory」屬性,使用NamedPipeSocketFactory,在Windows NT/2000/XP平台上,通過命名管道,Connector/J也支援對MySQL的訪問。如果不使用namedPipePath屬性,將使用\\.\pipe\MySQL的預設值。如果使用NamedPipeSocketFactory,將忽略JDBC url中的主機名和端口號。

在URL中新增下述屬性可啟用NamedPipeSocketFactory

 

socketFactory=com.mysql.jdbc.NamedPipeSocketFactory

命名管道僅能當連接到位於相同物理機器上的MySQL時才能正常工作,該機器上應使用了JDBC驅動程式。在簡單的性能測試中,命名管道的訪問速度比標準的TCP/IP訪問塊30~50%。

使用com.mysql.jdbc.NamedPipeSocketFactorycom.mysql.jdbc.StandardSocketFactory中的示範代碼,可建立您自己的套接字代理。

26.3.3.2. JDBC API實施說明

MySQL Connector/J通過了Sun JDBC兼容測試套件公共版中的所有測試。但是,在很多場合下,對於應如何實施特定的功能,JDBC規範並未給出明確的規定,或者說,該規範允許有一定的實施範圍。

在本節中,就特定實施方案將如何影響MySQL Connector/J的使用方式,給出了接口層面上的詳細介紹。

·         Blob

Blob實施不允許「原地」調整(它們是「副本」,正如DatabaseMetaData.locatorsUpdateCopies()方法所指明的那樣)。因此,應使用對應的PreparedStatement.setBlob()或ResultSet.updateBlob()(對於可更新結果集)方法,將變化保存到資料庫中。

自Connector/J version 3.1.0開始,通過在JDBC URL中新增屬性「emulateLocators=true」,能夠使用定位器模擬Blob。隨後,必須使用帶有列值的列別名,在您編寫的用於檢索Blob的SELECT中,將列值設為Blob列的世紀名稱。SELECT還必須僅引用1個資料表,該資料表必須有1個主鍵,而且SELECT必須涵蓋構成主鍵的所有列。隨後,驅動程式將延期加載實際的Blob數據,直至檢索了Blob並在其上使用了檢索方法為止(getInputStream(), getBytes(),等)。

·         CallableStatement

自Connector/J 3.1.1開始,當通過CallableStatement接口連接到MySQL 5.0或更高版本時,可支援儲存程式。目前,不支援CallableStatement的getParameterMetaData()方法。

·         Clob

Clob實施不允許「原地」調整(它們是「副本」,正如DatabaseMetaData.locatorsUpdateCopies()方法所指明的那樣)。因此,應使用PreparedStatement.setClob()方法將變更保存到資料庫中。JDBC API沒有ResultSet.updateClob()方法。

·         Connection

與MM.MySQL的早期版本不同,「isClosed()」不會對伺服器即行Ping操作以確定伺服器是否有效。按照JDBC規範,如果在連接上使用了「closed()」,它僅返回「真」。如果需要確定連接是否依然有效,應發出簡單查詢,如「SELECT 1」。如果連接不再有效,驅動程式將拋出異常。

·         DatabaseMetaData

對於外部鍵訊息(getImported/ExportedKeys()和getCrossReference()),僅在「InnoDB」類性的資料表中可用。但是,驅動程式會使用「SHOW CREATE TABLE」來檢索該訊息,因此,當其他資料表類型支援外部鍵時,驅動程式也能支援它們。

·         Driver

·         PreparedStatement

PreparedStatements是由驅動程式實現的,這是應為MySQL未提供預處理語句功能。出於該原因,驅動程式不實施getParameterMetaData()或getMetaData(),這是因為,它要求驅動程式在客戶端上具有完整的SQL語法分析程式。

從3.1.0版MySQL Connector/J開始,當伺服器支援時,將使用伺服器端預處理語句和「二進制編碼」的結果集。

使用帶有「large」參數(這類參數是通過setBinaryStream()、setAsciiStream()、setUnicodeStream()、setBlob()或setClob()設置的)的伺服器端預處理語句時應謹慎。如果打算再次執行已將任何「large」參數更改為非「large」參數的語句,需要使用clearParameters(),並再次設置所有參數。其原因如下:

o        設置了參數時,驅動程式會將「large」數據「out-of-band」發送給伺服器端的預處理語句(執行預處理語句之前)。

o        一旦完成,將關閉用於讀取客戶端上數據的流(根據JDBC規範),而且不能再次讀取流。

o        如果參數從「large」變為非「large」,驅動程式必須復位預處理語句的伺服器端狀態,以便允許已更改的參數區帶以前的「large」值。這將刪除已發送給伺服器的所有「large」數據,因而需要通過setBinaryStream()、setAsciiStream()、setUnicodeStream()、setBlob()或setClob()方法再次發送數據。

因而,如果您打算將參數類型更改為非「large」類型,必須使用clearParameters(),並在重新執行預處理語句之前再次設置預處理語句的所有參數。

·         ResultSet

在預設情況下,ResultSets(結果集)是可完全檢索的,並被保存在內存中。對於大多數情況,這是最有效的操作方式,而且還應歸因於更容易實施的MySQL網絡協議設計。如果您正在處理具有大量行或大數據的ResultSets,而且無法在JVM內為所需內存分配大量空間,可以通知驅動程式以「流」方式返回結果,一次一行。

要想允許該功能,需要以下述方式建立1個語句實例:

stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,
              java.sql.ResultSet.CONCUR_READ_ONLY);
stmt.setFetchSize(Integer.MIN_VALUE);

正向、只讀結果集,以及Integer.MIN_VALUE的組合用於指示驅動程式以「流」方式按行處理結果集。此後,對於該語句建立的結果集,將按行檢索。

對於該方式,有一些需注意的事項。能夠在連接上發出任何其他查詢之前,應讀取結果集中的所有行(或關閉結果集),否則將拋出異常。

能夠釋放這些鎖定語句(無論它們是MyISAM資料表級鎖定,還是某些其他儲存引擎如InnoDB中的行級鎖定)的最早時刻是完成語句時。

如果語句在事務的範圍內,當事務完成後將釋放鎖定(它意味著語句需首先完成)。與大多數其他資料庫一樣,在讀取了語句上所有的未決結果集或關閉了語句的活動結果集之前,語句不會結束。

因此,如果正在使用「流式」結果,如果希望保持對特定資料表的同時訪問,而這些資料表被生成結果集的語句所引用,就應盡快地處理「流式」結果。

·         ResultSetMetaData

僅當使用MySQL伺服器4.0或更高版本時,「isAutoIncrement()」方法才能正確工作。

·         Statement

使用版本低於3.2.1的JDBC驅動程式,而且所連接的伺服器版本低於5.0.3時,除了像前面介紹的那樣切換結果集外,「setFetchSize()」方法不起作用。

MySQL不支援SQL光標,而且JDBC驅動程式也不能模擬它們,因此「setCursorName()」沒有效果。

26.3.3.3. Java,JDBC和MySQL類型

MySQL Connector/J在處理MySQL數據類型和Java數據類型的轉換處理方面十分靈活。

儘管可能會出現捨入、溢出或精度損失,當在通常情況下,能夠將任何MySQL數據類型轉換為java.lang.String,並能將任何數值類型轉換為Java數值類型。

從Connector/J 3.1.0開始,按照JDBC規範的要求,JDBC驅動程式將發出警告或拋出DataTruncation異常,除非通過使用「jdbcCompliantTruncation」屬性並將其設為「假」,對連接進行相應配置取消了前述要求。

在下面的資料表格中,列出能可靠工作的轉換:

資料表26.2. 轉換資料表

下述MySQL數據類型

總能轉換為下述Java類型

CHAR, VARCHAR, BLOB, TEXT, ENUM, and SET

java.lang.String, java.io.InputStream, java.io.Reader, java.sql.Blob, java.sql.Clob

FLOAT, REAL, DOUBLE PRECISION, NUMERIC, DECIMAL, TINYINT, SMALLINT, MEDIUMINT, INTEGER, BIGINT

java.lang.String, java.lang.Short, java.lang.Integer, java.lang.Long, java.lang.Double, java.math.BigDecimal

註釋:

與希望轉換的MySQL數據類型相比,如果選擇了精度較低的Java數值類型,可能會出現捨入、溢出或精度損失。

DATE, TIME, DATETIME, TIMESTAMP

java.lang.String, java.sql.Date, java.sql.Timestamp

在MySQL類型和Java類型之間,ResultSet.getObject()方法採用了下述類型轉換方式,在可能的情況下遵從JDBC規範:

資料表26.3. 用於ResultSet.getObject()的MySQL類型和Java類型

MySQL類型名稱

Java類返回

BIT(1) (new in MySQL-5.0)

java.lang.Boolean

BIT( > 1) (new in MySQL-5.0)

byte[]

TINYINT

java.lang.Boolean,如果將配置屬性tinyInt1isBit」設為「真」(預設值),並將儲存大小設為「1」;或java.lang.Integer,如果不是的話。

BOOL , BOOLEAN

請參見上面的TINYINT,它們目前是TINYINT(1)的別名。

SMALLINT[(M)] [UNSIGNED]

java.lang.Integer(無論是否為UNSIGNED

MEDIUMINT[(M)] [UNSIGNED]

java.lang.Integer(無論是否為UNSIGNED

INT,INTEGER[(M)] [UNSIGNED]

java.lang.Integer,如果是UNSIGNEDjava.lang.Long

BIGINT[(M)] [UNSIGNED]

java.lang.Long,如果是UNSIGNEDjava.math.BigInteger

FLOAT[(M,D)]

java.lang.Float

DOUBLE[(M,B)]

java.lang.Double

DECIMAL[(M[,D])]

java.math.BigDecimal

DATE

java.sql.Date

DATETIME

java.sql.Timestamp

TIMESTAMP[(M)]

java.sql.Timestamp

TIME

java.sql.Time

YEAR[(2|4)]

java.sql.Date(日期設為21日晚上2點)

CHAR(M)

java.lang.String(除非列的字元編碼是BINARY),然後返回字節[]

VARCHAR(M) [BINARY]

java.lang.String(除非列的字元編碼是BINARY),然後返回字節[]

BINARY(M)

byte[]

VARBINARY(M)

byte[]

TINYBLOB

byte[]

TINYTEXT

java.lang.String

BLOB

byte[]

TEXT

java.lang.String

MEDIUMBLOB

byte[]

MEDIUMTEXT

java.lang.String

LONGBLOB

byte[]

LONGTEXT

java.lang.String

ENUM('value1','value2',...)

java.lang.String

SET('value1','value2',...)

java.lang.String

26.3.3.4. 使用字元編碼和Unicode

對於從JDBC驅動程式發往伺服器的所有字串,均將自動地從固有放熱Java Unicode形式轉換為客戶端字元編碼,包括通過Statement.execute()Statement.executeUpdate()和Statement.executeQuery()發出的所有查詢,以及除了用setBytes()、setBinaryStream()setAsiiStream()setUnicodeStream()setBlob()排除的參試之外的所有PreparedStatementCallableStatement參數

在MySQL伺服器4.1之前,Connector/J支援每連接單一字元編碼,能夠從伺服器配置自動檢測到它,也能由用戶通過使用useUnicodecharacterEncoding屬性配置它。

從MySQL伺服器4.1版起,Connector/J支援客戶端和伺服器之間的但以字元編碼,以及針對結果集中從伺服器返回至客戶端的數據的任意數目字元編碼。

連接時將自動檢測客戶端和伺服器之間的字元編碼。對於由驅動程式使用的編碼來說,它是在伺服器上通過使用配置變數「character_set」(低於4.1.0的伺服器版本)和「character_set_server」(4.1.0和更高的伺服器版本)指定的。更多訊息,請參見MySQL伺服器手冊中的伺服器字元編碼和校對一節。

要想覆蓋客戶端上的自動檢測編碼功能,可在用於連接到伺服器的URL中使用「characterEncoding」屬性。

在客戶端上指定字元編碼時,應使用Java風格名稱。在下面的資料表格中,列出了用於MySQL字元編碼的Java風格名稱:

資料表26.4. MySQL對Java編碼名稱的翻譯

MySQL字元編碼名稱 Java風格字元編碼名稱
usa7US-ASCII
big5Big5
gbkGBK
sjisSJIS
gb2312EUC_CN
ujisEUC_JP
euc_krEUC_KR
latin1ISO8859_1
latin1_deISO8859_1
german1ISO8859_1
danishISO8859_1
latin2ISO8859_2
czechISO8859_2
hungarianISO8859_2
croatISO8859_2
greekISO8859_7
hebrewISO8859_8
latin5ISO8859_9
latvianISO8859_13
latvian1ISO8859_13
estoniaISO8859_13
dosCp437
pclatin2Cp852
cp866Cp866
koi8_ruKOI8_R
tis620TIS620
win1250Cp1250
win1250chCp1250
win1251Cp1251
cp1251Cp1251
win1251ukrCp1251
cp1257Cp1257
macromanMacRoman
macceMacCentralEurope
utf8UTF-8
ucs2UnicodeBig

警告

不要用Connector/J發出查詢「set names」,這是因為驅動程式不會檢測已變化的字元編碼,而是會繼續使用在初始連接設置中檢測到的字元編碼。

為了允許從客戶端發出的多個字元編碼,應使用「UTF-8」編碼,方式是,將utf8配置為預設的伺服器字元編碼,或通過「characterEncoding」屬性配置JDBC驅動程式以使用「UTF-8」。

26.3.3.5. 使用SSL進行安全連接

MySQL Connector/J中的SSL能夠對JDBC驅動程式和伺服器之間傳輸的所有數據進行加密(除了初始握手數據)。啟用SSL會導致性能損失,體現在查詢時間將增加35~50%,具體情況取決於查詢的大小以及返回的數據量。

要想使SSL支援能夠工作,必須滿足下述要求:

·         包含JSSE(Java安全套接字延伸)的JDK,如JDK-1.4.1或更高版本。SSL目前不能與能夠為其新增JSSE的JDK一起工作,如JDK-1.2.x或JDK-1.3.x,原因在於下述JSSE問題:http://developer.java.sun.com/developer/bugParade/bugs/4273544.html

·         支援SSL並已編譯和配置了該功能的MySQL伺服器,如MySQL-4.0.4和更高版本,請參見:http://www.mysql.com/doc/en/Secure_connections.html

·         客戶端證書(在本節稍後介紹)。

首先,需要將MySQL伺服器CA證書導入到Java truststore。在MySQL原始碼分發版的「SSL」子目錄下給出了1個示範MySQL伺服器CA證書。SSL將使用它來確定是否與安全MySQL伺服器進行通信。

要想使用Java的「keytool」在當前目錄下建立truststore,並導入伺服器的CA證書(「cacert.pem」),可採取下述方式(假定「keytool」位於路徑中。它位於JDK或JRE的「bin」子目錄下):

shell> keytool -import -alias mysqlServerCACert -file cacert.pem -keystore truststore
        

Keytool將給出下述響應訊息:

Enter keystore password:  *********
Owner: EMAILADDRESS=walrus@example.com, CN=Walrus, O=MySQL AB, L=Orenburg, ST=Some
-State, C=RU
Issuer: EMAILADDRESS=walrus@example.com, CN=Walrus, O=MySQL AB, L=Orenburg, ST=Som
e-State, C=RU
Serial number: 0
Valid from: Fri Aug 02 16:55:53 CDT 2002 until: Sat Aug 02 16:55:53 CDT 2003
Certificate fingerprints:
         MD5:  61:91:A0:F2:03:07:61:7A:81:38:66:DA:19:C4:8D:AB
         SHA1: 25:77:41:05:D5:AD:99:8C:14:8C:CA:68:9C:2F:B8:89:C3:34:4D:6C
Trust this certificate? [no]:  yes
Certificate was added to keystore

隨後,需要生成客戶端證書,以便MySQL伺服器知道它正與安全客戶端進行通信:

 shell> keytool -genkey -keyalg rsa -alias mysqlClientCertificate -keystore keystore 

Keytool將給出下述提示訊息,並在當目錄下建立名為「keystore」的密鑰儲存器。

您應使用與具體情況相適應的新作出響應:

Enter keystore password:  *********
What is your first and last name?
  [Unknown]:  Matthews
What is the name of your organizational unit?
  [Unknown]:  Software Development
What is the name of your organization?
  [Unknown]:  MySQL AB
What is the name of your City or Locality?
  [Unknown]:  Flossmoor
What is the name of your State or Province?
  [Unknown]:  IL
What is the two-letter country code for this unit?
  [Unknown]:  US
Is <CN=Matthews, OU=Software Development, O=MySQL AB,
 L=Flossmoor, ST=IL, C=US> correct?
  [no]:  y
 
輸入<mysqlClientCertificate>的密碼
        如果與keystore的密碼相同,按回車):

最後,要想使JSSE能夠使用您生成的keystore和truststore,啟動JVM時,需要設置下述系統屬性,用您所建立的keystore檔案完整路徑替換「path_to_keystore_file」,用您所建立的truststore檔案完整路徑替換「path_to_truststore_file」,並為每個屬性使用恰當的密碼值。

-Djavax.net.ssl.keyStore=path_to_keystore_file
-Djavax.net.ssl.keyStorePassword=*********
-Djavax.net.ssl.trustStore=path_to_truststore_file
-Djavax.net.ssl.trustStorePassword=********* 

此外,還需要在用於MySQL Connector/J的連接參數中將「useSSL」設置為「真」,方法是,在URL中新增「useSSL=true」,或在準備傳遞給DriverManager.getConnection()的java.util.Properties實例中將「useSSL」設置為「真」。

您可以打開JSSE調試功能能夠,測試SSL是否工作(詳情如下),並搜尋下述關鍵事件:

...
 *** ClientHello, v3.1
 RandomCookie:  GMT: 1018531834 bytes = { 199, 148, 180, 215, 74, 12, 54, 244, 0, 168, 55, 103, 215, 64, 16, 138, 225, 190, 132, 153, 2, 217, 219, 239, 202, 19, 121, 78 }
 Session ID:  {}
 Cipher Suites:  { 0, 5, 0, 4, 0, 9, 0, 10, 0, 18, 0, 19, 0, 3, 0, 17 }
 Compression Methods:  { 0 }
 ***
 [write] MD5 and SHA1 hashes:  len = 59
 0000: 01 00 00 37 03 01 3D B6   90 FA C7 94 B4 D7 4A 0C  ...7..=.......J.
 0010: 36 F4 00 A8 37 67 D7 40   10 8A E1 BE 84 99 02 D9  6...7g.@........
 0020: DB EF CA 13 79 4E 00 00   10 00 05 00 04 00 09 00  ....yN..........
 0030: 0A 00 12 00 13 00 03 00   11 01 00                 ...........
 main, WRITE:  SSL v3.1 Handshake, length = 59
 main, READ:  SSL v3.1 Handshake, length = 74
 *** ServerHello, v3.1
 RandomCookie:  GMT: 1018577560 bytes = { 116, 50, 4, 103, 25, 100, 58, 202, 79, 185, 178, 100, 215, 66, 254, 21, 83, 187, 190, 42, 170, 3, 132, 110, 82, 148, 160, 92 }
 Session ID:  {163, 227, 84, 53, 81, 127, 252, 254, 178, 179, 68, 63, 182, 158, 30, 11, 150, 79, 170, 76, 255, 92, 15, 226, 24, 17, 177, 219, 158, 177, 187, 143}
 Cipher Suite:  { 0, 5 }
 Compression Method: 0
 ***
 %% Created:  [Session-1, SSL_RSA_WITH_RC4_128_SHA]
 ** SSL_RSA_WITH_RC4_128_SHA
 [read] MD5 and SHA1 hashes:  len = 74
 0000: 02 00 00 46 03 01 3D B6   43 98 74 32 04 67 19 64  ...F..=.C.t2.g.d
 0010: 3A CA 4F B9 B2 64 D7 42   FE 15 53 BB BE 2A AA 03  :.O..d.B..S..*..
 0020: 84 6E 52 94 A0 5C 20 A3   E3 54 35 51 7F FC FE B2  .nR..\ ..T5Q....
 0030: B3 44 3F B6 9E 1E 0B 96   4F AA 4C FF 5C 0F E2 18  .D?.....O.L.\...
 0040: 11 B1 DB 9E B1 BB 8F 00   05 00                    ..........
 main, READ:  SSL v3.1 Handshake, length = 1712
 ...

設置了下述系統屬性時,JSSE可提供調試功能(為STDOUT):-Djavax.net.debug=all。它用於設定要使用的keystores和truststores,以及在SSL握手和證書交換過程中將出現什麼。當您嘗試進行SSL連接時,如果打算確定不能工作的部分,該設置十分有用。

26.3.3.6. 使用主/從複製和ReplicationConnection

從Connector/J 3.1.7開始,我們提供了1個驅動程式變體,它能自動發出讀/寫主伺服器的查詢,或根據Connection.getReadOnly()的狀態對從主機進行故障切換或循環負載平衡設置。

應用程式發出信號,通過使用Connection.setReadOnly(true)指明事務為只讀的,該具有複製意識的連接將使用從連接之一,從連接是採用了循環方案的負載平衡per-vm(給定連接與從連接密切相關,除非在服務中刪除了從連接)。如果您有1項寫事務,或1項對時間敏感的讀事務(記住,在MySQL中,複製是以異步方式進行的),請使用Connection.setReadOnly(false),將連接設置為非只讀的,驅動程式會確保進一步的使用均將被發送到主MySQL伺服器。驅動程式負責傳播autocommit的當前狀態,隔離級別,以及用於完成該負載平衡功能的所有連接之間的目錄。

要想啟用該該功能,在配置應用伺服器的連接池時,或為獨立應用程式建立JDBC驅動實例時,請使用「com.mysql.jdbc.ReplicationDriver」類。由於它能接受與標準MySQL JDBC驅動相同的URL格式,ReplicationDriver目前不能與基於java.sql.DriverManager的連接一起使用,除非它是用DriverManager註冊的唯一MySQL JDBC驅動程式。

下面給出了一個簡短的簡單示範,介紹了如何在獨立應用程式中使用ReplicationDriver的方法。

import java.sql.Connection;
import java.sql.ResultSet;
import java.util.Properties;
 
import com.mysql.jdbc.ReplicationDriver;
 
public class ReplicationDriverDemo {
 
    public static void main(String[] args) throws Exception {
        ReplicationDriver driver = new ReplicationDriver();
 
        Properties props = new Properties();
 
        // We want this for failover on the slaves
        props.put("autoReconnect", "true");
 
        // We want to load balance between the slaves
        props.put("roundRobinLoadBalance", "true");
 
        props.put("user", "foo");
        props.put("password", "bar");
 
        //
        // Looks like a normal MySQL JDBC url, with a comma-separated list
        // of hosts, the first being the 'master', the rest being any number
        // of slaves that the driver will load balance against
        //
 
        Connection conn =
            driver.connect("jdbc:mysql://master,slave1,slave2,slave3/test",
                props);
 
        //
        // Perform read/write work on the master
        // by setting the read-only flag to "false"
        //
 
        conn.setReadOnly(false);
        conn.setAutoCommit(false);
        conn.createStatement().executeUpdate("UPDATE some_table ....");
        conn.commit();
 
        //
        // Now, do a query from a slave, the driver automatically picks one
        // from the list
        //
 
        conn.setReadOnly(true);
 
        ResultSet rs = conn.createStatement().executeQuery("SELECT a,b,c FROM some_other_table");
 
         .......
    }
}

26.3.4. 與J2EE和其他Java框架一起使用 Connector/J

本節介紹了在數種不同情況下使用Connector/J的方法。

26.3.4.1. 一般J2EE概念

在本節中,介紹了與Connector/J使用有關的J2EE概念的基本知識。
26.3.4.1.1. 理解連接池
連接池是建立和管理多個連接的一種技術,這些連接可被需要使用它們的任何線程使用。連接池技術基於下述事實:對於大多數應用程式,當它們正在處理通常需要數毫秒完成的事務時,僅需要能夠訪問JDBC連接的1個線程。未處理事務時,連接處於閒置狀態。使用連接池,允許其他線程使用閒置連接來執行有用的任務。

事實上,當某一線程需要用JDBC在MySQL或其他資料庫上執行操作時,需要用到由連接池提供的連接。使用連接完成線程後,線程會將連接返回給連接池,以便該連接能夠被其他需要使用連接的線程使用。

從連接池「借出」連接時,該連接僅供請求它的線程使用。從編程觀點看,其效果等同於每次需要JDBC連接時使用DriverManager.getConnection(),但是,採用連接池技術,可通過使用新的或已有的連接結束線程。

連接池技術能顯著增加Java應用程式的性能,同時還能降低資源使用率。連接池技術的主要優點包括:

·         縮短了連接建立時間

與其他資料庫相比,MySQL提供了快速的連接設置功能,連接時間通常不是問題,但建立新的JDBC連接仍會導致聯網操作和一定的IDBC驅動開銷,如果這類連接是「循環」使用的,使用該方式,可避免這類不利因素。

·         簡化的編程模型

使用連接池技術時,每個單獨線程能夠像建立了自己的JDBC連接那樣進行操作,從而允許使用直接的JDBC編程技術。

·         受控的資源使用

如果不使用連接池技術,而是在每次需要時為線程建立新的連接,那麼應用程式的資源使用將十分浪費,而且在負載較重的情況下會導致無法預期的結果。

注意,與MySQL的每個連接均會在客戶端和伺服器端造成一定的開銷(每寸、CPU、關聯轉換等)。每個連接均會對應用程式和MySQL伺服器的可用資源帶來一定的限制。無論連接是否執行任何有用的任務,仍將使用這些資源中的相當一部分。

連接池能夠使性能最大化,同時還能將資源利用控制在一定的水平之下,如果超過該水平,應用程式將崩潰而不僅僅是變慢。

幸運的是,Sun公司通過JDBC-2.0「可選」接口,完成了JDBC中連接池概念的標準化實施,所有主要應用伺服器均實施了能夠與MySQL Connector/J一起良好工作的這類API。

通常,您可以在應用伺服器的配置檔案中配置連接池,並通過Java命名和目錄接口(JNDI)訪問它。在下面的代碼中,介紹了在J2E應用伺服器上運行的應用程式中使用連接池的方法:

示範26.12. 與J2EE應用伺服器一起使用連接池

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

import javax.naming.InitialContext;
import javax.sql.DataSource;


public class MyServletJspOrEjb {

    public void doSomething() throws Exception {
        /*
         * Create a JNDI Initial context to be able to
         *  lookup  the DataSource
         *
         * In production-level code, this should be cached as
         * an instance or static variable, as it can
         * be quite expensive to create a JNDI context.
         *
         * Note: This code only works when you are using servlets
         * or EJBs in a J2EE application server. If you are
         * using connection pooling in standalone Java code, you
         * will have to create/configure datasources using whatever
         * mechanisms your particular connection pooling library
         * provides.
         */

        InitialContext ctx = new InitialContext();

         /*
          * Lookup the DataSource, which will be backed by a pool
          * that the application server provides. DataSource instances
          * are also a good candidate for caching as an instance
          * variable, as JNDI lookups can be expensive as well.
          */

        DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/MySQLDB");

        /*
         * The following code is what would actually be in your
         * Servlet, JSP or EJB 'service' method...where you need
         * to work with a JDBC connection.
         */

        Connection conn = null;
        Statement stmt = null;

        try {
            conn = ds.getConnection();

            /*
             * Now, use normal JDBC programming to work with
             * MySQL, making sure to close each resource when you're
             * finished with it, which allows the connection pool
             * resources to be recovered as quickly as possible
             */

            stmt = conn.createStatement();
            stmt.execute("SOME SQL QUERY");

            stmt.close();
            stmt = null;

            conn.close();
            conn = null;
        } finally {
            /*
             * close any jdbc instances here that weren't
             * explicitly closed during normal code path, so
             * that we don't 'leak' resources...
             */

            if (stmt != null) {
                try {
                    stmt.close();
                } catch (sqlexception sqlex) {
                    // ignore -- as we can't do anything about it here
                }

                stmt = null;
            }

            if (conn != null) {
                try {
                    conn.close();
                } catch (sqlexception sqlex) {
                    // ignore -- as we can't do anything about it here
                }

                conn = null;
            }
        }
    }
}

如上例所示,獲得JNDI InitialContext並搜尋到資料庫後,其餘代碼與過去在JDBC編程中使用的類似。

使用連接池時需要牢記的最重要事項是,無論在代碼中出現了什麼(異常、控制流等),連接以及由連接建立的任何部分(語句、結果集等)均應被關閉,以便能再次使用它們。如不然,它們將糾纏在一起,在最好的情況下,意味著它們所代資料表的MySQL伺服器資源(緩衝區、鎖定、套接字等)可能會捆綁一段時間,在最壞的情況下,可能會導致永久捆綁。

連接池的最佳大小是什麼?

與所有其他配置經驗規則一樣,回答是「它取決於具體情況」。儘管最佳大小取決與預期的負載和平均的資料庫事務時間,最佳的連接池大小小於您的預期。例如,如果使用的是Sun公司的Java Petstore Blueprint應用程式,對於包含15~20個連接的連接池,使用MySQL和Tomcat,在可接受的相應時間下,可服務於中等程度的負載(600個並發用戶)。

要想確定用於應用程式的連接池大小,應使用諸如Apache Jmeter或The Grinder等工具建立負載測試指令,並對應用程式進行負載測試。

確定出發點的一種簡單方法是,將連接池的最大連接數配置為「無限」,運行負載測試,並測量最大的並發連接數。隨後,應進行反向操作,確定出使應用程式具有最佳性能的連接池的最小和最大值。

26.3.4.2. 與Tomcat一起使用Connector/J

下述內容基於關於Tomcat-5.x的指示說明,http://jakarta.apache.org/tomcat/tomcat-5.0-doc/jndi-datasource-examples-howto.html,在編寫本文檔時它是最新的。

首先安裝與Connector/J in $CATALINA_HOME/common/lib一起提供的.jar檔案,以便它能用於已安裝的所有應用程式。

其次,在定義Web應用程式的Context(場景)內,通過為$CATALINA_HOME/conf/server.xml增加聲明資源,配置JNDI DataSource:

<Context ....>

  ...

  <Resource name="jdbc/MySQLDB"
               auth="Container"
               type="javax.sql.DataSource"/>

  <!-- The name you used above, must match _exactly_ here!

       The connection pool will be bound into JNDI with the name
       "java:/comp/env/jdbc/MySQLDB"
  -->

  <ResourceParams name="jdbc/MySQLDB">
    <parameter>
      <name>factory</name>
      <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
    </parameter>

    <!-- Don't set this any higher than max_connections on your
         MySQL server, usually this should be a 10 or a few 10's
         of connections, not hundreds or thousands -->

    <parameter>
      <name>maxActive</name>
      <value>10</value>
    </parameter>

    <!-- You don't want to many idle connections hanging around
         if you can avoid it, only enough to soak up a spike in
         the load -->

    <parameter>
      <name>maxIdle</name>
      <value>5</value>
    </parameter>

    <!-- Don't use autoReconnect=true, it's going away eventually
         and it's a crutch for older connection pools that couldn't
         test connections. You need to decide if your application is
         supposed to deal with SQLExceptions (hint, it should), and
         how much of a performance penalty you're willing to pay
         to ensure 'freshness' of the connection -->

    <parameter>
      <name>validationQuery</name>
      <value>SELECT 1</value>
    </parameter>

   <!-- The most conservative approach is to test connections
        before they're given to your application. For most applications
        this is okay, the query used above is very small and takes
        no real server resources to process, other than the time used
        to traverse the network.

        If you have a high-load application you'll need to rely on
        something else. -->

    <parameter>
      <name>testOnBorrow</name>
      <value>true</value>
    </parameter>

   <!-- Otherwise, or in addition to testOnBorrow, you can test
        while connections are sitting idle -->

    <parameter>
      <name>testWhileIdle</name>
      <value>true</value>
    </parameter>

    <!-- You have to set this value, otherwise even though
         you've asked connections to be tested while idle,
         the idle evicter thread will never run -->

    <parameter>
      <name>timeBetweenEvictionRunsMillis</name>
      <value>10000</value>
    </parameter>

    <!-- Don't allow connections to hang out idle too long,
         never longer than what wait_timeout is set to on the
         server...A few minutes or even fraction of a minute
         is sometimes okay here, it depends on your application
         and how much spikey load it will see -->

    <parameter>
      <name>minEvictableIdleTimeMillis</name>
      <value>60000</value>
    </parameter>

    <!-- Username and password used when connecting to MySQL -->

    <parameter>
     <name>username</name>
     <value>someuser</value>
    </parameter>

    <parameter>
     <name>password</name>
     <value>somepass</value>
    </parameter>

    <!-- Class name for the Connector/J driver -->

    <parameter>
       <name>driverClassName</name>
       <value>com.mysql.jdbc.Driver</value>
    </parameter>

    <!-- The JDBC connection url for connecting to MySQL, notice
         that if you want to pass any other MySQL-specific parameters
         you should pass them here in the URL, setting them using the
         parameter tags above will have no effect, you will also
         need to use &amp; to separate parameter values as the
         ampersand is a reserved character in XML -->

    <parameter>
      <name>url</name>
      <value>jdbc:mysql://localhost:3306/test</value>
    </parameter>

  </ResourceParams>
</Context>

一般而言,應遵循關於相應Tomcat版本的安裝說明,這是因為,在Tomcat中配置數據源的方式會隨時變化,很不幸,如果在XML檔案中使用了錯誤的語法,很可能會以異常結束,如下所示:

Error: java.sql.SQLException: Cannot load JDBC driver class 'null ' SQL
state: null 

26.3.4.3. 與JBoss一起使用Connector/J

下述說明適用於JBoss-4.x。要想使應用伺服器能夠使用JDBC驅動類,請將與Connector/J一起提供的.jar檔案拷貝到用於伺服器配置的lib目錄下(通常稱為「預設」)。隨後,在相同的配置目錄下,在名為「deploy」的子目錄下,建立以「-ds.xml」結尾的數據源配置檔案,用於通知Jboss將該檔案當作JDBC數據源。該檔案應包含下述內容:

<datasources>
    <local-tx-datasource>
        <!-- This connection pool will be bound into JNDI with the name
             "java:/MySQLDB" -->

        <jndi-name>MySQLDB</jndi-name>
        <connection-url>jdbc:mysql://localhost:3306/dbname</connection-url>
        <driver-class>com.mysql.jdbc.Driver</driver-class>
        <user-name>user</user-name>
        <password>pass</password>

        <min-pool-size>5</min-pool-size>

        <!-- Don't set this any higher than max_connections on your
         MySQL server, usually this should be a 10 or a few 10's
         of connections, not hundreds or thousands -->

        <max-pool-size>20</max-pool-size>

        <!-- Don't allow connections to hang out idle too long,
         never longer than what wait_timeout is set to on the
         server...A few minutes is usually okay here,
         it depends on your application
         and how much spikey load it will see -->

        <idle-timeout-minutes>5</idle-timeout-minutes>

        <!-- If you're using Connector/J 3.1.8 or newer, you can use
             our implementation of these to increase the robustness
             of the connection pool. -->

        <exception-sorter-class-name>com.mysql.jdbc.integration.jboss.ExtendedMysqlExceptionSorter</exception-sorter-class-name>
        <valid-connection-checker-class-name>com.mysql.jdbc.integration.jboss.MysqlValidConnectionChecker</valid-connection-checker-class-name>

    </local-tx-datasource>
</datasources> 

26.3.5. 診斷 Connector/J方面的問題

在本節中,介紹了如何解決使用Connector/J時遇到的問題。

26.3.5.1. 常見問題和解決方案

對於MySQL Connector/J用戶,會遇到一些常見的共同問題。在本節中,介紹了它們的症狀和相應的解決方法。 關於更進一步的訊息,請參見「支援」一節。

27.3.5.1.1:

問題:

當我嘗試用MySQL Connector/J連接到資料庫時,遇到下述異常:

SQLException: Server configuration denies access to data source
SQLState: 08001
VendorError: 0

出現了什麼問題? 使用MySQL命令行客戶端時,連接良好。

回答:

MySQL Connector/J必須使用TCP/IP套接字來連接MySQL,原因在於Java不支援Unix Domain套接字。因此,當MySQL Connector/J連接到MySQL時,MySQL伺服器的安全管理器將使用其授權資料表判斷是否允許連接。必須新增授權才能允許該操作。下面給出了一個執行該操作的示範(但並非最安全的)。

從mysql命令行客戶端以能夠授權的用戶身份登錄,並發出下述命令:

GRANT ALL PRIVILEGES ON [dbname].* to
                '[user]'@'[hostname]' identified by
                '[password]'

用您的資料庫名稱替換[dbname],用帳號替換[user],用MySQL Connector/J將連接的主機替換[hostname],並用打算使用的密碼替換[password]。注意,對於從本地主機進行連接的主機名部分,RedHat Linux將失敗。在這種情況下,對於[hostname]值,需要使用「localhost.localdomain」。隨後,發出FLUSH PRIVILEGES命令。

註釋:

除非新增了「--host」標誌,並為主機使用了不同於「localhost」的其他設置,否則將無法使用mysql命令行客戶端測試連通性。如果使用了特殊的主機名「localhost」,mysql命令行客戶端將使用Unix域套接字。如果正在測試與「localhost」的連通性,請使用「127.0.0.1」作為主機名。

警告

如果您不瞭解「GRANT」命令是幹什麼的,或不瞭解該命令的工作方式,在嘗試更改權限之前,請閱讀MySQL手冊中的 一般安全事宜以及MySQL訪問權限體系一節。

如果在MySQL中不恰當地更改了權限和授權,可能會使伺服器不會具有最佳的安全性能。

27.3.5.1.2:

問題:

我的應用程式拋出SQLException「無恰當的驅動程式」。為什麼會出現該情況?

回答:

出現了兩種情況之一。或是1驅動程式未位於您的CLASSPATH中(請參見前面的「安裝部分」),或是URL格式不正確(請參見用MySQL Connector/J開發應用程式)。

27.3.5.1.3:

問題:

當我試圖在Java程式或應用程式中使用MySQL Connector/J時,遇到類似下面的異常:

SQLException: 無法連接到host:3306上的MySQL伺服器。
在您嘗試連接的機器/端口上是否有正在運行的MySQL伺服器?
 
(java.security.AccessControlException)
SQLState: 08S01
VendorError: 0 

回答:

或許是因為您正在運行Applet,您的MySQL伺服器是採用「--skip-networking」選項集安裝的;或許是因為MySQL伺服器位於防火牆之後。

Applet僅能使網絡連接返回運行Web伺服器的機器,該Web伺服器提供了用於Applet的.class檔案。這意味著,要想使其工作,MySQL必須運行在相同的機器上(或必須使某類端口重定向)。這還意味著,您無法通過您的本地檔案系統來測試Java程式,您必須將它們放在Web伺服器上。

MySQL Connector/J僅能使用TCP/IP與MySQL進行通信,這是因為Java不支援Unix域套接字。如果MySQL是用「--skip-networking」標誌啟動的,或採用了防火牆,TCP/IP與MySQL的通信可能會受到影響。

如果MySQL是用「--skip-networking」選項集啟動的(例如MySQL伺服器的Debian Linux包即用於該目的),需要在檔案/etc/mysql/my.cnf或/etc/my.cnf中將其註釋掉。當然,my.cnf檔案也可能位於MySQl伺服器的「data」目錄下或其他地方(取決於系統中MySQL的編譯方式)。MySQL AB建立的二進制檔案總會在搜尋/etc/my.cnf和[datadir]/my.cnf。如果為MySQL伺服器部署了防火牆,需要對防火牆進行配置,允許從運行Java代碼的主機在MySQL監聽的端口上(預設為3306)建立與 MySQL伺服器的TCP/IP連接。

27.3.5.1.4:

問題:

I我的小服務程式/應用程式白天工作良好,但在晚上卻停止工作。

回答:

不工作時間超過8小時後,MySQL關閉了連接。您或許需要使用能處理失效連接的連接池,或使用「autoReconnect」參數(請參見用MySQL Connector/J開發應用程式)。

此外,您應在應用程式中俘獲 SQLException並處理它們,而不是在應用程式退出前一直傳播它們,這是1個好的編程習慣。在查詢處理過程中遇到網絡連通性方面的問題時,MySQL Connector/J會將SQLState(參見APIDOCS中的java.sql.SQLException.getSQLState())設置為「08S01」。隨後,應用程式代碼將嘗試再次連接到MySQL。

在下面的示範(simplistic)中,給出了能夠處理這類異常的代碼:

示範26.13. 重試邏輯的事務示範

public void doBusinessOp() throws SQLException {
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;

        //
        // How many times do you want to retry the transaction
        // (or at least _getting_ a connection)?
        //
        int retryCount = 5;

        boolean transactionCompleted = false;

        do {
            try {
                conn = getConnection(); // assume getting this from a
                                        // javax.sql.DataSource, or the
                                        // java.sql.DriverManager

                conn.setAutoCommit(false);

                //
                // Okay, at this point, the 'retry-ability' of the
                // transaction really depends on your application logic,
                // whether or not you're using autocommit (in this case
                // not), and whether you're using transacational storage
                // engines
                //
                // For this example, we'll assume that it's _not_ safe
                // to retry the entire transaction, so we set retry count
                // to 0 at this point
                //
                // If you were using exclusively transaction-safe tables,
                // or your application could recover from a connection going
                // bad in the middle of an operation, then you would not
                // touch 'retryCount' here, and just let the loop repeat
                // until retryCount == 0.
                //
                retryCount = 0;

                stmt = conn.createStatement();

                String query = "SELECT foo FROM bar ORDER BY baz";

                rs = stmt.executeQuery(query);

                while (rs.next()) {
                }

                rs.close();
                rs = null;

                stmt.close();
                stmt = null;

                conn.commit();
                conn.close();
                conn = null;

                transactionCompleted = true;
            } catch (SQLException sqlEx) {

                //
                // The two SQL states that are 'retry-able' are 08S01
                // for a communications error, and 41000 for deadlock.
                //
                // Only retry if the error was due to a stale connection,
                // communications problem or deadlock
                //

                String sqlState = sqlEx.getSQLState();

                if ("08S01".equals(sqlState) || "41000".equals(sqlState)) {
                    retryCount--;
                } else {
                    retryCount = 0;
                }
            } finally {
                if (rs != null) {
                    try {
                        rs.close();
                    } catch (SQLException sqlEx) {
                        // You'd probably want to log this . . .
                    }
                }

                if (stmt != null) {
                    try {
                        stmt.close();
                    } catch (SQLException sqlEx) {
                        // You'd probably want to log this as well . . .
                    }
                }

                if (conn != null) {
                    try {
                        //
                        // If we got here, and conn is not null, the
                        // transaction should be rolled back, as not
                        // all work has been done

                        try {
                            conn.rollback();
                        } finally {
                            conn.close();
                        }
                    } catch (SQLException sqlEx) {
                        //
                        // If we got an exception here, something
                        // pretty serious is going on, so we better
                        // pass it up the stack, rather than just
                        // logging it. . .

                        throw sqlEx;
                    }
                }
            }
        } while (!transactionCompleted && (retryCount > 0));
    }

27.3.5.1.5:

問題:

我正嘗試使用JDBC-2.0可更新結果集,但遇到異常,說我的結果集不可更新。

回答:

由於MySQL沒有行ID,MySQL Connector/J僅能更新來自查詢且位於有至少一個主鍵的資料表上的結果集,查詢必須選擇所有的主鍵,而且查詢即能作用在1個資料表上(即不存在聯合)。在JDBC規範中給出了這方面的介紹。

26.3.5.2. 如何通報問題和問題

通報問題的正常地址是http://bugs.mysql.com/,它也是我方問題資料庫的地址。這是1個公共資料庫,任何人都能瀏覽它並進行相應的搜索。如果您已登錄到系統,也應能輸入新的報告。

如果發現MySQL中存在敏感的安全問題,請發送電子郵件至security@mysql.com

編寫良好的問題報告需要耐心,但在第1時間正確地完成它不僅能節省我們的時間,也能節省您自己的時間。良好的問題報告應包含對問題的完整測試情況,以便我們您能夠在下個版本中更正該問題。

本節介紹的內容用於幫助您正確地編寫報告,從避免將您的時間浪費在對我們幫助不大或沒有幫助的事上,

如果有1份可重複的問題報告,請將其提交到問題資料庫,http://bugs.mysql.com/

對於任何我們能再現的問題,在下一個MySQL版本中修正它的機會很大。

要想通報其他問題,請使用MySQL郵件列資料表。

請注意,我們可能會對包含過多訊息的消息作出響應,但不太會對包含過少訊息的消息作出回應。人們常會省略掉一些事實,因為他們認為自己知道了故障的原因,並想當然地認為這類細節無關緊要。

良好的原則是:如果您對陳述某事猶豫不定,請陳述之。如果我們要求您提供初始報告中缺少的訊息,在報告中編寫多行資訊來源比等候回復要快,麻煩也更小。

在問題報告,最常犯的錯誤包括:(a)未包含所使用Connector/J或MySQL的版本號,以及(b)未完全描述安裝了Connector/J的平台(包括JVM版本,平台類型,以及所安裝MySQL本身的版本號)。

這是高度相關的訊息,如果沒有它,99%的問題報告無用。我們遇到這類問題,「為何它對我沒用」? 隨後,我們發現在該MySQL版本中,所請求的特性尚未實施,或在較新的MySQL版本中已更正了報告中描述的問題。

有些時候,錯誤與平台相關,在這類情況下,如果不知道作業系統和平台的版本號,我們幾乎不可能更正任何問題。

如果可能,您應建立1份可重複的、不含任何第三方類的獨立測試案例。

為了是該程序流線化,我們與Connector/J一起提供了用於測試的基本類,名為com.mysql.jdbc.util.BaseBugReport。要想使用該類為Connector/J建立1個測試案例,您應應建立自己的從com.mysql.jdbc.util.BaseBugReport繼承的類,並覆蓋方法setUp()tearDown()runTest()。

setUp()方法中,建立用於建立資料表的代碼,並用演示問題所需的數據填充資料表。

runTest ()方法中,使用在「setUp」方法中建立的資料表和數據,建立用於演示問題的代碼。

tearDown()方法中,撤銷在setUp()方法中建立的任何資料表。

對於上述三種方法中的任何一種,應使用getConnection ()各種變體中的一種建立與MySQL的JDBC連接。

·         getConnection():提供了與在getUrl()中指定的JDBC URL的連接。如果連接已存在,返回該連接,否則將建立新的連接。

·         getNewConnection():如果需要為問題報告獲得新的連接(即包含1個以上的連接),應使用它。

·         getConnection(String url):使用給定的URL返回連接。

·         getConnection(String url, Properties props):使用給定的URL和屬性返回連接。

如果需要使用不同於「jdbc:mysql:///test」的JDBC URL,還應覆蓋方法getUrl()

在演示您所預計行為的測試案例中(相對於您觀察到的世紀行為,這是您填充錯誤報告的最可能原因),使用assertTrue(boolean expression)assertTrue(String failureMessage, boolean expression)方法建立必須滿足的條件。

最後,建立用於建立測試案例實例的main ()方法,並使用run方法:

public static void main(String[] args) throws Exception {
      new MyBugReport().run();
 }

完成了測試案例並證實它能演示您所通報的問題後,請將該案例與問題報告一起上傳到http://bugs.mysql.com/

26.3.6. Changelog

# Changelog
# $Id: CHANGES,v 1.38.4.206 2005/05/12 15:25:54 mmatthews Exp $
 
05-17-05:版本3.2.1-alpha
 
    - 現已不再重視Autoreconnect功能(即autoReconnect=true)。
      如果嘗試並使用它將拋出異常,使用「enableDeprecatedAutoreconnect=true」可繼續使用autoReconnect。但是,在Connector/J 3.3中將刪除該項特性,請參見手冊中關於不需要使用autoReconnect的相應解決方案。
 
    - 現在,驅動程式將檢查是否設置了伺服器變數「init_connect」,如果設置了該變數,將檢查autocommit(自動提交)設置,並應用它。
  
    - 如果連接的伺服器版本在5.0.x以上,而且Statement.setFetchSize( > 0),驅動程式將嘗試使用伺服器預處理語句,並使用結果集「cursors」獲取語句。
  
    - ServerPreparedStatements現在能正確地將BLOB/CLOB數據以「流方式」發送至伺服器。您可以使用屬性「blobSendChunkSize」配置程式塊大小的閾值(預設值為1MB)。
  
    - 支援sql模式NO_BACKSLASH_ESCAPES以及非伺服器端預處理語句。
 
12-23-04:版本3.2.0-alpha
 
    -更正了DatabaseMetaData.supportsCatalogIn*()錯誤的返回值。
    
    -使用ServerPreparedStatements以及MySQL 5.0或更高版本時,支援基於「cursor」的結果集。結果集需為「僅正向」結果集,並需啟用針對該項特性的非零獲取大小。
      
    - 重新分解了預處理語句的where邏輯,伺服器端預處理語句保持有效。
 
10-07-05:版本3.1.11-stable
 
    - 更正了BUG#11629:當字元編碼是「utf8」時控制台上的偽「!」。
      
    -更正了為丟失「;」(用於「plain」語句)的測試案例生成的語句。
      
    - 更正了BUG#11663:為伺服器端預處理語句生成的不正確的testcase指令。
      
    -更正了因修補BUG#11552而導致的回歸,對於BUG#11552,當整數處於正號類型的範圍內時,對於無符號整數,該問題將導致驅動程式返回錯誤值。
    
    -將源代碼移到了svn repo。
    
    -更正了BUG#11797:轉義標誌不考慮用於轉義用途的層套式單引號。
  
    -使用伺服器端預處理語句時,不識別GEOMETRY類型。
    
    -更正了BUG#11879:ReplicationConnection不會切換至從連接,拋出「目錄不能為空」異常。
      
    -更正了BUG#12218,主連接和具有複製連接的從連接之間共享的屬性。
      
    - 更正了BUG#10630。如果語句已關閉,Statement.getWarnings()無法與NPE一起工作。
      
    -需要時,在PreparedStatement.ParseInfo()中,即能從SQL獲取char[]。
    
    -更正了BUG#12104,伺服器端預處理語句不能處理Geometry類型。
      
    -更正了BUG#11614,使用多字節字元編碼時,StringUtils.getBytes()不工作,在「_characters_」中指定了長度。
      
    -更正了BUG#11798,Pstmt.setObject(...., Types.BOOLEAN)拋出異常。
    
    -更正了BUG#11976,maxPerformance.properties拼錯「elideSetAutoCommits」。
  
    -更正了BUG#11575,對於在Window平台上的伺服器,DBMD.storesLower/Mixed/UpperIdentifiers()通報不正確的值。
  
    -更正了BUG#11190,在ResultSet.moveToCurrentRow()之前使用了ResultSet.moveToInsertRow()時,ResultSet.moveToCurrentRow()不起作用。
  
    -更正了BUG#11115,使用伺服器端預處理語句和.setBytes()時,VARBINARY數據發生崩潰。
 
    -更正了BUG#12229,伺服器端預處理語句掛起explainSlowQueries。
  
    -更正了BUG#11498,轉義處理器不考慮用雙引號分隔的字串。
  
    -對於伺服器端預處理語句,增加了對更改流參數的限制。只要在執行前設置了「_all_」流參數,可不必使用.clearParameters()。(由於客戶端/伺服器協議的限制,預處理語句不能復位伺服器端的「_individual_ stream」數據)。
   
    -修改了Field類,*Buffer和MysqlIO,能夠識別大於Integer.MAX_VALUE的字段長度。
  
    -更新了DBMD.supportsCorrelatedQueries(),當版本高於4.1時返回「真」,更新了supportsGroupByUnrelated()使之返回「真」,並更新了getResultSetHoldability()使之返回HOLD_CURSORS_OVER_COMMIT。
  
    -更正了BUG#12541,DatabaseMetaData.getIndexInfo()中的catalog(目錄)參量處理,它也意味著對DatabaseMetaData中下述方法的更改:
  
    - getBestRowIdentifier()
    - getColumns()
    - getCrossReference()
    - getExportedKeys()
    - getImportedKeys()
    - getIndexInfo()
    - getPrimaryKeys()
    - getProcedures() (and thus indirectly getProcedureColumns())
    - getTables()
  
上述所有方法中的「catalog」參量現具有下述行為特徵:
  
  -如果指定為Null,資料表示不會使用catalog來過濾結果(因此將搜索所有資料庫),除非在JDBC URL屬性中設置了「nullCatalogMeansCurrent=true」。
 
  -指定為「」資料表示當前catalog,儘管它不是十分兼容JDBC規範,但它是為傳統用戶保留的。
 
  -指定catalog,使之按API文檔中闡明的方式工作。
    
  -使得jdbc2.optional軟件包中的「封裝」連接能夠使用Connection.clientPrepare()(使用ConnectionPoolDataSource實例建立連接)。
 
    -為客戶端增加了Connection.isMasterConnection(),以確定多主機主/從連接是否連接至列資料表中的第1個主機。
 
    -更正了BUG#12753,URL屬性用於「=」的標誌會導致「sessionVariables=....」無法正確地參數化。
 
    -更正了BUG#11781,當DatabaseMetaData方法使用該訊息時,所引用的外部鍵訊息不能被正確解析。
 
    -考慮到流緩衝區大小和訊息包報頭,「sendBlobChunkSize」屬性現在與「max_allowed_packet」密切結合在一起,當max_allowed_packet的大小類似於預設的「sendBlobChunkSize」時(為1MB),能避免PacketTooBigExceptions。
 
    -CallableStatement.clearParameters()現能清除與INOUT/OUTPUT參數和INPUT參數相關的屬性。
 
    -更正了BUG#12417,Connection.prepareCall()是區分大小寫的資料庫名稱(在Windows系統上)。
 
    -更正了BUG#12752,對於版本高於4.0.x的伺服器,Cp1251不正確地映射至win1251。
 
    -更正了BUG#12970,使用DatabaseMetaData.getColumns()時,java.sql.Types.OTHER返回BINARY和VARBINARY列。
  
    -引用參數約束列資料表前,ServerPreparedStatement.getBinding()現在將檢查語句是否已關閉,以避免拋出NullPointerException。
 
    -更正了BUG#13277,無論何時,當使用需要連接引用的方法時,來自Statement.getGeneratedKeys()的ResultSetMetaData將導致NullPointerExceptions的拋出。
 
    -自5.0起,Field類ResultSetMetaData.getColumnClassName()和ResultSet.getObject(int)的反向移植出現了變化,更正了VARCHAR BINARY/VARBINARY和相關類型有關的行為。
 
    -更正了NullPointerException,當參數為NULL時,在很多DatabaseMetaDataMethods中將「catalog」參數轉換為byte[]時出現的異常(對於結果集)。(根據JDBC規範,從技術角度上不允許「null」,但從歷史觀點上,我們允許使用它)。
 
    -從5.0起,VAR[BINARY|CHAR] [BINARY]類型檢測的反向移植。
    
    -即使無法打開本地檔案,也能讀取MysqlIO.sendFileToServer()中響應,否則,下一個發出的查詢將失敗,這是因為,它正在讀取對發送至伺服器的空LOAD DATA INFILE訊息包的響應。
 
    -避開了BUG#13374,已關閉結果集上的ResultSet.getStatement()返回NULL(按照JDBC 4.0規範,但不具有向後相容性)。將連接屬性「retainStatementAfterResultSetClose」設為「真」,以便能夠在通過.getStatement()關閉了結果集後檢索結果集的語句(預設為「假」以便與JDBC兼容,並降低使用JDBC的代碼名洩漏語句實例的機會)。
 
    -更正了BUG#13453,URL配置參數不允許在它們的值中使用「&」或「=」。現在JDBC驅動程式能夠對配置參數進行相應地解析,就像它們是使用application/x-www-form-urlencoded格式(在java.net.URLDecoder中指定,http://java.sun.com/j2se/1.5.0/docs/api/java/net/URLDecoder.html)進行編碼那樣。
 
如果在配置屬性中出現字元「%」,現在必須用「%25」資料表示,它是使用「application/x-www-form-urlencoded」編碼使「%」的已編碼形式。
 
    -配置屬性「sessionVariables」現在允許您指定以「@」符號開始的變數。
 
    -更正了BUG#13043,為低於4.1.0版的伺服器允許了「gatherPerfMetrics」時,如果查詢未使用任何資料表,結果集的構造函數將拋出NullPointerException。
 
06-23-05:版本3.1.10-stable
 
    -更正了因無指定資料庫而導致的MysqlIO.changeDatabaseTo()中的異常。
  
    -首次實現了用於PreparedStatement.getParameterMetadata()的ParameterMetadata。僅能與CallableStatements一起完全發揮作用,這是因為當前的伺服器端預處理語句會將所有參數返回為VARCHAR類型。
    
06-22-05:版本3.1.9-stable
 
    -徹底檢查了字元編碼配置,現在所有相關項均能位於屬性檔案中。
  
    -如果在用於Windows-31J的伺服器上可用,驅動程式能正確使用CP932,以及CP932和MS932 java編碼名稱,否則將求助於僅為近似的SJIS。目前,僅在MySQL-5.0.3和更高版本上(以及MySQL-4.1.12/13,取決於何時反向移植字元編碼),才能可靠地支援任何CP932變體。
 
    -更正了BUG#9064,com.mysql.jdbc.PreparedStatement.ParseInfo對toCharArray()的不必要使用。
 
    -更正了Bug#10144,如果serverPrepare()失敗,ServerPreparedStatement中的內存洩漏。
 
    -將清單檔案實際寫入正確位置,以便其終止於二進制jar檔案。
 
    -增加了「createDatabaseIfNotExist」屬性(預設為「假」),該屬性會使驅動程式請求伺服器建立在URL中指定的資料庫(如果該資料庫不存在的話)。必須擁有恰當的資料庫建立權限才能執行該任務。
 
    -更正了BUG#10156,對於ResultSet.getInt(),無符號SMALLINT被當作帶符號類型,更正了所有的UNSIGNED整數和伺服器端預處理語句,以及用於UNSIGNED TINYINT的ResultSet.getObject()。
 
    -更正了BUG#10155,解析客戶端預處理語句時不能識別雙引號。
  
    -使得enableStreamingResults()在com.mysql.jdbc.jdbc2.optional.StatementWrapper上可見。
  
    -使得ServerPreparedStatement.asSql()能正確工作,自動解釋功能可以與伺服器端預處理語句一起工作。
  
    -使得兼容JDBC2的軟件包成為公共包,以便允許訪問廠家延伸。
  
    -整理了剖析工具事件的記錄功能,移動了代碼以將剖析工具事件轉儲為com.mysql.jdbc.log.LogUtils的字串,以便第三方能夠使用它。
  
    - DatabaseMetaData.supportsMultipleOpenResults()現在返回「真」。DBMD剛剛丟失某一內容時,驅動程式在一段時間內支援它。
  
    -更正了BUG#10310,驅動程式不支援用來使用儲存程式的{?=CALL(...)}。其中包括,為DatabaseMetaData.getProcedures()和getProcedureColumns()增加了函數檢索支援。
 
    -更正了BUG#10485,用ResultSet.getString()檢索YEAR(2)時拋出SQLException。現在,驅動程式總是將YEAR類型當作java.sql.Dates對待,並為getString()返回正確值。
另外,可以將「yearIsDateType」連接屬性設置為「假」,並將值作為SHORT進行處理。
  
    -當「tinyInt1isBit=true」時(預設),使用新的配置屬性「transformedBitIsBoolean」(預設為「假」),對於TINYINT(1)列,返回的數據類型可在Types.BOOLEAN和Types.BIT之間切換。如果設為「假」(預設),對於TINYINT(1)列,DatabaseMetaData.getColumns()和ResultSetMetaData.getColumnType()將返回Types.BOOLEAN。如果為「真」,將返回Types.BOOLEAN。無論該配置屬性是如何設置的,如果允許了「tinyInt1isBit」,具有TINYINT(1)類型的列將作為ResultSet.getObject(..)的java.lang.Boolean實例返回,而且ResultSetMetaData.getColumnClassName()將返回「java.lang.Boolean」。
 
    -更正了BUG#10496,與cp932或eucjpms一起使用「characterSetResults」屬性時將拋出SQLException。
 
    -重組了目錄格局,原始碼現位於「src」檔案夾下,建立時不填充父目錄,輸出位於「./build」下,分發版位於「./dist」下。
 
    -這類支援/問題跟蹤特性,將「autoGenerateTestcaseScript」設置為「真」時,該特性能夠為STDERR生成.sql測試指令。
 
    -更正了BUG#10850,使用伺服器端預處理語句時,不會將「0長度」流發送給伺服器。
    
    -現在,如果設置了「cachePrepStmts=true」,也會使連接進行高速緩衝操作,檢查驅動程式的執行情況,以判斷預處理語句是否能夠在伺服器端工作,並能在連接的生命期內對伺服器端預處理語句進行高速緩衝處理。與以往一樣,參數「prepStmtCacheSize」負責控制這些高速緩衝區的大小。
 
    -進行了嘗試,以更為優美的方式處理OutOfMemoryErrors。儘管所能作的事情不是很多,但在大多數情況下它們能關閉所遇到的連接,這樣,進一步的操作不會進入狀態不明的連接。出現OOM時,連接上的任何進一步操作均將失敗,同時拋出「連接已關閉」異常,還將列出作為隱式連接關閉事件原因的OOM異常。
 
    -如果未要求,執行伺服器端預處理語句時不發送COM_RESET_STMT。
 
    -驅動程式將檢測是否正在運行MySQL-5.0.7或更高版本,而且不掃瞄正在處理的語句中的「LIMIT ?[,?]」,這是因為目前伺服器支援這類查詢。
 
    -更正了BUG#11115,使用伺服器端預處理語句和ResultSet.getBytes()時,VARBINARY數據發生崩潰
 
    -Connection.setCatalog()想在能夠識別「useLocalSessionState」配置屬性,將該屬性設為「真」時,如果所請求的catalog與當前catalog相同,會阻止驅動程式將「USE ...」發送給伺服器。
 
    -增加了下述配置捆包,通過「useConfigs」配置屬性使用1個或多個:
    
  * maxPerformance:考慮後果時的最大性能
  * solarisMaxPerformance:Solaris的需性能,在可能的情況下避免系統使用。
  * 3-0-Compat:與Connector/J 3.0.x功能兼容。
  
    -增加了「"maintainTimeStats」配置屬性(預設為「真」),用於通知驅動程式是否應跟蹤上次查詢時間,以及上次成功將訊息包發送到伺服器的時間。如果將其設置為「假」,將刪除每查詢的兩次系統使用。
    
    -更正了BUG#11259,autoReconnect的ping操作會導致連接啟動時的異常。
 
    -更正了BUG#11360,Connector/J將查詢兩次轉儲到SQLException。
    
    -更正了PreparedStatement.setClob(),不接受Null作為參數。
    
    -更正了BUG#11411,生產包不包括JBoss集成類。
 
 
    -刪除了使用「usage advisor」時無意義的「開銷昂貴的類型轉換」告警。
 
 
04-14-05:版本3.1.8-stable
 
    -更正了DatabaseMetaData.getTables(),未要求時,以請求資料表的類型之一返回視圖。
 
    -在5.0.3和更高版本的MySQL中,增加了對新精度數學DECIMAL類型的支援。
 
    -更正了ResultSet.getTime(),作用於伺服器端預處理語句的Null值上時拋出NPE。   -使Connection.ping()成為public方法。   -更正了Bug#8868,DATE_FORMAT()查詢從getObject()返回BLOB。   - ServerPreparedStatements現在能正確地將BLOB/CLOB數據以「流方式」發送至伺服器。您可以使用屬性「blobSendChunkSize」配置程式塊大小的閾值(預設值為1MB)。
 
    -生成預處理語句時,BlobFromLocator現在能使用正確的ID引用。
 
    -使用連接屬性「sessionVariables」的逗號分隔列資料表方式傳遞它們,能夠在連接時預先設置伺服器端會話變數。
 
    -為使用「autoReconnect=true」的用戶更正了ping()中的回歸問題。
 
    -更正了BUG#9040,PreparedStatement.addBatch()不能與伺服器端預處理語句和流式BINARY數據一起工作。
 
    -更正了BUG#8800,對於運行於區分大小寫的檔案系統上的伺服器,DBMD.supportsMixedCase*Identifiers()返回錯誤值。
 
    -更正了BUG#9206,對於characterSetResults配置屬性,不能使用「UTF-8」。
 
    -更正了BUG#9236,連續BUG#8868,在查詢中使用了多個函數,查詢本應返回非字串類型,但當臨時資料表解析它們時,返回類型突然變為難以理解的二進制字串(針對伺服器限制採取了相應的避規措施)。此外,還更正了類型為CHAR(n) CHARACTER SET BINARY的字段,使其能夠為RSMD.getColumnClassName()和ResultSet.getObject()返回正確/匹配的類。
 
    -更正了BUG#8792,對於「僅正向/只讀」結果集(我們支援該方式),DBMD.supportsResultSetConcurrency()未返回「真」。
 
    -更正了BUG#8803,訪問時,DBMD.getBestRowIdentifier()的「DATA_TYPE」列導致ArrayIndexOutOfBoundsException(事實上,未返回任何值)。
 
    -檢查了將char/varchar列數據轉換為數值時的空字串(''),如果配置屬性「emptyStringsConvertToZero」被設為「假」,拋出異常(為了與3.0版的向後兼容,預設情況下,將其設為「真」,但在3.2版中,最可能的預設設置為「假」)。
 
    -更正了BUG#9320,在特定條件下,當未使用伺服器端預處理語句時,PreparedStatement.getMetaData()在資料庫中插入了空白行。
 
    -Connection.canHandleAsPreparedStatement()現在將盡「最大努力」來識別帶有佔位符的LIMIT子句,目的在於,對於伺服器目前不能將其當作伺服器端預處理語句予以處理的語句,為其生成處理措施時,獲得較少的錯誤肯定結果。
 
    -更正了build.xml,如果log4j不可用,不編譯log4j日誌功能。
 
    -增加了對c3p0連接池的(http://c3p0.sf.net/)驗證/連接檢驗器接口的支援,如果伺服器可用,該檢驗器接口將使用輕型「COM_PING」使用。要想使用它,請配置c3p0連接持的「connectionTesterClassName」屬性,以使用「com.mysql.jdbc.integration.c3p0.MysqlConnectionTester」。
 
    -更好的檢測引用字串的內外LIMIT,以便驅動程式能更加正確地判斷是否可以在伺服器上處理預處理語句。
 
    -更正了BUG#9319,當驅動程式試圖確定參數計數/類型時,分不清不同資料庫中具有相同名稱的儲存程式。
 
    -為ResultSet和Statement實施增加了最終確定器,以便與JDBC規範兼容,該規範要求,如果它們未明確關閉,在無用單元收集階段應關閉這些資源。
 
    -更正了BUG#9682,對於具有DECIMAL參數和儲存要求的儲存程式,如果包含「,」,將失敗。
 
    - PreparedStatement.setObject(int, Object, int type, int scale)現在能使用針對BigDecimal實例的標度值。
 
    -更正了BUG#9704,當已有結果集是.close()d時,Statement.getMoreResults()可能拋出NPE。
 
    -性能度量特性現能收集關於SELECT中引用的資料表數量的訊息。
 
    -現在能夠自動配置日誌系統。如果用戶通過URL屬性「logger」或系統屬性「com.mysql.jdbc.logger」設置了值,那麼將使用用戶的設置,否則將採用下述步驟自動檢測設置:
 
   如果Log4j可用,將使用它,接下來是JDK1.4日誌功能,再接下來是STDERR日誌功能。
 
    -更正了BUG#9778,即使資料庫版本不支援視圖,如果請求了視圖,DBMD.getTables()不應返回資料表。
 
    -更正了驅動程式,當在伺服器端預處理語句返回的結果集上使用了ResultSet.getBoolean()時,對於「-1」不返回「真」。
 
    -為.jar檔案增加了Manifest.MF檔案以及實施訊息。
 
    -在Field.isOpaqueBinary()中提供了更多測試,以識別晦澀的二進制字段(即具有CHAR(n)和CHARACTER SET BINARY類型的字段),這類字段來自各種標量函數和聚合函數(返回字串)的輸出。
 
    -更正了BUG#9917,出於傳統方面的考慮,即使它與JDBC不兼容,也應接受DBMD方法中用於catalog(使用當前值)的Null。將連接屬性「nullCatalogMeansCurrent」設置為「假」可禁止它(在C/J 3.2.x中,它是預設設置)。
 
    -更正了BUG#9769,出於傳統方面的考慮,即使它與JDBC不兼容,也應接受DBMD中用於名稱(「%」)的Null。將連接屬性「nullNamePatternMatchesAll」設置為「假」可禁止它(在C/J 3.2.x中,它是預設設置)。
 
02-18-05:版本3.1.7-stable
 
    -更正了BUG#7686,Timestamp關鍵字列數據需要分離的「_binary」,用於UpdatableResultSet.refreshRow()。
 
    -更正了BUG#7715,對於伺服器端預處理語句和可更新結果集,Timestamps錯誤地轉換為字串。
 
    -檢測字串資料表單(以前為整數)中的sql_mode變數,並恰當調整字串的引用方法。
 
    -增加了「holdResultsOpenOverStatementClose」屬性(預設為「假」),它能將statement.close()的結果集保持打開狀態,或執行相同語句(由Kevin Burton推薦)。
 
    -更正了BUG#7952,在故障切換配置下回退至主連接時的無限遞歸。
 
    -如果允許了高速緩衝,將禁止4.1.10版之前MySQL-4.1版本的多語句功能(如果以允許的話),這是因為在該配置下,伺服器會返回錯誤的結果。
 
    -更正了configureClientCharset()中的重複代碼,該類代碼將阻止useOldUTF8Behavior=true的恰當運行。
 
    -刪除了「dontUnpackBinaryResults」功能,現在,驅動程式將按原樣保存來自伺服器端預處理語句的結果(與伺服器提供的相同,並在需要時展開)。
 
    -更正了BUG#8096,使用伺服器端預處理語句時,模擬定位器破壞了二進制數據。
 
    -更正了ServerPreparedStatement.serverPrepare()的同步事宜,如果在多個線程間共享連接,可能會導致死鎖/崩潰。
 
    -預設情況下,驅動程式能通過各種Connection.prepareStatement()的各種變體掃瞄SQL,以判斷它是否是能夠在伺服器端支援的語句類型,如果不被伺服器端支援,會將其作為客戶端模擬預處理語句進行處理(BUG#4718))。也可以通過在JDBC URL中傳遞「emulateUnsupportedPstmts=false」禁止該特性。
 
    -從CallableStatement中刪除了用作輸入/輸出參數的「_binary」引介詞。
 
    -對於註冊為*BINARY的輸出參數,總返回byte[]。
 
    -對於PreparedStatement.setObject(n, "true", Types.BIT),將布爾「True」的正確值發送給伺服器。
 
    -更正了與連接有關的問題,當語句不是伺服器端預處理語句時,無法對來自prepareStatement()的語句進行高速緩衝處理。
 
    -使用ResultSet.get(..., cal)和PreparedStatement.set(...., cal)時,如果客戶端和伺服器均位於GMT(格林威治標準時間)時區,選擇進行時間調整的正確方向。
 
    -增加了「dontTrackOpenResources」選項(預設為「假」以便兼容JDBC),對於具有不良特性的應用程式(例如應關閉語句時,卻未關閉語句的應用程式),它有助於改善內存的使用。
 
    -更正了BUG#8428,ResultSet.getString()不能保持儲存在伺服器上的格式,僅當將「noDatetimeStringSync」屬性設置為「真」(預設為「假」)時,才能允許問題更正。
 
    -更正了使用「usage advisor」而且結果集已關閉時ResultSet.realClose()中的NPE。
 
    -更正了BUG#8487,不建立流式結果集的PreparedStatements。
 
    -不將NULL傳給給ResultSet.getNativeConvertToString()中的String.valueOf(),原因在於String.valueOf()會對其進行字串處理(即返回「null」),對於所述方法,這是錯誤的。
 
    -更正了BUG#8484,當需要捨入操作以設定標度時,ResultSet.getBigDecimal()拋出異常。如果非捨入性BigDecimal.setScale()失敗,驅動程式現在將選擇「半向上」捨入模式。
 
    -增加了「useLocalSessionState」配置屬性,將其設置為「真」時,JDBC驅動程式將認為應用程式行為良好,並會使用java.sql.Connection提供的方法僅設置autocommit和事務隔離級別,因此,能夠在大多數情況下處理這些值,而不引發資料庫伺服器循環。
 
    -為連接池實施實例的語句增加了enableStreamingResults(),可檢查Statement.setFetchSize()是否存在兼容規範的值。使用「Statement.setFetchSize(>=0)」可禁止關於該語句的流式結果。
 
    -增加了對MySQL-5.0.3中BIT類型的支援。驅動程式會將BIT(1-8)當作JDBC的BIT類型對待(映射至java.lang.Boolean),這是因為當聲明了「< 9 bits」)時,伺服器目前不會發送能確定比特字段(bitfield)大小的足夠訊息。BIT(>9)將被當作VARBINARY對待,並當使用getObject()時返回byte[]。
 
12-23-04:版本3.1.6-stable
 
    -更正了SocketInputStream.read()的掛起問題,當驅動程式必須直接截取結果集,而不是跟蹤結果集末尾的「LIMIT n」時,與Statement.setMaxRows()和多個結果集一起使用時SocketInputStream.read()掛起。
 
    -更正了BUG#7026,DBMD.getProcedures()不考慮catalog參數。
 
12-02-04:版本3.1.5-gamma
 
    -更正了字串常數和動態字串之間的比較事宜,或是toUpperCase()d或是toLowerCase()d,以使用Locale.ENGLISH,將其用作英語的覆蓋規則。此外,還使用StringUtils.indexOfIgnoreCase()替代了.toUpperCase().indexOf(),以避免建立很短的過渡性字串實例。
 
    -更正了BUG#5235,伺服器端預處理語句不考慮「zeroDateTimeBehavior」屬性,而且當使用ResultSet.getObject()時會導致類拋棄異常,這是因為總返回全0字串。
 
    -更正了批更新和伺服器預處理語句有關的問題,與以前的集合相比,如果在給定的批參數集合中發生了類型變更,伺服器預處理語句不會檢測這類變化,從而導致伺服器返回錯誤「Wrong arguments to mysql_stmt_execute()」。
 
    -解決了當時間戳的字串資料表示包含後綴「.」但其後沒有數字時的情況。
 
    -更正了BUG#5706,對ResultSet.getNativeString()中以前存在字串實例的低效檢測。
 
    -不拋出針對Connection.releaseSavepoint()的異常。
 
    -解碼來自ServerPreparedStatements的日期時,預設情況下使用按會話進行的日曆實例(通過設置「dynamicCalendars=true」,設置為早期的性能較低的方式)。
 
    -增加了實驗性配置屬性「dontUnpackBinaryResults」,它延遲瞭解包二進制結果集取值的功能,直至請求了它們為止(預設情況下設為「假」)。對於某些usecase/jvm組合,它對無用訊息收集器更友好。
 
    -更正了BUG#5729,對來自伺服器端預處理語句結果集的UNSIGNED BIGINT,未能正確解包。
 
    -更正了BUG#6225,ServerSidePreparedStatement,分配了不必要的具有短生存時間的對象。
 
    -刪除了ResultSet構造函數中有害的新Throwable(),原因在於不良合併(導致任何所建立結果集永遠不會使用的新對像),分析BUG#6359時發現。
 
    -更正了在EscapeProcessor.escapeSQL()中過早建立StringBuffer的問題,而且在不需要轉義功能時仍返回字串(防止不必要的對象分配)。分析BUG#6359時發現。
 
    -為可更新結果集中的鍵比較使用「null-safe-equals」。
 
    -更正了BUG#6537,如果需要0填充,作用在Decimal上的SUM()以及伺服器端預處理語句均將忽略標度(由於伺服器將其轉換為DOUBLE,0填充將結束,將其轉換為BigDecimal類型的字串進行解析時,丟失所有的填充「0」)。
 
    -建立DBMD查詢時使用DatabaseMetaData.getIdentifierQuoteString()。
 
    -如果在伺服器上LOAD DATA LOCAL INFILE小於「max_allowed_packet」,使用1MB的訊息包發送檔案。
 
    -更正了BUG#6399,對於多字節字元編碼,ResultSetMetaData.getColumnDisplaySize()返回錯誤值。
 
    -通過「autoDeserialize」屬性(預設為「假」),能夠對保存在BLOB中的java.lang.Objects的自動串並轉換功能進行配置。
 
    -修改了Field.isOpaqueBinary()以檢測「CHAR(n) CHARACTER SET BINARY」,從而能夠支援用於ResultSet.getObject()的固定長度二進制字段。
 
    -使用我們自己的緩衝輸入流實施方式來處理java.io.BufferedInputStream的封閉行為。使用「useReadAheadInput=false」可禁止它。
 
    -更正了BUG#6348,當給定主機名的某一地址是IPV6時無法連接到伺服器(伺服器尚未與IPV6捆綁) 驅動程式現在能夠搜尋給定主機的所有IP地址,並停在接受socket.connect()的第1個地址上。
 
09-04-04:版本3.1.4-beta
 
    -更正了BUG#4510,Connector/j 3.1.3 beta不能正確處理整數(由為了支援Buffer.readInt() -> Buffer.readShort()中的無符號讀取操作所作的更改而導致)。
 
    -在DatabaseMetaData.getTables()和getTableTypes()中增加了對VIEW的支援,該類特性現已在MySQL伺服器5.0.x版中提供。
 
    -更正了BUG#4642,解包字段元數據時,ServerPreparedStatement.execute*()有時會拋出ArrayIndexOutOfBoundsException。
 
    -最佳化了整數解析功能,通過「useFastIntParsing=false」屬性,允許使用JDK類較慢的解析功能。
 
    -增加了「useOnlyServerErrorMessages」屬性,它會使伺服器生成的異常中的消息文本僅包含由伺服器發送的文本(與SQLState「標準」介紹中給出的相反,此時文本後面還包括伺服器的錯誤消息)。預設情況下,該屬性被設置為「真」。
 
    -更正了BUG#4689,如果前面的Null已被返回,對於原語,ResultSet.wasNull()不工作。
 
    -如果「enablePacketDebug=true」,跟蹤訊息包的序列號,如果收到的訊息包次序混亂,拋出異常。
 
    -更正了BUG#4482,使用預處理語句時,對於字串,ResultSet.getObject()返回錯誤類型。
 
    -兩次使用MysqlPooledConnection.close()(雖然也是應用程式錯誤)會導致NPE。已更正。
 
    -更正了BUG#5012,處理DECIMAL類型的返回值的ServerPreparedStatements不工作。
 
    -更正了BUG#5032,對於來自4.1.x版預處理語句的偽位類型,ResultSet.getObject()不返回布爾類型(在針對偽位類型的getObject()中使用二進制編碼的結果集模糊測試時,它提供了避免額外類型轉換的快捷方式)。
 
    -現在能夠在「LOAD DATA LOCAL INFILE」語句中使用URL,而且驅動程式將使用Java的內置處理程式來檢索數據,並將其發送到伺服器。預設情況下不允許該特性,要想使用它,必須將「allowUrlInLocalInfile」連接屬性設置為「真」。
 
    -對於在ResultSet.get*()的數值上執行的截取操作,驅動程式將更加嚴格,而且當檢測到截取操作時將拋出SQLException。將「jdbcCompliantTruncation」設置為「假」,可以禁止該功能(在預設情況下允許該功能,這是因為該功能是兼容JDBC所需的)。
 
    -從結果集讀取「全零」日期時間值時,增加了三種處理它們的方法,「exception」,(預設值),用代碼為「S1009」的SQLState拋出SQLException;「convertToNull」,返回NULL而不是數據;以及「round」,對日期進行捨入處理,使之成為最接近的值,即「0001-01-01」。
 
    -更正了ServerPreparedStatement,使之能夠「以脫線」方式讀取預處理語句元數據,儘管在目前它是取代在任何時侯均不工作的MysqlIO.clearInputStream()的佔位符,之所以如此,是因為目前尚未從伺服器讀取數據。通過拋出ArrayIndexOutOfBoundExceptions的erverPreparedStatements,它修正了用戶遇到的偶發性錯誤。
 
    -加載資源捆包時使用com.mysql.jdbc.Message的類加載器,應能更正使用器的類加載器不能確定資源捆包位置時出現的偶發性錯誤。
 
07-07-04:版本3.1.3-beta
 
    -對CallableStatements的輸出參數名進行Mangle處理,使得在與用戶變數名一起使用時,這類名稱不會崩潰。
 
    -增加了對CallableStatements中INPUT參數的支援。
 
    -更正了BUG#4119,為伺服器端預處理語句發送的null比特掩碼不正確。
 
    -預設情況下使用SQL的標準SQL狀態,除非將「useSqlStateCodes」屬性設置為「假」。
 
    -增加了訊息包調試代碼(請參見「enablePacketDebug」屬性文檔)。
 
    -為MySQL錯誤編號增加了常量(可公共訪問,請參見com.mysql.jdbc.MysqlErrorNumbers),並增加了生成映射的能力,能夠將廠家代碼映射為驅動程式使用的SQLStates(出於文檔編製目的)。
 
    -使更多消息更為具體(正在努力)。
 
    -更正了BUG#4311,在檢索具有預處理語句和二進制協議特性的mediumint列時發生錯誤。
 
    -當「useTimezone=true」時,在MySQL-4.1.3中支援新的時區變數。
 
    -支援無符號數值作為預處理語句返回的類型。對於「bigint unsigned」類型,這也會導致ResultSet.getObject()中的內容發生變化,「bigint unsigned」類型用於返回BigDecimal實例,現在它將返回java.lang.BigInteger實例。
 
06-09-04:版本3.1.2-alpha
 
    更正了為參數(如char(), varchar())指定大小時儲存程式參數的解析訊息。
 
    -通過「cacheCallableStmts」屬性,允許對可使用語句進行高速緩衝處理。
 
    -更正了下述問題:未為儲存程式指定輸出參數時,發出虛假查詢來檢索輸出參數,從而導致伺服器語法錯誤。
 
    -更正了在CallableStatement.setOutputParameters()中沒有任何參數會導致NullPointerException的問題。
 
    -刪除了MysqlIO.changeUser()中的異常捆包。
 
    -更正了關於發送大型查詢分離訊息包方面的問題,也允許發送大訊息包的nio功能。
 
    -為ServerPreparedStatement增加了.toString()功能,如果您正在調試作為預處理語句(顯示為伺服器應處理的SQL)的查詢,它應有所幫助。
 
    -增加了「gatherPerformanceMetrics」屬性,以及用於控制在何時/何處記錄這類訊息的多種屬性(更多訊息請參見相關文檔)。
 
    -使用.close()時,ServerPreparedStatements實際上不能取消對伺服器端資源的分配。
 
    -增加了「logSlowQueries」屬性,以及「slowQueriesThresholdMillis」屬性,以控制應在何時將查詢視為「緩慢」。
 
    -相對於registerOutParameter()中隱含的順序,正確地將輸出參數映射到prepareCall()中給定的位置,;更正了BUG#3146
 
    -對於版本等於高於4.1.0的伺服器,能正確地檢測字元編碼。
 
    -整理了伺服器屬性的檢測功能。
 
    -對於版本等於高於4.1.2的伺服器,支援用於參數元數據的佔位符。
 
    -更正了BUG#3539,getProcedures()未返回結果集中的任何程序。
 
    -更正了BUG#3540,getProcedureColumns()不能與程式名的通配符一起使用。
 
    -更正了BUG#3520,DBMD.getSQLStateType()返回不正確的值。
 
    -增加了「connectionCollation」屬性,如果給定字元編碼的預設校對不恰當,驅動程式將在連接初始過程中發出「set collation_connection=...」查詢。
 
    -更正了在MySQL-5.0.0上運行時的DatabaseMetaData.getProcedures()問題(在5.0.1和5.0.0間,「show procedure status」的輸出有所不同)。
 
    -更正了BUG#3804,getWarnings()返回SQLWarning而不是DataTruncation。
 
    -對於版本為5.0.0或5.0.1的伺服器,不要啟用伺服器端預處理語句,這是因為,它們與驅動程式使用的「4.1.2+」風格不兼容(驅動程式預計返回的訊息並不存在,因而掛起)。
 
02-14-04:版本3.1.1-alpha
 
    -更正了與不使用客戶端預處理語句的UpdatableResultSets有關的問題。
 
    -當MySQL不提供字元編碼並將JVM設置為多字節編碼時,更正了將字節轉換為ASCII時的字元編碼事宜(通常會影響數值檢索)。
 
    -將伺服器預處理語句的「未知」數據類型解包為字串。
 
    -為伺服器預處理語句實現了長數據類型(Blob、Clob、InputStreams、Readers)。
 
    -為MySQL-4.1和更高版本實現了Statement.getWarnings()(使用「SHOW WARNINGS」)。
 
    -預設結果集類型更改為TYPE_FORWARD_ONLY(兼容JDBC)。
 
    - 結果集類型和並發性的集中設置。
 
    -再次確定了連接屬性的設置方式和顯示為DriverPropertyInfo的方式,以及Connection和DataSource屬性。
 
    -支援NIO。在支援NIO的平台上使用「useNIO=true」。
 
    -支援SAVEPOINTs(MySQL >= 4.0.14或4.1.1)。
 
    -支援「mysql_change_user()...」,請參見「com.mysql.jdbc.Connection」中的changeUser()方法。
 
    -減少了平均查詢中使用的方法數目,使之更有效率。
 
    -自動再連接時重新處理預處理語句。任何遇到的錯誤均被延遲,直至首次嘗試再執行經過重新處理的語句為止。
 
    -按照JDBC規範,確保在預處理語句上執行查詢前給出的警告是明確的(目前,我們支援警告功能)。
 
    -在ConnectionProperties中,支援「舊的」profileSql大寫特性。該屬性已受到冷落,應盡量使用「profileSQL」。
 
    -最佳化了Buffer.readLenByteArray(),以便當長度為0時返回共享的空字節數組。
 
    -在對.execute*()的多次使用之間,允許保留PreparedStatement.setBlob()的內容。
 
    -處理了EscapeProcessor中的0長度令牌(由可使用語句轉義語法導致)。
 
    -在UpdatableResultSet中的刪除/更新/插入行操作上,檢查關閉的連接。
 
    -更正了檢查UpdatableResultSet中的所有主鍵時對資料表別名的支援事宜。
 
    -刪除了useFastDates連接屬性。
 
    -對來自JNDI Refs的數據源屬性進行了正確的初始化,包括明確指定的URL。
 
    -對於版本為5.0.0或更高的MySQL,DatabaseMetaData現在能通報supportsStoredProcedures()。
 
    -更正了Connection.prepareCall()中的堆棧溢出問題(不良合併)。
 
    -對低於1.4版的JDK,更正了對DateTimeValue中Calendar.getTimeInMillis()的IllegalAccessError(非法訪問錯誤)。
 
    -更正了BUG#1673,對於非「%」列名,DatabaseMetaData.getColumns()未返回正確的列順序訊息。
 
    -合併了數據類型映射的更正事項,從MySQL類型「FLOAT」到java.sql.Types.REAL(自3.0版起)的數據類型映射。
 
    -檢測用於RSMD.isCaseSensitive()的列校對。
 
    -更正了與發送大於16M查詢有關的問題。
 
    -為CallableStatement增加了命名和索引式輸入/輸出參數支援。
MySQL-5.0.x或更高版本。
 
    -更正了ServerPreparedStatement.setTimestamp()中的NullPointerException,以及ServerPreparedStatement.setTimestamp()、setDate()中的年月差異。
 
    -為build.xml中的一致性和遞歸/單元測試增加了擁有多個資料庫/JVM目標的能力。
 
    -更正了訪問ServerPreparedStatements和其結果集中某些日期時間功能時的NPE和不良年月轉換問題。
 
    -顯示關閉連接的位置和原因(用於幫助調試)。
 
    -實現了CommunicationsException,它能嘗試判斷與伺服器失去通信的原因,並能在使用.getMessage()時顯示可能的原因。
 
    -更正了BUG#2359,二進制編碼結果集中數值類型的NULL值會導致NullPointerExceptions。
 
    -實現了Connection.prepareCall(),DatabaseMetaData.getProcedures(),以及getProcedureColumns()。
 
    -使用clearParameters()時,通過發送COM_RESET_STMT至伺服器,復位了ServerPreparedStatement中的「long binary」參數。
 
    -自3.0版起,合併了預處理語句高速緩衝和.getMetaData()支援。
 
    -解包來自伺服器端預處理語句的結果時,在某些情況下,對於TimeUtil.fastDate/TimeCreate()的年份,會出現off-by-1900錯誤,更正了該錯誤。
 
    -更正了BUG#2502,getTables()中的字元編碼轉換事宜。
 
    -實現了由語句或儲存程式返回的多個結果集。
 
    -更正了BUG#2606,伺服器端預處理語句未正確返回數據類型「YEAR」。
 
    -允許對來自伺服器端預處理語句的結果集進行流處理。
 
    -更正了BUG#2623,使用滾動結果集和伺服器端預處理語句時出現類捨棄異常。
 
    -自3.0版起,合併了無緩衝輸入代碼。
 
    -更正了不能通過存取器恰當顯示的ConnectionProperties,並整理了ConnectionProperties代碼。
 
    -更正了BUG#2671,在伺服器端預處理語句中,在任何情況下均不能正確編碼NULL字段。
 
    -更正了將數字寫入緩衝以發送預處理語句執行請求時出現的罕見緩衝區下溢問題。
 
    -對於交付的驅動程式,使用了文檔的DocBook版。
 
02-18-03:版本3.1.0-alpha
 
    -增加了「requireSSL」屬性。
 
    -增加了「useServerPrepStmts」屬性(預設為「假」)。當伺服器版本支援並將該屬性設置為「真」時(4.1和更高版本),驅動程式將使用伺服器端預處理語句。目前其預設設置為「假」,除非所有的捆綁/獲取功能均已實施。目前,僅為4.1版的伺服器端預處理語句實現了DML預處理語句。
 
    -跟蹤打開的語句,並在使用Connection.close()時關閉所有打開的語句(JDBC兼容)。
 
06-23-05:版本3.0.17-ga
 
    -更正了BUG#5874,當useTimeZone='true'而且伺服器時區不同於客戶端時區時,Timestamp/Time轉換出現方向錯誤。
 
    -更正了BUG#7081,DatabaseMetaData.getIndexInfo()忽略「唯一」參數。
 
    -支援新的協議類型「MYSQL_TYPE_VARCHAR」。
 
    -增加了「useOldUTF8Behavoior」配置屬性,連接到MySQL-4.1或更高版本且字元編碼為「utf-8」時,該屬性能使JDBC驅動程式的行為方式類似於在MySQL-4.0.x和更早版本下的行為方式。
 
    -更正了BUG#7316,使用getConnection()時,從連接池建立的語句返回實際連接而不是邏輯連接。
 
    -更正了BUG#7033,在靜態SQL字串中,PreparedStatements不能正確編碼Big5(以及其他多字節)字元編碼。
 
    -更正了BUG#6966,啟動了故障切換的連接(由於主連接失敗)從不再次嘗試主連接。
 
    -更正了BUG#7061,PreparedStatement.fixDecimalExponent()增加額外「+」,使得MySQL伺服器無法解析數值。
 
    -更正了BUG#7686,Timestamp關鍵字列數據需要分離的「_binary」,用於UpdatableResultSet.refreshRow()。
 
    -反向移植了來自Connector/J 3.1的SQLState代碼映射,使用連接屬性「useSqlStateCodes=true」可啟用它,在本版本中預設為「假」,以免破壞傳統應用程式(對於Connector/J 3.1,預設為「真」)。
 
    -更正了BUG#7061,PreparedStatement.fixDecimalExponent()增加額外「+」,使得MySQL伺服器無法解析數值。
 
    -轉義序列{fn convert(..., type)}現在支援由SQL預先設定的ODBC類型。
 
    -更正了configureClientCharset()中的重複代碼,該類代碼將阻止useOldUTF8Behavior=true的恰當運行。
 
    -通過更正行數計數器的環繞式處理程式,能正確處理大於20億行的流式結果集。
 
    -更正了BUG#7607,MS932、SHIFT_JIS和Windows_31J不接受針對sjis的別名。
 
    -更正了BUG#6549(更正#7607的同時),為sjis增加了CP943別名。
 
    -更正了BUG#8064,與預處理語句一起使用多字節字元編碼時,要求對二進制數據進行十六進制轉義處理。
 
    -更正了BUG#8812,DBMD.getIndexInfo()的NON_UNIQUE列返回倒置值。
 
    -解決了伺服器BUG#9098,無法將DATE/TIME/TIMESTAMP/TIMESTAMP列CURRENT_*的預設值與「字串」值區別開,因此,插入預設值時,UpdatableResultSet.moveToInsertRow()會生成不良的SQL。
 
    -更正了BUG#8629,將「EUCKR」作為「SET NAMES euc_kr」發送,MySQL-4.1以及更高版本不能理解該特性。
 
    -根據伺服器的版本,DatabaseMetaData.supportsSelectForUpdate()返回正確值。
 
    -對於含別名Windows-31J、CP934、MS932的雙字節字元編碼,對於PreparedStatement.setBytes(),採用十六進制轉義特性。
 
    -增加了對「EUC_JP_Solaris」字元編碼的支援,映射到「eucjpms」的MySQL編碼(從3.1版開始的反向移植)。它只能在支援eucjpms的伺服器山工作,也就是說5.0.3或更高版本。
 
11-15-04:版本3.0.16-ga
 
    -連接至MySQL-4.1或更高版本且再次使用連接池和/或Connection.changeUser()時,將再次發出字元編碼配置命令。
 
    -更正了ResultSetMetaData.isReadOnly(),以便在連接至MySQL-4.1或更高版本時,能根據「原始的」資料表名和列名,檢測不可寫的列。
 
    -更正了BUG#5664,當ResultSet.updateByte()位於插入行上時拋出ArrayOutOfBoundsException。
 
    -更正了DatabaseMetaData.getTypes(),對於NUMERIC類型,它返回不正確的(非負)標度。
 
    -更正了BUG#6198,Buffer.readString(string)中的「off-by-one」問題。
 
    -通過「tinyInt1isBit」屬性,使得能夠對TINYINT(1) -> BIT/Boolean轉換進行配置(為了與JDBC兼容,預設為「真」)。
 
    -如果伺服器版本大於等於4.1.1,在連接建立過程中僅設置「character_set_results」。
 
    -更正了回歸問題,其中,useUnbufferedInput預設為「假」。
 
    -更正了BUG#6231,ResultSet.getTimestamp()作用在具有TIME的列上時失敗。
 
09-04-04:版本3.0.15-production
 
    -更正了BUG#4010,對於GBK,StringUtils.escapeEasternUnicodeByteStream仍被破壞。
 
    -更正了BUG#4334,對於autoReconnect的故障切換,對任何主機均不使用端口「#」,而且不重試所有主機。(警告:需要更改SocketFactory connect()方法的特徵,它目前是公共套接字連接(String host,int portNumber,Properties props)。也能次,必須更改任何第三方套接字實施方式以支援該特徵。
 
    -當它們已被關閉並被返回到連接池時,由MysqlConnectionPoolDataSource建立的邏輯連接將發出rollback()。如果您的應用伺服器/連接池已幫助您完成了該任務,可以將「rollbackOnPooledClose」屬性設置為「假」以避免額外的rollback()開銷。
 
    -刪除了結果集中對checkRowPos()的多餘使用。
 
    -更正了BUG#4742,在DBMD.getTypeInfo()中,「DOUBLE」映射了兩次。
 
    -增加了FLOSS授權豁免。
 
    -更正了BUG#4808,在PooledConnection上使用兩次.close()將導致NPE。
 
    -更正了BUG#4138BUG#4860,對於無符號列,DBMD.getColumns()返回錯誤的JDBC類型。這也會影響對RSMD.getColumnType()和RSMD.getColumnTypeNames()方法中所有數值類型的類型映射,以確保DBMD.getColumns()的類似類型與RSMD.getColumnType()和RSMD.getColumnTypeNames()返回的類型匹配。
 
    -分發版命名方案中的「Production」-「GA」。
 
    -更正了BUG#4880,對於非數值類型,RSMD.getPrecision()返回0(對於非二進制類型,應返回字元的最大長度,對於二進制類型,應返回最大字節長度)。根據伺服器發回的長度(在網絡協議層,伺服器不區分TINYBLOB、BLOB、MEDIUMBLOB或LONGBLOB),它還更正了針對BLOB類型的RSMD.getColumnType()和RSMD.getColumnTypeName()映射。
 
    -更正了BUG#5022,結果集應在「.close()」中釋放Field[]實例。
 
    -更正了BUG#5069,如果結果集已關閉,ResultSet.getMetaData()不應返回未正確初始化的元數據,而是應拋出SQLException。此外,在對實例級別的字段(.close()過程中取消的字段)進行操作之前,通過使用checkClosed(),它還更正了getRow()、getWarnings()和遍歷方法。
 
    -從4.1.x版伺服器開始,能解析新的時區變數。
 
    -與MySQL-4.1.x或更高版本連接時,為PreparedStatement.setBytes()和set*Stream()使用「_binary」引介詞,以防止在字元編碼轉換過程中出現錯誤判斷。
 
05-28-04:版本3.0.14-production
 
    -更正了URL解析錯誤。
 
05-27-04:版本3.0.13-production
 
    -更正了BUG#3848,無伺服器名稱時,不能使用MySQLDatasource。
 
    -更正了BUG#3920,使用MysqlConnectionPoolDataSource時出現「No Database Selected」(未選擇資料庫)。
 
    -更正了BUG#3873,對於批插入,PreparedStatement.getGeneratedKeys()方法僅返回1個結果。
 
05-18-04:版本3.0.12-production
 
    -為TYPE_NAME列中的DatabaseMetaData.getColumns()輸出增加了無符號屬性。
 
    -增加了「failOverReadOnly」屬性,允許最終用戶配置出現故障切換時的連接狀態(只讀/可寫)。
 
    -自3.1開始,反向移植了「change user」和「reset server state」功能,允許MysqlConnectionPoolDataSource的客戶端復位連接池上getConnection()的伺服器狀態。
 
    -使用MySQL-4.1或更高版本時,不對SJIS/GBK/BIG5進行轉義處理。
 
    -允許MysqlDataSource和MysqlConnectionPool數據源使用「url」參數,以便能夠從內部應用伺服器傳遞其他屬性。
 
    -將複製鍵和外部鍵錯誤映射到「23000」的SQLState。
 
    -自3.1開始,反向移植了文檔編製工具。
 
    -返回用於結果集的建立語句,該結果集由getGeneratedKeys()建立(BUG#2957)。
 
    -允許作為參數將java.util.Date發送到PreparedStatement.setObject(),將其轉換為Timestamp類型以保持完整精度(BUG#3103)。
 
    -使用setBytes()和/或setBinary/CharacterStream()時,不截取BLOB/CLOB(BUG#2670)。
 
    -連接時,在使用「SHOW COLLATION」的MySQL-4.1.0和更高版本上,為字段級字元編碼動態配置字元編碼映射。
 
    -將「binary」字元編碼映射到「US-ASCII」,以支援4.1.2和更高版本伺服器的DATETIME字元編碼識別功能。
 
    -在初始化過程中使用「SET character_set_results」,允許將結果集的任何字元編碼返回到驅動程式。
 
    -在>= 4.1.0的MySQL上發出「SET NAMES」之前,在連接至編碼查詢的過程中,使用返回的charsetnr。
 
    -為ResultSetMetaData(getColumnCharacterEncoding()和getColumnCharacterSet())增加了Helper(助手)方法,允許最終用戶查看驅動程式認為應在列上使用的字元編碼。
 
    -在>= 4.1.0的MySQL上僅設置character_set_results。
 
    -更正了BUG#3511,StringUtils.escapeSJISByteStream()不能正確處理所有的東方雙字節字元編碼。
 
    -將StringUtils.escapeSJISByteStream()重新命名為更貼切的escapeEasternUnicodeByteStream()。
 
    -更正了BUG#3554,在URL中未指定資料庫將導致MalformedURL exception。
 
    -如果使用了characterEncoding屬性,自動將MySQL編碼名稱轉換為Java編碼名稱。
 
    -增加了在某些JVM上能識別的編碼名稱,以更正錯誤地將其逆向映射為MySQL編碼名稱的問題。
 
    -為所有單元測試使用junit.textui.TestRunner(允許在Ant或Eclipse以外的命令行上運行它們)。
 
    -更正了BUG#3557,UpdatableResultSet不能獲取moveToInsertRow()的預設值。
 
    -更正了BUG#3570,不一致的列類型通報。伺服器仍不能正確返回*BLOBs *TEXT的所有類型,因此驅動程式也不能正確返回它們。
 
    -更正了BUG#3520,DBMD.getSQLStateType()返回不正確的值。
 
    -更正了PreparedStatement.setString()和東方字元編碼中的遞歸問題。
 
    - 增加了對StringRegressionTest 4.1-unicode的識別。
 
02-19-04:版本3.0.11-stable
 
    -通過「characterEncoding」屬性將編碼方式強制設為「utf8」或「utf-8」時,觸發「SET NAMES utf8」。以前,只能用Java風格的「utf-8」編碼名稱才能觸發該操作。
 
    -AutoReconnect時間的增長速度快於指數速度(BUG#2447)。
 
    -更正了故障切換總跳至列資料表中最後1個主機的問題(BUG#2578)。
 
    -增加了「useUnbufferedInput」參數,它也是目前的預設參數(因JVM事宜,http://developer.java.sun.com/developer/bugParade/bugs/4401235.html)。
 
    -檢測伺服器上lower_case_table_names的「on/off」,或「1」、「2」、「3」形式。
 
    -為ResultSetMetaData.getColumnClassName()的TINYINT和SMALLINT類型返回「java.lang.Integer」(更正了BUG#2852)。
 
    -為ResultSetMetaData.getColumnClassName()的FLOAT類型返回「java.lang.Double」(更正了BUG#2855)。
 
    -為ResultSetMetaData.getColumnClassName()的BINARY、VARBINARY和LONGVARBINARY類型返回「[B」而不是「java.lang.Object」(兼容JDBC)。
 
    -在由ConnectionPoolDataSource建立的所有實例上發出連接事件。
 
01-13-04:版本3.0.10-stable
 
    -在PreparedStatement解析中,當位於「字串」內時,不對引用的ID進行計數(更正了BUG#1511)。
 
    -關於PacketTooLargeException的「Friendlier」異常消息(BUG#1534)。
 
    -從3.1版開始,反向移植了對checkUpdatability()方法中別名資料表和UpdatableResultSets的補丁。
 
    -更正了使用Statement.setMaxRows()時出現的ArrayIndexOutOfBounds異常(BUG#1695)。
 
    -更正了BUG#1576,處理未正確讀取的大BLOB和分離訊息包。
 
    -更正了Statement.getGeneratedKeys()和REPLACE語句的遞歸問題。
 
    -更正了BUG#1630,如果結果集是不可更新的,對ResultSet.updateFoo()的後續使用將導致NPE。
 
    -確定了4.1.1風格的auth,無密碼。
 
    -更正了BUG#1731,外部鍵列的順序與DatabaseMetaData.getImported/Exported/CrossReference()不一致。
 
    -更正了BUG#1775,DatabaseMetaData.getSystemFunction()返回錯誤函數「VResultsSion」。
 
    -更正了BUG#1592,未正確檢查交叉資料庫可更新結果集的可更新性。
 
    -對於MySQL LONGTEXT類型,DatabaseMetaData.getColumns()應返回Types.LONGVARCHAR。
 
    -作用在TINYINT和SMALLINT列上的ResultSet.getObject()應返回Java類型「Integer」(BUG#1913)。
 
    -增加了「alwaysClearStream」連接屬性,它會使驅動程式在每次查詢前清空輸入流上任何余留的數據。
 
    -增加了更具描述性的錯誤消息「Server Configuration Denies Access to DataSource」(伺服器配置拒絕對數據源的訪問),並能從伺服器上檢索消息。
 
    -如果已發生變化,Autoreconnect代碼在紅心連接時不設置catalog。
 
    -實現了ResultSet.updateClob()。
 
    -對於CHAR/VARCHAR列,ResultSetMetaData.isCaseSensitive()返回錯誤值。
 
    -更正了BUG#1933,不尊重連接屬性「maxRows」。
 
    -更正了BUG#1925,在DBMD.extractForeignKeyFromCreateTable()中,建立語句的次數太多。
 
    -更正了BUG#1914,支援轉義序列{fn convert ... }
 
    -更正了BUG#1958,當參數編號等於參數數目+1時,ArrayIndexOutOfBounds。
 
    -更正了BUG#2006,當SELECT查詢中有多個重複列名時,ResultSet.findColumn()應使用第1個匹配的列名(兼容JDBC)。
 
    -從PreparedStatement.setTimestamp()中刪除了靜態同步瓶頸。
 
    -從SingleByteCharsetConverter的實例方法中刪除了靜態同步瓶頸。
 
    -允許通過「cachePrepStmts」、「prepStmtCacheSize」和「prepStmtCacheSqlLimit」屬性,對預處理語句的解析步驟進行高速緩衝處理(預設情況下禁止)。
 
    -加快了PreparedStatements的解析操作,只要可能,盡量採用一次性方式。
 
    -更正了在小應用程式中使用時的安全異常問題(小應用程式不能讀取LOAD DATA LOCAL INFILE所需的系統屬性「file.encoding」)。
 
    -為SQLStates使用常數。
 
    -連接至MySQL-4.1.0或更高版本時,將字元編碼「ko18_ru」映射到「ko18r」。
 
    -確保Buffer.writeString()保存在「\0」之外的空間內。
 
    -更正了「connect w/ JDK-1.4.0」上的異常「未知字元編碼danish」。
 
    -更正了SQLError中的映射功能,用「41000」SQLStates通報死鎖狀態。
 
    -「maxRows」屬性會影響內部語句,因此,應檢查為驅動程式建立的所有內部語句,並在不是內部語句的情況下將其設為0。
 
10-07-03:版本3.0.9-stable
 
    -ResultSet和PreparedStatement中更快的日期處理代碼(不再使用用來同步靜態日曆的Date方法)。
 
    -更正了對Buffer.readString()中緩衝區末端的測試。
 
    -更正了ResultSet.previous()行為方式,當位於結果集的第1行上時,將當前位置移到結果集之前(bugs.mysql.com BUG#496)。
 
    -更正了當已使用setMaxRows()而且在查詢中包含LIMIT子句時發出偽查詢的語句和PreparedStatement。
 
    -更正了BUG#661,當主鍵值包含需要轉義的值時refreshRow不工作(以雙倍轉義結束)。
 
    -提取DatabaseMetaData中的外部鍵訊息時,支援InnoDB約束名,BUG#517BUG#664(由Parwinder Sekhon提出)。
 
    -從3.1版開始,反向移植了4.1協議變化(伺服器端SQL狀態,新字段訊息,較大的客戶端能力標誌,與資料庫的連接等)。
 
    -更正了UpdatableResultSet,作用在插入行上時,為getXXX()返回值(BUG#675)。
 
    -使用moveToInsertRow()時,能夠用預設的列值加載UpdatableResultSet中的insertRow(BUG#688)。
 
    -對於指定為NULL的預設值,DatabaseMetaData.getColumns()未返回NULL。
 
    -將預設的語句類型/並發行更改為TYPE_FORWARD_ONLY和CONCUR_READ_ONLY(兼容規範)。
 
    -如果MySQL不支援,不要嘗試或復位再連接上的隔離級別。
 
    -不將SQLExceptions封在RowDataDynamic內。
 
    -如果useTimezone==true,不更改時間戳TZ兩次(BUG#774)。
 
    -更正了大的分離訊息包處理中存在的回歸問題(BUG#848)。
 
    -更好地診斷「流式」結果集異常中的錯誤消息。
 
    -在空結果集上拋出關於ResultSet.getXXX()的異常(在某些情況未被俘獲)。
 
    -不隱藏關於在I/O層中拋出異常的消息。
 
    -關閉連接池時或在具有已打開連接的PooledConnection.getConnection()上,不觸發連接關閉時間(BUG#884)。
 
    -截短+/- INF(最小和最大代資料表值,對於MySQL中的類型),以及NaN(至0,對於setDouble/setFloat()),當伺服器不支援+/- INF或NaN時,就語句發出警告。
 
    -更正了BUG#879,當字元編碼為SJIS或GBK時,以及「\」出現在非轉義輸入中時對「\」的雙轉義處理。
 
    -清空「流式」結果集未使用行的輸入流時,每100行均有當前線程yield(),以免獨佔CPU時間。
 
    -更正了BUG#1099,DatabaseMetaData.getColumns()弄不清字元列中的關鍵字「set」。
 
    -更正了與Statement.setMaxRows()相關的死鎖事宜。
 
    -更正了CLOB.truncate(),BUG#1130
 
    -最佳化了CLOB.setChracterStream(), BUG#1131
 
    -使databaseName、portNumber以及serverName成為MysqlDataSourceFactory的可選參數(BUG#1246)。
 
    -修訂了BUG#1247,導致字元127損壞的ResultSet.get/setString。
 
    -從3.1版開始,反向移植了針對4.11和更高版本的auth.更改。
 
    -增加了com.mysql.jdbc.util.BaseBugReport,以幫助建立問題報告的測試範例。
 
    -通過將「clobberStreamingResults」屬性設置為「真」(預設為「假」),為「clobber」流式結果增加了屬性。這會使「流式」結果集被自動關閉,如果在所有數據尚未從伺服器中讀取完之前,執行了另一查詢,正在從伺服器流出的任何未完成數據均將被捨棄。
 
05-23-03:版本3.0.8-stable
 
    -允許在Driver.getPropertyInfo()中使用偽URL。
 
    -與Statement.getGeneratedKeys()一起使用多值INSERTS時,返回所生成鍵的列資料表。
 
    -與檔案名和「LOAD DATA [LOCAL] INFILE」一起使用JVM字元編碼。
 
    -更正了與Connection.cleanup()有關的無限循環。
 
    -將Ant目標「compile-core」更改為「compile-driver」,並使測試套件編譯成為單獨的目標。
 
    -更正了未獲得關於Statement.executeUpdate()的集合的結果集,在某些情況下,它會影響getGeneratedKeys()和getUpdateCount()。
 
    -字串中的Unicode字元0xFFFF會導致驅動程式拋出ArrayOutOfBoundsException(Bug #378)。
 
    -使用「REPLACE」語句時返回所生成鍵的正確數目。
 
    -更正了在某些情況下檢測伺服器字元編碼的問題。
 
    -更正了使用極大訊息包時的行數據解碼錯誤。
 
    -最佳化了行數據解碼。
 
    -在已關閉預處理語句上執行操作使拋出異常。
 
    -更正了SJIS編碼問題,感謝Naoto Sato。
 
    -最佳化了EscapeProcessor的使用。
 
    -允許對Statement.close()的多次使用。
 
04-08-03:版本3.0.7-stable
 
    -更正了使用錯誤事件類型的MysqlPooledConnection.close()。
 
    -更正了PreparedStatement.setClob()中的StringIndexOutOfBoundsException。
 
    - 4.1版列元數據更正。
 
    -從Driver.connect()和Driver.acceptsUrl()中刪除了同步功能。
 
    -事務過程中的IOExceptions現在會導致關閉連接。
 
    -更正了ResultSetMetaData.getColumnTypeName()中丟失的「YEAR」類型轉換。
 
    -對於DBMD.getPrimaryKeys(),不提取以「pri」作為主鍵起始的索引。
 
    -試圖在強制關閉的連接上執行操作時拋出SQLExceptions(即,通信鏈路失敗時)。
 
    -現在,可以使用Connection.setProfileSql(boolean)來打開或關閉仿型功能。
 
    更正了與資料庫元數據有關的字元編碼事宜(字元編碼不能正確獲取集合)。
 
    -與MySQL-4.1或更高版本連接時,現在能夠為別名資料表/列建立可更新結果集。
 
    -更正了檔案大於「max_allowed_packet」時的「LOAD DATA LOCAL INFILE」問題。
 
    -對於GBK和Big5字元編碼,更正了0x5c ('\')字元的轉義功能。
 
    -更正了基礎字段為DATE類型時的ResultSet.getTimestamp()問題。
 
    -保證了來自alignPacketSize()的訊息包大小不超過MAX_ALLOWED_PACKET(JVM問題)。
 
    -autoReconnecting(自動再連接)時不復位Connection.isReadOnly()。
 
02-18-03:版本3.0.6-stable
 
    -更正了ResultSetMetaData,當catalog未知時返回""。更正了與Sun CachedRowSet有關的NullPointerExceptions。
 
    -更正了DBMD.getTypeInfo()和DBMD.getColumns()為TEXT/BLOB類型中的精度返回不同值的問題。
 
    -通過將「ignoreNonTxTables」設置為「真」,在回退期間(相容性/可用性),允許忽略「non transactional tables」(非事務資料表)告警。
 
    -更正了在初始連接上SQLExceptions耗盡的問題。
 
    -更正了Statement.setMaxRows(),當其不需要時,停止發送「LIMIT」類型的查詢(性能)。
 
    -整理了語句查詢/方法失配測試(即,不允許與.executeQuery()一起使用INSERT)。
 
    -在ResultSet遍歷方法中增加了更多檢查,以獲取何時處於關閉狀態的訊息。
 
    -更正了ResultSetMetaData.isWritable()以返回正確值。
 
    -為DBMD.nullsAreSortedAtStart增加了不同NULL分類行為的「窗口」(4.0.2至4.0.10,真,其他為「否」)。
 
    -實現了Blob.setBytes()。仍需要將所得的Blob傳回到可更新ResultSet(結果集)或PreparedStatement以保持變更,這是因為MySQL不支援「定位器」。
 
    -從Connector/J 3.1反向移植了4.1字元編碼字段。
 
01-22-03:版本3.0.5-gamma
 
    -更正瞭解包字段時對某些查詢Buffer.fastSkipLenString()導致ArrayIndexOutOfBounds異常的問題。
 
    -為Connection.getTypeMap()實現了空的TypeMap,以便某些第三方應用程式能與MySQL一起工作(IBM WebSphere 5.0連接池)。
 
    -為DBMD.getColumns()增加了丟失的LONGTEXT類型。
 
    -當MySQL版本支援時,Connection.getTransactionIsolation()能從資料庫檢索TX_ISOLATION,而不是實例變數。
 
    -引用DatabaseMetaData.getColumns()、getPrimaryKeys()、getIndexInfo()、getBestRowIdentifier()中的資料表名。
 
    -大幅度降低了PreparedStatements中setBinaryStream()所需的內存。
 
    -更正了ResultSet.isBeforeFirst()處理空結果集方面的問題。
 
    -為外部鍵元數據增加了「更新」選項。
 
 
01-06-03:版本3.0.4-gamma
 
    -為Connection.setCatalog增加了對資料庫名的引用ID。
 
    -在PreparedStatement分析程式中增加了對引用ID的支援。
 
    -對於setByte(),在PreparedStatements中,流線式字元轉換和byte[]處理。
 
    -通過與MysqlIO共享出站訊息包,降低了PreparedStatements的內存佔用。
 
    -增加了「strictUpdates」屬性,能夠對可更新結果集的大量「正確性」檢查進行控制。如果希望獲得更快的可更新結果集,並使用主鍵通過作用在資料表上的SELECT建立了結果集,而且在查詢中選擇了所有的主鍵,應將其設置為「假」。
 
    -增加了對4.0.8風格大訊息包的支援。
 
    -更正了PreparedStatement.executeBatch()參數重寫的問題。
 
12-17-02:版本3.0.3-dev
 
    -將SingleByteCharConverter中的charsToByte更改為非靜態類型。
 
    -更改了SingleByteCharConverter,以使用各轉換器的空閒初始化特性。
 
    -更正了Fields.java中的字元編碼處理功能。
 
    -實現了Connection.nativeSQL()。
 
    -更可靠的轉義標誌「-- recognize '--'」註釋,並允許嵌套式轉義序列(請參見testsuite.EscapeProcessingTest)。
 
    -DBMD.getImported/ExportedKeys()現在能處理每個資料表上的多個外部鍵。
 
    -更正了對某些浮點類型ResultSetMetaData.getPrecision()返回錯誤值的問題。
 
    -更正了ResultSetMetaData.getColumnTypeName()對TEXT類型返回BLOB,對BLOB類型返回TEXT的問題。
 
    -對於4.1和更高版本伺服器,更正了Buffer.isLastDataPacket()。
 
    -增加了CLIENT_LONG_FLAG,以便能獲得更多的列標誌(isAutoIncrement()最重要)。
 
    -由於上述原因,實現了ResultSetMetaData.isAutoIncrement()以使用Field.isAutoIncrement()。
 
    -在DatabaseMetaData方法中比較資料表名且在伺服器中允許時,優先考慮「lower_case_table_names」。
 
    -一些MySQL-4.1協議支援(延伸字段訊息)。
 
    -使用非別名資料表/列名和資料庫名,以完全限定UpdatableResultSet中的資料表和列(需要MySQL-4.1或更高版本)。
 
    -允許用戶通過「continueBatchOnError」屬性(預設為「真」)更改Statement/PreparedStatement.executeBatch()的行為。
 
    -在更多連接方法(createStatement、prepareStatement、setTransactionIsolation、setAutoCommit)中檢查關閉的連接。
 
    -更可靠地實現了可更新結果集。檢查資料表的所有主鍵是否已被選擇。
 
    -如果在伺服器的配置允許,「LOAD DATA LOCAL INFILE ...」現在能正常工作。不能使用「allowLoadLocalInfile」屬性關閉它(請參見README)。
 
    -在單字節字元編碼中,對於未知的字元轉換,用「?」替代「\0」。
 
    - NamedPipeSocketFactory現能正常工作(僅對Windows平台)。具體說明請參見README。
 
11-08-02:版本3.0.2-dev
 
    -更正了可更新結果集和PreparedStatements不工作的問題。
 
    -更正了ResultSet.setFetchDirection(FETCH_UNKNOWN)。
 
    -更正了使用任意值並使用Statement.setFetchSize()時的問題。
 
    -更正了ResultSet.getLong()中的不正確轉換。
 
    -實現了ResultSet.updateBlob()。
 
    -刪除了UpdatableResultSet中的重複代碼(能從ResultSet繼承而來,不需要各方法處理可更新性的額外代碼,但我認為在將來可能需要)。
 
    -更正了通過屬性「強制」字元編碼時拋出的「UnsupportedEncodingException」。
 
    -更正了各種非ASCII字元編碼問題。
 
    -增加了驅動程式屬性「useHostsInPrivileges」。預設值為「真」。它將影響是否在「DBMD.getColumn/TablePrivileges」中使用「@hostname」。
 
    -描述方案的所有DBMD結果集列現返回NULL,以便能與用於其他資料庫的其他JDBC驅動程式的行為更兼容(MySQL不支援方案)。
 
    -增加了SSL支援。關於如何使用它的更多訊息,請參見README。
 
    -執行自動再連接或故障切換時,恰當恢復連接屬性,包括autoCommit狀態以及隔離級別。
 
    -可能時,使用「SHOW CREATE TABLE」,以確定用於DatabaseMetaData的外部鍵訊息,對於返回的DELETE訊息還允許級聯選項。
 
    -對於SJIS字元編碼,轉義了字串中的「0x5c」字元。
 
    -更正了Clob.getSubString()中起始位置偏離1的錯誤。
 
    -實現了Clob.truncate()。
 
    -實現了Clob.setString()。
 
    -實現了Clob.setAsciiStream()。
 
    -實現了Clob.setCharacterStream()。
 
    -增加了com.mysql.jdbc.MiniAdmin類,該類允許您將「shutdown」命令發送至MySQL伺服器。在最終用戶應用中嵌入Java和MySQL伺服器時使用。
 
    -增加了「connectTimeout」參數,允許JDK-1.4和更高版本的用戶指定建立連接所需等候的最長時間。
 
    -僅當連接處於autoCommit(false)狀態時,故障切換和autoReconnect才能工作,目的在於保持事務的安全。
 
    -增加了「queriesBeforeRetryMaster」屬性,出現故障切換時而且在重新連接到主伺服器之前,該屬性指定了能夠發出的查詢數目(預設為50)。
 
    -更正了DBMD.supportsResultSetConcurrency(),以便為ResultSet.TYPE_SCROLL_INSENSITIVE和ResultSet.CONCUR_READ_ONLY或ResultSet.CONCUR_UPDATABLE返回「真」。
 
    -更正了ResultSet.isLast()處理空結果集方面的問題(應返回「假」)。
 
    - PreparedStatement現在將優先考慮setBinary/Ascii/Character Stream()中的流長度,除非將連接屬性「useStreamLengthsInPrepStmts」設置為「假」。
 
    -刪除了一些使用EscapeProcessor、Connection和DatabaseMetaData類中的「Strings smarter」建立的不需要的臨時對象。
 
09-21-02:版本3.0.1-dev
 
    -更正了ResultSet.getRow()偏差1的問題。
 
    -更正了RowDataStatic.getAt()偏差1的問題。
 
    -增加了有限Clob功能(ResultSet.getClob()、PreparedStatemtent.setClob()、PreparedStatement.setObject(Clob))。
 
    -為URL增加了socketTimeout參數。
 
    - Connection.isClosed()不再對伺服器執行「Ping」操作。
 
    -當「getAutoCommit() == false」時Connection.close()發出rollback()。
 
    -增加了「妄想」參數,通過刪除其中的「敏感」訊息清理了錯誤消息(即,主機名、端口、帳號等),並在可能的情況下,清理了「敏感」的數據結構。
 
    -更正了ResultSetMetaData.isSigned()在處理TINYINT和BIGINT方面的問題。
 
    - 現在將自動檢測字元編碼。最佳化了單字節字元編碼轉換的代碼。
 
    -實現了ResultSet.getCharacterStream()。
 
    -為DatabaseMetaData.getTableTypes()中的資料表類型增加了「LOCAL TEMPORARY」。
 
    - 整理了大塊代碼,以遵循Java編碼慣例(時機成熟)。
 
 
07-31-02:版本3.0.0-dev
 
    - !!! 授權變化!!! 驅動現在是GPL。如果需要非GPL授權,請與我們聯繫(mark@mysql.com)。
 
    - JDBC-3.0功能包括Statement/PreparedStatement.getGeneratedKeys()和ResultSet.getURL()。
 
    -性能增強,在大多數情況下,驅動程式快了50-100%,而且建立的臨時對像更少。
 
    -重新封裝...新的驅動程式名是「com.mysql.jdbc.Driver」,但舊名稱依然有效(驅動程式現由MySQL-AB提供)。
 
    -更好地在語句和PreparedStatement中檢查已關閉的連接。
 
    -支援流式結果集(按行),請參見README,感謝Doron。
 
    -支援大訊息包(MySQL-4.0協議的新增內容),更多訊息請參見README。
 
    - JDBC兼容,除了儲存程式測試外,提供了所有測試。
 
 
    -更正並分類了DBMetaData中的主鍵名稱(SF問題582086和582086)。
 
    -浮點類型現為java.sql.Types.FLOAT(SF問題579573)。
 
    - ResultSet.getTimestamp()現在能處理DATE類型(SF問題559134)。
 
    - ResultSet.getDate/Time/Timestamp現在能識別由MySQL設置為全零的所有形式的無效值(SF問題586058)。
 
    - Testsuite現在將使用Junit(可從www.junit.org獲得)。
 
    -驅動程式現在僅能與JDK-1.2或更高版本一起工作。
 
    -增加了多主機故障切換支援(請參見README)。
 
    -進行了一般性的原始碼清理。
 
    -讀取訊息包時,通過控制MysqlIO類建立的過渡對象,改善了總的速度。
 
    -改善了字串處理和字段元數據建立的性能(例示),由Alex Twisleton-Wykeham-Fiennes提供。
 
 
05-16-02:版本2.0.14
 
    -更多代碼整理。
 
    - PreparedStatement現在能釋放.close()上的資源(SF問題553268)。
 
    -如果伺服器版本不支援,不使用引用ID。此外,如果伺服器是以「ansi」或「--sql-mode=ANSI_QUOTES」開始,那麼「"」將用作ID引用,否則將使用「`」。
 
    - ResultSet.getDouble()現在能更準確地使用JDK內置的代碼(但較慢)。
 
    - LogicalHandle.isClosed()使用,直至物理連接。
 
    -增加了SQL仿型功能(到STDERR)。在JDBC url中設置「profileSql=true」。更多訊息請參見README。
 
    -更正了relaxAutoCommit參數的類型。
 
04-24-02:版本2.0.13
 
    -更多代碼整理。
 
    -更正了未能正確讀取的unicode字元(SF問題541088)。
 
    -為PrepStmt提供了更快的Blob轉義功能。
 
    -為DataSource(s)增加了set/getPortNumber()(SF問題548167)。
 
    -為MySQLXADataSource增加了setURL()(SF問題546019)。
 
    -更正了PreparedStatement.toString()(SF問題534026)。
 
    -實現了ResultSetMetaData.getColumnClassName()。
 
    - 現在實施了來自JDBC-3.0的Statement.getGeneratedKeys()的初級版本(要想使之工作,需要使用JDK-1.4,我個人認為)。
 
    - DBMetaData.getIndexInfo(),更正了不良的PAGES(SF問題542201)。
 
04-07-02:版本2.0.12
 
    -一般性代碼整理。
 
    -為Connection和MysqlLogicalHandle增加了getIdleFor()方法。
 
    -放鬆了所有類中的功能,應更正520615和520393。
 
    -為DBMD增加了getTable/ColumnPrivileges()(更正484502)。
 
    -為getTypeInfo()增加了新類型,更正了已有類型,感謝Al Davis和Kid Kalanon。
 
    -為PreparedStatement增加了BIT類型支援(51870)。
 
    -更正了ResultSet中的getRow()問題(527165)。
 
    -更正了PreparedStatement中的ResultSet可更新性。
    -更正了PreparedStatement中時區偏差1小時的問題(538286、528785)。
 
    - ResultSet: 更正了可更新性(如果不可更新,將值設為NULL)。
 
    - DataSources,更正了setUrl問題(511614、525565),錯誤的數據源類名(532816、528767)。
 
    -為需要它們的所有DatabaseMetaData方法增加了ID引用(應更正518108)。
 
    -增加了對YEAR類型的支援(533556)。
 
    - ResultSet.insertRow()目前能夠在大多數情況下檢測auto_increment字段,並在新行中使用該值。但是,該檢測不適用於多值鍵,原因在於MySQL協議不返回該類訊息。
 
    -實現了ResultSet.refreshRow()。
 
    -更正了testsuite.Traversal afterLast()問題,感謝Igor Lastric。
 
01-27-02:版本2.0.11
 
    
-更正了DBMD.getImported/ExportedKeys()getCrossReference()中丟失的DELETE_RULE值。
 
    -Statement.java的完全同步。
 
    -多處修改,更正了讀取BLOB時的「Unexpected end of input stream」(輸入流意外結束)錯誤。這應是最後更正。
 
01-24-02:版本2.0.10
 
     -更正了MysqlIO中的虛假「Unexpected end of input stream」(輸入流意外結束)錯誤(問題507456)。
 
     -更正了與Websphere 4一起使用MysqlConnectionPoolDataSource時的「null-pointer-exceptions」(問題505839)。
 
01-13-02:版本2.0.9
 
     - Ant建立失敗,包括jar檔案,已更正(問題487669)。
 
     -更正了MysqlIO.readPacket()中額外的內存分配(問題488663)。
 
     -實現了DatabaseMetaData.getExported/ImportedKeys()和getCrossReference()。
 
     -在更改實例和類共享引用的方法上,實現了完全同步,驅動程式現在是完全線程安全的(如果遇到問題,請告訴我)。
 
     -將DataSource實施移至org.gjt.mm.mysql.jdbc2.optional軟件包,PooledConnectionDataSource和XADataSource的原始實施仍保留在原處(感謝Todd Wolff給出了PooledConnectionDataSource與IBM WebSphere 4一起的實施方案和測試結果)。
 
     -增加了讀取訊息包時對關閉網絡連接的檢測(感謝Todd Lizambri)。
 
     -更正了與轉義處理其有關的錯誤(問題486265)。
 
     -通過DatabaseMetaData,支援批更新(問題495101)。
 
     -更正了PreparedStatement.setTimestamp()中偏差1小時的錯誤(問題491577)。
 
     -從驅動程式中刪除了級連支援(「||」操作符),較早的VisualAge版本似乎是使用它的唯一軟件,它與邏輯「||」操作符衝突。要想使用「||」操作符作為級聯,需要用「--ansi」標誌啟動mysqld(問題491680)。
 
     -更正了PreparedStatement中的捨棄問題(488663)。
 
11-25-01:版本2.0.8
 
     -現在支援批更新(感謝Daniel Rall的鼓勵)。
 
     - XADataSource/ConnectionPoolDataSource代碼(實驗性)。
 
     - PreparedStatement.setAnyNumericType()現在能正確處理正指數(增加了「+」,因此MySQL能理解它)。
 
     - DatabaseMetaData.getPrimaryKeys()和getBestRowIdentifier()目前在識別主鍵方面更加可靠(匹配,不管主鍵在Key_type列中的大小寫、或縮寫/全名)。
 
10-24-01:版本2.0.7
 
     - PreparedStatement.setCharacterStream()現已實現。
 
     -更正了處於高利用率模式(autoReconnect=true)下時的懸掛套接字問題,連接的finalizer將關閉任何在GC上懸掛的套接字。
 
     -更正了在較新版本的MySQL上ResultSetMetaData.getPrecision()返回的值比實際值小1的問題。
 
     -如果列值為NULL,ResultSet.getBlob()現在將返回NULL。
 
     -如果useUnicode=true而且未設置characterEncoding,將從資料庫讀取字元編碼。(感謝Dmitry Vereshchagin)。
 
     -從資料庫讀取初始事務隔離級別(如果可用的話)(感謝Dmitry Vereshchagin)。
 
     -更正了DatabaseMetaData.supportsTransactions(),supportsTransactionIsolationLevel(),getTypeInfo() SQL_DATETIME_SUB,以及不可讀取的SQL_DATA_TYPE字段。
 
     -更正了用於生成SQL並回在某些查詢中以語法錯誤結束的PreparedStatement。
 
     -更正了ResultSet.isAfterLast()總返回「假」的問題。
 
     -更正了PreparedStatement.setTimestamp()中的時區問題(感謝Erik Olofsson)。
 
     -在URL或屬性中傳遞了「captializeTypeNames=true」時,將類型名轉換為大寫(對於WebObjects,感謝Anjo Krank)。
 
     -可更新結果集現在能正確處理字段中的NULL值。
 
     - PreparedStatement.setDouble()現在能使用雙精度值(撤銷了以前所作的截取更正)。
 
     -如果MySQL的版本高於或等於3.21.23,PreparedStatement.setBoolean()將使用1/0值。
 
06-16-01:版本2.0.6
 
     -更正了PreparedStatement參數檢查功能。
 
     -更正了ResultSet.java中區分大小寫的列名。
 
06-13-01:版本2.0.5
 
     - 更正了ResultSet.getBlob() ArrayIndex超出範圍的問題。
 
     -更正了ResultSetMetaData.getColumnTypeName關於TEXT/BLOB的問題。
 
     -更正了發送大BLOB查詢時的ArrayIndexOutOfBounds問題(未設置最大訊息包大小)。
 
     -為Connection.setIsolationLevel()增加了ISOLATION級別支援。
 
     -更正了所有列均未設置時在PreparedStatement.executeUpdate()上的NPE問題。
 
     -更正了採用兩位數字年份的TIMESTAMP的數據解析問題。
 
     -為PreparedStatement.setObject()增加了Byte。
 
     - ResultSet.getBoolean()現在能將「-1」識別為「真」。
 
     - ResultSet具有+/-Inf/inf支援特性。
 
     -即使並非所有列均已被設置(設為NULL),ResultSet.insertRow()現在也能工作。
 
     - DataBaseMetaData.getCrossReference()不再使用ArrayIndexOOB。
 
     -作用在結果集上的getObject()能正確執行TINYINT->Byte和SMALLINT->Short操作。
 
12-03-00:版本2.0.3
 
     -為JDBC2實現了不帶標度組分的getBigDecimal()。
 
     -更正了與可更新結果集有關的復合鍵問題。
 
     -增加了-/+INF對雙精度的檢測。
 
     -更快的ASCII字串操作。
 
     -更正了MAX_ALLOWED_PACKET的不正確檢測,因此,現在能發送大的Blob。
 
     -更正了java.sql.Blob實施代碼中的「偏差1」錯誤。
 
     -增加了「ultraDevHack」URL參數,將其設置為「真」,可允許Macromedia UltraDev使用該驅動程式。
 
04-06-00:版本2.0.1
 
     -更正了RSMD.isWritable()返回錯誤值的問題。感謝Moritz Maass。
 
     -整理了連接確定時的異常處理功能。
 
     -使用getObject(),具有TEXT類型的列現在會作為字串返回。
 
     - DatabaseMetaData.getPrimaryKeys()現在能正確工作(寫入到key_seq)。感謝Brian Slesinsky。
 
     -按照JDBC規範,在PreparedStatements上,不再進行轉義處理。
 
     -更正了很多JDBC-2.0遍歷、定位錯誤,尤其是寫入空結果集的問題。感謝Ron Smits、Nick Brook、Cessar Garcia和Carlos Martinez。
 
     -更正了使用多個主鍵時,與結果集中可更新性支援有關的一些問題。
 
02-21-00:版本2.0pre5
 
     -更正了不良的握手問題。
 
01-10-00:版本2.0pre4
 
     -更正了針對insertRow()的結果集,感謝Cesar Garcia。
 
     -對驅動程式進行了修改,使之能夠通過加載JDBC-2.0類來識別JDBC-2.0,而不是依靠JDK版本號。感謝John Baker。
 
     -更正了結果集,以返回正確的行號。
 
     - Statement.getUpdateCount()現在能返回匹配的行,而不是實際更新的行,它更像SQL-92。
 
10-29-99
 
     -更正了Statement/PreparedStatement.getMoreResults()問題。感謝Noel J. Bergman。
 
     -為PreparedStatement.setObject()增加了Short類型。感謝Jeff Crowder。
 
     -驅動程式現在能通過查詢伺服器自動配置最大/首選的訊息包大小。
 
     -如果伺服器支援,Autoreconnect代碼將使用更快的ping命令。
 
     -更正了從伺服器讀取訊息包、以及為寫入到伺服器而分配訊息包時與訊息包大小有關的多種問題。
 
08-17-99:版本2.0pre
 
     -目前是在JDK-1.2下編譯的。通過核心類集合,驅動程式同時支援JDK-1.1和JDK-1.2。在運行時,通過判斷您所使用的JVM版本,驅動程式將加載恰當的接口類。
 
     -修正了在首行中全為NULL的結果集。(由Tim Endres指出)。
 
     -更正了結果集內SQLExceptions的列編號(感謝Blas Rodriguez Somoza)。
 
     -不再需要將資料庫指定給連接。(感謝Christian Motschke)。
 
07-04-99:版本1.2b
 
     -更好的文檔(不斷改善),doc/mm.doc/book1.html。
 
     -對於列名模式,DBMD現在允許null(未在規範中定義),它將被更改為「%」。
 
     - DBMD現在提供了針對getXXX()的正確類型/長度。
 
     -修改了ResultSet.getDate()、getTime()和getTimestamp()。(由Alan Wilken提供)。
 
     - EscapeProcessor現在能正確處理引號內的「\{ \}」和「{ or }」。(感謝Alik就如何修正它給出的觀點)。
 
     -對連接中的屬性處理功能進行了修正。(由Juho Tikkala提供)。
 
     -對於資料表中的NULL列,ResultSet.getObject()現在能返回NULL,而不是銷毀。(感謝Ben Grosman)。
 
     -對於MySQL不瞭解的類型,ResultSet.getObject()現在能返回字串。(由Chris Perdue建議)。
 
     -刪除了不需要的DataInput/Output流,對於每次IO操作,1/2的方法使用都是不需要的。
 
     -如果未指定字元編碼,使用預設的字元編碼。這是對已損壞JVM的一種避規措施,這是因為,按照規範,所有的JVM都必須支援「ISO8859_1」,但並非如此。
 
     -更正了連接事宜,如果未明確設置字元編碼,將使用平台的字元編碼,而不是「ISO8859_1」。它修正了加載並不總存在的字元轉換器類時存在的問題(JVM問題)。(感謝Fritz Elfert指出了該問題)。
 
     -修改了MysqlIO,使之在可能的情況下再次使用訊息包,而不是降低內存使用率。
 
     -更正了與引號內「{}」有關的轉義處理器問題。
 
04-14-99:版本1.2a
 
     -更正了對非Javasoft JVM的字元編碼支援(感謝很多指出該問題的人員)。
 
     -更正了ResultSet.getBoolean(),使之能夠識別作為布爾標誌的「y」和「n」,以及「1」和「0」。(感謝Tim Pizey)。
 
     -更正了ResultSet.getTimestamp(),以提供更好的性能。(感謝Richard Swift)。
 
     - 更正了getByte()在處理數值類型方面的問題。(感謝Ray Bellis)。
 
     - 更正了DatabaseMetaData.getTypeInfo()在處理DATE類型時存在的問題。(感謝Paul Johnston)。
 
     -更正了用於「fn」使用的EscapeProcessor。(感謝locomotive.org的Piyush Shah)。
 
     -更正了EscapeProcessor,如果沒有轉義代碼,不執行額外操作。(感謝Ryan Gustafson)。
 
     -更正了驅動程式,使之能解析「jdbc:mysql://host:port」形式的URL(感謝Richard Lobb)。
 
03-24-99:版本1.1i
 
     -更正了關於PreparedStatements的Timestamps問題。
 
     -更正了RSMD和RS中的Null指針異常。
 
     -對於有效的類檔案,與jikes一起進行了再編譯(感謝ms!)。
 
03-08-99:版本1.1h
 
     -更正了轉義處理器,以處理不匹配的「{」和「}」(感謝Craig Coles)。
 
     -更正了轉義處理器,以建立移植性更好的(在DATETIME和TIMESTAMP類型間)資料表達式,以便能與BETWEEN子句一起使用。(感謝Craig Longman。
 
     - MysqlIO.quit()現在能關閉套接字連接。在此之前,多次連接失敗後,某些作業系統將耗盡檔案描述符。(感謝Michael Brinkman)。
 
     -更正了Driver.getPropertyInfo中的NullPointerException(感謝Dave Potts)。
 
     -修正了MysqlDefs,允許字字串形式檢索所有的*text字段。(感謝Chris at Leverage)。
 
     -更正了PreparedStatement中的setDouble,使之能用於處理大數字,防止將科學記數法發送到資料庫。(感謝J.S. Ferguson)。
 
     -更正了RSMD中的getScale()和getPrecision()。(由James Klicman貢獻)。
 
     -更正了字段為DECIMAL或NUMERIC時的getObject()(感謝Bert Hobbs)。
 
     -傳遞Null資料表名時,DBMD.getTables()出現嚴重故障。已更正(感謝Richard Lobb)。
 
     -增加了在連接過程中對「client not authorized」(客戶端未被授權)錯誤的檢查。(感謝Hannes Wallnoefer)。
 
02-19-99:版本1.1g
 
     -結果集行現在是字節數組。Blob和Unicode現在能雙向工作。目前實施了useUnicode和編碼選項。
 
     -修正了PreparedStatement,使用setXXXStream(不改變地發送)將二進制集合發送到MySQL伺服器。
 
     -修正了getDriverPropertyInfo()。
 
12-31-98:版本1.1f
 
     -將所有的結果集字段更改為字串,這樣,應能使Unicode工作,但您的JVM必須能夠在字元編碼間進行轉換。它還能使對伺服器的數據讀取更快,原因在於,現在不存在從StringBuffer到String(字串)的轉換。
 
     -更改了PreparedStatement.streamToString(),使之更有效(代碼由Uwe Schaefer提供)。
 
     - URL解析功能更可靠(對於錯誤,拋出SQL異常,而不是NullPointerExceptions)。
 
     - PreparedStatement現在能通過setObject()將String轉換為Time/Date值(代碼由Robert Currey提供)。
 
     -在Buffer.readInt()中,IO程序不再被掛起,該問題是在1.1d中當將結果集更改為全字節數組時引入的。(由Samo Login指出)。
 
11-03-98:版本1.1b
 
     -修正了DatabaseMetaData,允許IBM VA和J-Builder同時工作。請告訴我它的工作機制。(感謝Jac Kersing)。
 
     -修正了ResultSet.getBoolean()在處理NULL字串方面的問題(感謝Barry Lagerweij)。
 
     -開始代碼整理,並進行了格式處理。開始將其分出為並行的JDBC-2.0源樹。
 
     -為MysqlIO和Buffer內的關鍵部分增加了「最終」限定符,允許編譯器採用內聯方法以提高速度。
 
9-29-98
 
     -如果傳遞給PreparedStatement中setXXX()的對象引用是空的,將自動使用setNull()。(感謝Erik Ostrom給出的提議)。
 
     -對於Types.OTHER對像和未知類型對象,PreparedStatement中的setObject()現在會嘗試將對象的串行化資料表示寫入到資料庫。
 
     - Util現在有了1個靜態方法readObject(),結果集和列索引將以上述方式在此例示序列化的對象。
 
9-02-98 – 版本1.1
 
     -消除了MysqlIO.nextRow()中的「醜陋問題」。更正了Buffer.isLastDataPacket(),而不是獲取異常。
 
     - Connection.getCatalog()和Connection.setCatalog()現在能夠工作。
 
     - Statement.setMaxRows()能夠正常工作,也能使用屬性maxRows進行設置。通過屬性或URL參數,Statement.setMaxRows()能覆蓋maxRows設置。
 
     -提供了自動再連接功能。由於在每次查詢前不得不Ping資料庫,在預設情況下,它將被關閉。要想使用該功能,請在連接URL中傳遞「autoReconnect=true」。通過「maxReconnects=n」(預設為3)和「initialTimeout=n」(預設為2秒)參數,您也可以更改再連接嘗試的次數和初始超時值。Timeout是超時的指數補償類型。例如,如果初始超時設置為2秒,maxReconnects為3,那麼再連接嘗試之間的間隔分別是2秒,4秒和16秒。
 
8-24-98:版本1.0
 
     - 更正了Buffer.java中Blob數據的處理功能。
 
     -更正了與尺寸過小的鑒定訊息包有關的問題。
 
     -JDBC驅動程式現在採用LPGL。
 
8-14-98 -
 
     - 更正了 Buffer.readLenString(),使之能正確讀取BLOB數據。
 
     -更正了PreparedStatement.stringToStream,使之能正確讀取BLOB數據。
 
     -更正了PreparedStatement.setDate(),使之不增加1天。(感謝Vincent Partington在上述修正項方面的貢獻)。
 
     -增加了URL參數解析功能(?user=...等等)。
 
 
8-04-98:版本0.9d
 
     - 重大新聞! 新的軟件包名。ICE工程公司的Tim Endres著手為GNU GPL的Java軟件建立新的源樹。他友好地將org.gjt.mm軟件包目錄提供給我,因此,現在驅動程式在org.gjt.mm.mysql軟件包中。目前我是合法用戶。期待Tim項目的更多訊息。
 
     -現在採用了動態確定大小的訊息包,向資料庫發送命令時,能夠減少內存使用。
 
     -對getTypeInfo()的參數等方面進行了小的修正。
 
     - DatabaseMetaData現已完全實現。如果這些驅動程式能與各種IDE一起工作,請告知。我已聽說它們正與Jbuilder一起使用。
 
     -在軟件包中增加了JavaDoc文檔。
 
     -軟件包採用.zip或.tar.gz格式提供。
 
7-28-98:版本0.9
 
     -實現了getTypeInfo()。根據JDBC規範,Connection.rollback()現在能拋出SQLException。
 
     -增加了PreparedStatement,它支援預處理語句的所有JDBC API方法,包括InputStreams。請檢查該點,如有問題,請告知。
 
     -更正了ResultSet中的1個問題,該問題會破壞僅返回1行的某些查詢。
 
     - 更正了DatabaseMetaData.getTables()、DatabaseMetaData.getColumns()和DatabaseMetaData.getCatalogs()中存在的問題。
 
     -增加了語句的功能,允許executeUpdate()保存由AUTO_INCREMENT字段自動生成的ID值。一般而言,執行executeUpdate()後,將搜尋SQLWarnings以瞭解警告訊息,如LAST_INSERTED_ID = 'some number',COMMAND = 'your SQL query'。
 
 如果在資料表中正使用AUTO_INCREMENT字段,並在一條語句上執行了多個executeUpdate(),務必每次都執行clearWarnings()以節省內存。
 
7-06-98:版本0.8
 
     -將MysqlIO和Buffer分離為單獨類。對於這兩個類中的某些字段,一些ClassLoader(類加載器)會給出IllegalAccess(非法訪問)錯誤。現在,mm.mysql能夠在小應用程式和所有類加載器中正常工作。
 
 感謝Joe Ennis jce@mail.boone.com指出該問題,並與我一起進行了修正。
 
7-01-98:版本0.7
 
     -更正了getColumns()中的DatabaseMetadata problems,並更正了字段構造函數內開關語句中存在的問題。
 
 感謝Costin Manolache costin@tdiinc.com指出了它們。
 
5-21-98:版本0.6
 
     -在MysqlIO.java和ResultSet.java中,結合Richard Swift Richard.Swift@kanatek.ca給出的有效變更內容。
 
     -現在,我們的驅動程式比GWE的驅動程式快15%。
 
     - 開始著手處理DatabaseMetaData。
 
 實現了下述方法:
  * getTables()
  * getTableTypes()
  * getColumns
  * getCatalogs()

26.4. MySQL Connector/MXJ

26.4.1. 前言

MySQL Connector/MXJ是一種Java實用工具軟件包,用於部署和管理MySQL資料庫。可以將Connector/MXJ捆綁到已有的Java應用程式,或將其作為JMX Mbean部署。MySQL的部署和使用十分簡單,就像為JDBC連接URL新增額外參數一樣簡單,連接建立後,連接URL將啟動資料庫。這樣,Java開發人員能夠通過降低其最終用戶的安裝難度,更容易地部署需要資料庫的應用程式。

MySQL Connector/MXJ使得MySQL資料庫像是基於java的組件。它通過下述步驟完成該任務,確定系統所運行的平台,選擇恰當的二進制檔案,並執行程式。也能可選地部署具有任何指定參數的個初始資料庫。

作為一種JMX Mbean,MySQL Connector/MXJ需要與JMX v1.2兼容的Mbean容器,如Jboss版本4。Mbean將使用標準的JMX管理API來展示與平台相適應的參數(並允許設置參數)。

其中包含與JDBC驅動程式一起使用的說明,以及以JMX Mbean方式將其部署至Jboss的說明。

可從下述站點下載源版本和二進製版本:http://dev.mysql.com/downloads/connector/mxj/

這是一種測試板,歡迎反饋和鼓勵。

如有任何問題或意見,請發送電子郵件至java@lists.mysql.com

26.4.2. 支援平台:

  • Linux, i386

  • Windows NT, x86

  • Windows 2000, x86

  • Windows XP, x86

  • Solaris 9, SPARC 32

26.4.3. Junit測試要求

要想確保您的平台是在支援範圍內,最好方法是運行Junit測試。

首先應確保組件能夠在平台上工作。由於「MysqldResource」類實際上是MySQL固有版本的包裝器,並非所有的平台均支援它。編寫本文時,對運行在i386架構上的Linux進行了測試,看上去工作良好,就像在OS X v10.3上一樣。在Windows和Solaris平台上進行了有限測試。

要求:

1.    JDK-1.4或更高版本(或JRE,如果不打算編譯源檔案或JSP的話)。

2.    通過CLASSPATH安裝了並提供了MySQL Connector/J版本3.1或更高版本(http://dev.mysql.com/downloads/connector/j/ )。

3.    用於JMX版本1.2.1的javax.management類,它們位於下述應用伺服器上:

·         JBoss - 4.0rc1或更高版本

·         Apache Tomcat - 5.0或更高版本

·         Sun公司的JMX參考實施版本1.2.1,http://java.sun.com/products/JavaManagement/

4.      Junit 3.8.1(http://www.junit.org/

如果從原始碼建立,除了上述所有要求外,還須滿足:

1.      Ant版本1.5或更高版本(可從http://ant.apache.org/上下載)。

26.4.4. 運行Junit測試

1.    這類測試將嘗試在3336端口上啟動MySQL。如果有正在運行的MySQL,可能會出現衝突,但可能性不大,原因在於MySQL的預設端口是3306。然而,也可以將「c-mxj_test_port」Java屬性設置為您所選擇的端口。作為可選方式,您也可以通過關閉運行在目標機器上的MySQL實例來啟動測試。

預設情況下,測試結果將輸出到控制台。要想獲得詳細輸出,可以將「c-mxj_test_silent」Java屬性設置為「假」。

2.    要想運行Junit測試套件,$CLASSPATH必須包含下述部分:

·         JUnit

·         JMX

·         Connector/J

·         MySQL Connector/MXJ

3.    如果您下載的檔案中不含connector-mxj.jar,請解包MySQL Connector/MXJ原始碼檔案檔案。

4.           cd mysqldjmx
5.           ant dist
     

隨後,將$TEMP/cmxj/stage/connector-mxj/connector-mxj.jar新增到CLASSPATH(類路徑)。

6.    如果有junit,執行單元測試。從命令行上輸入:

7.           java junit.textui.TestRunner com.mysql.management.AllTestsSuite
    

輸出與下面給出的類似:

.........................................
.........................................
..........
Time: 259.438
 
OK (101 tests)
  

注意,在快結束時速度會變慢,請耐心等候。

26.4.5. 作為JDBC驅動程式的一部分運行

MySQL Connector/J JDBC驅動程式的1個特點是,能夠在JDBC連接字串中將「SocketFactory」指定為參數。MySQL Connector/MXJ包含1個定制的SocketFactory。首次連接時,SocketFactory將部署並啟動MySQL資料庫。SocketFactory也會顯示1個「shutdown」方法。

要想使用它,請在JDBC連接字串上指定「socketFactory」參數,並將其值設為「com.mysql.management.driverlaunched.ServerLauncherSocketFactory」。

在下面的示範中,有1個能建立連接的程式,執行查詢,並將結果輸出到System.out。MySQL資料庫將作為連接程序的組成部分予以部署並啟動,最後是結束部分。

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

import com.mysql.management.driverlaunched.ServerLauncherSocketFactory;

public class ConnectorMXJTestExample {
    public static void main(String[] args) throws Exception {
        String hostColonPort = "localhost:3336";
        
        String driver = com.mysql.jdbc.Driver.class.getName();
        String url = "jdbc:mysql://" + hostColonPort + "/" + "?"
                + "socketFactory="
                + ServerLauncherSocketFactory.class.getName();
        String userName = "root";
        String password = "";

        Class.forName(driver);
        Connection conn = null;
        try {
            conn = DriverManager.getConnection(url, userName, password);
            Statement stmt = conn.createStatement();
            ResultSet rs = stmt.executeQuery("SELECT VERSION()");
            rs.next();
            String version = rs.getString(1);
            rs.close();
            stmt.close();

            System.out.println("------------------------");
            System.out.println(version);
            System.out.println("------------------------");
        } finally {
            try {
                conn.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            ServerLauncherSocketFactory.shutdown(hostColonPort);
        }
    }
}
  

要想運行上述程式,在CLASSPATH中必須有connector-mxj.jar和Connector/J。然後鍵入:

java ConnectorMXJTestExample
  

當然,對於MySQL資料庫,有很多可設置的選項。通過為每個伺服器選項冠以前綴「server」,可將其作為JDBC連接字串的部分,簡單地指定這些選項。在下述示範中,我們設置了3個驅動程式參數和2個伺服器參數:

        String url = "jdbc:mysql://" + hostColonPort + "/" 
                + "?"
                + "socketFactory="
                + ServerLauncherSocketFactory.class.getName();
                + "&"
                + "cacheServerConfiguration=true"
                + "&"
                + "useLocalSessionState=true"
                + "&"
                + "server.basedir=/opt/myapp/db"
                + "&"
                + "server.datadir=/mnt/bigdisk/myapp/data";
  

26.4.6. 在Java對像中運行

有1個java應用程式並打算嵌入MySQL資料庫,直接使用com.mysql.management.MysqldResource類。可以使用預設的構造函數(無參量)例示該類,或者通過在java.io.File對像(代資料表希望伺服器解包至的目錄)中傳遞類來例示之。也可用針對「stdout」和「stderr」(用於記錄)的輸出流例示它。

一旦完成例示,java.util.Map,該對像將能提供與平台以及希望使用的MySQL版本相適應的伺服器選項的java.util.Map。

MysqldResource允許您使用所提供的伺服器選項的java.util.Map啟動MySQL,並允許您關閉資料庫。在下面的示範中,給出了使用明碼java對像將MySQL嵌入到應用程式的簡單方法。

import com.mysql.management.MysqldResource;

 ...

    public void startMySQL() {
        File baseDir = new File(ourAppDir, "mysql");
        mysqldResource = new MysqldResource(baseDir);
        Map options = new HashMap();
        options.put("port", "3336");
        String threadName = "OurApp MySQL";
        mysqldResource.start(threadName, options);
    }
    
    public void stopMySQL() {
        if (mysqldResource != null) {
            mysqldResource.shutdown();
        }
        mysqldResource = null;
    }
    
    public java.sql.Connection getConnection() throws Exception {
        String db = "test";
        String url = "jdbc:mysql://localhost:3336/" + db;
        String userName = "root";
        String password = "";
        Class.forName(com.mysql.jdbc.Driver.class.getName());
        return DriverManager.getConnection(url, userName, password);
    }
  

26.4.7. MysqldResource API

構造函數:

·         public MysqldResource(File baseDir, PrintStream out, PrintStream err);

允許設置安裝MySQL檔案的「basedir」,並設置標準輸出和標準錯誤的輸出流。

·         public MysqldResource(File baseDir);

允許設置安裝MySQL檔案的「basedir」。標準輸出和標準錯誤的輸出將被導至System.out和System.err。

·         public MysqldResource();

Basedir是java.io.tempdir的預設子目錄。標準輸出和標準錯誤的輸出將被導至System.out和System.err。

MysqldResource API包含下述方法:

·         void start(String threadName, Map mysqldArgs);

部署並啟動MySQL。「threadName」字串用於命名實際執行MySQL命令行命令的線程。「map」是將要傳遞給命令行的參量和參聯值的集合。

·         void shutdown();

關閉由MysqldResource對像管理的MySQL實例。

·         Map getServerOptions();

返回所有選項以及MySQL資料庫可用的當前選項(或預設選項,如果未運行的話)的映射。

·         boolean isRunning();

如果MySQL資料庫正在運行,返回「真」。

·         boolean isReadyForConnections();

一旦資料庫通報它已做好連接準備,返回「真」。

·         void setKillDelay(int millis);

預設的「Kill Delay」是30秒。它資料表示發出初始關閉請求和發出「強制殺死」(如果資料庫未關閉)命令之間需要等待的時間。

·         void addCompletionListenser(Runnable listener);

當伺服器程序完成時,允許通知應用程式。每個「listener」(監聽程式)將在自己的線程中發出。

·         String getVersion();

返回MySQL的版本。

·         void setVersion(int MajorVersion, int minorVersion, int patchLevel);

標準分發版本僅提供了1種版本的MySQL軟件包。但也能將多個版本封裝在一起,並指定要使用的版本。

26.4.8. 在JMX代理(custom)中運行

如果您正在使用JMX的SUN參考實施版本,可跳過本節。或者,如果您正在部署Jboss,請跳到下一節。

我們希望在JMX代理的活動中看到MysqldDynamicMBean。在com.mysql.management.jmx.sunri軟件包中,它是帶有2個Mbeans的JMX代理:

1.      MysqldDynamicMBean,以及

2.    com.sun.jdmk.comm.HtmlAdaptorServer,它提供了用於操控JMX代理內眾多元素的Web接口。

啟動了這個十分簡單的代理程式後,允許用Web瀏覽器啟動並停止MySQL資料庫。

1.    如前所述,完成平台測試。

·         當前JDK, JUnit, Connector/J, MySQL Connector/MXJ

·         本節需要JMX的SUN參考實施版本

·         PATH, JAVA_HOME, ANT_HOME, CLASSPATH

2.      如果不是從原始碼建立的,跳到下一步。

rebuild with the "sunri.present"

ant -Dsunri.present=true dist 
re-run tests:
java junit.textui.TestRunner com.mysql.management.AllTestsSuite

3.    從命令行啟動測試代理:

4.    java com.mysql.management.jmx.sunri.MysqldTestAgentSunHtmlAdaptor &
     

5.    從瀏覽器:

6.           http://localhost:9092/
     

7.      在MysqldAgent下

8.             選擇「name=mysqld」
     

9.      觀察Mbean視圖

10.  滾動到屏幕底部,按startMysqld按鈕

11.  點擊「Back to MBean View」(返回Mbean視圖)

12.  滾動到屏幕底部,按stopMysqld按鈕

13.  殺死運行測試代理的Java程序(jmx伺服器)

26.4.9. 部署在標準的JMX代理環境下 (JBoss)

一旦確定Mbean能夠在平台上工作,接下來應在標準的JMX代理內部署Mbean。其中包含部署到Jboss的說明。

1.    確保有最新版本的java開發工具箱(v1.4.x),請參見前面的介紹。

·         確保設置JAVA_HOME(Jboss要求JAVA_HOME)。

·         確保JAVA_HOME/bin位於PATH中(不需要設置CLASSPATH,也不需要以前測試中使用的任何jar檔案)。

2.      確保安裝了Jboss的最新版本(v4.0RC1或更高)。

3.             http://www.jboss.org/index.html
4.             選擇「Downloads」。
5.             選擇「jboss-4.0.zip」。
6.             選擇1個鏡像。
7.             unzip ~/dload/jboss-4.0.zip
8.             建立JBOSS_HOME環境變數,設置解包目錄。
9.             僅對Unix:
10.       cd $JBOSS_HOME/bin
11.       chmod +x *.sh

12.connector-mxj.jar安裝(拷貝)到$JBOSS_HOME/server/default/lib

13.mysql-connector-java-3.1.4-beta-bin.jar安裝(拷貝)到$JBOSS_HOME/server/default/lib

14.$JBOSS_HOME/server/default/deploy下建立mxjtest.war目錄。

15.  index.jsp安裝(拷貝)到$JBOSS_HOME/server/default/deploy/mxjtest.war。

16.$JBOSS_HOME/server/default/deploy下建立mysqld-service.xml檔案

17.       <?xml version="1.0" encoding="UTF-8"?>
18.        <server>
19.         <mbean code="com.mysql.management.jmx.jboss.JBossMysqldDynamicMBean"
20.            name="mysql:type=service,name=mysqld">
21.         <attribute name="datadir">/tmp/xxx_data_xxx</attribute>
22.         <attribute name="autostart">true</attribute>
23.         </mbean>
24.        </server>
     

25.啟動jboss:

·         在Unix上:$JBOSS_HOME/bin/run.sh

·         在Windows上:%JBOSS_HOME%\bin\run.bat

準備就緒:Jboss在屏幕上顯示大量輸出。

26.  當Jboss看上去停止將訊息輸出到屏幕上時,打開Web瀏覽器:http://localhost:8080/jmx-console

27.滾動到mysql部分頁面底部,選擇bulleted mysqld連結。

28.觀察JMX MBean View頁面。MySQL應已運行。

29.  (如果設置了「autostart=true」可跳過該步)。滾動到屏幕底部。按Invoke按鈕停止(或啟動)MySQL,觀察已成功完成而且無返回值的操作。點擊「Back to MBean View」(返回Mbean視圖)

30.  要想確定MySQL是否正在運行,打開Web瀏覽器http://localhost:8080/mxjtest/,應看到:

SELECT 1

returned with a result of

1

31.按照$JBOSS_HOME/server/default/deploy/mxjtest.war/index.jsp中的介紹,能夠在您的Web應用程式中使用MySQL。其中提供了供測試用的測試資料庫和根用戶(無密碼)。建立資料表,插入一些行,並進行一些選擇。

32.  關閉MySQL。停止Jboss時,MySQL將自動停止,或:在瀏覽器中,滾動到MBean View底部,並按停止服務Invoke按鈕中止服務。觀察已成功完成而且無返回值的操作。使用ps或任務管理器查看MySQL是否已不再運行。

對於1.0.6-beta版,能夠在啟動時讓Mbean啟動MySQL資料庫。此外,我們還借鑒了Jboss生命週期延伸方法的優點,關閉Jboss時能優雅地關閉資料庫。

26.4.10. 安裝

如果閱讀了上述部分,應已完成了這些步驟。但我們在下面列出了它們,以供快速參考。

啟動了驅動程式:

1.      下載並解包Connector/MXJ,將connector-mxj.jar新增到CLASSPATH。

2.    為JDBC連接字串新增下述參數:"socketFactory=" + ServerLauncherSocketFactory.class.getName()

JBoss:

1.    下載Connector/MXJ,將connector-mxj.jar檔案拷貝到目錄$JBOSS_HOME/server/default/lib

2.    下載Connector/J,將connector-mxj.jar檔案拷貝到目錄$JBOSS_HOME/server/default/lib

3.    有任意屬性設置在$JBOSS_HOME/server/default/deploy目錄下建立Mbean服務xml檔案,例如datadirautostart

4.      設置Web應用程式的JDBC參數,以使用:String driver = "com.mysql.jdbc.Driver"; String url = "jdbc:mysql:///test?propertiesTransform="+ "com.mysql.management.jmx.ConnectorMXJPropertiesTransform"; String user = "root"; String password = ""; Class.forName(driver); Connection conn = DriverManager.getConnection(url, user, password);

您或許希望為每個應用程式建立單獨用戶和資料庫資料表空間,而不是使用根用戶和測試資料庫。

強烈建議定期備份,將資料庫檔案備份到datadir目錄下。


這是MySQL參考手冊的翻譯版本,關於MySQL參考手冊,請訪問dev.mysql.com。原始參考手冊為英文版,與英文版參考手冊相比,本翻譯版可能不是最新的。