分类: Mysql/postgreSQL
2008-05-12 15:15:49
· 更正了在未填充Connection.Database的情况下使用存储程序时出现的异常 () 。
· 特定的残缺查询将触发“连接必须是有效和打开的”错误消息 () 。
· 调用其某一参数含有特殊字符(如“@”)的存储程序将产生异常。注意,必须启用ANSI_QUOTES才会使之成为可能 () 。
· 如果语句包含对相同参数的多个引用,无法对其进行预处理 () 。
· Ping()方法不更新Connection对象的State属性 () 。
· Nant构建序列有问题()
· 如果传递的第1个值是NULL,参数的串行化操作失败 () 。
· 含下述字符的字段名将导致错误:()%<>/ () 。
· MySQL Connector/NET 1.0.5安装程序不能同时安装MySQL Connector/NET 1.0.4. ()。
· 在Mono上MySQL Connector/NET 1.0.5不能连接 () 。
· 连接字符串中有多个主机时,MySQL Connector/NET无法与列表中的1个主机相连 () 。
· MySQL Connector/NET将新的十进制数据类型解释为字节数组 () 。
· 不支持cp1250字符集 () 。
· 当.NET线程池无可用的工作线程时,连接可能失败 () 。
· 十进制参数导致语法错误 (, , )。
· 如果存储程序不含参数,调用存储程序将导致异常 () 。
· 特定的残缺查询将触发“连接必须是有效和打开的”错误消息 () 。
· 除了默认数据库外,MySqlCommandBuilder类不能处理引用了其他数据库中表的查询 () 。
· MySQL Connector/NET无法特定的局部设置一起正常工作 (WL#8228)。
· 未填充Connection.Database时使用存储程序导致异常 () 。
· 读取TIMESTAMP列时产生异常 () 。
· 用换行符隔开参数时,无法识别参数 () 。
· 在初始连接上未设置连接字符串时,调用MySqlConnection.clone将导致错误 () 。
· 增加了对从MySQL Connector/NET调用存储函数的支持 () 。
· MySQL Connector/NET不能连接到MySQL 4.1.14. ()。
· 用设计器添加了MySqlConnection对象时,无法设置ConnectionString属性 (, )。
· :调用准备导致异常[已更正]。
· 更正了与预处理语句有关的另一个小问题。
· :MySqlCommand.Connection返回IDbConnection [已更正]。
· :MySqlAdapter.Fill方法抛出错误消息:需要非负数值[已更正]。
· :MySqlCommand中的克隆方法缺陷[已更正]。
· :当字段为NULL时,MySqlDataReader.GetString(index)返回了非Null值[已更正]。
· :如果列是无符号类型,MySqlReader.GetInt32抛出异常[已更正]。
· :GetBytes不再工作[已更正]。
· :引用字符“\222”在EscapeString中未被引用[已更正]。
· 更正了命名管道不能与某些Blob功能一起工作的问题。
· 更正了与共享内存连接有关的问题。
· :与多个结果集有关的问题… [已更正]。
· 在API参考文档中增加了多个主题。
· 使MySQL成为默认的命名管道名称。
· 现在,连接时SHOW COLLATION可用于检索完整的字符集ID列表。
· 更正了无效字符集索引:200 () 。
· 安装器现在包含了多个选项,可安装至GAC中,并创建“开始”菜单项。
· :MySqlCommand参数中的Int64支持[已更正]。
· 对于连接,现在无需在连接字符串上给出数据库。
· :MySqlDataReader.GetChar(int i)抛出IndexOutOfRange异常[已更正]。
· 更正了因具有不同行数的多个结果集而导致的问题。
· :再次抛出异常时异常堆栈跟踪丢失[已更正]。
· 更正了与使用预处理语句检测Null值有关的主要问题。
· :解析存储程序参数时的错误[已更正]。
· :存储程序的整数输出参数返回为字符串[已更正]。
· :按文本分类的数据表中的MySqlDateTime,无数据 [已更正]。
· :使用inout参数时的无效查询字符串[已更正]。
· :与MySQL 4.0一起时,测试失败,原因在于表名的大小写敏感性[已更正]。
· :插入DateTime导致System.InvalidCastException的抛出[已更正]。
· :使用DATE_ADD-function时的InvalidCast[已更正]。
· :1个打开的连接被主机系统关闭[已更正]。
· 为MySqlConnection添加了ServerThread属性以显示服务器线程ID。
· 为MySqlConnection增加了Ping方法。
· 将测试包的名称更改为MySql.Data.Tests.dll。
· 更正了与MySqlBinary有关的问题,其中,无法使用字符串值更新扩展的文本列。
· 更正了使用定制安装时忽略的安装目录问题()。
· 更正了设置命令文本将命令留在预处理状态的问题。
· 更正了MySqlParameter双类型处理问题(字符串parameterName,对象值)()。
· 更正了填充数据集时返回零日期“0000-00-00”错误()。
· 更正了调用存储程序可能会导致“Illegal mix of collations”(非法校对组合)的问题。
· 增加了charset连接字符串选项。
· 更正了#HY000“Illegal mix of collations”(非法校对组合)(latin1_swedish_ci,IMPLICIT)和(utf8_general_ ()问题。
· 增加了TableEditor CS和VB示例。
· 更正了关于UCS-2的Charset-map问题()。
· 更新了安装器,包含了新的示例。
· 更正规了Long插入耗时很长的问题(Bug #5453)。
· 更正了对象无法被处理的问题()。
· 提供方正将服务器指定的字符集用作默认字符集。
· 更正了MySqlParameter(string, object)构造函数中的可能缺陷。
· 更正了,在longtext列上调用GetChars将抛出异常。
· 更正了,无法运行存储程序来填充mysqlcommand.parameters。
· 更正了,设置DbType时抛出NullReferenceException。
· 更正了在关闭套接字之前连接器无法发出CMD_QUIT的问题。
· 更正了,MySqlCommand在字符串文本内容中发现作为参数的“?”。
· 更正了与ConnectionInternal有关的问题,其中,1个键可能会被添加多次。
· 当服务器版本为4.1.2或更高时,CP1252仅用于Latin1。
· 更正了,如果1行为NULL,DataReader通报所有行均为NULL。
· 虚拟化了驱动子系统,以便未来版本能轻易地支持客户端或嵌入式服务器。
· 再次使用字段缓冲,以减少内存分配并增加速度。
· 更正了相应的问题,使用接口时使用旧语法将导致问题。
· 对于写入流操作,使用PacketWriter取代Packet。
· 在CompressedStream中再分解压缩代码,以清理NativeDriver。
· 增加了用于在预处理命令上重置命令文本的测试范例。
· 更正了给定Null值时MySqlParameterCollection.Add()将抛出不明异常的问题()。
· 更正了MySqlCommand()中的构造函数初始化问题()。
· 更正了解析“;”字符的问题()。
· 更正了在DbType设置器中丢失引用的问题()。
· 更正了使用YEAR数据类型时的System.OverflowException问题()。
· 增加了聚合函数测试(实际上不是缺陷)。
· 更正了浮点参数(double, numeric, single, decimal)的序列化问题()。
· IsNullable错误()。
· 更正了不遵守连接字符串上给出的连接寿命的问题。
· 更正了不遵守Min Pool Size(最小池大小)的问题。
· 更正了MySqlDataReader和“show tables from ...”(从…显示表)行为()。
· 实施了SequentialAccess。
· 更正了发现第1个0后MySqlDateTime在所有subseq.records上设置IsZero属性的问题()。
· 更正了无法正确显示中文字的问题()。
· 还更正了俄文字符支持。
· 更正了Method TokenizeSql()仅将有限的有效字符用于参数的问题()。
· 更正了丢失resx文件的NET Connector源()。
· 更正了与检索/更新查询一起使用是会导致问题的DBNull值 () 。
· 更正了仍有另一个“未设置给对象实例的对象引用”()。
· 更正了PacketReader中的问题,其中,会试图在EnsureCapacity中分配错误的缓冲大小。
· 更正了GetBoolean返回错误值的问题()。
· 更正了带有GetString(index)的DataReader一起读取BLOB时的IndexOutOfBounds问题()。
· 更正了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"连接字符串参数,允许使用“@”参数标记符。
· 更正了,MySqlCommandBuilder。
· 更正了,如果“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增加了字符集映射。
· 更正了,使用bytefx .net mysql驱动时,时间字段溢出。
· 在数据类型测试定位器中修改了时间测试,以便能够检查“hours > 24”的时间跨度。
· 更正了,在ByteFx.Data.MySqlClient.MySqlParameter中带有反斜杠转义的错误字符串。
· 为参数测试范例TestQuoting增加了代码,以测试反斜线符号。
· 更正了,与multi-word列名一起工作时,mysqlcommandbuilder失败。
· 更正了TokenizeSql中的缺陷,其中,下划线将中止获取参数名中的字符。
· 为列名空间增加了测试范例。
· 更正了bug# 4324,MySqlDataReader.GetBytes不能正确工作。
· 为DataReader测试定位器增加了GetBytes()测试范例。
· 现在,能够将InternalConnection.Configure中的所有服务器变量读入到Hashtable。
· 目前使用字符串[],用于CharSetMap中的索引映射。
· 为SQL中的carriage返回增加了CRInSQL测试范例。
· 在Driver.ctor中,将maxPacketSize设为默认值。
· 更正了,在参数上设置MySqlDbType的操作不设置一般类型。
· 删除了过时的列类型Long和LongLong。
· 更正了bug# 4071,在连接字符串上使用“use pipe”时,抛出溢出异常。
· 将关键字“use pipe”更改为“pipe name”或“pipe”。
· 允许从单个查询读取多个结果集。
· 为ServerStatusFlags enum增加了标志属性。
· 将ServerStatus enum的名称更改为ServerStatusFlags。
· 更正了,插入的数据行未正确更新。
· 更正了,错误处理表明创建了表。
· 将Packet.ReadLenInteger更改为ReadPackedLong,并增加了packet.ReadPackedInteger,它总读取用2、3、4组装的整数。
· 增加了syntax.cs测试定位器,以测试各种SQL语法缺陷。
· 更正了bug# 4149,对时间值的不当处理。现在,值“00:00:00”不再被当作Null。
· 将所有的测试包文件移到了TestSuite文件夹。
· 更正了空列会将结果信息包指针向后移的问题。
· 增加了新的nant创建脚本。
· 更正了,清除表名,以便能在下一GenerateSchema执行期间恰当地重新生成它。
· 更正了,GetValues总返回0,而且总是试图复制所有字段,而不是根据所传入数组的大小。
· 实施了共享内存访问协议。
· 实施了针对的MySQL 4.1的预处理语句。
· 实施了针对MySQL 5.0的存储程序。
· 将MySqlInternalConnection重新命名为InternalConnection。
· SQL现在被解释为字符,更正了与其他语言有关的问题。
· 增加了日志功能,并允许批连接字符串选项。
· 更正了,设置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 )。
· 为参数序列化代码增加了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死锁条件Second。(感谢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类,以便能够使用设计器编辑参数。
· 更新了连接字符串设计器,支持使用压缩标志。
· 更正了字符串编码功能,从而使得欧洲字符(如ä)能够正确工作。
· 创建了基本类,以帮助创建新的数据Provider。
· 在连接字符串中增加了对UID关键字的支持。
· 字段、参数和命令现在都能使用DBNull.Value,而不是null。
· 使用DBNull.Value的CommandBuilder。
· 未出现auto_insert字段时,CommandBuilder现在能正确创建插入命令。
· 现在,字段使用typeof关键字来返回System.Types(性能)。
· 目前实现了MySQLCommandBuilder。
· 目前实现了事务支持(并非所有的表类型均支持它)。
· 更正了GetSchemaTable,不再使用xsd(对于Mono)。
· 驱动程序先能兼容Mono!!
· 现在支持TIME数据类型。
· 需要更多工作以改善Timestamp数据类型处理。
· 更改了所有类的特征以匹配对应的SqlClient类。
· 采用SharpZipLib的协议压缩()。
· Windows平台上的命名管道现工作正常。
· 完成了更多工作,改善了Timestamp数据类型处理。
· 在DataReader上实现了Ienumerable,以使DataGrid能恰当工作。
· 通过删除网络同步代码中的缺陷,大幅度提高了速度。
· 驱动程序不再对数据行进行缓冲处理(更兼容ADO.Net)。
· 更正了与TIMESTAMP和DATETIME字段有关的转换缺陷。
通过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,应考虑使用流行的架构,如、或等,使用它们来完成大多数重复性工作,以及在某些时侯需要用到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
//
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的一个版本升级到另一版本(或考虑到JDBC的功能,升级到MySQL服务器的新版本)的用户应了解的信息。
设计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属性,将使用的默认值。如果使用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”类性的表中可用。但是,驱动程序会使用“SHO
· 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?
[
What is the name of your State or Province?
[Unknown]: IL
What is the two-letter country code for this unit?
[Unknown]: US
Is
L=Flossmoor, ST=IL, C=US> correct?
[no]: y
输入的密码
如果与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连接时,如果打算确定不能工作的部分,该设置十分有用。