目錄
本參考適用於MyODBC 3.51。對於相應的版本,您可以找到舊的二進製版或原始碼版MyODBC手冊。
這是關於MySQL ODBC驅動程式的參考手冊,而不是通用ODBC參考。關於ODBC的更多訊息,請參閱http://www.microsoft.com/data/。
對於本參考的應用程式開發部分,假定用戶在C語言方面有著良好的實踐知識,對DBMS有一般瞭解,最後,還應熟悉MySQL。關於MySQL功能及其語法的更多訊息,請參閱http://dev.mysql.com/doc/。
如果您的問題未能在本文檔中得到解答,請發送電子郵件至myodbc@lists.mysql.com。
關於ODBC的更多訊息,請參閱http://www.microsoft.com/data/。
關於MyODBC的更多訊息,請訪問http://www.mysql.com/products/myodbc/。
關於授權的更多訊息,請訪問http://www.mysql.com/company/legal/licensing/。
· Windows 95, 98, Me, NT, 2000, XP和2003
· 所有Unix作業系統
o AIX
o Amiga
o BSDI
o DEC
o FreeBSD
o HP-UX 10, 11
o Linux
o Mac OS X Server
o Mac OS X
o NetBSD
o OpenBSD
o OS/2
o SGI Irix
o Solaris
o SunOS
o SCO OpenServer
o SCO UnixWare
o Tru64 Unix
對於特定平台,如果無法下載二進製版本,可通過下載驅動程式原始碼自行建立驅動程式。您也可以為MySQL貢獻二進制代碼,方式是發送郵件至myodbc@lists.mysql.com,這樣其他用戶就能使用您貢獻的內容。
關於訂閱MySQL郵件列資料表或瀏覽列資料表檔案的更多訊息,請訪問http://lists.mysql.com/。
其中,關注程度最高的是論壇MySQL連接器部分的ODBC論壇。
如果遇到與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日誌檔案。
請記住,您提供給我們的訊息越多,我們更正問題的機會就越大。
開放式資料庫連接性(ODBC)是廣泛接受的用於資料庫訪問的應用程式編程接口(API)。它基於針對資料庫API的CLI(使用層接口)規範(來自X/Open和ISO/IEC),並採用了結構化查詢語言(SQL)作為其資料庫訪問語言。
在26.1.16節,「MyODBC API引用」中,概要介紹了MyODBC支援的ODBC功能。關於ODBC的更多訊息,請參閱http://www.microsoft.com/data/。
· 應用程式:
應用程式指的是通過使用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 開放原始碼軟件
· 解析數據源名(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。
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屏幕上還顯示了其他選項,如果遇到問題,可嘗試這些選項(如跟蹤、連接時不提示等)。
在Windows平台上,安裝較舊的MyODBC 2.50驅動時,可能會遇到下述錯誤:
拷貝C:\WINDOWS\SYSTEM\MFC30.DLL時出現錯誤。
重啟Windows,並再次安裝(在運行任何使用ODBC的應用程式之前)。
問題在於其他程式正使用ODBC。由於Windows的設計方式,在這種情況下,您可能無法使用Microsoft的ODBC設置程式安裝新的ODBC驅動。在大多數情況下,可以通過連續按「忽略」鍵拷貝剩餘的MyODBC檔案,最終安裝應仍能工作。如不然,解決方案是在「安全模式」下重新啟動計算機。在重啟的過程中,在機器啟動Windows前按F8,選擇「安全模式」,安裝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
要想從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檔案。
· 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/。
要想建立驅動程式,請採取下述步驟:
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_PATH和MYSQL_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*。
· 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,它們應位於恰當位置。
一旦完成了所有所需檔案的安裝,將原始碼檔案解包到單獨目錄下,並按照下面給出的說明進行操作。
shell> ./configure --help
下面介紹了一些常用的「configure」選項。
1. 要想編譯MyODBC,須使用「--with-mysql-path=DIR」選項來提供MySQL客戶端庫檔案和包含檔案路徑,其中,「DIR」是MySQL的安裝目錄。
可通過運行「DIR/bin/mysql_config」來確定MySQL編譯選項。
2. 為ODBC驅動管理器(iodbc或unixobc)提供標準的頭檔案和庫檔案路徑。
· 如果您正在使用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/include和DIR/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
--enable-thread-safe
也可以使用下述選項禁止它:
--disable-thread-safe
使用該選項,能夠通過mysql線程安全客戶端庫libmysqlclient_r.so(延伸名與作業系統有關)的連結,建立驅動程式線程安全庫libmyodbc3_r.so。
在配置線程安全選項時,如果出現了配置錯誤,應檢查config.log,檢查錯誤是否是因系統中缺少線程庫而導致的,如果是,使用LIBS選項提供一個,即
LIBS="-lpthread" ./configure ..
可以使用下述選項啟用或禁止共享和靜態選項:
--enable-shared[=yes/no] --disable-shared --enable-static[=yes/no] --disable-static
shell> make
如果出現錯誤,更正後,繼續執行建立程序。如果無法建立,請發送詳細的電子郵件至myodbc@lists.mysql.com,以獲取進一步幫助。
在大多數平台上,預設情況下,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
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在所有平台上均能良好工作。
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版本中,cc和gcc實際上均是gcc3的符號連結。
將該庫拷貝到$prefix/lib目錄下,並將symlink拷貝到libmyodbc3.so。
可以使用下述命令交叉檢驗輸出的共享庫屬性:
shell> otool -LD .libs/libmyodbc3-3.51.01.so
如果使用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」。
要想在AIX環境下建立驅動程式,可使用下述configure示範:
shell> ./configure --prefix=/usr/local
--with-unixodbc=/usr/local
--with-mysql-path=/usr/local/mysql
--disable-shared
--enable-thread-safe
註釋: 關於在不同平台上建立和設置靜態和共享庫方式的更多訊息,請參見跨平台使用靜態和共享庫。註釋: 如果您對協助我們測試新的代碼感興趣,應閱讀本節的內容。
要想獲得我方的最新開發原始碼樹,請:
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.4,libtool 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-Makefile和WIN-Makefile_debug,更多訊息,請參見26.1.6節,「在Windows平台上從原始碼版本安裝MyODBC」。
10.完成建立後,運行make install,將MyODBC 3.51驅動程式安裝到您的系統上。
11.如果進入了make階段,但並未編譯分發版本,請將其通報給myodbc@lists.mysql.com。
12.啟動了bk clone操作獲得原始碼樹後,應定期運行bk pull進行更新。
13.可以使用「bk sccstool」檢查樹的變更史。如果您發現了有趣的差異,並對代碼存在一問,請立刻發送電子郵件至myodbc@lists.mysql.com。
此外,如果您認為有更好的主意,請發送電子郵件至相同的地址並附上補丁。更改了原始碼後,使用「bk diffs」可生成補丁。如果您沒有時間就您的觀點編寫代碼,可發送描述性訊息。
14.BitKeeper具有一個可通過bk helptool訪問的幫助工具。
通過瀏覽http://mysql.bkbits.net:8080/myodbc3,也能線上瀏覽變化集、註釋和源代碼。
事實上,數據源就是數據的路徑。在不同的情況下,它可能有著不同的內容,但是在典型情況下,它指明了正在運行的MySQL伺服器(例如,通過網絡地址或伺服器名),連接時該伺服器的預設資料庫,以及必要的連接訊息(如端口)。MySQL驅動程式(以及Windows系統上的ODBC驅動管理器)將使用數據源進行連接。對於該目的,名為Microsoft ODBC數據源管理器的管理工具可能十分有用。
有兩處可能保存初始化訊息的位置: Windows註冊資料表(Windows系統),或DSN檔案(任何系統)。
如果訊息位於Windows註冊資料表中,它稱為「機器數據源」。它可以是「用戶數據源」,在這種情況下,只有一位用戶能看到它。它也可以是「系統數據源」,在這種情況下,計算機上的所有用戶均能訪問它,如果用戶是通過Microsoft Windows NT服務連接在一起的話,與該計算機相連的所有用戶均能訪問它。運行ODBC數據管理程式時,可以選擇是否使用「用戶」或「系統」,它們位於不同的選項卡上。
如果訊息位於DSN檔案中,它稱為「檔案數據源」。這是一種文本檔案。其優點在於: (a)它適合於任何類型的計算機,而不僅僅是使用Windows作業系統的計算機;(b)其內容的拷貝或傳輸相對容易。
要想在Windows平台上新增和配置新的MyODBC數據源,請使用ODBC數據源管理器。ODBC管理器能夠更新數據源連接訊息。新增了數據源時,ODBC管理器能夠更新註冊訊息。
要想從控制面板打開ODBC管理器:
1. 點擊「開始」,將指針指向「設置」,然後點擊「控制面板」。
2. 在運行Microsoft Windows 2000或更新版本的計算機上,雙擊「管理工具」,然後雙擊「數據源」(ODBC)。在運行舊版本Windows的計算機上,雙擊32位ODBC或ODBC。
打開ODBC數據源管理器對話框,如下圖所示:
點擊「幫助」以瞭解ODBC數據源管理器對話框各選項卡的詳細訊息。
要想在Windows平台上新增數據源:
1. 打開ODBC數據源管理器。
2. 在ODBC數據源管理器對話框中,點擊「新增」。打開「建立新數據源」對話框。
3. 選擇MySQL ODBC 3.51驅動程式,然後點擊「完成」。打開「MySQL ODBC 3.51驅動程式-DSN配置」對話框,如下圖所示:
4. 在「數據源名」框中,輸入打算訪問的數據源的名稱。它可以是您選擇的任何有效名稱。
5. 在「描述」框中,輸入DSn所需的描述訊息。
6. 在「主機」或「伺服器名」(或IP)框中,輸入準備訪問的MySQL伺服器主機的名稱。預設情況下為localhost(本地主機)。
7. 在「資料庫名」框中,輸入準備用作預設資料庫的MySQL資料庫名稱。
8. 在「用戶」框中,輸入您的MySQL帳號(資料庫用戶ID)。
9. 在「密碼」框中輸入密碼。
10.在「端口」框中,如果端口不是預設端口,輸入端口號。
11.在「SQL命令」框中,可輸入建立連接後自動執行的SQL語句。
最後,對話框與下圖顯示的類似:
點擊「OK」新增該數據源。
註釋: 點擊「OK」後,將打開「數據源」對話框,ODBC管理器將更新註冊訊息。連接到該數據源時,您所輸入的帳號和連接字串將成為該數據源的預設連接值。
您也可以使用「測試數據源」按鈕,測試您的設置是否適合於連接到伺服器。該特性僅對MyODBC 3.51驅動程式有效。成功完成測試後,將顯示下述窗口:
如果測試失敗,將顯示錯誤消息。
DNS配置對話框也有一個「選項」按鈕。如果選擇了它,將打開下述選項對話框,顯示控制驅動程式的行為。關於這些選項的含義,請參見26.1.9.4節,「連接參數」。
註釋: 在「驅動程式跟蹤」選項下列出的選項已被禁止(灰色),除非您使用的是驅動DLL的調試版本。
要想在Windows平台上更改數據源:
1. 打開ODBC數據源管理器。點擊恰當的選項卡「DSN」。
2. 選擇打算更改的MySQL數據源,然後點擊「配置」。打開「MySQL ODBC 3.51驅動程式-DSN配置」對話框。
3. 更改適用的數據源字段,然後點擊「OK」。
更改完該對話框中的訊息後,ODBC管理器將更新註冊訊息。
在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(數據源名不存在,未指定預設驅動程式)
如果出現該情況,請確認ODBCINI和ODBCSYSINI環境變數指向正確的odbc.ini檔案。例如,如果您的odbc.ini檔案位於目錄「/usr/local/etc」下,可將環境變數設為:
export ODBCINI=/usr/local/etc/odbc.ini
export ODBCSYSINI=/usr/local/etc
您可以在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_qualifier和Table_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 |
是。通過指定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節,「連接參數」。
如果您打算使用myuser和mypassword作為帳號和密碼從系統B連接到系統A,可參考下面給出的簡單步驟。
在系統A上,執行下述步驟:
1. 啟動MySQL伺服器。
2. 使用GRANT建立帳號為myuser的帳號,該帳號可使用密碼myuser從系統B建立連接。
3. GRANT ALL ON *.* to 'myuser'@'B' IDENTIFIED BY 'mypassword';
4. GRANT語句為用戶myuser授予了使用密碼mypassword從系統B進行連接的所有權限。要想執行該語句,必須在系統A上擁有根用戶權限,或是具有恰當權限的另一用戶。關於MySQL權限的更多訊息,請參見5.8節,「MySQL用戶帳號管理」。
在系統B上,執行下述步驟:
1. 使用下述連接參數配置MyODBC DSN:
2. DSN = remote_test
3. SERVER or HOST = A (or IP address of system A)
4. DATABASE = test (The default database or an appropriate one)
5. USER = myuser
6. PASSWORD = mypassword
關於建立DSN-less連接的更多訊息,請參見26.1.9.5節,「沒有預定義DSN下的連接」。
7. 使用Ping命令或其它方式檢查是否能從系統B訪問系統A。如果無法訪問系統A,請檢查網絡或Internet連接,或與您的系統管理員聯繫。
8. 嘗試使用DSN=remote_test進行連接。如果失敗,請跟蹤查詢MyODBC日誌,並根據日誌給出的錯誤訊息採取進一步的步驟。如果需要進一步幫助,請發送詳細的電子郵件至myodbc@lists.mysql.com。
在下述站點,您可以找到關於如何完成該操作的簡單示範:http://www.phphelp.com/tutorial/using-myodbc-to-connect-to-a-remote-database.html.
如果遇到與MyODBC有關的困難或問題,首先應使用ODBC管理器和MyODBC生成一份日誌檔案(請求來自ODBC ADMIN的日誌時獲得的日誌檔案)。
要想通過驅動管理器獲得ODBC跟蹤檔案,可採取下述步驟:
· 打開ODBC數據源管理器:
1. 點擊「開始」,將指針指向「設置」,然後點擊「控制面板」。
2. 在運行Microsoft Windows 2000、XP或2003的計算機上,雙擊「管理工具」,然後雙擊「數據源」(ODBC),如下圖所示。
在運行早期Microsoft Windows版本的計算機上,雙擊「控制面板」中的32位ODBC或ODBC。
3. 打開ODBC數據源管理器對話框,如下圖所示:
4. 點擊「幫助」以瞭解ODBC數據源管理器對話框各選項卡的詳細訊息。
· 啟用跟蹤選項 對於Windows和Unix平台,該步驟不同。
要想在Windows平台上啟用跟蹤選項:
1. 通過「ODBC數據源管理器」對話框的「跟蹤」選項卡,可對跟蹤ODBC函數的方式進行配置。
2. 從「跟蹤」選項卡激活了跟蹤功能後,驅動管理器會對後續運行的所有應用程式的ODBC函數使用進行跟蹤。
3. 激活跟蹤功能前所運行應用程式的ODBC函數使用不會被記錄。ODBC函數使用將被記錄在您指定的日誌檔案中。
4. 點擊「現在停止跟蹤」後,跟蹤功能將停止。請記住,啟動跟蹤功能後,日誌檔案將不斷增大,而且跟蹤功能會影響所有ODBC應用程式的性能。
要想在Unix平台上啟用跟蹤選項:
5. 在Unix平台上,需要在ODBC.INI檔案中明確設置跟蹤選項。
使用TraceFile和odbc.ini中的Trace(跟蹤)參數打開或關閉跟蹤功能,如下所示:
TraceFile = /tmp/odbc.trace
Trace = 1
TraceFile指明了跟蹤檔案的名稱和完整路徑,將Trace(跟蹤)設為ON或OFF。也可以使用「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\system32或C:\winnt\system32目錄下。注意,完成測試後,您或許希望恢復舊的myodbc.dll檔案,這是因為它比myodbc3d.dll(或myodbcd.dll)快很多,因此,請保存原始DLL的備份。
7. 在「MyODBC連接/配置」屏幕上啟用「跟蹤MyODBC」選項。日誌將被寫入檔案C:\myodbc.log。當您返回上述屏幕時,如果您設置的跟蹤選項未被記住,表明您正在使用的是myodbcd.dll驅動(參見前面的介紹)。在Linux平台上,或您使用的是DSN-Less連接,需在連接字串中提供「OPTION=4」。
8. 啟動應用程式,並嘗試著使其出現問題。然後檢查MyODBC跟蹤檔案,找出可能出錯的地方。
如果發現某些事項出錯,請發送電子郵件至myodbc@lists.mysql.com(或support@mysql.com,如果有與MySQL AB簽訂的支援合同),簡要描述出現的問題,並提供下述額外訊息:
o MyODBC版本
o ODBC驅動管理器的類型和版本
o MySQL伺服器的版本
o 驅動管理器的ODBC跟蹤
o 來自MyODBC驅動的MyODBC日誌檔案
o 簡單的可複製示範
請記住,您提供給我們的訊息越多,我們更正問題的機會就越大。
此外,在提供問題訊息前,請檢查MyODBC郵件列資料表(http://lists.mysql.com/)。
使用下述應用程式測試了MyODBC:
MS Access 95, 97, 2000, and 2002
C++-Builder, Borland Builder 4
Centura Team Developer (formerly Gupta SQL/Windows)
ColdFusion (on Solaris and NT with service pack 5), How-to: MySQL and Coldfusion. Troubleshooting Data Sources and Database Connectivity for UnixPlatforms.
Crystal Reports
DataJunction
Delphi
ERwin
MS Excel
iHTML
FileMaker Pro
FoxPro
Notes 4.5/4.6
MS Visio Enterprise 2000
Vision
Visual Objects
Visual Interdev
SBSS
Perl DBD-ODBC
Paradox
Powerbuilder
Powerdesigner 32-bit
MS Visual C++
Visual Basic
ODBC.NET through CSharp(C#), VB and C++
Data Architect(http://thekompany.com/products/dataarchitect/)
SQLExpress for Xbase++(http://www.SQLExpress.net)
Open Office (http://www.openoffice.org) How-to: MySQL + OpenOffice. How-to: OpenOffice + MyODBC + unixODBC.
Star Office (http://wwws.sun.com/software/star/staroffice/6.0/index.html)
G2-ODBC bridge (http://www.gensym.com)
Sambar Server (http://www.sambarserver.info) How-to: MyODBC + SambarServer + MySQL.
如果您知道能夠與MyODBC一起工作的其他應用程式,請以電子郵件的方式指明它:myodbc@lists.mysql.com。
大多數程式均能與MyODBC一起工作,對上面所列的每一程式,我們自己進行了測試,或得到用戶的確認。很多介紹中均給出了您可能會遇到問題的描述。
· 程式
註釋
要想使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 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應用程式
要想使這類應用程式工作,應選擇「不最佳化列寬度並返回匹配行」選項。
開始查詢時,可使用Active屬性或Open方法。注意,Active將通過自動發出「SELECT * FROM ...」查詢開始。如果資料表很大,這不是什麼好事。
下述訊息取自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註冊檔案。
應對其進行更改,使之輸出VARCHAR而不是ENUM,因為其導出ENUM的方式會造成MySQL問題。
工作。一些提示:
o 如果遇到日期方面的問題,請使用CONCAT()函數,將其選擇為字串。例如:
o SELECT CONCAT(rise_time), CONCAT(set_time)
o FROM sunrise_sunset;
採用該方式以字串提取的值應能被Excel97正確識別為時間值。
在本例中,CONCAT()的目的是讓ODBC認為列是「字串類型」。如果沒有CONCAT(),ODBC會將列視為時間類型,Excel無法理解它。
注意,Excel存在1個問題,這是因為它會自動將字串轉換為時間。如果源是文本檔案,不存在問題,但當源是通報各列準確類型的ODBC連接時,將出現問題。
要想將數據從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文檔中將看到插入的行。
ODBC的測試程式。
必須使用BDE 3.2版或更新的版本。連接到MySQL時,選擇「不最佳化列寬度」選項。
此外,這裡給出了一些可能有用的Delphi代碼,這些代碼可設置為MyODBC設置ODBC條目和BDE條目。BDE條目要求用到「BDE別名編輯器」,它位於靠近您的「Delphi Super Page」上,可自由拖動。(下述內容由Bryan Brunton <bryan@flesherfab.com>提供):
fReg:= TRegistry.Create;
fReg.OpenKey('\Software\ODBC\ODBC.INI\DocumentsFab', True);
fReg.WriteString('Database', 'Documents');
fReg.WriteString('Description', ' ');
fReg.WriteString('Driver', 'C:\WINNT\System32\myodbc.dll');
fReg.WriteString('Flag', '1');
fReg.WriteString('Password', '');
fReg.WriteString('Port', ' ');
fReg.WriteString('Server', 'xmark');
fReg.WriteString('User', 'winuser');
fReg.OpenKey('\Software\ODBC\ODBC.INI\ODBC Data Sources', True);
fReg.WriteString('DocumentsFab', 'MySQL');
fReg.CloseKey;
fReg.Free;
Memo1.Lines.Add('DATABASE NAME=');
Memo1.Lines.Add('USER NAME=');
Memo1.Lines.Add('ODBC DSN=DocumentsFab');
Memo1.Lines.Add('OPEN MODE=READ/WRITE');
Memo1.Lines.Add('BATCH COUNT=200');
Memo1.Lines.Add('LANGDRIVER=');
Memo1.Lines.Add('MAX ROWS=-1');
Memo1.Lines.Add('SCHEMA CACHE DIR=');
Memo1.Lines.Add('SCHEMA CACHE SIZE=8');
Memo1.Lines.Add('SCHEMA CACHE TIME=-1');
Memo1.Lines.Add('SQLPASSTHRU MODE=SHARED AUTOCOMMIT');
Memo1.Lines.Add('SQLQRYMODE=');
Memo1.Lines.Add('ENABLE SCHEMA CACHE=FALSE');
Memo1.Lines.Add('ENABLE BCD=FALSE');
Memo1.Lines.Add('ROWSET SIZE=20');
Memo1.Lines.Add('BLOBS TO CACHE=64');
Memo1.Lines.Add('BLOB SIZE=32');
AliasEditor.Add('DocumentsFab','MySQL',Memo1.Lines);
用BDE 3.0版進行了測試。目前已知的唯一問題是,更改資料表方案時,查詢字段不更新。然而,BDE看上去不會識別主鍵,它僅是名為PRIMARY的索引,儘管這談不上是問題。
· Vision
應選擇「返回匹配行」選項。
要想更新資料表,必須為資料表定義主鍵。
帶有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。
要想使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伺服器的前端程式。
除非已安裝了MyODBC,否則不能將資料表或查詢導出到MySQL。
要想將資料表從Access導入MySQL,請遵循下述說明:
1. 打開Access資料庫或Access項目時,出現「資料庫」窗口。其中顯示了用於建立新資料庫對像和打開已有對象的快捷方式。
2. 點擊打算導出的資料表名或查詢名,然後在「檔案」菜單中選擇「導出」。
3. 在「導出對像類型對像名至」對話框中,在「另存為類型」框中,選擇「ODBC資料庫()」,如下圖所示:
4. 在「導出」對話框中,輸入檔案名(或使用建議的檔案名),然後選擇OK。
5. 顯示「選擇數據源」對話框,其中列出了為計算機上已安裝的各ODBC驅動定義的數據源。點擊「檔案數據源」或「機器數據源」選項卡,然後雙擊打算導出至的MyODBC或MyODBC 3.51數據源。關於為MyODBC定義新數據源的方法,請參見26.1.9.2節,「在Windows上配置MyODBC DSN」。
Microsoft Access通過該數據源連接至MySQL伺服器,並導出新的資料表和/或數據。
除非已安裝了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。
是。當連結資料表的結構或位置發生變化時,可採取下述步驟查看或刷新連結。「連結資料表管理器」列出了當前連結的所有資料表的路徑。
要想查看或刷新連結:
1. 打開包含資料表連結的資料庫。
2. 在「工具」菜單上,指向「加載項」(在Access 2000或更新版本中為「資料庫實用工具」),然後點擊「連結資料表管理器」。
3. 選中打算刷新連結的資料表的復選框。
4. 點擊OK,刷新連結。
Microsoft Access將確認成功的刷新操作,或者,如果未找到資料表,將顯示「選擇<table name>新位置」對話框,在該對話框中,可指定資料表的新位置。如果您所選擇的數個資料表已被移至您所指定的新位置,連結資料表管理器將針對所有所選的資料表搜索該位置,並一次性地更新所有連結。
要想更改連結資料表集合的路徑:
1. 打開包含資料表連結的資料庫。
2. 在「工具」菜單上,指向「加載項」(在Access 2000或更新版本中為「資料庫實用工具」),然後點擊「連結資料表管理器」。
3. 選中「對新位置始終提示」復選框。
4. 選中打算更改連結的資料表的復選框,然後點擊OK。
5. 在「選擇<table name>新位置」對話框中,指定新位置,點擊「打開」,然後點擊OK。
如果在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#」,但新增/更新的記錄會恰當顯示。
對於某些程式,可能會出現該錯誤: 另一用戶更改了您所修改的記錄。在大多數情況下,可通過下述措施解決該問題:
· 如果主鍵不存在,為資料表新增1個主鍵。
· 如果時間戳不存在,新增1個時間戳列。
· 僅應使用DOUBLE浮點字段。與單精度浮點值比較時,某些程式會出錯。
如果這些措施未能解決問題,首先應從ODBC管理器生成1個日誌檔案(請求來自ODBC ADMIN的日誌時獲得的日誌檔案),以及1個MyODBC日誌,使用它們找出出錯的原因。具體介紹,請參見26.1.9.7節,「獲取ODBC跟蹤檔案」。
將光標位置指定為adUseServer時,ADO的GetChunk()和AppendChunk()方法不能按預期的方式工作。從另一方面上講,可使用adUseClient克服該問題。
在http://www.dwam.net/iishelp/ado/docs/adomth02_4.htm上給出了一個簡單示範。
下面給出了Mike Hillyer(m.hillyer@telusplanet.net)寫的一篇好文章,其中解釋了如何在ADO中通過MyODBC插入數據和/或從Blob列獲取數據的方法。MySQL BLOB列和Visual Basic 6。
下面給出了ADO、DAO和RDO與VB一起使用的用法示範:
· ADO示範: 26.1.19節,「MyODBC與VB:ADO、DAO和RDO」
· DAO示範: 26.1.19節,「MyODBC與VB:ADO、DAO和RDO」
· RDO示範: 26.1.19節,「MyODBC與VB:ADO、DAO和RDO」
如果您有其他好的例子,或關於ADO/DAO/RDO的基本知識,請將詳情發送至myodbc@lists.mysql.com。
在http://support.microsoft.com/default.aspx?scid=/Support/ActiveServer/faq/data/adofaq.asp中,給出了關於ASP的常見問題清單。
例如,用含有兩列文本的資料表建立1個資料庫:
· 使用mysql客戶端命令行工具插入行。
· 使用ODBC管理器建立1個DSN檔案,例如,針對剛建立資料庫的「my」。
· 打開Word應用程式。
· 建立1個新的空白文檔。
· 在資料庫工具欄上,按「插入資料庫」按鈕。
· 按「獲取數據」按鈕。
· 在「獲取數據」屏幕右側,按「Ms Query」按鈕。
· 在「Ms Query」中使用「my DSN」檔案建立1個新數據源。
· 選擇新查詢。
· 選擇打算使用的列。
· 如果願意,建立1個過濾器。
· 如果願意,建立1個分類。
· 選擇「將數據返回到Microsoft Word」。
· 點擊「完成」。
· 點擊「插入數據」並選擇記錄。
· 點擊OK,在您的Word文檔中將看到插入的行。
一個常見問題是,如何獲取從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;
是。您可以使用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,可獲取針對它的補丁。
MyODBC比其他ODBC驅動程式快很多。緩慢可能是因未使用下述選項造成的:
· 打開「ODBC跟蹤」選項。遵循這裡給出的指示說明,交叉檢查是否未啟用該選項。
如上圖所示,「ODBC數據源管理器」「跟蹤」選項卡的「何時跟蹤」選項應始終指向「現在開始跟蹤」,而不是「現在停止跟蹤」。
· 使用了驅動程式的調試版本。如果您正在使用驅動DLL的調試版本,也會使查詢處理變慢。您可以執行交叉檢查,通過驅動DLL屬性(在系統目錄下,右擊驅動DLL並點擊「屬性」)的「註釋」區,檢查DLL是否是調試版或發佈版,如下圖所示:
· 啟用了「驅動跟蹤和查詢日誌」。即使您打算使用驅動程式的調試版(在生產環境下總應使用發佈版),也應確保禁止了「驅動跟蹤和查詢日誌」選項(OPTION=4,524288),如下圖所示:
· 配置MyODBC DSN。
· 連接到MySQL伺服器。
· 初始化操作。
· 執行SQL語句。
· 檢索結果。
· 執行事務。
· 中斷與伺服器的連接。
大多數應用程式均使用了這些步驟的某些變體。在下圖中,給出了基本的應用步驟:
在本節中,概要介紹了按功能分類的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 |
釋放連接句柄。 |
在下資料表中,介紹了驅動程式將伺服器數據類型映射為預設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 |
在下資料表中,列出了驅動程式返回的除伺服器錯誤之外的錯誤代碼列資料表:
本機代碼 |
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 |
通信連結失敗。 |
在下面的ADO(ActiveX數據對像)示範中,建立了資料表my_ado,並演示了rs.addNew、rs.delete和rs.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 insert(rs插入)
rs.Open "select * from my_ado", conn, adOpenDynamic, adLockOptimistic
rs.AddNew
rs!Name = "Monty"
rs!txt = "Insert row"
rs.Update
rs.Close
'rs update(rs更新)
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 delete(rs刪除)
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
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 Scrolling(rs滾動)
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
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 insert(rs插入)
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 insert(rs插入)
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 update(rs更新)
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
在下面的簡單示範中建立了資料表my_odbc_net,並介紹了它在C#中的使用。
/** * @sample : mycon.cs * @purpose : Demo sample for ODBC.NET using MyODBC * @author : Venu, <venu@mysql.com> * * (C) Copyright MySQL AB, 1995-2004 * **/ /* build command * * csc /t:exe * /out:mycon.exe mycon.cs * /r:Microsoft.Data.Odbc.dll */ using Console = System.Console; using Microsoft.Data.Odbc; namespace myodbc3 { class mycon { static void Main(string[] args) { try { //Connection string for MyODBC 2.50 /*string MyConString = "DRIVER={MySQL};" + "SERVER=localhost;" + "DATABASE=test;" + "UID=venu;" + "PASSWORD=venu;" + "OPTION=3"; */ //Connection string for MyODBC 3.51 string MyConString = "DRIVER={MySQL ODBC 3.51 Driver};" + "SERVER=localhost;" + "DATABASE=test;" + "UID=venu;" + "PASSWORD=venu;" + "OPTION=3"; //Connect to MySQL using MyODBC OdbcConnection MyConnection = new OdbcConnection(MyConString); MyConnection.Open(); Console.WriteLine("\n !!! success, connected successfully !!!\n"); //Display connection information Console.WriteLine("Connection Information:"); Console.WriteLine("\tConnection String:" + MyConnection.ConnectionString); Console.WriteLine("\tConnection Timeout:" + MyConnection.ConnectionTimeout); Console.WriteLine("\tDatabase:" + MyConnection.Database); Console.WriteLine("\tDataSource:" + MyConnection.DataSource); Console.WriteLine("\tDriver:" + MyConnection.Driver); Console.WriteLine("\tServerVersion:" + MyConnection.ServerVersion); //Create a sample table OdbcCommand MyCommand = new OdbcCommand("DROP TABLE IF EXISTS my_odbc_net",MyConnection); MyCommand.ExecuteNonQuery(); MyCommand.CommandText = "CREATE TABLE my_odbc_net(id int, name varchar(20), idb bigint)"; MyCommand.ExecuteNonQuery(); //Insert MyCommand.CommandText = "INSERT INTO my_odbc_net VALUES(10,'venu', 300)"; Console.WriteLine("INSERT, Total rows affected:" + MyCommand.ExecuteNonQuery());; //Insert MyCommand.CommandText = "INSERT INTO my_odbc_net VALUES(20,'mysql',400)"; Console.WriteLine("INSERT, Total rows affected:" + MyCommand.ExecuteNonQuery()); //Insert MyCommand.CommandText = "INSERT INTO my_odbc_net VALUES(20,'mysql',500)"; Console.WriteLine("INSERT, Total rows affected:" + MyCommand.ExecuteNonQuery()); //Update MyCommand.CommandText = "UPDATE my_odbc_net SET id=999 WHERE id=20"; Console.WriteLine("Update, Total rows affected:" + MyCommand.ExecuteNonQuery()); //COUNT(*) MyCommand.CommandText = "SELECT COUNT(*) as TRows FROM my_odbc_net"; Console.WriteLine("Total Rows:" + MyCommand.ExecuteScalar()); //Fetch MyCommand.CommandText = "SELECT * FROM my_odbc_net"; OdbcDataReader MyDataReader; MyDataReader = MyCommand.ExecuteReader(); while (MyDataReader.Read()) { if(string.Compare(MyConnection.Driver,"myodbc3.dll") == 0) { Console.WriteLine("Data:" + MyDataReader.GetInt32(0) + " " + MyDataReader.GetString(1) + " " + MyDataReader.GetInt64(2)); //Supported only by MyODBC 3.51 } else { Console.WriteLine("Data:" + MyDataReader.GetInt32(0) + " " + MyDataReader.GetString(1) + " " + MyDataReader.GetInt32(2)); //BIGINTs not supported by MyODBC } } //Close all resources MyDataReader.Close(); MyConnection.Close(); } catch (OdbcException MyOdbcException)//Catch any ODBC exception .. { for (int i=0; i < MyOdbcException.Errors.Count; i++) { Console.Write("ERROR #" + i + "\n" + "Message: " + MyOdbcException.Errors[i].Message + "\n" + "Native: " + MyOdbcException.Errors[i].NativeError.ToString() + "\n" + "Source: " + MyOdbcException.Errors[i].Source + "\n" + "SQL: " + MyOdbcException.Errors[i].SQLState + "\n"); } } } } }
在下面的簡單示範中建立了資料表my_vb_net,並介紹了它在VB中的用法。
' @sample : myvb.vb ' @purpose : Demo sample for ODBC.NET using MyODBC ' @author : Venu, <venu@mysql.com> ' ' (C) Copyright MySQL AB, 1995-2004 ' ' ' ' build command ' ' vbc /target:exe ' /out:myvb.exe ' /r:Microsoft.Data.Odbc.dll ' /r:System.dll ' /r:System.Data.dll ' Imports Microsoft.Data.Odbc Imports System Module myvb Sub Main() Try 'MyODBC 3.51 connection string Dim MyConString As String = "DRIVER={MySQL ODBC 3.51 Driver};" & _ "SERVER=localhost;" & _ "DATABASE=test;" & _ "UID=venu;" & _ "PASSWORD=venu;" & _ "OPTION=3;" 'Connection Dim MyConnection As New OdbcConnection(MyConString) MyConnection.Open() Console.WriteLine ("Connection State::" & MyConnection.State.ToString) 'Drop Console.WriteLine ("Dropping table") Dim MyCommand As New OdbcCommand() MyCommand.Connection = MyConnection MyCommand.CommandText = "DROP TABLE IF EXISTS my_vb_net" MyCommand.ExecuteNonQuery() 'Create Console.WriteLine ("Creating....") MyCommand.CommandText = "CREATE TABLE my_vb_net(id int, name varchar(30))" MyCommand.ExecuteNonQuery() 'Insert MyCommand.CommandText = "INSERT INTO my_vb_net VALUES(10,'venu')" Console.WriteLine("INSERT, Total rows affected:" & MyCommand.ExecuteNonQuery()) 'Insert MyCommand.CommandText = "INSERT INTO my_vb_net VALUES(20,'mysql')" Console.WriteLine("INSERT, Total rows affected:" & MyCommand.ExecuteNonQuery()) 'Insert MyCommand.CommandText = "INSERT INTO my_vb_net VALUES(20,'mysql')" Console.WriteLine("INSERT, Total rows affected:" & MyCommand.ExecuteNonQuery()) 'Insert MyCommand.CommandText = "INSERT INTO my_vb_net(id) VALUES(30)" Console.WriteLine("INSERT, Total rows affected:" & MyCommand.ExecuteNonQuery()) 'Update MyCommand.CommandText = "UPDATE my_vb_net SET id=999 WHERE id=20" Console.WriteLine("Update, Total rows affected:" & MyCommand.ExecuteNonQuery()) 'COUNT(*) MyCommand.CommandText = "SELECT COUNT(*) as TRows FROM my_vb_net" Console.WriteLine("Total Rows:" & MyCommand.ExecuteScalar()) 'Select Console.WriteLine ("Select * FROM my_vb_net") MyCommand.CommandText = "SELECT * FROM my_vb_net" Dim MyDataReader As OdbcDataReader MyDataReader = MyCommand.ExecuteReader While MyDataReader.Read If MyDataReader("name") Is DBNull.Value Then Console.WriteLine ("id = " & CStr(MyDataReader("id")) & " name = " & _ "NULL") Else Console.WriteLine ("id = " & CStr(MyDataReader("id")) & " name = " & _ CStr(MyDataReader("name"))) End If End While 'Catch ODBC Exception Catch MyOdbcException As OdbcException Dim i As Integer Console.WriteLine (MyOdbcException.ToString) 'Catch program exception Catch MyException As Exception Console.WriteLine (MyException.ToString) End Try End Sub End Module
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檔案。
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版本。
下面介紹了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檔案。
MySqlCommand類代資料表對MySQL資料庫進行執行操作的SQL語句。
註釋:在以前的版本中,採用符號「@」來標識SQL中的參數。它與MySQL用戶變數不兼容,因此,現採用符號「?」來定位SQL中的參數。為了支援早期代碼,也可以在連接字串中設置「old syntax=yes」。如果進行了這類設置,請注意,如果無法定義希望在SQL中使用的參數(定義失敗),不會給出異常提示。
· CommandText:獲取或設置將在數據源上執行的SQL語句。
· CommandTimeout:獲取或設置中止執行命令並生成錯誤之前應等待的時間。
· CommandType:獲取或設置值,該值指明了解釋CommandText的方式。可能的值包括StoredProcedure、TableDirect和Text。
· Connection:獲取或設置該MySqlCommand實例使用的MySqlConnection。
· IsPrepared:如果該命令已準備好,為「真」,否則為「假」。
· Parameters:獲取MySqlParameterCollection。
· Transaction:獲取或設置MySqlTransaction,MySqlCommand將在其中執行。
· UpdatedRowSource:當DbDataAdapter的Update方法使用它時,用於獲取或設置命令結果作用在DataRow上的方式。
· Cancel:嘗試取消MySqlCommand的執行。不支援該操作。
· Clone:建立該MySqlCommand對象的克隆對象。包括CommandText、Connection和Transaction屬性,以及整個參數列資料表。
· CreateParameter:建立MySqlParameter對象的新實例。
· Dispose:處理該MySqlCommand實例。
· ExecuteNonQuery:根據連接情況執行SQL語句,並返回受影響的行數。
· ExecuteReader:將CommandText發送給Connection,並建立MySqlDataReader。
· ExecuteScalar:執行查詢,並返回查詢操作所返回的結果集中第1行的第1列。多餘的列或行將被忽略。
· Prepare:在MySQL伺服器的1個實例上建立命令的預製版本。
在下例中,介紹了在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
在下例中,介紹了在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(); }
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的關聯,已生成的命令將不再使用。
可用屬性如下:
· DataAdapter:MySqlCommandBuilder將自己註冊為針對RowUpdating事件的監聽程式,RowUpdating事件是由在該屬性中指定的MySqlDataAdapter生成的。建立了新的MySqlCommandBuilder實例時,將釋放任何已有的與MySqlDataAdapter關聯的MySqlCommandBuilder。
· QuotePrefix, QuoteSuffix:MySQL中的資料庫對像能夠包含特殊字元,如空格等,這會使得正常的SQL字串無法解析。使用QuotePrefix和QuoteSuffix屬性,MySqlCommandBuilder能夠建立處理該問題的SQL命令。
可用方法如下:
· DeriveParameters:從MySqlCommand指定的儲存程式中檢索參數訊息,並填充所指定MySqlCommand對象的參數集。目前不支援該方法,這是因為MySQL中未提供儲存程式。
· GetDeleteCommand:獲取用於在資料庫上執行刪除操作所需的、自動生成的MySqlCommand對象。
· GetInsertCommand:獲取用於在資料庫上執行插入操作所需的、自動生成的MySqlCommand對象。
· GetUpdateCommand:獲取用於在資料庫上執行更新操作所需的、自動生成的MySqlCommand對象。
· RefreshSchema:刷新用於生成INSERT、UPDATE或DELETE語句的資料庫方案訊息。
在下例中,介紹了在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
在下例中,介紹了在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; }
MySqlConnection對像代資料表與MySQL伺服器數據源的會話。建立MySqlConnection實例時,所有屬性均將被設置為它們的初始值。關於這些值的列資料表,請參見MySqlConnection構造函數。
如果MySqlConnection超出範圍,不會被關閉。因此,必須通過使用Close或Dispose明確地關閉連接。
· ConnectionString:設置或獲取用於連接至MySQL伺服器資料庫的字串。
· ConnectionTimeout:獲取在中止嘗試並生成錯誤之前為建立連接所需的等待時間。
· Database:獲取當前資料庫的名稱或打開連接後將使用的資料庫的名稱。
· DataSource:獲取將要連接的MySQL伺服器的名稱。
· ServerThread:返回該連接所使用的伺服器線程的ID。
· ServerVersion:獲取包含客戶端與之相連的MySQL伺服器版本的字串。
· State:獲取連接的當前連接的狀態。
· UseConnection:與伺服器進行通信時,指明該連接是否將使用壓縮特性。
在下例中,介紹了在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
在下例中,介紹了在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(); }
當MySQLDataAdapter填充DataSet時,如果資料表或列不存在,它將為返回的數據建立必要的資料表和列。但是,在隱式建立的方案中不包括主鍵訊息,除非將MissingSchemaAction屬性設為AddWithKey。在使用FillSchema用數據填充它之前,也能讓MySQLDataAdapter建立DataSet方案,包含主鍵訊息。
MySQLDataAdapter用於MySqlConnection和MySqlCommand的連接,用以提升連接至MySQL資料庫時的性能。
MySQLDataAdapter還包括SelectCommand、InsertCommand、DeleteCommand、UpdateCommand和TableMappings屬性,用於簡化數據的加載和更新操作。
可用屬性如下:
· AcceptChangesDuringFill:獲取或設置值,該值指明了在任何填充操作過程中,在將DataRow新增到DataTable後,是否要在DataRow上使用AcceptChanges。
· ContinueUpdateOnError:獲取或設置值,該值指定了在行更新過程中出現錯誤時是否要生成異常項。
· DeleteCommand:獲取或設置用於將記錄從數據集中刪除的SQL語句或儲存程式。
· InsertCommand:獲取或設置用於在數據集中插入記錄的SQL語句或儲存程式。
· MissingMappingAction:確定當進入的數據不含匹配資料表或列時需要採取的動作。
· MissingSchemaAction:確定當已有的DataSet方案與進入數據不匹配時需要採取的動作。
· SelectCommand:獲取或設置用於在數據源中選擇記錄的SQL語句或儲存程式。
· TableMappings:獲取提供了源資料表和DataTable之間主映射的集合。
· UpdateCommand:獲取或設置用於在數據源中更新記錄的SQL語句或儲存程式。
在下例中,介紹了在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
在下例中,介紹了在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; }
要想建立MySQLDataReader,必須使用MySqlCommand對象的ExecuteReader方法,而不是直接使用構造函數。
使用MySqlDataReader的同時,相關的MySqlConnection將忙於MySqlDataReader。除了關閉它之外,不能在MySqlConnection上執行任何操作。該情況將一直持續到使用了MySqlDataReader的「Close」方法為止。
關閉了MySqlDataReader後,您只能使用IsClosed和RecordsAffected屬性。儘管在MySqlDataReader存在同時能夠訪問RecordsAffected屬性,但在返回RecordsAffected的值之前總應使用「Close」,以確保準確的返回值。
為了獲得最佳性能,MySqlDataReader將避免建立不必要的對象或執行不必要的數據拷貝。其結果是,對諸如GetValue等方法的多個使用會返回對相同對象的引用。如果您準備更改由諸如GetValue等方法返回的對象的基本值,請仔細小心。
· 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跳到下一條記錄。
在下例中,介紹了在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
在下例中,介紹了在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(); }
該示範介紹在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
該示範介紹在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 ); } }
· ExecuteDataRow:執行單個SQL語句並返回結果集的第1行。在該方法的執行過程中,將建立、打開並關閉1個新的MySqlConnection對象。
· ExecuteDataset:執行單個SQL命令並返回DataSet中的結果集。在該方法的執行過程中,將建立、打開並關閉1個新的MySqlConnection對象。
· ExecuteNonQuery:在MySQL資料庫上執行單個命令。使用該方法時,將認為MySqlConnection已打開,方法執行完後,MySqlConnection仍保持打開狀態。
· ExecuteReader:Overloaded:在MySQL資料庫上執行單個命令。
· ExecuteScalar:在MySQL資料庫上執行單個命令。
· UpdateDataSet:用來自給定DataSet的數據更新給定資料表。
在下例中,介紹了在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
在下例中,介紹了在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(); } }
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, Addr和Network Address。
· Uid:連接時使用的MySQL用戶帳號。別名包括User Id, Username和User name。
· Pwd:MySQL帳號的密碼。也可以使用別名密碼。
· Database:所有語句作用於的預設資料庫。預設為mysql。也可以使用別名Initial Catalog。
· Port:MySQL用於監聽連接的端口。預設為3306。將該值指定為「-1」將使用命名管道連接。
一旦建立了連接字串,可使用它打開與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); }
由於與外部伺服器的連接不可預測,應為您的.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"); } }
輸入語句後,使用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);
}
隨著MySQL版本5的發佈,MySQL伺服器目前支援儲存程式,它採用了SQL 2003儲存程式的語法。
儲存程式指的是能夠保存在伺服器上的一組SQL語句。 一旦完成了該操作,客戶端無需再次發出單獨語句,而僅需引用儲存程式取而代之。
在下述情況下,儲存程式尤其有用:
· 多個客戶端應用程式是採用不同語言編寫的或工作在不同平台上,但需執行相同的資料庫操作。
· 安全性極其重要時。例如,對於所有共同操作,銀行採用了儲存程式。這樣,就能提供一致且安全的環境,而且這類儲存程式能夠保證每次操作均具有恰當登錄。在這類設置下,應用程式和用戶無法直接訪問資料庫資料表,但能執行特定的儲存程式。
MySQL Connector/NET支援通過MySqlCommand對象的儲存程式使用。使用MySqlCommand.Parameters集,能夠將數據傳入和傳出MySQL儲存程式。
在本節中,未深度介紹建立儲存程式方面的訊息,要想瞭解這類訊息,請參見MySQL參考手冊的儲存程式。
在MySQL Connector/NET安裝的Samples目錄下,可找到1個相應的示範,該示範演示了與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); }
要想使用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); }
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數據需要一段時間。恰當地設置該值,使之與預期使用相符,並在必要時增大該值。
要想將檔案寫入資料庫,需要將檔案轉換為字節數組,然後將字節數組用作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); }
一旦將檔案加載到了檔案資料表中,就能使用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); }
在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); }
如果您選擇使用Connector/ODBC來設計報告,可從dev.mysql.com下載它。
嚮導首先要求您提供數據源。如果您正使用Connector/ODBC作為數據源,選擇數據源時,請使用OLE DB (ADO)樹的「用於ODBC的OLEDB provider」選項,,而不是來自ODBC (RDO)的對應選項。如果您使用的是已保存的數據集,請選擇ADO.NET (XML)選項,並瀏覽您保存的數據集。
在報告的建立過程中,剩餘部分將由嚮導自動完成。
建立完報告後,選擇「檔案」菜單中的「Report Options...」菜單項。取消對「Save Data With Report」(與報告一起保存數據)選項的選擇。這樣,就能防止保存的數據干擾應用程式中的數據加載操作。
要想顯示報告,首先用報告所需的數據填充數據集,然後加載報告,並將其與綁定到數據集。最後,將報告傳遞給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); }
在客戶端上限制無效日期十分簡單,即總使用.NET DateTime類來處理日期。DateTime類僅允許有效日期,從而確保了資料庫中的值也是有效的。該方法的缺點是,在使用.NET和非.NET代碼操作資料庫的混合環境下不能使用它,這是因為各應用程式必須執行自己的日期驗證。
MySQL 5.0.2和更高版本的用戶可使用新的傳統SQL模式來限制無效日期值。關於使用傳統SQL模式的更多訊息,請參見http://dev.mysql.com/doc/mysql/en/server-sql-mode.html。
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時,會導致錯誤。
由於存在上述已知事宜,最佳建議仍是,在您的應用程式中僅使用有效日期。
.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;
· 更正了在未填充Connection.Database的情況下使用儲存程式時出現的異常 (Bug #11450) 。
· 特定的殘缺查詢將觸發「連接必須是有效和打開的」錯誤消息 (Bug #11490) 。
· 使用其某一參數含有特殊字元(如「@」)的儲存程式將產生異常。注意,必須啟用ANSI_QUOTES才會使之成為可能 (Bug #13753) 。
· 如果語句包含對相同參數的多個引用,無法對其進行預處理 (Bug #13541) 。
· Ping()方法不更新Connection對象的State屬性 (Bug #13658) 。
· 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) 。
· 連接字串中有多個主機時,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)。
· 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參考文檔中增加了多個主題。
· 使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。
· 更正了與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)。
· 提供方正將伺服器指定的字元編碼用作預設字元編碼。
· 更正了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)。
· 更正了BUG# 3889,不能正確支援Thai編碼。
· 更新了很多測試範例。
· 更正了與使用壓縮有關的問題。
· 將貝塔1版本的版本號擴充為1.0.0。
· 增加了用於安裝器的COPYING.rtf檔案。
· 刪除了所有的XML註釋警告(以後將更好地清理它們)。
· 刪除了一些對ByteFX的最近引用。
· 為預處理語句增加了測試定位器。
· 目前,所有類型的類均實施了SerializeBinary方法,用於將其數據發送給PacketWriter。
· 增加了PacketWriter類,允許將來的低內存大對像處理。
· 更正了運行預處理語句和儲存程式中存在的很多小問題。
· 更改了多條命令,使得在執行帶有特定參數(採用舊語法模式)的儲存程式時不再拋出異常。
· SingleRow現在工作正常,即使在存在限制的情況下也同樣。
· GetBytes目前僅作用在二進制列上。
· Logger現在能夠截短長的SQL命令,從而使得blob列不會「撐爆」日誌。
· 主機和資料庫目前的預設值為「」,除非作了其他設置。
· 更正了BUG# 5214,忽略了連接超時。
· 增加了測試範例,針對bug# 5051:GetSchema不能正確工作。
· 更正了當列為關鍵字時GetSchema為IsUnique返回「假」的問題。
· MySqlDataReader GetXXX方法目前採用了字段級MySqlValue對象,不執行轉換。
· 更正了BUG# 5097:DataReader為時間列返回NULL。
· A增減了針對LOAD DATA LOCAL INFILE的測試範例。
· 增加了replacetext custom nant任務。
· 增加了CommandBuilderTest定位器。
· 為CommandBuilder增加了Last One Wins(最後一個勝出)特性。
· 更正了持續性安全訊息問題。
· 更正了GetBool,使得1, true, "true"和"yes"均可資料表示trueWL# 2024,從而使得參數標誌成為可配置的。
· 增加了"old syntax"連接字串參數,允許使用「@」參數標記符。
· 更正了Bug #4658,MySqlCommandBuilder。
· 更正了Bug #4864,如果「Persist Security Info」(持續性安全訊息)為假,ByteFX.MySqlClient將對密碼進行緩衝處理。
· 在所有的源檔案中更新了授權標誌,以包含FLOSS異常。
· 針對目前所有的MySql類型,增加了新的.Types名稱空間和具體實施。
· 增加了作為MySqlField子類的MySqlField41。
· 更改了很多類,使之能夠使用新的.Types類型。
· 將enum int類型更改為Int32,將short類型更改為Int16,並將bigint類型更改為Int64。
· 增加了偽類型UInt16、UInt32和UInt64,允許建立無符號參數。
· 現在,從連接池拉出連接時,連接將被復位。
· 在驅動程式中再次分解了auth代碼,使得其即能用於auth,也能用於reset。
· 在PoolingTests.cs中增加了UserReset測試。
· 現在,使用COM_CHANGE_USER從池中拉出連接時,連接將被復位。
· 實現了SingleResultSet行為。
· 實現了對unicode的支援。
· 為utf-8和ucs-2增加了字元編碼映射。
· 更正了Bug #4520,使用bytefx .net mysql驅動時,時間字段溢出。
· 在數據類型測試定位器中修改了時間測試,以便能夠檢查「hours > 24」的時間跨度。
· 更正了Bug #4505,在ByteFx.Data.MySqlClient.MySqlParameter中帶有反斜槓轉義的錯誤字串。
· 為參數測試範例TestQuoting增加了代碼,以測試反斜線符號。
· 更正了Bug #4486,與multi-word列名一起工作時,mysqlcommandbuilder失敗。
· 更正了TokenizeSql中的問題,其中,下劃線將中止獲取參數名中的字元。
· 為列名空間增加了測試範例。
· 更正了bug# 4324,MySqlDataReader.GetBytes不能正確工作。
· 為DataReader測試定位器增加了GetBytes()測試範例。
· 現在,能夠將InternalConnection.Configure中的所有伺服器變數讀入到Hashtable。
· 目前使用字串[],用於CharSetMap中的索引映射。
· 為SQL中的carriage返回增加了CRInSQL測試範例。
· 在Driver.ctor中,將maxPacketSize設為預設值。
· 更正了bug #4442,在參數上設置MySqlDbType的操作不設置一般類型。
· 刪除了過時的列類型Long和LongLong。
· 更正了bug# 4071,在連接字串上使用「use pipe」時,拋出溢出異常。
· 將關鍵字「use pipe」更改為「pipe name」或「pipe」。
· 允許從單個查詢讀取多個結果集。
· 為ServerStatusFlags enum增加了標誌屬性。
· 將ServerStatus enum的名稱更改為ServerStatusFlags。
· 更正了BUG #4386,插入的數據行未正確更新。
· 更正了bug #4074,錯誤處理表明建立了資料表。
· 將Packet.ReadLenInteger更改為ReadPackedLong,並增加了packet.ReadPackedInteger,它總讀取用2、3、4組裝的整數。
· 增加了syntax.cs測試定位器,以測試各種SQL語法問題。
· 更正了bug# 4149,對時間值的不當處理。現在,值「00:00:00」不再被當作Null。
· 將所有的測試包檔案移到了TestSuite檔案夾。
· 更正了空列會將結果訊息包指針向後移的問題。
· 增加了新的nant建立指令。
· 更正了BUG #3917,清除資料表名,以便能在下一GenerateSchema執行期間恰當地重新生成它。
· 更正了bug #3915,GetValues總返回0,而且總是試圖複製所有字段,而不是根據所傳入數組的大小。
· 實施了共享內存訪問協議。
· 實施了針對的MySQL 4.1的預處理語句。
· 實施了針對MySQL 5.0的儲存程式。
· 將MySqlInternalConnection重新命名為InternalConnection。
· SQL現在被解釋為字元,更正了與其他語言有關的問題。
· 增加了日誌功能,並允許批連接字串選項。
· 更正了bug #3888,設置DataAdapter屬性時未設置RowUpdating事件。
· 更正了字元編碼映射中存在的問題。
· 實施了4.1鑒定。
· 改善了驅動中的open/auth代碼。
· 改善了在連接過程中連接位的設置方式。
· 現在,在初始的握手階段,將資料庫名傳遞給了伺服器。
· 將客戶端的名稱空間更改為MySql.Data.MySqlClient。
· 將客戶端的裝配名稱更改為MySql.Data.dll。
· 將所有源檔案中的授權文本更改為了GPL。
· 增加了MySqlClient.build Nant檔案。
· 刪除了mono批處理檔案。
· 將一些未使用的檔案移到了notused檔案夾,從而使得nant建立檔案能夠使用通配符。
· 實施了共享內存訪問。
· 對代碼結構進行了較大修補。
· 現在,預處理語句能夠在MySql 4.1.1和更高版本中使用。
· 對4.0、4.1.0和4.1.1完成了auth實施。
· 將名稱空間從MySQL.Data.MySQLClient更改為MySql.Data.MySqlClient。
· 更正了CharSetMapping中存在的問題,其中,它試圖將文本名稱用作ints。
· 將名稱空間更改為MySQL.Data.MySQLClient。
· 集成了來自UC2004的auth變動。
· 更正了在讀取數據之前和值後、在datareader上使用任何GetXXX方法時不能拋出恰當異常的問題(感謝Luca Morelli morelli.luca@iol.it)。
· 在parameter.cs中增加了TimeSpan代碼,以便能恰當地將timespan對像處理為mysql時間格式(感謝Gianluca Colombo g.colombo@alfi.it)。
· 為參數序列化代碼增加了TimeStamp。防止DataAdatper不正常的更新(感謝MIchael King)。
· 更正了MySqlHelper.cs中的拼寫錯誤(感謝Patrick Kristiansen)。
· 驅動程式現在能使用握手協議中給定的字元編碼編號建立編碼。
· 更改了命令編輯器,使之指向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)。
· 現在,可將Enum值作為參數值加以支援(感謝Philipp Sumi)。
· 支援Year數據類型。
· 更正了壓縮問題。
· 更正了以TimeSpan作為值的參數無法恰當序列化的問題。
· 更正了預設ctor不能設置預設連接字串值的問題。
· 為一些新成員增加了一些XML註釋。
· 著手更正/改善壓縮處理事宜。
· 改善了ConnectionString處理功能,使之能夠與SqlClient設定的標準更好地匹配。
· 如果帳號未包含在連接字串中,將拋出MySqlException。
· 如果在連接字串中未指定,本地主機將用作預設主機。
· 如果在連接打開的同時試圖設置連接字串,將拋出異常。
· 對ConnectionString文檔進行了小的修改。
· 刪除了MultiHostStream和MySqlStream。採用Common/StreamCreator取而代之。
· 增加了對「Use Pipe」連接字串值的支援。
· 增加了Platform類,以便能更容易地訪問平台的實用工具功能。
· 更正了小的連接池問題,即,在IsAlive失敗後,不能建立新的連接。
· 增加了Platform.cs和StreamCreator.cs。
· 更正了Field.cs,以便能恰當處理4.1版分格的時間戳。
· 將Common.Version更改為Common.DBVersion,以避免名稱衝突。
· 更正了field.cs,從而使得文本列能返回正確的字段類型(感謝beni27@gmx.net)。
· 增加了MySqlError類,以提供對錯誤代碼的一些引用(感謝Geert Veenstra)。
· 增加了Unix套接字支援(感謝Mohammad DAMT [md@mt.web.id])。
· 沒有可用數據時,僅使用Thread.Sleep。
· 該井了參數數據中引用字元的轉義特性。
· 刪除了parameter.cs中易造成誤解的註釋。
· 更正了連接池問題。
· 再次更正了相同的連接池問題!! ;-)
· 更正了ConnectionSTring編輯器對話框(感謝marco p (pomarc))。
· 現在,在連接字串中支援UserId(感謝Jeff Neeley)。
· 建立非輸入參數時拋出異常(感謝Ryan Gregg)。
· 增加了更多文檔。
· 提供了新的MultiHostStream能力。誠摯感謝Dan Guisinger對此的貢獻。是他首次提供了在連接字串上支援多台機器的代碼和觀念。
· 增加了大量文檔。仍有很多文檔需要增加。
· 更正了與0.73有關的速度事宜。
· 更改了MySqlDataStream中的Thread.Sleep(0),以便在不需要等待時最佳化性能(感謝Todd German)。
· 預先將idlepools填充到了MinPoolSize。
· 個高質量MySqlPool死鎖條件以及愚蠢的問題,其中,CreateNewPooledConnection從不為連接池新增新連接。此外,還更正了MySqlStream.ReadBytes和ReadByte,從而不再使用並非始終正確的TicksPerSecond。(感謝Matthew J. Peddlesden)。
· 修正了精度和標度(感謝Matthew J. Peddlesden)。
· 為流讀取方法增加了Thread.Sleep(1),使之對CPU更友好(感謝Sean McGinnis)。
· 更正了ExecuteReader有時會返回Null的問題(感謝Lloyd Dupont)。
· 更正了與Null字段處理有關的主要問題(感謝Naucki)。
· 封裝了針對max_allowed_packet的查詢,以及Try Catch中的字元編碼(並設置為預設)。
· 更正了套接字未能恰當關閉的問題(感謝Steve)。
· 更正了ExecuteNonQuery不能始終返回正確值的問題。
· 更正了InternalConnection,不使用@@session.max_allowed_packet,而是使用@@max_allowed_packet。(感謝Miguel)。
· 增加了很多新XML文檔行。
· 更正了SQL解析功能,不發送控查詢(感謝Rory)。
· 更正了閱讀器在關閉時不能unpeeking訊息包的問題。
· 更正了不能處理用戶變數的問題(感謝Sami Vaaraniemi)。
· 更正了MySqlPool中的循環檢查功能(感謝Steve M. Brown)。
· 更正了ParameterCollection.Add方法,以與SqlClient匹配(感謝Joshua Mouch)。
· 更正了ConnectionSTring解析功能,以處理布爾類型的NO和YES,以及非小寫值(感謝Naucki)。
· 增加了InternalConnection類,修改了連接池功能。
· 實現了Persist Security Info(持續性安全訊息)。
· 為項目增加了security.cs和version.cs。
· 更正了Parameter.cs中的DateTime處理功能(感謝Burkhard Perkens-Golomb)。
· 更正了某些類型拋出cast異常的參數序列化問題。
· 更正了DataReader,轉換所有的返回值以防止拋棄錯誤(感謝Keith Murray)。
· 為Command.ExecuteReader增加了代碼,如果初始SQL命令拋出異常,將返回Null(感謝Burkhard Perkens-Golomb)。
· 構造了與重組一起引入ExecuteScalar問題。
· 進行了重新構造,允許LOCAL DATA INFILE,以及更好的訊息包排序。
· 更正了與重組有關的數個問題。
· 完成了前期工作,支援Mysql 4.1中更安全的密碼。不再支援4.1版中的舊密碼。
· 正確處理系統參數後顯示參數(Adam M. (adammil))。
· 現在,可將字串直接賦給blob字段(Adam M.)。
· 更正了浮點參數(感謝Pent)。
· 改善了參數ctor和ParameterCollection.Add方法,以更好地匹配SqlClient(感謝Joshua Mouch)。
· 更正了Connection.CreateCommand以返回MySqlCommand類型。
· 更正了連接字串設計器的對話框問題(感謝Abraham Guyt)。
· 更正了與發送命令無法總是讀取響應訊息包有關的問題(感謝Joshua Mouch)。
· 更正了某些Blob類型無法被處理的參數序列化問題(感謝Sean McGinnis)。
· 從DataReader代碼中刪除了偽MessageBox.show(感謝Joshua Mouch)。
· 更正了split sql代碼中的醜陋問題(感謝所有人! :-) )
· 更正了MySqlStream中的問題,即可能會讀取過多數據(感謝Peter Belbin)。
· 實現了HasRows(感謝Nash Pherson)。
· 更正了大於256列的資料表會導致異常的問題(感謝Joshua Kessler)。
· 更正了以「;」結束的SQL語句會導致問題的問題(感謝Shane Krueger)。
· 更正了驅動中的問題,即,錯誤消息被截去1個字元(感謝Shane Krueger)。
· 使得MySqlException成為可序列化的(感謝Mathias Hasselmann)。
· 更新了一些字元代碼頁,使之更加準確。
· 更正了閱讀器能夠在已有打開閱讀器的連接上打開的問題。
· 發佈了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。
· 更正了驅動程式中的順序問題。
· 增加了DbParametersEditor,使得參數編輯更像SqlClient。
· 更正了Command類,以便能夠使用設計器編輯參數。
· 更新了連接字串設計器,支援使用壓縮標誌。
· 更正了字串編碼功能,從而使得歐洲字元(如a)能夠正確工作。
· 建立了基本類,以幫助建立新的數據Provider。
· 在連接字串中增加了對UID關鍵字的支援。
· 字段、參數和命令現在都能使用DBNull.Value,而不是null。
· 使用DBNull.Value的CommandBuilder。
· 未出現auto_insert字段時,CommandBuilder現在能正確建立插入命令。
· 現在,字段使用typeof關鍵字來返回System.Types(性能)。
· 目前實現了MySQLCommandBuilder。
· 目前實現了事務支援(並非所有的資料表類型均支援它)。
· 更正了GetSchemaTable,不再使用xsd(對於Mono)。
· 驅動程式先能兼容Mono!!
· 現在支援TIME數據類型。
· 需要更多工作以改善Timestamp數據類型處理。
· 更改了所有類的特徵以匹配對應的SqlClient類。
· 採用SharpZipLib的協議壓縮(www.icsharpcode.net)。
· Windows平台上的命名管道現工作正常。
· 完成了更多工作,改善了Timestamp數據類型處理。
· 在DataReader上實現了Ienumerable,以使DataGrid能恰當工作。
通過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,應考慮使用流行的架構,如Hibernate、Spring的JDBC模板或Ibatis SQL Maps等,使用它們來完成大多數重複性工作,以及在某些時侯需要用到JDBC的繁重任務。
本節不是作為完整的JDBC教程而設計的。如果需要瞭解使用JDBC方面的更多訊息,或許會對下述線上教程感興趣,與這裡提供的訊息相比,它們介紹的更為詳細和更具深度。
· JDBC基礎,Sun公司提供的教程,涵蓋了JDBC的基本主題。。
· JDBC簡明課程,Sun和JGuru提供了更深的教程。
需要告訴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,並檢索關於資料庫的元數據。在下面數節內,給出了進一步的解釋。
使用語句,可執行基本的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; } }
從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.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 } } }
由於實現了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。
與MySQL伺服器4.1版或更高版本建立連接時,最好使用MySQL Connector/J 3.1版,這是因為它全面支援較新版本的伺服器提供的特性,包括Unicode字元、視圖、儲存程式和伺服器端預處理語句。
儘管3.0版Connector/J能夠與MySQL伺服器4.1或更高版本建立連接,但由於實現了Unicode字元和新的鑒定機制,將無法更新Connector/J 3.0以支援當前和未來伺服器版本中提供的新特性。
從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
設計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值。請注意,這也會阻止使用任何時區轉換功能,因此,驅動程式將禁止同時啟用noDatetimeStringSync和useTimezone。
· 新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檔案中。
· 使用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
用於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字元「&」來隔開配置參數,「&」是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.NamedPipeSocketFactory或com.mysql.jdbc.StandardSocketFactory中的示範代碼,可建立您自己的套接字代理。
在本節中,就特定實施方案將如何影響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()」沒有效果。
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,如果是UNSIGNED,java.lang.Long |
BIGINT[(M)] [UNSIGNED] |
java.lang.Long,如果是UNSIGNED,java.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(日期設為2月1日晚上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 |
對於從JDBC驅動程式發往伺服器的所有字串,均將自動地從固有放熱Java Unicode形式轉換為客戶端字元編碼,包括通過Statement.execute()、Statement.executeUpdate()和Statement.executeQuery()發出的所有查詢,以及除了用setBytes()、setBinaryStream()、setAsiiStream()、setUnicodeStream()和setBlob()排除的參試之外的所有PreparedStatement和CallableStatement參數。
在MySQL伺服器4.1之前,Connector/J支援每連接單一字元編碼,能夠從伺服器配置自動檢測到它,也能由用戶通過使用useUnicode和characterEncoding屬性配置它。
從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風格字元編碼名稱 |
---|---|
usa7 | US-ASCII |
big5 | Big5 |
gbk | GBK |
sjis | SJIS |
gb2312 | EUC_CN |
ujis | EUC_JP |
euc_kr | EUC_KR |
latin1 | ISO8859_1 |
latin1_de | ISO8859_1 |
german1 | ISO8859_1 |
danish | ISO8859_1 |
latin2 | ISO8859_2 |
czech | ISO8859_2 |
hungarian | ISO8859_2 |
croat | ISO8859_2 |
greek | ISO8859_7 |
hebrew | ISO8859_8 |
latin5 | ISO8859_9 |
latvian | ISO8859_13 |
latvian1 | ISO8859_13 |
estonia | ISO8859_13 |
dos | Cp437 |
pclatin2 | Cp852 |
cp866 | Cp866 |
koi8_ru | KOI8_R |
tis620 | TIS620 |
win1250 | Cp1250 |
win1250ch | Cp1250 |
win1251 | Cp1251 |
cp1251 | Cp1251 |
win1251ukr | Cp1251 |
cp1257 | Cp1257 |
macroman | MacRoman |
macce | MacCentralEurope |
utf8 | UTF-8 |
ucs2 | UnicodeBig |
不要用Connector/J發出查詢「set names」,這是因為驅動程式不會檢測已變化的字元編碼,而是會繼續使用在初始連接設置中檢測到的字元編碼。
為了允許從客戶端發出的多個字元編碼,應使用「UTF-8」編碼,方式是,將utf8配置為預設的伺服器字元編碼,或通過「characterEncoding」屬性配置JDBC驅動程式以使用「UTF-8」。
要想使SSL支援能夠工作,必須滿足下述要求:
· 包含JSSE(Java安全套接字延伸)的JDK,如JDK-1.4.1或更高版本。SSL目前不能與能夠為其新增JSSE的JDK一起工作,如JDK-1.2.x或JDK-1.3.x,原因在於下述JSSE問題:http://developer.java.sun.com/developer/bugParade/bugs/4273544.html
· 支援SSL並已編譯和配置了該功能的MySQL伺服器,如MySQL-4.0.4和更高版本,請參見:http://www.mysql.com/doc/en/Secure_connections.html
· 客戶端證書(在本節稍後介紹)。
首先,需要將MySQL伺服器CA證書導入到Java truststore。在MySQL原始碼分發版的「SSL」子目錄下給出了1個示範MySQL伺服器CA證書。SSL將使用它來確定是否與安全MySQL伺服器進行通信。
要想使用Java的「keytool」在當前目錄下建立truststore,並導入伺服器的CA證書(「cacert.pem」),可採取下述方式(假定「keytool」位於路徑中。它位於JDK或JRE的「bin」子目錄下):
shell> keytool -import -alias mysqlServerCACert -file cacert.pem -keystore truststore
Keytool將給出下述響應訊息:
Enter keystore password: *********
Owner: EMAILADDRESS=walrus@example.com, CN=Walrus, O=MySQL AB, L=Orenburg, ST=Some
-State, C=RU
Issuer: EMAILADDRESS=walrus@example.com, CN=Walrus, O=MySQL AB, L=Orenburg, ST=Som
e-State, C=RU
Serial number: 0
Valid from: Fri Aug 02 16:55:53 CDT 2002 until: Sat Aug 02 16:55:53 CDT 2003
Certificate fingerprints:
MD5: 61:91:A0:F2:03:07:61:7A:81:38:66:DA:19:C4:8D:AB
SHA1: 25:77:41:05:D5:AD:99:8C:14:8C:CA:68:9C:2F:B8:89:C3:34:4D:6C
Trust this certificate? [no]: yes
Certificate was added to keystore
隨後,需要生成客戶端證書,以便MySQL伺服器知道它正與安全客戶端進行通信:
shell> keytool -genkey -keyalg rsa -alias mysqlClientCertificate -keystore keystore
Keytool將給出下述提示訊息,並在當目錄下建立名為「keystore」的密鑰儲存器。
您應使用與具體情況相適應的新作出響應:
Enter keystore password: *********
What is your first and last name?
[Unknown]: Matthews
What is the name of your organizational unit?
[Unknown]: Software Development
What is the name of your organization?
[Unknown]: MySQL AB
What is the name of your City or Locality?
[Unknown]: Flossmoor
What is the name of your State or Province?
[Unknown]: IL
What is the two-letter country code for this unit?
[Unknown]: US
Is <CN=Matthews, OU=Software Development, O=MySQL AB,
L=Flossmoor, ST=IL, C=US> correct?
[no]: y
輸入<mysqlClientCertificate>的密碼
如果與keystore的密碼相同,按回車):
最後,要想使JSSE能夠使用您生成的keystore和truststore,啟動JVM時,需要設置下述系統屬性,用您所建立的keystore檔案完整路徑替換「path_to_keystore_file」,用您所建立的truststore檔案完整路徑替換「path_to_truststore_file」,並為每個屬性使用恰當的密碼值。
-Djavax.net.ssl.keyStore=path_to_keystore_file
-Djavax.net.ssl.keyStorePassword=*********
-Djavax.net.ssl.trustStore=path_to_truststore_file
-Djavax.net.ssl.trustStorePassword=*********
此外,還需要在用於MySQL Connector/J的連接參數中將「useSSL」設置為「真」,方法是,在URL中新增「useSSL=true」,或在準備傳遞給DriverManager.getConnection()的java.util.Properties實例中將「useSSL」設置為「真」。
您可以打開JSSE調試功能能夠,測試SSL是否工作(詳情如下),並搜尋下述關鍵事件:
...
*** ClientHello, v3.1
RandomCookie: GMT: 1018531834 bytes = { 199, 148, 180, 215, 74, 12, 54, 244, 0, 168, 55, 103, 215, 64, 16, 138, 225, 190, 132, 153, 2, 217, 219, 239, 202, 19, 121, 78 }
Session ID: {}
Cipher Suites: { 0, 5, 0, 4, 0, 9, 0, 10, 0, 18, 0, 19, 0, 3, 0, 17 }
Compression Methods: { 0 }
***
[write] MD5 and SHA1 hashes: len = 59
0000: 01 00 00 37 03 01 3D B6 90 FA C7 94 B4 D7 4A 0C ...7..=.......J.
0010: 36 F4 00 A8 37 67 D7 40 10 8A E1 BE 84 99 02 D9 6...7g.@........
0020: DB EF CA 13 79 4E 00 00 10 00 05 00 04 00 09 00 ....yN..........
0030: 0A 00 12 00 13 00 03 00 11 01 00 ...........
main, WRITE: SSL v3.1 Handshake, length = 59
main, READ: SSL v3.1 Handshake, length = 74
*** ServerHello, v3.1
RandomCookie: GMT: 1018577560 bytes = { 116, 50, 4, 103, 25, 100, 58, 202, 79, 185, 178, 100, 215, 66, 254, 21, 83, 187, 190, 42, 170, 3, 132, 110, 82, 148, 160, 92 }
Session ID: {163, 227, 84, 53, 81, 127, 252, 254, 178, 179, 68, 63, 182, 158, 30, 11, 150, 79, 170, 76, 255, 92, 15, 226, 24, 17, 177, 219, 158, 177, 187, 143}
Cipher Suite: { 0, 5 }
Compression Method: 0
***
%% Created: [Session-1, SSL_RSA_WITH_RC4_128_SHA]
** SSL_RSA_WITH_RC4_128_SHA
[read] MD5 and SHA1 hashes: len = 74
0000: 02 00 00 46 03 01 3D B6 43 98 74 32 04 67 19 64 ...F..=.C.t2.g.d
0010: 3A CA 4F B9 B2 64 D7 42 FE 15 53 BB BE 2A AA 03 :.O..d.B..S..*..
0020: 84 6E 52 94 A0 5C 20 A3 E3 54 35 51 7F FC FE B2 .nR..\ ..T5Q....
0030: B3 44 3F B6 9E 1E 0B 96 4F AA 4C FF 5C 0F E2 18 .D?.....O.L.\...
0040: 11 B1 DB 9E B1 BB 8F 00 05 00 ..........
main, READ: SSL v3.1 Handshake, length = 1712
...
設置了下述系統屬性時,JSSE可提供調試功能(為STDOUT):-Djavax.net.debug=all。它用於設定要使用的keystores和truststores,以及在SSL握手和證書交換過程中將出現什麼。當您嘗試進行SSL連接時,如果打算確定不能工作的部分,該設置十分有用。
從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");
.......
}
}
事實上,當某一線程需要用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等工具建立負載測試指令,並對應用程式進行負載測試。
確定出發點的一種簡單方法是,將連接池的最大連接數配置為「無限」,運行負載測試,並測量最大的並發連接數。隨後,應進行反向操作,確定出使應用程式具有最佳性能的連接池的最小和最大值。
下述內容基於關於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 & 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
下述說明適用於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>
對於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規範中給出了這方面的介紹。
如果發現MySQL中存在敏感的安全問題,請發送電子郵件至security@mysql.com。
編寫良好的問題報告需要耐心,但在第1時間正確地完成它不僅能節省我們的時間,也能節省您自己的時間。良好的問題報告應包含對問題的完整測試情況,以便我們您能夠在下個版本中更正該問題。
本節介紹的內容用於幫助您正確地編寫報告,從避免將您的時間浪費在對我們幫助不大或沒有幫助的事上,
如果有1份可重複的問題報告,請將其提交到問題資料庫,http://bugs.mysql.com/。
對於任何我們能再現的問題,在下一個MySQL版本中修正它的機會很大。
要想通報其他問題,請使用MySQL郵件列資料表。
請注意,我們可能會對包含過多訊息的消息作出響應,但不太會對包含過少訊息的消息作出回應。人們常會省略掉一些事實,因為他們認為自己知道了故障的原因,並想當然地認為這類細節無關緊要。
良好的原則是:如果您對陳述某事猶豫不定,請陳述之。如果我們要求您提供初始報告中缺少的訊息,在報告中編寫多行資訊來源比等候回復要快,麻煩也更小。
在問題報告,最常犯的錯誤包括:(a)未包含所使用Connector/J或MySQL的版本號,以及(b)未完全描述安裝了Connector/J的平台(包括JVM版本,平台類型,以及所安裝MySQL本身的版本號)。
這是高度相關的訊息,如果沒有它,99%的問題報告無用。我們遇到這類問題,「為何它對我沒用」? 隨後,我們發現在該MySQL版本中,所請求的特性尚未實施,或在較新的MySQL版本中已更正了報告中描述的問題。
有些時候,錯誤與平台相關,在這類情況下,如果不知道作業系統和平台的版本號,我們幾乎不可能更正任何問題。
如果可能,您應建立1份可重複的、不含任何第三方類的獨立測試案例。
為了是該程序流線化,我們與Connector/J一起提供了用於測試的基本類,名為com.mysql.jdbc.util.BaseBugReport。要想使用該類為Connector/J建立1個測試案例,您應應建立自己的從com.mysql.jdbc.util.BaseBugReport繼承的類,並覆蓋方法setUp()、tearDown()和runTest()。
在setUp()方法中,建立用於建立資料表的代碼,並用演示問題所需的數據填充資料表。
在runTest ()方法中,使用在「setUp」方法中建立的資料表和數據,建立用於演示問題的代碼。
在tearDown()方法中,撤銷在setUp()方法中建立的任何資料表。
對於上述三種方法中的任何一種,應使用getConnection ()各種變體中的一種建立與MySQL的JDBC連接。
· getConnection():提供了與在getUrl()中指定的JDBC URL的連接。如果連接已存在,返回該連接,否則將建立新的連接。
· getNewConnection():如果需要為問題報告獲得新的連接(即包含1個以上的連接),應使用它。
· getConnection(String url):使用給定的URL返回連接。
· getConnection(String url, Properties props):使用給定的URL和屬性返回連接。
如果需要使用不同於「jdbc:mysql:///test」的JDBC URL,還應覆蓋方法getUrl()。
在演示您所預計行為的測試案例中(相對於您觀察到的世紀行為,這是您填充錯誤報告的最可能原因),使用assertTrue(boolean expression)和assertTrue(String failureMessage, boolean expression)方法建立必須滿足的條件。
最後,建立用於建立測試案例實例的main ()方法,並使用run方法:
public static void main(String[] args) throws Exception {
new MyBugReport().run();
}
完成了測試案例並證實它能演示您所通報的問題後,請將該案例與問題報告一起上傳到http://bugs.mysql.com/。
# 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#4138和BUG#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#517和BUG#664(由Parwinder Sekhon提出)。
-從3.1版開始,反向移植了4.1協議變化(伺服器端SQL狀態,新字段訊息,較大的客戶端能力標誌,與資料庫的連接等)。
-更正了UpdatableResultSet,作用在插入行上時,為getXXX()返回值(BUG#675)。
-使用moveToInsertRow()時,能夠用預設的列值加載UpdatableResultSet中的insertRow(BUG#688)。
-對於指定為NULL的預設值,DatabaseMetaData.getColumns()未返回NULL。
-將預設的語句類型/並發行更改為TYPE_FORWARD_ONLY和CONCUR_READ_ONLY(兼容規範)。
-如果MySQL不支援,不要嘗試或復位再連接上的隔離級別。
-不將SQLExceptions封在RowDataDynamic內。
-如果useTimezone==true,不更改時間戳TZ兩次(BUG#774)。
-更正了大的分離訊息包處理中存在的回歸問題(BUG#848)。
-更好地診斷「流式」結果集異常中的錯誤消息。
-在空結果集上拋出關於ResultSet.getXXX()的異常(在某些情況未被俘獲)。
-不隱藏關於在I/O層中拋出異常的消息。
-關閉連接池時或在具有已打開連接的PooledConnection.getConnection()上,不觸發連接關閉時間(BUG#884)。
-截短+/- INF(最小和最大代資料表值,對於MySQL中的類型),以及NaN(至0,對於setDouble/setFloat()),當伺服器不支援+/- INF或NaN時,就語句發出警告。
-更正了BUG#879,當字元編碼為SJIS或GBK時,以及「\」出現在非轉義輸入中時對「\」的雙轉義處理。
-清空「流式」結果集未使用行的輸入流時,每100行均有當前線程yield(),以免獨佔CPU時間。
-更正了BUG#1099,DatabaseMetaData.getColumns()弄不清字元列中的關鍵字「set」。
-更正了與Statement.setMaxRows()相關的死鎖事宜。
-更正了CLOB.truncate(),BUG#1130。
-最佳化了CLOB.setChracterStream(), BUG#1131。
-使databaseName、portNumber以及serverName成為MysqlDataSourceFactory的可選參數(BUG#1246)。
-修訂了BUG#1247,導致字元127損壞的ResultSet.get/setString。
-從3.1版開始,反向移植了針對4.11和更高版本的auth.更改。
-增加了com.mysql.jdbc.util.BaseBugReport,以幫助建立問題報告的測試範例。
-通過將「clobberStreamingResults」屬性設置為「真」(預設為「假」),為「clobber」流式結果增加了屬性。這會使「流式」結果集被自動關閉,如果在所有數據尚未從伺服器中讀取完之前,執行了另一查詢,正在從伺服器流出的任何未完成數據均將被捨棄。
05-23-03:版本3.0.8-stable
-允許在Driver.getPropertyInfo()中使用偽URL。
-與Statement.getGeneratedKeys()一起使用多值INSERTS時,返回所生成鍵的列資料表。
-與檔案名和「LOAD DATA [LOCAL] INFILE」一起使用JVM字元編碼。
-更正了與Connection.cleanup()有關的無限循環。
-將Ant目標「compile-core」更改為「compile-driver」,並使測試套件編譯成為單獨的目標。
-更正了未獲得關於Statement.executeUpdate()的集合的結果集,在某些情況下,它會影響getGeneratedKeys()和getUpdateCount()。
-字串中的Unicode字元0xFFFF會導致驅動程式拋出ArrayOutOfBoundsException(Bug #378)。
-使用「REPLACE」語句時返回所生成鍵的正確數目。
-更正了在某些情況下檢測伺服器字元編碼的問題。
-更正了使用極大訊息包時的行數據解碼錯誤。
-最佳化了行數據解碼。
-在已關閉預處理語句上執行操作使拋出異常。
-更正了SJIS編碼問題,感謝Naoto Sato。
-最佳化了EscapeProcessor的使用。
-允許對Statement.close()的多次使用。
04-08-03:版本3.0.7-stable
-更正了使用錯誤事件類型的MysqlPooledConnection.close()。
-更正了PreparedStatement.setClob()中的StringIndexOutOfBoundsException。
- 4.1版列元數據更正。
-從Driver.connect()和Driver.acceptsUrl()中刪除了同步功能。
-事務過程中的IOExceptions現在會導致關閉連接。
-更正了ResultSetMetaData.getColumnTypeName()中丟失的「YEAR」類型轉換。
-對於DBMD.getPrimaryKeys(),不提取以「pri」作為主鍵起始的索引。
-試圖在強制關閉的連接上執行操作時拋出SQLExceptions(即,通信鏈路失敗時)。
-現在,可以使用Connection.setProfileSql(boolean)來打開或關閉仿型功能。
更正了與資料庫元數據有關的字元編碼事宜(字元編碼不能正確獲取集合)。
-與MySQL-4.1或更高版本連接時,現在能夠為別名資料表/列建立可更新結果集。
-更正了檔案大於「max_allowed_packet」時的「LOAD DATA LOCAL INFILE」問題。
-對於GBK和Big5字元編碼,更正了0x5c ('\')字元的轉義功能。
-更正了基礎字段為DATE類型時的ResultSet.getTimestamp()問題。
-保證了來自alignPacketSize()的訊息包大小不超過MAX_ALLOWED_PACKET(JVM問題)。
-autoReconnecting(自動再連接)時不復位Connection.isReadOnly()。
02-18-03:版本3.0.6-stable
-更正了ResultSetMetaData,當catalog未知時返回""。更正了與Sun CachedRowSet有關的NullPointerExceptions。
-更正了DBMD.getTypeInfo()和DBMD.getColumns()為TEXT/BLOB類型中的精度返回不同值的問題。
-通過將「ignoreNonTxTables」設置為「真」,在回退期間(相容性/可用性),允許忽略「non transactional tables」(非事務資料表)告警。
-更正了在初始連接上SQLExceptions耗盡的問題。
-更正了Statement.setMaxRows(),當其不需要時,停止發送「LIMIT」類型的查詢(性能)。
-整理了語句查詢/方法失配測試(即,不允許與.executeQuery()一起使用INSERT)。
-在ResultSet遍歷方法中增加了更多檢查,以獲取何時處於關閉狀態的訊息。
-更正了ResultSetMetaData.isWritable()以返回正確值。
-為DBMD.nullsAreSortedAtStart增加了不同NULL分類行為的「窗口」(4.0.2至4.0.10,真,其他為「否」)。
-實現了Blob.setBytes()。仍需要將所得的Blob傳回到可更新ResultSet(結果集)或PreparedStatement以保持變更,這是因為MySQL不支援「定位器」。
-從Connector/J 3.1反向移植了4.1字元編碼字段。
01-22-03:版本3.0.5-gamma
-更正瞭解包字段時對某些查詢Buffer.fastSkipLenString()導致ArrayIndexOutOfBounds異常的問題。
-為Connection.getTypeMap()實現了空的TypeMap,以便某些第三方應用程式能與MySQL一起工作(IBM WebSphere 5.0連接池)。
-為DBMD.getColumns()增加了丟失的LONGTEXT類型。
-當MySQL版本支援時,Connection.getTransactionIsolation()能從資料庫檢索TX_ISOLATION,而不是實例變數。
-引用DatabaseMetaData.getColumns()、getPrimaryKeys()、getIndexInfo()、getBestRowIdentifier()中的資料表名。
-大幅度降低了PreparedStatements中setBinaryStream()所需的內存。
-更正了ResultSet.isBeforeFirst()處理空結果集方面的問題。
-為外部鍵元數據增加了「更新」選項。
01-06-03:版本3.0.4-gamma
-為Connection.setCatalog增加了對資料庫名的引用ID。
-在PreparedStatement分析程式中增加了對引用ID的支援。
-對於setByte(),在PreparedStatements中,流線式字元轉換和byte[]處理。
-通過與MysqlIO共享出站訊息包,降低了PreparedStatements的內存佔用。
-增加了「strictUpdates」屬性,能夠對可更新結果集的大量「正確性」檢查進行控制。如果希望獲得更快的可更新結果集,並使用主鍵通過作用在資料表上的SELECT建立了結果集,而且在查詢中選擇了所有的主鍵,應將其設置為「假」。
-增加了對4.0.8風格大訊息包的支援。
-更正了PreparedStatement.executeBatch()參數重寫的問題。
12-17-02:版本3.0.3-dev
-將SingleByteCharConverter中的charsToByte更改為非靜態類型。
-更改了SingleByteCharConverter,以使用各轉換器的空閒初始化特性。
-更正了Fields.java中的字元編碼處理功能。
-實現了Connection.nativeSQL()。
-更可靠的轉義標誌「-- recognize '--'」註釋,並允許嵌套式轉義序列(請參見testsuite.EscapeProcessingTest)。
-DBMD.getImported/ExportedKeys()現在能處理每個資料表上的多個外部鍵。
-更正了對某些浮點類型ResultSetMetaData.getPrecision()返回錯誤值的問題。
-更正了ResultSetMetaData.getColumnTypeName()對TEXT類型返回BLOB,對BLOB類型返回TEXT的問題。
-對於4.1和更高版本伺服器,更正了Buffer.isLastDataPacket()。
-增加了CLIENT_LONG_FLAG,以便能獲得更多的列標誌(isAutoIncrement()最重要)。
-由於上述原因,實現了ResultSetMetaData.isAutoIncrement()以使用Field.isAutoIncrement()。
-在DatabaseMetaData方法中比較資料表名且在伺服器中允許時,優先考慮「lower_case_table_names」。
-一些MySQL-4.1協議支援(延伸字段訊息)。
-使用非別名資料表/列名和資料庫名,以完全限定UpdatableResultSet中的資料表和列(需要MySQL-4.1或更高版本)。
-允許用戶通過「continueBatchOnError」屬性(預設為「真」)更改Statement/PreparedStatement.executeBatch()的行為。
-在更多連接方法(createStatement、prepareStatement、setTransactionIsolation、setAutoCommit)中檢查關閉的連接。
-更可靠地實現了可更新結果集。檢查資料表的所有主鍵是否已被選擇。
-如果在伺服器的配置允許,「LOAD DATA LOCAL INFILE ...」現在能正常工作。不能使用「allowLoadLocalInfile」屬性關閉它(請參見README)。
-在單字節字元編碼中,對於未知的字元轉換,用「?」替代「\0」。
- NamedPipeSocketFactory現能正常工作(僅對Windows平台)。具體說明請參見README。
11-08-02:版本3.0.2-dev
-更正了可更新結果集和PreparedStatements不工作的問題。
-更正了ResultSet.setFetchDirection(FETCH_UNKNOWN)。
-更正了使用任意值並使用Statement.setFetchSize()時的問題。
-更正了ResultSet.getLong()中的不正確轉換。
-實現了ResultSet.updateBlob()。
-刪除了UpdatableResultSet中的重複代碼(能從ResultSet繼承而來,不需要各方法處理可更新性的額外代碼,但我認為在將來可能需要)。
-更正了通過屬性「強制」字元編碼時拋出的「UnsupportedEncodingException」。
-更正了各種非ASCII字元編碼問題。
-增加了驅動程式屬性「useHostsInPrivileges」。預設值為「真」。它將影響是否在「DBMD.getColumn/TablePrivileges」中使用「@hostname」。
-描述方案的所有DBMD結果集列現返回NULL,以便能與用於其他資料庫的其他JDBC驅動程式的行為更兼容(MySQL不支援方案)。
-增加了SSL支援。關於如何使用它的更多訊息,請參見README。
-執行自動再連接或故障切換時,恰當恢復連接屬性,包括autoCommit狀態以及隔離級別。
-可能時,使用「SHOW CREATE TABLE」,以確定用於DatabaseMetaData的外部鍵訊息,對於返回的DELETE訊息還允許級聯選項。
-對於SJIS字元編碼,轉義了字串中的「0x5c」字元。
-更正了Clob.getSubString()中起始位置偏離1的錯誤。
-實現了Clob.truncate()。
-實現了Clob.setString()。
-實現了Clob.setAsciiStream()。
-實現了Clob.setCharacterStream()。
-增加了com.mysql.jdbc.MiniAdmin類,該類允許您將「shutdown」命令發送至MySQL伺服器。在最終用戶應用中嵌入Java和MySQL伺服器時使用。
-增加了「connectTimeout」參數,允許JDK-1.4和更高版本的用戶指定建立連接所需等候的最長時間。
-僅當連接處於autoCommit(false)狀態時,故障切換和autoReconnect才能工作,目的在於保持事務的安全。
-增加了「queriesBeforeRetryMaster」屬性,出現故障切換時而且在重新連接到主伺服器之前,該屬性指定了能夠發出的查詢數目(預設為50)。
-更正了DBMD.supportsResultSetConcurrency(),以便為ResultSet.TYPE_SCROLL_INSENSITIVE和ResultSet.CONCUR_READ_ONLY或ResultSet.CONCUR_UPDATABLE返回「真」。
-更正了ResultSet.isLast()處理空結果集方面的問題(應返回「假」)。
- PreparedStatement現在將優先考慮setBinary/Ascii/Character Stream()中的流長度,除非將連接屬性「useStreamLengthsInPrepStmts」設置為「假」。
-刪除了一些使用EscapeProcessor、Connection和DatabaseMetaData類中的「Strings smarter」建立的不需要的臨時對象。
09-21-02:版本3.0.1-dev
-更正了ResultSet.getRow()偏差1的問題。
-更正了RowDataStatic.getAt()偏差1的問題。
-增加了有限Clob功能(ResultSet.getClob()、PreparedStatemtent.setClob()、PreparedStatement.setObject(Clob))。
-為URL增加了socketTimeout參數。
- Connection.isClosed()不再對伺服器執行「Ping」操作。
-當「getAutoCommit() == false」時Connection.close()發出rollback()。
-增加了「妄想」參數,通過刪除其中的「敏感」訊息清理了錯誤消息(即,主機名、端口、帳號等),並在可能的情況下,清理了「敏感」的數據結構。
-更正了ResultSetMetaData.isSigned()在處理TINYINT和BIGINT方面的問題。
- 現在將自動檢測字元編碼。最佳化了單字節字元編碼轉換的代碼。
-實現了ResultSet.getCharacterStream()。
-為DatabaseMetaData.getTableTypes()中的資料表類型增加了「LOCAL TEMPORARY」。
- 整理了大塊代碼,以遵循Java編碼慣例(時機成熟)。
07-31-02:版本3.0.0-dev
- !!! 授權變化!!! 驅動現在是GPL。如果需要非GPL授權,請與我們聯繫(mark@mysql.com)。
- JDBC-3.0功能包括Statement/PreparedStatement.getGeneratedKeys()和ResultSet.getURL()。
-性能增強,在大多數情況下,驅動程式快了50-100%,而且建立的臨時對像更少。
-重新封裝...新的驅動程式名是「com.mysql.jdbc.Driver」,但舊名稱依然有效(驅動程式現由MySQL-AB提供)。
-更好地在語句和PreparedStatement中檢查已關閉的連接。
-支援流式結果集(按行),請參見README,感謝Doron。
-支援大訊息包(MySQL-4.0協議的新增內容),更多訊息請參見README。
- JDBC兼容,除了儲存程式測試外,提供了所有測試。
-更正並分類了DBMetaData中的主鍵名稱(SF問題582086和582086)。
-浮點類型現為java.sql.Types.FLOAT(SF問題579573)。
- ResultSet.getTimestamp()現在能處理DATE類型(SF問題559134)。
- ResultSet.getDate/Time/Timestamp現在能識別由MySQL設置為全零的所有形式的無效值(SF問題586058)。
- Testsuite現在將使用Junit(可從www.junit.org獲得)。
-驅動程式現在僅能與JDK-1.2或更高版本一起工作。
-增加了多主機故障切換支援(請參見README)。
-進行了一般性的原始碼清理。
-讀取訊息包時,通過控制MysqlIO類建立的過渡對象,改善了總的速度。
-改善了字串處理和字段元數據建立的性能(例示),由Alex Twisleton-Wykeham-Fiennes提供。
05-16-02:版本2.0.14
-更多代碼整理。
- PreparedStatement現在能釋放.close()上的資源(SF問題553268)。
-如果伺服器版本不支援,不使用引用ID。此外,如果伺服器是以「—ansi」或「--sql-mode=ANSI_QUOTES」開始,那麼「"」將用作ID引用,否則將使用「`」。
- ResultSet.getDouble()現在能更準確地使用JDK內置的代碼(但較慢)。
- LogicalHandle.isClosed()使用,直至物理連接。
-增加了SQL仿型功能(到STDERR)。在JDBC url中設置「profileSql=true」。更多訊息請參見README。
-更正了relaxAutoCommit參數的類型。
04-24-02:版本2.0.13
-更多代碼整理。
-更正了未能正確讀取的unicode字元(SF問題541088)。
-為PrepStmt提供了更快的Blob轉義功能。
-為DataSource(s)增加了set/getPortNumber()(SF問題548167)。
-為MySQLXADataSource增加了setURL()(SF問題546019)。
-更正了PreparedStatement.toString()(SF問題534026)。
-實現了ResultSetMetaData.getColumnClassName()。
- 現在實施了來自JDBC-3.0的Statement.getGeneratedKeys()的初級版本(要想使之工作,需要使用JDK-1.4,我個人認為)。
- DBMetaData.getIndexInfo(),更正了不良的PAGES(SF問題542201)。
04-07-02:版本2.0.12
-一般性代碼整理。
-為Connection和MysqlLogicalHandle增加了getIdleFor()方法。
-放鬆了所有類中的功能,應更正520615和520393。
-為DBMD增加了getTable/ColumnPrivileges()(更正484502)。
-為getTypeInfo()增加了新類型,更正了已有類型,感謝Al Davis和Kid Kalanon。
-為PreparedStatement增加了BIT類型支援(51870)。
-更正了ResultSet中的getRow()問題(527165)。
-更正了PreparedStatement中的ResultSet可更新性。
-更正了PreparedStatement中時區偏差1小時的問題(538286、528785)。
- ResultSet: 更正了可更新性(如果不可更新,將值設為NULL)。
- DataSources,更正了setUrl問題(511614、525565),錯誤的數據源類名(532816、528767)。
-為需要它們的所有DatabaseMetaData方法增加了ID引用(應更正518108)。
-增加了對YEAR類型的支援(533556)。
- ResultSet.insertRow()目前能夠在大多數情況下檢測auto_increment字段,並在新行中使用該值。但是,該檢測不適用於多值鍵,原因在於MySQL協議不返回該類訊息。
-實現了ResultSet.refreshRow()。
-更正了testsuite.Traversal afterLast()問題,感謝Igor Lastric。
01-27-02:版本2.0.11
-更正了DBMD.getImported/ExportedKeys()和getCrossReference()中丟失的DELETE_RULE值。
-Statement.java的完全同步。
-多處修改,更正了讀取BLOB時的「Unexpected end of input stream」(輸入流意外結束)錯誤。這應是最後更正。
01-24-02:版本2.0.10
-更正了MysqlIO中的虛假「Unexpected end of input stream」(輸入流意外結束)錯誤(問題507456)。
-更正了與Websphere 4一起使用MysqlConnectionPoolDataSource時的「null-pointer-exceptions」(問題505839)。
01-13-02:版本2.0.9
- Ant建立失敗,包括jar檔案,已更正(問題487669)。
-更正了MysqlIO.readPacket()中額外的內存分配(問題488663)。
-實現了DatabaseMetaData.getExported/ImportedKeys()和getCrossReference()。
-在更改實例和類共享引用的方法上,實現了完全同步,驅動程式現在是完全線程安全的(如果遇到問題,請告訴我)。
-將DataSource實施移至org.gjt.mm.mysql.jdbc2.optional軟件包,PooledConnectionDataSource和XADataSource的原始實施仍保留在原處(感謝Todd Wolff給出了PooledConnectionDataSource與IBM WebSphere 4一起的實施方案和測試結果)。
-增加了讀取訊息包時對關閉網絡連接的檢測(感謝Todd Lizambri)。
-更正了與轉義處理其有關的錯誤(問題486265)。
-通過DatabaseMetaData,支援批更新(問題495101)。
-更正了PreparedStatement.setTimestamp()中偏差1小時的錯誤(問題491577)。
-從驅動程式中刪除了級連支援(「||」操作符),較早的VisualAge版本似乎是使用它的唯一軟件,它與邏輯「||」操作符衝突。要想使用「||」操作符作為級聯,需要用「--ansi」標誌啟動mysqld(問題491680)。
-更正了PreparedStatement中的捨棄問題(488663)。
11-25-01:版本2.0.8
-現在支援批更新(感謝Daniel Rall的鼓勵)。
- XADataSource/ConnectionPoolDataSource代碼(實驗性)。
- PreparedStatement.setAnyNumericType()現在能正確處理正指數(增加了「+」,因此MySQL能理解它)。
- DatabaseMetaData.getPrimaryKeys()和getBestRowIdentifier()目前在識別主鍵方面更加可靠(匹配,不管主鍵在Key_type列中的大小寫、或縮寫/全名)。
10-24-01:版本2.0.7
- PreparedStatement.setCharacterStream()現已實現。
-更正了處於高利用率模式(autoReconnect=true)下時的懸掛套接字問題,連接的finalizer將關閉任何在GC上懸掛的套接字。
-更正了在較新版本的MySQL上ResultSetMetaData.getPrecision()返回的值比實際值小1的問題。
-如果列值為NULL,ResultSet.getBlob()現在將返回NULL。
-如果useUnicode=true而且未設置characterEncoding,將從資料庫讀取字元編碼。(感謝Dmitry Vereshchagin)。
-從資料庫讀取初始事務隔離級別(如果可用的話)(感謝Dmitry Vereshchagin)。
-更正了DatabaseMetaData.supportsTransactions(),supportsTransactionIsolationLevel(),getTypeInfo() SQL_DATETIME_SUB,以及不可讀取的SQL_DATA_TYPE字段。
-更正了用於生成SQL並回在某些查詢中以語法錯誤結束的PreparedStatement。
-更正了ResultSet.isAfterLast()總返回「假」的問題。
-更正了PreparedStatement.setTimestamp()中的時區問題(感謝Erik Olofsson)。
-在URL或屬性中傳遞了「captializeTypeNames=true」時,將類型名轉換為大寫(對於WebObjects,感謝Anjo Krank)。
-可更新結果集現在能正確處理字段中的NULL值。
- PreparedStatement.setDouble()現在能使用雙精度值(撤銷了以前所作的截取更正)。
-如果MySQL的版本高於或等於3.21.23,PreparedStatement.setBoolean()將使用1/0值。
06-16-01:版本2.0.6
-更正了PreparedStatement參數檢查功能。
-更正了ResultSet.java中區分大小寫的列名。
06-13-01:版本2.0.5
- 更正了ResultSet.getBlob() ArrayIndex超出範圍的問題。
-更正了ResultSetMetaData.getColumnTypeName關於TEXT/BLOB的問題。
-更正了發送大BLOB查詢時的ArrayIndexOutOfBounds問題(未設置最大訊息包大小)。
-為Connection.setIsolationLevel()增加了ISOLATION級別支援。
-更正了所有列均未設置時在PreparedStatement.executeUpdate()上的NPE問題。
-更正了採用兩位數字年份的TIMESTAMP的數據解析問題。
-為PreparedStatement.setObject()增加了Byte。
- ResultSet.getBoolean()現在能將「-1」識別為「真」。
- ResultSet具有+/-Inf/inf支援特性。
-即使並非所有列均已被設置(設為NULL),ResultSet.insertRow()現在也能工作。
- DataBaseMetaData.getCrossReference()不再使用ArrayIndexOOB。
-作用在結果集上的getObject()能正確執行TINYINT->Byte和SMALLINT->Short操作。
12-03-00:版本2.0.3
-為JDBC2實現了不帶標度組分的getBigDecimal()。
-更正了與可更新結果集有關的復合鍵問題。
-增加了-/+INF對雙精度的檢測。
-更快的ASCII字串操作。
-更正了MAX_ALLOWED_PACKET的不正確檢測,因此,現在能發送大的Blob。
-更正了java.sql.Blob實施代碼中的「偏差1」錯誤。
-增加了「ultraDevHack」URL參數,將其設置為「真」,可允許Macromedia UltraDev使用該驅動程式。
04-06-00:版本2.0.1
-更正了RSMD.isWritable()返回錯誤值的問題。感謝Moritz Maass。
-整理了連接確定時的異常處理功能。
-使用getObject(),具有TEXT類型的列現在會作為字串返回。
- DatabaseMetaData.getPrimaryKeys()現在能正確工作(寫入到key_seq)。感謝Brian Slesinsky。
-按照JDBC規範,在PreparedStatements上,不再進行轉義處理。
-更正了很多JDBC-2.0遍歷、定位錯誤,尤其是寫入空結果集的問題。感謝Ron Smits、Nick Brook、Cessar Garcia和Carlos Martinez。
-更正了使用多個主鍵時,與結果集中可更新性支援有關的一些問題。
02-21-00:版本2.0pre5
-更正了不良的握手問題。
01-10-00:版本2.0pre4
-更正了針對insertRow()的結果集,感謝Cesar Garcia。
-對驅動程式進行了修改,使之能夠通過加載JDBC-2.0類來識別JDBC-2.0,而不是依靠JDK版本號。感謝John Baker。
-更正了結果集,以返回正確的行號。
- Statement.getUpdateCount()現在能返回匹配的行,而不是實際更新的行,它更像SQL-92。
10-29-99
-更正了Statement/PreparedStatement.getMoreResults()問題。感謝Noel J. Bergman。
-為PreparedStatement.setObject()增加了Short類型。感謝Jeff Crowder。
-驅動程式現在能通過查詢伺服器自動配置最大/首選的訊息包大小。
-如果伺服器支援,Autoreconnect代碼將使用更快的ping命令。
-更正了從伺服器讀取訊息包、以及為寫入到伺服器而分配訊息包時與訊息包大小有關的多種問題。
08-17-99:版本2.0pre
-目前是在JDK-1.2下編譯的。通過核心類集合,驅動程式同時支援JDK-1.1和JDK-1.2。在運行時,通過判斷您所使用的JVM版本,驅動程式將加載恰當的接口類。
-修正了在首行中全為NULL的結果集。(由Tim Endres指出)。
-更正了結果集內SQLExceptions的列編號(感謝Blas Rodriguez Somoza)。
-不再需要將資料庫指定給連接。(感謝Christian Motschke)。
07-04-99:版本1.2b
-更好的文檔(不斷改善),doc/mm.doc/book1.html。
-對於列名模式,DBMD現在允許null(未在規範中定義),它將被更改為「%」。
- DBMD現在提供了針對getXXX()的正確類型/長度。
-修改了ResultSet.getDate()、getTime()和getTimestamp()。(由Alan Wilken提供)。
- EscapeProcessor現在能正確處理引號內的「\{ \}」和「{ or }」。(感謝Alik就如何修正它給出的觀點)。
-對連接中的屬性處理功能進行了修正。(由Juho Tikkala提供)。
-對於資料表中的NULL列,ResultSet.getObject()現在能返回NULL,而不是銷毀。(感謝Ben Grosman)。
-對於MySQL不瞭解的類型,ResultSet.getObject()現在能返回字串。(由Chris Perdue建議)。
-刪除了不需要的DataInput/Output流,對於每次IO操作,1/2的方法使用都是不需要的。
-如果未指定字元編碼,使用預設的字元編碼。這是對已損壞JVM的一種避規措施,這是因為,按照規範,所有的JVM都必須支援「ISO8859_1」,但並非如此。
-更正了連接事宜,如果未明確設置字元編碼,將使用平台的字元編碼,而不是「ISO8859_1」。它修正了加載並不總存在的字元轉換器類時存在的問題(JVM問題)。(感謝Fritz Elfert指出了該問題)。
-修改了MysqlIO,使之在可能的情況下再次使用訊息包,而不是降低內存使用率。
-更正了與引號內「{}」有關的轉義處理器問題。
04-14-99:版本1.2a
-更正了對非Javasoft JVM的字元編碼支援(感謝很多指出該問題的人員)。
-更正了ResultSet.getBoolean(),使之能夠識別作為布爾標誌的「y」和「n」,以及「1」和「0」。(感謝Tim Pizey)。
-更正了ResultSet.getTimestamp(),以提供更好的性能。(感謝Richard Swift)。
- 更正了getByte()在處理數值類型方面的問題。(感謝Ray Bellis)。
- 更正了DatabaseMetaData.getTypeInfo()在處理DATE類型時存在的問題。(感謝Paul Johnston)。
-更正了用於「fn」使用的EscapeProcessor。(感謝locomotive.org的Piyush Shah)。
-更正了EscapeProcessor,如果沒有轉義代碼,不執行額外操作。(感謝Ryan Gustafson)。
-更正了驅動程式,使之能解析「jdbc:mysql://host:port」形式的URL(感謝Richard Lobb)。
03-24-99:版本1.1i
-更正了關於PreparedStatements的Timestamps問題。
-更正了RSMD和RS中的Null指針異常。
-對於有效的類檔案,與jikes一起進行了再編譯(感謝ms!)。
03-08-99:版本1.1h
-更正了轉義處理器,以處理不匹配的「{」和「}」(感謝Craig Coles)。
-更正了轉義處理器,以建立移植性更好的(在DATETIME和TIMESTAMP類型間)資料表達式,以便能與BETWEEN子句一起使用。(感謝Craig Longman。
- MysqlIO.quit()現在能關閉套接字連接。在此之前,多次連接失敗後,某些作業系統將耗盡檔案描述符。(感謝Michael Brinkman)。
-更正了Driver.getPropertyInfo中的NullPointerException(感謝Dave Potts)。
-修正了MysqlDefs,允許字字串形式檢索所有的*text字段。(感謝Chris at Leverage)。
-更正了PreparedStatement中的setDouble,使之能用於處理大數字,防止將科學記數法發送到資料庫。(感謝J.S. Ferguson)。
-更正了RSMD中的getScale()和getPrecision()。(由James Klicman貢獻)。
-更正了字段為DECIMAL或NUMERIC時的getObject()(感謝Bert Hobbs)。
-傳遞Null資料表名時,DBMD.getTables()出現嚴重故障。已更正(感謝Richard Lobb)。
-增加了在連接過程中對「client not authorized」(客戶端未被授權)錯誤的檢查。(感謝Hannes Wallnoefer)。
02-19-99:版本1.1g
-結果集行現在是字節數組。Blob和Unicode現在能雙向工作。目前實施了useUnicode和編碼選項。
-修正了PreparedStatement,使用setXXXStream(不改變地發送)將二進制集合發送到MySQL伺服器。
-修正了getDriverPropertyInfo()。
12-31-98:版本1.1f
-將所有的結果集字段更改為字串,這樣,應能使Unicode工作,但您的JVM必須能夠在字元編碼間進行轉換。它還能使對伺服器的數據讀取更快,原因在於,現在不存在從StringBuffer到String(字串)的轉換。
-更改了PreparedStatement.streamToString(),使之更有效(代碼由Uwe Schaefer提供)。
- URL解析功能更可靠(對於錯誤,拋出SQL異常,而不是NullPointerExceptions)。
- PreparedStatement現在能通過setObject()將String轉換為Time/Date值(代碼由Robert Currey提供)。
-在Buffer.readInt()中,IO程序不再被掛起,該問題是在1.1d中當將結果集更改為全字節數組時引入的。(由Samo Login指出)。
11-03-98:版本1.1b
-修正了DatabaseMetaData,允許IBM VA和J-Builder同時工作。請告訴我它的工作機制。(感謝Jac Kersing)。
-修正了ResultSet.getBoolean()在處理NULL字串方面的問題(感謝Barry Lagerweij)。
-開始代碼整理,並進行了格式處理。開始將其分出為並行的JDBC-2.0源樹。
-為MysqlIO和Buffer內的關鍵部分增加了「最終」限定符,允許編譯器採用內聯方法以提高速度。
9-29-98
-如果傳遞給PreparedStatement中setXXX()的對象引用是空的,將自動使用setNull()。(感謝Erik Ostrom給出的提議)。
-對於Types.OTHER對像和未知類型對象,PreparedStatement中的setObject()現在會嘗試將對象的串行化資料表示寫入到資料庫。
- Util現在有了1個靜態方法readObject(),結果集和列索引將以上述方式在此例示序列化的對象。
9-02-98 – 版本1.1
-消除了MysqlIO.nextRow()中的「醜陋問題」。更正了Buffer.isLastDataPacket(),而不是獲取異常。
- Connection.getCatalog()和Connection.setCatalog()現在能夠工作。
- Statement.setMaxRows()能夠正常工作,也能使用屬性maxRows進行設置。通過屬性或URL參數,Statement.setMaxRows()能覆蓋maxRows設置。
-提供了自動再連接功能。由於在每次查詢前不得不Ping資料庫,在預設情況下,它將被關閉。要想使用該功能,請在連接URL中傳遞「autoReconnect=true」。通過「maxReconnects=n」(預設為3)和「initialTimeout=n」(預設為2秒)參數,您也可以更改再連接嘗試的次數和初始超時值。Timeout是超時的指數補償類型。例如,如果初始超時設置為2秒,maxReconnects為3,那麼再連接嘗試之間的間隔分別是2秒,4秒和16秒。
8-24-98:版本1.0
- 更正了Buffer.java中Blob數據的處理功能。
-更正了與尺寸過小的鑒定訊息包有關的問題。
-JDBC驅動程式現在採用LPGL。
8-14-98 -
- 更正了 Buffer.readLenString(),使之能正確讀取BLOB數據。
-更正了PreparedStatement.stringToStream,使之能正確讀取BLOB數據。
-更正了PreparedStatement.setDate(),使之不增加1天。(感謝Vincent Partington在上述修正項方面的貢獻)。
-增加了URL參數解析功能(?user=...等等)。
8-04-98:版本0.9d
- 重大新聞! 新的軟件包名。ICE工程公司的Tim Endres著手為GNU GPL的Java軟件建立新的源樹。他友好地將org.gjt.mm軟件包目錄提供給我,因此,現在驅動程式在org.gjt.mm.mysql軟件包中。目前我是合法用戶。期待Tim項目的更多訊息。
-現在採用了動態確定大小的訊息包,向資料庫發送命令時,能夠減少內存使用。
-對getTypeInfo()的參數等方面進行了小的修正。
- DatabaseMetaData現已完全實現。如果這些驅動程式能與各種IDE一起工作,請告知。我已聽說它們正與Jbuilder一起使用。
-在軟件包中增加了JavaDoc文檔。
-軟件包採用.zip或.tar.gz格式提供。
7-28-98:版本0.9
-實現了getTypeInfo()。根據JDBC規範,Connection.rollback()現在能拋出SQLException。
-增加了PreparedStatement,它支援預處理語句的所有JDBC API方法,包括InputStreams。請檢查該點,如有問題,請告知。
-更正了ResultSet中的1個問題,該問題會破壞僅返回1行的某些查詢。
- 更正了DatabaseMetaData.getTables()、DatabaseMetaData.getColumns()和DatabaseMetaData.getCatalogs()中存在的問題。
-增加了語句的功能,允許executeUpdate()保存由AUTO_INCREMENT字段自動生成的ID值。一般而言,執行executeUpdate()後,將搜尋SQLWarnings以瞭解警告訊息,如LAST_INSERTED_ID = 'some number',COMMAND = 'your SQL query'。
如果在資料表中正使用AUTO_INCREMENT字段,並在一條語句上執行了多個executeUpdate(),務必每次都執行clearWarnings()以節省內存。
7-06-98:版本0.8
-將MysqlIO和Buffer分離為單獨類。對於這兩個類中的某些字段,一些ClassLoader(類加載器)會給出IllegalAccess(非法訪問)錯誤。現在,mm.mysql能夠在小應用程式和所有類加載器中正常工作。
感謝Joe Ennis jce@mail.boone.com指出該問題,並與我一起進行了修正。
7-01-98:版本0.7
-更正了getColumns()中的DatabaseMetadata problems,並更正了字段構造函數內開關語句中存在的問題。
感謝Costin Manolache costin@tdiinc.com指出了它們。
5-21-98:版本0.6
-在MysqlIO.java和ResultSet.java中,結合Richard Swift Richard.Swift@kanatek.ca給出的有效變更內容。
-現在,我們的驅動程式比GWE的驅動程式快15%。
- 開始著手處理DatabaseMetaData。
實現了下述方法:
* getTables()
* getTableTypes()
* getColumns
* getCatalogs()
MySQL Connector/MXJ使得MySQL資料庫像是基於java的組件。它通過下述步驟完成該任務,確定系統所運行的平台,選擇恰當的二進制檔案,並執行程式。也能可選地部署具有任何指定參數的個初始資料庫。
作為一種JMX Mbean,MySQL Connector/MXJ需要與JMX v1.2兼容的Mbean容器,如Jboss版本4。Mbean將使用標準的JMX管理API來展示與平台相適應的參數(並允許設置參數)。
其中包含與JDBC驅動程式一起使用的說明,以及以JMX Mbean方式將其部署至Jboss的說明。
可從下述站點下載源版本和二進製版本:http://dev.mysql.com/downloads/connector/mxj/
這是一種測試板,歡迎反饋和鼓勵。
如有任何問題或意見,請發送電子郵件至java@lists.mysql.com。
Linux, i386
Windows NT, x86
Windows 2000, x86
Windows XP, x86
Solaris 9, SPARC 32
首先應確保組件能夠在平台上工作。由於「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/上下載)。
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)
注意,在快結束時速度會變慢,請耐心等候。
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";
有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); }
· 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軟件包。但也能將多個版本封裝在一起,並指定要使用的版本。
我們希望在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. 滾動到屏幕底部,按 按鈕
11. 點擊「Back to MBean View」(返回Mbean視圖)
12. 滾動到屏幕底部,按 按鈕
13. 殺死運行測試代理的Java程序(jmx伺服器)
一旦確定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」可跳過該步)。滾動到屏幕底部。按 按鈕停止(或啟動)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底部,並按停止服務 觀察已成功完成而且無返回值的操作。使用ps或任務管理器查看MySQL是否已不再運行。
對於1.0.6-beta版,能夠在啟動時讓Mbean啟動MySQL資料庫。此外,我們還借鑒了Jboss生命週期延伸方法的優點,關閉Jboss時能優雅地關閉資料庫。
如果閱讀了上述部分,應已完成了這些步驟。但我們在下面列出了它們,以供快速參考。
啟動了驅動程式:
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檔案,例如datadir和autostart。
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。原始參考手冊為英文版,與英文版參考手冊相比,本翻譯版可能不是最新的。