第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/

如果你的問題未能在本文檔中得到解答,請發送電子郵件至[email protected]

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貢獻二進制代碼,方式是發送郵件至[email protected],這樣其他用戶就能使用你貢獻的內容。

26.1.1.7. MyODBC郵件列表

MySQL AB通過其郵件列表為用戶社區提供幫助。對于與MyODBC有關的事宜,可使用[email protected]郵件列表,從有經驗的用戶處獲得幫助。

關于訂閱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補丁

你可以通過電子郵件,就已有代碼或問題發送補丁或提出更好的解決方案:[email protected]

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

如果出現錯誤,更正后,繼續執行創建進程。如果無法創建,請發送詳細的電子郵件至[email protected],以獲取進一步幫助。

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階段,但并未編譯分發版本,請將其通報給[email protected]

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

13.可以使用“bk sccstool”檢查樹的變更史。如果你發現了有趣的差異,并對代碼存在一問,請立刻發送電子郵件至[email protected]

此外,如果你認為有更好的主意,請發送電子郵件至相同的地址并附上補丁。更改了源碼后,使用“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日志,并根據日志給出的錯誤信息采取進一步的步驟。如果需要進一步幫助,請發送詳細的電子郵件至[email protected]

在下述站點,你可以找到關于如何完成該操作的簡單示例: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跟蹤文件,找出可能出錯的地方。

如果發現某些事項出錯,請發送電子郵件至[email protected](或[email protected],如果有與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一起工作的其他應用程序,請以電子郵件的方式指明它:[email protected]

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 <[email protected]>提供):

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([email protected])寫的一篇好文章,其中解釋了如何在ADO中通過MyODBC插入數據和/或從Blob列獲取數據的方法。MySQL BLOB列和Visual Basic 6

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

下面給出了Mike Hillyer([email protected])的另一篇好文章。如何將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的基本知識,請將詳情發送至[email protected]

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一起工作的任何事項,請發送電子郵件至[email protected]

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, <[email protected]>
*
* (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, <[email protected]>
'
' (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 [email protected])。

·         在parameter.cs中增加了TimeSpan代碼,以便能恰當地將timespan對象處理為mysql時間格式(感謝Gianluca Colombo [email protected])。

·         為參數序列化代碼增加了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,從而使得文本列能返回正確的字段類型(感謝[email protected])。

·         增加了MySqlError類,以提供對錯誤代碼的一些引用(感謝Geert Veenstra)。

26.2.5.13. 版本0.74

·         增加了Unix套接字支持(感謝Mohammad DAMT [[email protected]])。

·         沒有可用數據時,僅調用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類,以便能夠使用設計器編輯參數。

·         更新了連接字符串設計器,支持使用壓縮標志。

·         更正了字符串編碼功能,從而使得歐洲字符(如?)能夠正確工作。

·         創建了基本類,以幫助創建新的數據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: [email protected], CN=Walrus, O=MySQL AB, L=Orenburg, ST=Some
-State, C=RU
Issuer: [email protected], 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  [email protected]
 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中存在敏感的安全缺陷,請發送電子郵件至[email protected]

編寫良好的缺陷報告需要耐心,但在第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許可,請與我們聯系([email protected])。
 
    - 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 [email protected]指出該問題,并與我一起進行了修正。
 
7-01-98:版本0.7
 
     -更正了getColumns()中的DatabaseMetadata problems,并更正了字段構造函數內開關語句中存在的缺陷。
 
 感謝Costin Manolache [email protected]指出了它們。
 
5-21-98:版本0.6
 
     -在MysqlIO.java和ResultSet.java中,結合Richard Swift [email protected]給出的有效變更內容。
 
     -現在,我們的驅動程序比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/

這是一種測試板,歡迎反饋和鼓勵。

如有任何問題或意見,請發送電子郵件至[email protected]

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。原始參考手冊為英文版,與英文版參考手冊相比,本翻譯版可能不是最新的。

广西11选五走势图彩经网