Country: "+country_name+"
"); + ps.setString(1, country_name); + rs = ps.executeQuery(); + if (!rs.next()){ + writer.println("Country does not exist!
"); + } + else { + rs.beforeFirst(); + while(rs.next()) { + writer.println("Name: "+rs.getString("Name")+"
"); + writer.println("Population: "+rs.getString("Population")+ +"
"); + } + } + writer.println(""); + writer.close(); + } + catch (Exception e) { + e.printStackTrace(); + } + } + + public void doGet(HttpServletRequest req, HttpServletResponse resp){ + try { + resp.setContentType("text/html"); + PrintWriter writer = resp.getWriter(); + writer.println(""); + writer.println("Hello from servlet doGet()
"); + writer.println(""); + writer.close(); + } + catch (Exception e) { + e.printStackTrace(); + } + } +} + + + In the preceding code a basic doGet() method is implemented, + but is not used in the example. The code to establish the + connection with the database is as shown in the previous + example, Section 13.1, "A Simple JSP Application with + GlassFish, Connector/J and MySQL," and is most conveniently + located in the servlet init() method. The corresponding + freeing of resources is located in the destroy method. The + main functionality of the servlet is located in the doPost() + method. If the user enters into the input form a country name + that can be located in the database, the population of the + country is returned. The code is invoked using a POST action + associated with the input form. The form is defined in the + file index.html: + + +Please enter country name:
+ + + + + + + + The XML files web.xml and sun-web.xml are as for the example + in the preceding section, Section 13.1, "A Simple JSP + Application with GlassFish, Connector/J and MySQL," no + additional changes are required. + + When compiling the Java source code, you will need to specify + the path to the file javaee.jar. On Windows, this can be done + as follows: +shell> javac -classpath c:\glassfishv3\glassfish\lib\javaee.jar HelloW +ebServlet.java + + Once the code is correctly located within its directory + structure, and compiled, the application can be deployed in + GlassFish. This is done in exactly the same way as described + in the preceding section, Section 13.1, "A Simple JSP + Application with GlassFish, Connector/J and MySQL." + + Once deployed the application can be launched from within the + GlassFish Administration Console. Enter a country name such + as "England", and the application will return "Country does + not exist!". Enter "France", and the application will return + a population of 59225700. + +Chapter 14 Using Connector/J with MySQL Fabric + + MySQL Fabric is a system for managing a farm of MySQL servers + (and other components). Fabric provides an extensible and + easy to use system for managing a MySQL deployment for + sharding and high-availability. + + For more information on MySQL Fabric, see MySQL Fabric + (http://dev.mysql.com/doc/mysql-utilities/1.5/en/fabric.html) + . For instructions on how to use Connector/J with MySQL + Fabric, see Using Connector/J with MySQL Fabric + (http://dev.mysql.com/doc/mysql-utilities/1.5/en/connector-j- + fabric.html). + +Chapter 15 Troubleshooting Connector/J Applications + + This section explains the symptoms and resolutions for the + most commonly encountered issues with applications using + MySQL Connector/J. + + Questions + + * 15.1: When I try to connect to the database with MySQL + Connector/J, I get the following exception: +SQLException: Server configuration denies access to data source +SQLState: 08001 +VendorError: 0 + + What is going on? I can connect just fine with the MySQL + command-line client. + + * 15.2: My application throws an SQLException 'No Suitable + Driver'. Why is this happening? + + * 15.3: I'm trying to use MySQL Connector/J in an applet or + application and I get an exception similar to: +SQLException: Cannot connect to MySQL server on host:3306. +Is there a MySQL server running on the machine/port you +are trying to connect to? + +(java.security.AccessControlException) +SQLState: 08S01 +VendorError: 0 + + + * 15.4: I have a servlet/application that works fine for a + day, and then stops working overnight + + * 15.5: I'm trying to use JDBC 2.0 updatable result sets, + and I get an exception saying my result set is not + updatable. + + * 15.6: I cannot connect to the MySQL server using + Connector/J, and I'm sure the connection parameters are + correct. + + * 15.7: I am trying to connect to my MySQL server within my + application, but I get the following error and stack + trace: +java.net.SocketException +MESSAGE: Software caused connection abort: recv failed + +STACKTRACE: + +java.net.SocketException: Software caused connection abort: recv faile +d +at java.net.SocketInputStream.socketRead0(Native Method) +at java.net.SocketInputStream.read(Unknown Source) +at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:1392) +at com.mysql.jdbc.MysqlIO.readPacket(MysqlIO.java:1414) +at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:625) +at com.mysql.jdbc.Connection.createNewIO(Connection.java:1926) +at com.mysql.jdbc.Connection.Abstract
+ This manual describes how to install, configure, and develop + database applications using MySQL Connector/J, the JDBC driver + for communicating with MySQL servers. +
+ For notes detailing the changes in each release of Connector/J, + see MySQL + Connector/J Release Notes. +
+ For legal information, see the Legal + Notices. +
+ For help with using MySQL, please visit either the + MySQL Forums or + MySQL Mailing Lists, + where you can discuss your issues with other MySQL users. + +
+ For additional documentation on MySQL products, including + translations of the documentation into other languages, and + downloadable versions in variety of formats, including HTML and PDF + formats, see the MySQL + Documentation Library. +
Licensing information. + This product may include third-party software, used under + license. If you are using a Commercial + release of MySQL Connector/J 5.1, see + this + document for licensing information, including + licensing information relating to third-party software that + may be included in this Commercial release. If you are using a + Community release of MySQL Connector/J + 5.1, see + this + document for licensing information, including + licensing information relating to third-party software that + may be included in this Community release. +
+ Document generated on: + + 2016-03-28 + + + + (revision: 47177) +
Table of Contents
+ This manual describes how to install, configure, and develop + database applications using MySQL Connector/J, the JDBC driver for + communicating with MySQL servers. +
+ Copyright © 1998, 2016, Oracle and/or its affiliates. All + rights reserved. +
+ This software and related documentation are provided under a license + agreement containing restrictions on use and disclosure and are + protected by intellectual property laws. Except as expressly + permitted in your license agreement or allowed by law, you may not + use, copy, reproduce, translate, broadcast, modify, license, + transmit, distribute, exhibit, perform, publish, or display any + part, in any form, or by any means. Reverse engineering, + disassembly, or decompilation of this software, unless required by + law for interoperability, is prohibited. +
+ The information contained herein is subject to change without notice + and is not warranted to be error-free. If you find any errors, + please report them to us in writing. +
+ If this is software or related documentation that is delivered to + the U.S. Government or anyone licensing it on behalf of the U.S. + Government, then the following notice is applicable: +
+ U.S. GOVERNMENT END USERS: Oracle programs, including any operating + system, integrated software, any programs installed on the hardware, + and/or documentation, delivered to U.S. Government end users are + "commercial computer software" pursuant to the applicable Federal + Acquisition Regulation and agency-specific supplemental regulations. + As such, use, duplication, disclosure, modification, and adaptation + of the programs, including any operating system, integrated + software, any programs installed on the hardware, and/or + documentation, shall be subject to license terms and license + restrictions applicable to the programs. No other rights are granted + to the U.S. Government. +
+ This software or hardware is developed for general use in a variety + of information management applications. It is not developed or + intended for use in any inherently dangerous applications, including + applications that may create a risk of personal injury. If you use + this software or hardware in dangerous applications, then you shall + be responsible to take all appropriate fail-safe, backup, + redundancy, and other measures to ensure its safe use. Oracle + Corporation and its affiliates disclaim any liability for any + damages caused by use of this software or hardware in dangerous + applications. +
+ Oracle and Java are registered trademarks of Oracle and/or its + affiliates. Other names may be trademarks of their respective + owners. +
+ Intel and Intel Xeon are trademarks or registered trademarks of + Intel Corporation. All SPARC trademarks are used under license and + are trademarks or registered trademarks of SPARC International, Inc. + AMD, Opteron, the AMD logo, and the AMD Opteron logo are trademarks + or registered trademarks of Advanced Micro Devices. UNIX is a + registered trademark of The Open Group. +
+ This software or hardware and documentation may provide access to or + information about content, products, and services from third + parties. Oracle Corporation and its affiliates are not responsible + for and expressly disclaim all warranties of any kind with respect + to third-party content, products, and services unless otherwise set + forth in an applicable agreement between you and Oracle. Oracle + Corporation and its affiliates will not be responsible for any loss, + costs, or damages incurred due to your access to or use of + third-party content, products, or services, except as set forth in + an applicable agreement between you and Oracle. +
Documentation Accessibility
+ For information about Oracle's commitment to accessibility, visit + the Oracle Accessibility Program website at + + + + http://www.oracle.com/pls/topic/lookup?ctx=acc&id=docacc. +
Access to Oracle Support
+ Oracle customers that have purchased support have access to + electronic support through My Oracle Support. For information, + visit + + + + http://www.oracle.com/pls/topic/lookup?ctx=acc&id=info + or visit + http://www.oracle.com/pls/topic/lookup?ctx=acc&id=trs + if you are hearing impaired. +
+ This documentation is NOT distributed under a GPL license. Use of + this documentation is subject to the following terms: +
+ You may create a printed copy of this documentation solely for your + own personal use. Conversion to other formats is allowed as long as + the actual content is not altered or edited in any way. You shall + not publish or distribute this documentation in any form or on any + media, except if you distribute the documentation in a manner + similar to how Oracle disseminates it (that is, electronically for + download on a Web site with the software) or on a CD-ROM or similar + medium, provided however that the documentation is disseminated + together with the software on the same medium. Any other use, such + as any dissemination of printed copies or use of this documentation, + in whole or in part, in another publication, requires the prior + written consent from an authorized representative of Oracle. Oracle + and/or its affiliates reserve any and all rights to this + documentation not expressly granted above. +
+ MySQL provides connectivity for client applications developed in + the Java programming language with MySQL Connector/J, a driver + that implements the + Java + Database Connectivity (JDBC) API. +
+ MySQL Connector/J is a JDBC Type 4 driver. Different versions are + available that are compatible with the JDBC 3.0 and JDBC 4.x + specifications (see Chapter 2, Connector/J Versions). The + Type 4 designation means that the driver is a pure Java + implementation of the MySQL protocol and does not rely on the + MySQL client libraries. +
+ For large-scale programs that use common design patterns of data + access, consider using one of the popular persistence frameworks + such as Hibernate, + Spring's JDBC + templates or Ibatis + SQL Maps to reduce the amount of JDBC code for you to + debug, tune, secure, and maintain. +
+ For help with connection strings, connection options, and + setting up your connection through JDBC, see + Section 5.1, “Driver/Datasource Class Names, URL Syntax and Configuration Properties + for Connector/J”. +
+ There are currently four versions of MySQL Connector/J available: +
+ Connector/J 5.1 is a Type 4 pure Java JDBC driver, which
+ conforms to the JDBC 3.0, 4.0, 4.1, and 4.2 specifications. It
+ provides compatibility with all the functionality of MySQL,
+ including 4.1, 5.0, 5.1, 5.5, 5.6, and 5.7. Connector/J 5.1
+ provides ease of development features, including
+ auto-registration with the Driver Manager, standardized
+ validity checks, categorized SQLExceptions, support for large
+ update counts, support for local and offset date-time variants
+ from the java.time package, support for
+ JDBC-4.x XML processing, support for per connection client
+ information, and support for the
+ NCHAR,
+ NVARCHAR and
+ NCLOB data types. This release also
+ includes all bug fixes up to and including Connector/J 5.0.6.
+
+ Connector/J 5.0 provides support for all the functionality + offered by Connector/J 3.1 and includes distributed + transaction (XA) support. +
+ Connector/J 3.1 was designed for connectivity to MySQL 4.1 and + MySQL 5.0 servers and provides support for all the + functionality in MySQL 5.0 except distributed transaction (XA) + support. +
+ Connector/J 3.0 provides core functionality and was designed + for connectivity to MySQL 3.x or MySQL 4.1 servers, although + it provides basic compatibility with later versions of MySQL. + Connector/J 3.0 does not support server-side prepared + statements, and does not support any of the features in + versions of MySQL later than 4.1. +
+ The following table summarizes the Connector/J versions available, + along with the details of JDBC driver type, what version of the + JDBC API it supports, what versions of MySQL Server it works with, + and whether it is currently supported or not: +
+
Table 2.1 Summary of Connector/J Versions
| Connector/J version | Driver Type | JDBC version | MySQL Server version | Status |
|---|---|---|---|---|
| 5.1 | 4 | 3.0, 4.0, 4.1, 4.2 | 4.1, 5.0, 5.1, 5.5, 5.6, 5.7 | Recommended version |
| 5.0 | 4 | 3.0 | 4.1, 5.0 | Released version |
| 3.1 | 4 | 3.0 | 4.1, 5.0 | Obsolete |
| 3.0 | 4 | 3.0 | 3.x, 4.1 | Obsolete |
+
+ The current recommended version for Connector/J is 5.1. This guide + covers all four connector versions, with specific notes given + where a setting applies to a specific option. +
+ For details of new features and bug fixes in each Connector/J + release, see the + MySQL + Connector/J Release Notes. +
+ The following table summarizes what version of JRE is required + to use Connector/J with Java applications, and what version of + JDK is required to build Connector/J source code: +
+
Table 2.2 Summary of Java Versions Required by Connector/J
| Connector/J version | JRE Supported | JDK required (to build source code) |
|---|---|---|
| 5.1 | 1.5.x, 1.6.x, 1.7.x, 1.8.x | 1.6.x and 1.5.x |
| 5.0 | 1.3.x, 1.4.x, 1.5.x, 1.6.x | 1.4.2, 1.5.x, 1.6.x |
| 3.1 | 1.2.x, 1.3.x, 1.4.x, 1.5.x, 1.6.x | 1.4.2, 1.5.x, 1.6.x |
| 3.0 | 1.2.x, 1.3.x, 1.4.x, 1.5.x, 1.6.x | 1.4.2, 1.5.x, 1.6.x |
+
+ If you are building Connector/J from source code using the + source distribution (see + Section 3.4, “Installing from Source”), you must use + JDK 1.4.2 or newer to compile the package for Connector/J 5.0 or + earlier. For Connector/J 5.1, you must have both JDK-1.6.x + AND JDK-1.5.x installed to be able to build + the source code. +
+ JRE 1.7 support requires Connector/J 5.1.21 and higher. +
+ JRE 1.8 is required for Connector/J 5.1 to connect to MySQL + 5.6.27 and later and 5.7 with SSL/TLS when using some cipher + suites. +
+ Several JDBC 4.1 methods were implemented for the first time in + Connector/J 5.1.21. +
+ Because of the implementation of
+ java.sql.Savepoint, Connector/J 3.1.0 and
+ newer will not run on a Java runtime older than 1.4 unless the
+ class verifier is turned off (by setting the
+ -Xverify:none option to the Java runtime). This
+ is because the class verifier will try to load the class
+ definition for java.sql.Savepoint even
+ though it is not accessed by the driver unless you actually use
+ savepoint functionality.
+
+ Caching functionality provided by Connector/J 3.1.0 or newer is
+ also not available on JVMs older than 1.4.x, as it relies on
+ java.util.LinkedHashMap, which was first
+ available in JDK-1.4.0.
+
+ MySQL Connector/J does not support JDK-1.1.x or JDK-1.0.x. +
Table of Contents
+ You can install the Connector/J package using either the binary or
+ source distribution. The binary distribution provides the easiest
+ method for installation; the source distribution lets you
+ customize your installation further. With either solution, you
+ manually add the Connector/J location to your Java
+ CLASSPATH.
+
+ If you are upgrading from a previous version, read the upgrade + information in Section 3.3, “Upgrading from an Older Version” + before continuing. +
+ Connector/J is also available as part of the Maven project. For + more information and to download the Connector/J JAR files, see + the + Maven + repository. +
+ For the easiest method of installation, use the binary
+ distribution of the Connector/J package. The binary distribution
+ is available either as a tar/gzip or zip file. Extract it to a
+ suitable location, then optionally make the information about
+ the package available by changing your
+ CLASSPATH (see
+ Section 3.2, “Installing the Driver and Configuring the CLASSPATH”).
+
+ MySQL Connector/J is distributed as a .zip or
+ .tar.gz archive containing the sources, the
+ class files, and the JAR archive named
+ mysql-connector-java-.
+ version-bin.jar
+ Starting with Connector/J 3.1.9, the .class
+ files that constitute the JAR files are only included as part of
+ the driver JAR file.
+
+ Starting with Connector/J 3.1.8, the archive also includes a
+ debug build of the driver in a file named
+ mysql-connector-java-.
+ Do not use the debug build of the driver unless instructed to do
+ so when reporting a problem or a bug, as it is not designed to
+ be run in production environments, and will have adverse
+ performance impact when used. The debug binary also depends on
+ the Aspect/J runtime library, which is located in the
+ version-bin-g.jarsrc/lib/aspectjrt.jar file that comes with
+ the Connector/J distribution.
+
+ Use the appropriate graphical or command-line utility to extract + the distribution (for example, WinZip for the .zip archive, and + tar for the .tar.gz archive). Because there + are potentially long file names in the distribution, we use the + GNU tar archive format. Use GNU tar (or an application that + understands the GNU tar archive format) to unpack the .tar.gz + variant of the distribution. +
+ Once you have extracted the distribution archive, you can
+ install the driver by placing
+ mysql-connector-java-in your classpath, either by adding the full path to
+ it to your version-bin.jar
+ CLASSPATH environment variable, or
+ by directly specifying it with the command line switch
+ -cp when starting the JVM.
+
+ To use the driver with the JDBC
+ DriverManager, use
+ com.mysql.jdbc.Driver as the class that
+ implements java.sql.Driver.
+
+ You can set the CLASSPATH environment
+ variable under Unix, Linux, or OS X either locally for a user
+ within their .profile,
+ .login or other login file. You can also set
+ it globally by editing the global
+ /etc/profile file.
+
+ For example, add the Connector/J driver to your
+ CLASSPATH using one of the following forms,
+ depending on your command shell:
+
+# Bourne-compatible shell (sh, ksh, bash, zsh): +shell> export CLASSPATH=/path/mysql-connector-java-ver-bin.jar:$CLASSPATH + +# C shell (csh, tcsh): +shell> setenv CLASSPATH /path/mysql-connector-java-ver-bin.jar:$CLASSPATH +
+ For Windows platforms, you set the environment variable through + the System Control Panel. +
+ To use MySQL Connector/J with an application server such as
+ GlassFish, Tomcat, or JBoss, read your vendor's documentation
+ for more information on how to configure third-party class
+ libraries, as most application servers ignore the
+ CLASSPATH environment variable. For
+ configuration examples for some J2EE application servers, see
+ Chapter 7, Connection Pooling with Connector/J,
+ Section 8.2, “Configuring Load Balancing with Connector/J”,
+ and
+ Section 8.4, “Advanced Load-balancing and Failover Configuration”.
+
+
+
+ However, the authoritative source for JDBC connection pool
+ configuration information for your particular application server
+ is the documentation for that application server.
+
+ If you are developing servlets or JSPs, and your application
+ server is J2EE-compliant, you can put the driver's
+ .jar file in the
+ WEB-INF/lib subdirectory of your webapp, as
+ this is a standard location for third party class libraries in
+ J2EE web applications.
+
+ You can also use the MysqlDataSource or
+ MysqlConnectionPoolDataSource classes in
+ the com.mysql.jdbc.jdbc2.optional package, if
+ your J2EE application server supports or requires them. Starting
+ with Connector/J 5.0.0, the
+ javax.sql.XADataSource interface is
+ implemented using the
+ com.mysql.jdbc.jdbc2.optional.MysqlXADataSource
+ class, which supports XA distributed transactions when used in
+ combination with MySQL server version 5.0 and later.
+
+ The various MysqlDataSource classes
+ support the following parameters (through standard set
+ mutators):
+
+ user
+
+ password
+
+ serverName (see the previous section
+ about failover hosts)
+
+ databaseName
+
+ port
+
+ This section has information for users who are upgrading from + one version of Connector/J to another, or to a new version of + the MySQL server that supports a more recent level of JDBC. A + newer version of Connector/J might include changes to support + new features, improve existing functionality, or comply with new + standards. +
+ In Connector/J 5.0.x and earlier, the alias for a table in
+ a SELECT statement is
+ returned when accessing the result set metadata using
+ ResultSetMetaData.getColumnName().
+ This behavior however is not JDBC compliant, and in
+ Connector/J 5.1, this behavior has been changed so that
+ the original table name, rather than the alias, is
+ returned.
+
+ The JDBC-compliant behavior is designed to let API users
+ reconstruct the DML statement based on the metadata within
+ ResultSet and
+ ResultSetMetaData.
+
+ You can get the alias for a column in a result set by
+ calling
+ ResultSetMetaData.getColumnLabel().
+ To use the old noncompliant behavior with
+ ResultSetMetaData.getColumnName(),
+ use the useOldAliasMetadataBehavior
+ option and set the value to true.
+
+ In Connector/J 5.0.x, the default value of
+ useOldAliasMetadataBehavior was
+ true, but in Connector/J 5.1 this was
+ changed to a default value of false.
+
+ Using the UTF-8 Character Encoding -
+ Prior to MySQL server version 4.1, the UTF-8 character
+ encoding was not supported by the server, however the JDBC
+ driver could use it, allowing storage of multiple
+ character sets in latin1 tables on the
+ server.
+
+ Starting with MySQL-4.1, this functionality is deprecated. + If you have applications that rely on this functionality, + and can not upgrade them to use the official Unicode + character support in MySQL server version 4.1 or newer, + add the following property to your connection URL: +
+ useOldUTF8Behavior=true
+
+ Server-side Prepared Statements - + Connector/J 3.1 will automatically detect and use + server-side prepared statements when they are available + (MySQL server version 4.1.0 and newer). If your + application encounters issues with server-side prepared + statements, you can revert to the older client-side + emulated prepared statement code that is still presently + used for MySQL servers older than 4.1.0 with the following + connection property: +
+ useServerPrepStmts=false
+
+ Connector/J 3.1 is designed to be backward-compatible with
+ Connector/J 3.0 as much as possible. Major changes are
+ isolated to new functionality exposed in MySQL-4.1 and newer,
+ which includes Unicode character sets, server-side prepared
+ statements, SQLState codes returned in
+ error messages by the server and various performance
+ enhancements that can be enabled or disabled using
+ configuration properties.
+
+ Unicode Character Sets:
+ See the next section, as well as
+ Character Set Support, for information on this MySQL
+ feature. If you have something misconfigured, it will
+ usually show up as an error with a message similar to
+ Illegal mix of collations.
+
+ Server-side Prepared + Statements: Connector/J 3.1 will automatically + detect and use server-side prepared statements when they + are available (MySQL server version 4.1.0 and newer). +
+ Starting with version 3.1.7, the driver scans SQL you are
+ preparing using all variants of
+ Connection.prepareStatement() to
+ determine if it is a supported type of statement to
+ prepare on the server side, and if it is not supported by
+ the server, it instead prepares it as a client-side
+ emulated prepared statement. You can disable this feature
+ by passing
+ emulateUnsupportedPstmts=false in your
+ JDBC URL.
+
+ If your application encounters issues with server-side
+ prepared statements, you can revert to the older
+ client-side emulated prepared statement code that is still
+ presently used for MySQL servers older than 4.1.0 with the
+ connection property
+ useServerPrepStmts=false.
+
+ Datetimes with all-zero
+ components (0000-00-00 ...): These
+ values cannot be represented reliably in Java. Connector/J
+ 3.0.x always converted them to NULL
+ when being read from a ResultSet.
+
+ Connector/J 3.1 throws an exception by default when these
+ values are encountered, as this is the most correct
+ behavior according to the JDBC and SQL standards. This
+ behavior can be modified using the
+ zeroDateTimeBehavior configuration
+ property. The permissible values are:
+
+ exception (the default), which
+ throws an SQLException with an SQLState of
+ S1009.
+
+ convertToNull, which returns
+ NULL instead of the date.
+
+ round, which rounds the date to the
+ nearest closest value which is
+ 0001-01-01.
+
+ Starting with Connector/J 3.1.7,
+ ResultSet.getString() can be decoupled
+ from this behavior using
+ noDatetimeStringSync=true (the default
+ value is false) so that you can
+ retrieve the unaltered all-zero value as a String. Note
+ that this also precludes using any time zone conversions,
+ therefore the driver will not allow you to enable
+ noDatetimeStringSync and
+ useTimezone at the same time.
+
+ New SQLState Codes:
+ Connector/J 3.1 uses SQL:1999 SQLState codes returned by
+ the MySQL server (if supported), which are different from
+ the legacy X/Open state codes that Connector/J 3.0 uses.
+ If connected to a MySQL server older than MySQL-4.1.0 (the
+ oldest version to return SQLStates as part of the error
+ code), the driver will use a built-in mapping. You can
+ revert to the old mapping by using the configuration
+ property useSqlStateCodes=false.
+
+ ResultSet.getString():
+ Calling ResultSet.getString() on a
+ BLOB column will now return
+ the address of the byte[] array that
+ represents it, instead of a String
+ representation of the BLOB.
+ BLOB values have no
+ character set, so they cannot be converted to
+ java.lang.Strings without data loss or
+ corruption.
+
+ To store strings in MySQL with LOB behavior, use one of
+ the TEXT types, which the
+ driver will treat as a java.sql.Clob.
+
+ Debug builds: Starting
+ with Connector/J 3.1.8 a debug build of the driver in a
+ file named
+ mysql-connector-java-
+ is shipped alongside the normal binary jar file that is
+ named
+ version-bin-g.jarmysql-connector-java-.
+ version-bin.jar
+ Starting with Connector/J 3.1.9, we do not ship the
+ .class files unbundled, they are only
+ available in the JAR archives that ship with the driver.
+
+ Do not use the debug build of the driver unless instructed
+ to do so when reporting a problem or bug, as it is not
+ designed to be run in production environments, and will
+ have adverse performance impact when used. The debug
+ binary also depends on the Aspect/J runtime library, which
+ is located in the
+ src/lib/aspectjrt.jar file that comes
+ with the Connector/J distribution.
+
+ To just get MySQL Connector/J up and running on your system, + install Connector/J + using a + standard binary release distribution. Instructions in + this section is only for users who, for various reasons, want + to compile Connector/J from source. +
+ The requirements and steps for installing from source + Connector/J 5.1.37 + or later, + 5.1.34 to + 5.1.36, and + 5.1.33 or + earlier are different; check the section below that is + relevant for the version you want. +
Installing Connector/J 5.1.37 or later from source. + To install MySQL Connector/J from its source tree on GitHub, + you need to have the following software on your system: +
+ A Git client, to check out the sources from our GitHub + repository (available from + http://git-scm.com/downloads). +
+ Apache Ant version 1.8.2 or newer (available from + http://ant.apache.org/). +
+ JDK 1.8.x AND JDK 1.5.x. +
+ JRE 1.6.x (optional) +
+ JUnit libraries (available from + https://github.com/junit-team/junit/wiki/Download-and-Install). +
+ The required .jar files from the
+ Hibernate ORM 4.1 or 4.2 Final release bundle, which is
+ available at
+ http://sourceforge.net/projects/hibernate/files/hibernate4/.
+
+ To check out and compile MySQL Connector/J, follow these steps: +
+ Check out the code from the source code repository for MySQL + Connector/J located on GitHub at + https://github.com/mysql/mysql-connector-j; + for the latest release of the Connector/J 5.1 series, use + the following command: +
+shell> git clone https://github.com/mysql/mysql-connector-j.git
+
+ To check out a release other than the latest one, use the
+ --branch option to specify the revision tag
+ for it:
+
+
+shell> git clone --branch 5.1.xx https://github.com/mysql/mysql-connector-j.git
++
+ Under the current directory, the commands create a
+ mysql-connector-j subdirectory , which
+ contains the code you want.
+
+ Make sure that you have both JDK 1.8.x + AND JDK 1.5.x installed. You need both + JDKs because besides supporting JDBC from 4.0 to 4.2, + Connector/J 5.1 also supports JDBC 3.0, which is an older + version and requires the older JDK 1.5.x. +
+ Consider also having JRE 1.6.x installed. This is optional:
+ if JRE 1.6.x is not available or not supplied to Ant with
+ the property com.mysql.jdbc.java6.rtjar,
+ the Java 8 bootstrap classes will be used. A warning will be
+ returned, saying that the bootstrap class path was not set
+ with the option to compile sources written for Java 6.
+
+ Place the required junit.jar file in a
+ separate directory—for example,
+ /home/username/ant-extralibs.
+
+ In the same directory for extra libraries described in the
+ last step, create a directory named
+ hibernate4, and put under it all the
+ .jar files you can find under the
+ /lib/required/ folder in the Hibernate
+ ORM 4 Final release bundle.
+
+ Change your current working directory to the
+ mysql-connector-j directory created in
+ step 1 above.
+
+ In the directory, create a file named
+ build.properties to indicate to Ant the
+ locations of the root directories for your JDK 1.8.x and JDK
+ 1.5.x installations, the location of the
+ rt.jar of your JRE 1.6.x (optional),
+ and the location of the extra libraries. The file should
+ contain the following property settings, with the
+ “path_to_*” parts
+ replaced by the appropriate filepaths:
+
+com.mysql.jdbc.jdk8=path_to_jdk_1.8+com.mysql.jdbc.jdk5=path_to_jdk_1.5+com.mysql.jdbc.java6.rtjar=path_to_rt.jar_under_jre_1.6/rt.jar +com.mysql.jdbc.extra.libs=path_to_folder_for_extra_libraries+
+ Alternatively, you can set the values of those properties
+ through the Ant -D options.
+
+ Issue the following command to compile the driver and create
+ a .jar file for Connector/J:
+
+shell> ant dist
+
+ This creates a build directory in the
+ current directory, where all the build output goes. A
+ directory is created under the build
+ directory, whose name includes the version number of the
+ release you are building. That directory contains the
+ sources, the compiled .class files, and
+ a .jar file for deployment. For more
+ information and other possible targets, including those that
+ create a fully packaged distribution, issue the following
+ command:
+
+shell> ant -projecthelp
+
+ Install the newly created .jar file for
+ the JDBC driver as you would install a binary
+ .jar file you download from MySQL by
+ following the instructions given in
+ Section 3.2, “Installing the Driver and Configuring the CLASSPATH”.
+
+ Note that a package containing both the binary and source code + for Connector/J 5.1 can also be found at + + Connector/J 5.1 Download. +
Installing Connector/J 5.1.34 to 5.1.36 from source. + To install MySQL Connector/J 5.1.34 to 5.1.36 from the + Connector/J source tree on GitHub, make sure that you have the + following software on your system: +
+ A Git client, to check out the sources from our GitHub + repository (available from + http://git-scm.com/downloads). +
+ Apache Ant version 1.8.2 or newer (available from + http://ant.apache.org/). +
+ JDK 1.6.x AND JDK 1.5.x. +
+ JUnit libraries (available from + https://github.com/junit-team/junit/wiki/Download-and-Install). +
+ The required .jar files from the
+ Hibernate ORM 4.1 or 4.2 Final release bundle, which is
+ available at
+ http://sourceforge.net/projects/hibernate/files/hibernate4/.
+
+ To check out and compile MySQL Connector/J, follow these steps: +
+ Check out the code from the source code repository for MySQL
+ Connector/J located on GitHub at
+ https://github.com/mysql/mysql-connector-j,
+ using the --branch option to specify the
+ revision tag for release 5.1.xx:
+
+
+shell> git clone --branch 5.1.xx https://github.com/mysql/mysql-connector-j.git
++
+ Under the current directory, the commands create a
+ mysql-connector-j subdirectory , which
+ contains the code you want.
+
+ Make sure that you have both JDK 1.6.x + AND JDK 1.5.x installed. You need both + JDKs because Connector/J 5.1 supports both JDBC 3.0 (which + has existed prior to JDK 1.6.x) and JDBC 4.0. +
+ Place the required junit.jar file in a
+ separate directory—for example,
+ /home/username/ant-extralibs.
+
+ In the same directory for extra libraries described in the
+ last step, create a directory named
+ hibernate4, and put under it all the
+ .jar files you can find under the
+ /lib/required/ folder in the Hibernate
+ ORM 4 Final release bundle.
+
+ Change your current working directory to the
+ mysql-connector-j directory created in
+ step 1 above.
+
+ In the directory, create a file named
+ build.properties to indicate to Ant the
+ locations of the root directories for your JDK 1.5.x and JDK
+ 1.6.x installations, as well as the location of the extra
+ libraries. The file should contain the following property
+ settings, with the
+ “path_to_*” parts
+ replaced by the appropriate filepaths:
+
+com.mysql.jdbc.jdk5=path_to_jdk_1.5+com.mysql.jdbc.jdk6=path_to_jdk_1.6+com.mysql.jdbc.extra.libs=path_to_folder_for_extra_libraries+
+ Alternatively, you can set the values of those properties
+ through the Ant -D options.
+
+ Issue the following command to compile the driver and create
+ a .jar file for Connector/J:
+
+shell> ant dist
+
+ This creates a build directory in the
+ current directory, where all the build output goes. A
+ directory is created under the build
+ directory, whose name includes the version number of the
+ release you are building. That directory contains the
+ sources, the compiled .class files, and
+ a .jar file for deployment. For more
+ information and other possible targets, including those that
+ create a fully packaged distribution, issue the following
+ command:
+
+shell> ant -projecthelp
+
+ Install the newly created .jar file for
+ the JDBC driver as you would install a binary
+ .jar file you download from MySQL by
+ following the instructions given in
+ Section 3.2, “Installing the Driver and Configuring the CLASSPATH”.
+
Installing Connector/J 5.1.33 or earlier from the source tree. + To install MySQL Connector/J 5.1.33 or earlier from the + Connector/J source tree on GitHub, make sure that you have the + following software on your system: +
+ A Git client, to check out the source code from our GitHub + repository (available from + http://git-scm.com/downloads). +
+ Apache Ant version 1.7 or newer (available from + http://ant.apache.org/). +
+ JDK 1.6.x AND JDK 1.5.x. Refer to + Section 2.2, “Java Versions Supported” for the version + of Java you need to build or run any Connector/J release. +
+ The Ant Contrib (version 1.03b is available from + http://sourceforge.net/projects/ant-contrib/files/ant-contrib/1.0b3/) + and JUnit (available from + https://github.com/junit-team/junit/wiki/Download-and-Install) + libraries. +
+ The required .jar files from the
+ Hibernate ORM 4.1 or 4.2 Final release bundle, which is
+ available at
+ http://sourceforge.net/projects/hibernate/files/hibernate4/.
+
+ To check out and compile a specific branch of MySQL Connector/J, + follow these steps: +
+ Check out the code from the source code repository for MySQL
+ Connector/J located on GitHub at
+ https://github.com/mysql/mysql-connector-j,
+ using the --branch option to specify the
+ revision tag for release 5.1.xx:
+
+
+shell> git clone --branch 5.1.xx https://github.com/mysql/mysql-connector-j.git
++
+ Under the current directory, the commands create a
+ mysql-connector-j subdirectory , which
+ contains the code you want.
+
+ To build Connector/J 5.1, make sure that you have both JDK
+ 1.6.x AND JDK 1.5.x installed. You need
+ both JDKs because Connector/J 5.1 supports both JDBC 3.0
+ (which has existed prior to JDK 1.6.x) and JDBC 4.0. Set
+ your JAVA_HOME environment variable to
+ the path to the JDK 1.5.x installation.
+
+ Place the required ant-contrib.jar file
+ (in exactly that name, without the version number in it;
+ rename the jar file if needed) and
+ junit.jar file in a separate
+ directory—for example,
+ /home/username/ant-extralibs.
+
+ In the same directory for extra libraries described in the
+ last step, create a directory named
+ hibernate4, and put under it all the
+ .jar files you can find under the
+ /lib/required/ folder in the Hibernate
+ ORM 4 Final release bundle.
+
+ Change your current working directory to the
+ mysql-connector-j directory created in
+ step 1 above.
+
+ In the directory, create a file named
+ build.properties to indicate to Ant the
+ locations of the Javac and rt.jar of
+ your JDK 1.6.x, as well as the location of the extra
+ libraries. The file should contain the following property
+ settings, with the
+ “path_to_*” parts
+ replaced by the appropriate filepaths:
+
+com.mysql.jdbc.java6.javac=path_to_javac_1.6/javac +com.mysql.jdbc.java6.rtjar=path_to_rt.jar_under_jdk_1.6/rt.jar +com.mysql.jdbc.extra.libs=path_to_folder_for_extra_libraries+
+ Alternatively, you can set the values of those properties
+ through the Ant -D options.
+
+ Issue the following command to compile the driver and create
+ a .jar file for Connector/J:
+
+shell> ant dist
+
+ This creates a build directory in the
+ current directory, where all the build output goes. A
+ directory is created under the build
+ directory, whose name includes the version number of the
+ release you are building. That directory contains the
+ sources, the compiled .class files, and
+ a .jar file for deployment. For more
+ information and other possible targets, including those that
+ create a fully packaged distribution, issue the following
+ command:
+
+shell> ant -projecthelp
+
+ Install the newly created .jar file for
+ the JDBC driver as you would install a binary
+ .jar file you download from MySQL by
+ following the instructions given in
+ Section 3.2, “Installing the Driver and Configuring the CLASSPATH”.
+
+ The Connector/J source code repository or packages that are + shipped with source code include an extensive test suite, + containing test cases that can be executed independently. The + test cases are divided into the following categories: + +
+ Functional or unit tests: Classes
+ from the package testsuite.simple.
+ Include test code for the main features of the
+ Connector/J.
+
+ Performance tests: Classes from the
+ package testsuite.perf. Include
+ test code to make measurements for the performance of
+ Connector/J.
+
+ Fabric tests: Classes from the
+ package testsuite.fabric. Includes
+ the code to test Fabric-specific features. These tests
+ require the setting of some special properties that are
+ not documented here. Consult the code or the
+ Fabric-related targets in the bundled Ant build file,
+ build.xml.
+
+ Regression tests: Classes from the
+ package testsuite.regression.
+ Includes code for testing bug and regression fixes.
+
+
+ The bundled Ant build file contains targets like
+ test and test-multijvm,
+ which can facilitate the process of running the Connector/J
+ tests; see the target descriptions in the build file for
+ details. Besides the requirements for building Connector/J from
+ the source code described in
+ Section 3.4, “Installing from Source”, a number of the
+ tests also require the File System Service Provider 1.2 for the
+ Java Naming and Directory Interface (JNDI), available at
+ http://www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloads-java-plat-419418.html)—place
+ the jar files downloaded from there into the
+ lib directory or in the directory pointed
+ to by the property com.mysql.jdbc.extra.libs.
+
+ To run the test using Ant, in addition to the properties
+ required for Section 3.4, “Installing from Source”,
+ you must set the following properties in the
+ build.properties file or through the Ant
+ -D options:
+
+
+ com.mysql.jdbc.testsuite.url: it
+ specifies the JDBC URL for connection to a MySQL test
+ server; see
+ Section 5.1, “Driver/Datasource Class Names, URL Syntax and Configuration Properties
+ for Connector/J”.
+
+ com.mysql.jdbc.testsuite.jvm: the JVM
+ to be used for the tests. If the property is set, the
+ specified JVM will be used for all test cases except if it
+ points to a Java 5 directory, in which case any test cases
+ for JDBC 4.0 and later are run with the JVM supplied with
+ the property com.mysql.jdbc.jdk8 (for
+ 5.1.36 and earlier, supplied with the property
+ com.mysql.jdbc.jdk6). If the property
+ is not set, the JVM supplied with
+ com.mysql.jdbc.jdk5 will be used to run
+ test cases for JDBC 3.0 and the one supplied with
+ com.mysql.jdbc.jdk8 (for 5.1.36 and
+ earlier, supplied with the property
+ com.mysql.jdbc.jdk6) will be used to
+ run test cases for JDBC 4.0 and later.
+
+
+ After setting these parameters, run the tests with Ant in the + following ways: + +
+ Building the test target with
+ ant test runs all test cases by default
+ on a single server instance. If you want to run a
+ particular test case, put the test's fully qualified class
+ names in the test variable; for
+ example:
+
+
+shell > ant -Dtest=testsuite.simple.StringUtilsTest test
+
+ You can also run individual tests in a test case by
+ specifying the names of the corresponding methods in the
+ methods variable, separating multiple
+ methods by commas; for example:
+
+
+shell > ant -Dtest=testsuite.simple.StringUtilsTest -Dmethods=testIndexOfIgnoreCase,testGetBytes test
++
+ Building the test-multijvm target with
+ ant test-multijvm runs all the test
+ cases
+
+
+ using multiple JVMs of different versions on multiple
+ server instances. For example, if you want to run the
+ tests using a Java 7 and a Java 8 JVM on three server
+ instances with different configurations, you will need to
+ use the following properties:
+
+
+com.mysql.jdbc.testsuite.jvm.1=path_to_Java_7+com.mysql.jdbc.testsuite.jvm.2=path_to_Java_8+com.mysql.jdbc.testsuite.url.1=URL_to_1st_server+com.mysql.jdbc.testsuite.url.2=URL_to_2nd_server+com.mysql.jdbc.testsuite.url.3=URL_to_3rd_server
+
+ Unlike the target test, the target
+ test-multijvm only recognizes the
+ properties
+ com.mysql.jdbc.testsuite.jvm.
+ and
+ Ncom.mysql.jdbc.testsuite.url.,
+ where NN is a numeric suffice; the
+ same properties without the suffices are ignored by
+ test-multijvm. As with the target
+ test, if any of the
+ com.mysql.jdbc.testsuite.jvm.
+ settings points to Java 5, then Ant relies on the property
+ Ncom.mysql.jdbc.jdk8 to run the tests
+ specific to JDBC 4.0 and later.
+
+ You can choose to run individual test cases or specific
+ tests by using the test or
+ methods property, as explained in the
+ last bullet for the target test. Each
+ test is run once per possible combination of JVMs and
+ server instances (that is, 6 times in total for in this
+ example).
+
+ When a test for a certain JVM-server combination has
+ failed, test-multijvm does not throw an
+ error, but moves on to the next combination, until all
+ tests for all combinations are finished.
+
+
+ While the test results are partially reported by the console, + complete reports in HTML and XML formats are provided: + +
+ For results of test: view the HTML
+ report by opening
+ build/junit/unitregress/report/index.html.
+ XML version of the reports are located in the folder
+ build/junit/unitregress.
+
+ For results of test-multijvm: view the
+ HTML report for each JVM-server combination by opening
+ build/junit/MySQL.
+ XML version of the reports are located in the folder
+ N.server_version/operating_system_version/jvm-version/unitregress/report/index.htmlbuild/junit/MySQL.
+ N.server_version/operating_system_version/jvm-version/unitregress
+
+ Examples of using Connector/J are located throughout this + document. This section provides a summary and links to these + examples. +
+ Example 6.1, “Connector/J: Obtaining a connection from the
+ DriverManager”
+
+ Example 6.2, “Connector/J: Using java.sql.Statement to execute a
+ SELECT query”
+
+ Example 6.3, “Connector/J: Calling Stored Procedures” +
+ Example 6.4, “Connector/J: Using Connection.prepareCall()”
+
+ Example 6.5, “Connector/J: Registering output parameters” +
+ Example 6.6, “Connector/J: Setting CallableStatement input
+ parameters”
+
+ Example 6.7, “Connector/J: Retrieving results and output parameter values” +
+ Example 6.10, “Connector/J: Retrieving AUTO_INCREMENT column values
+ in Updatable ResultSets”
+
+ Example 7.1, “Connector/J: Using a connection pool with a J2EE application server” +
+ Example 15.1, “Connector/J: Example of transaction with retry logic” +
Table of Contents
+ This section of the manual contains reference material for MySQL + Connector/J. +
+ The name of the class that implements
+ java.sql.Driver in MySQL Connector/J is
+ com.mysql.jdbc.Driver. The
+ org.gjt.mm.mysql.Driver class name is also
+ usable for backward compatibility with MM.MySQL, the predecessor
+ of Connector/J. Use this class name when registering the driver,
+ or when configuring a software to use MySQL Connector/J.
+
+ The general format for a JDBC URL for connecting to a MySQL + server is as follows, with items in square brackets ([ ]) being + optional: +
+jdbc:mysql://[host1][:port1][,[host2][:port2]]...[/[database]] » +[?propertyName1=propertyValue1[&propertyName2=propertyValue2]...] +
+ Here is a simple example for a connection URL: +
+jdbc:mysql://localhost:3306/sakila?profileSQL=true +
+ Supply multiple hosts for a server failover setup (see + Chapter 8, Multi-Host Connections for + details): +
+# Connection URL for a server failover setup: +jdbc:mysql//primaryhost,secondaryhost1,secondaryhost2/test
+ There are specialized URL schemes for configuring Connector/J's + multi-host functions like load balancing and replication; here + are some examples (see + Chapter 8, Multi-Host Connections for + details): + +
+# Connection URL for load balancing: +jdbc:mysql:loadbalance://localhost:3306,localhost:3310/sakila + +# Connection URL for server replication: +jdbc:mysql:replication://master,slave1,slave2,slave3/test +
+
+ If no hosts are not specified, the host name defaults to
+ 127.0.0.1. If the port for a host is not
+ specified, it defaults to 3306, the default
+ port number for MySQL servers.
+
+ If the database is not specified, the connection is made with no
+ default database. In this case, either call the
+ setCatalog() method on the Connection
+ instance, or fully specify table names using the database name
+ (that is, SELECT
+ ) in your SQL. Opening a
+ connection without specifying the database to use is generally
+ only useful when building tools that work with multiple
+ databases, such as GUI database managers.
+ dbname.tablename.colname
+ FROM dbname.tablename...
+ Always use the Connection.setCatalog()
+ method to specify the desired database in JDBC applications,
+ rather than the USE
+ statement.
+ database
+ For IPv6 connections, use this alternative syntax to specify + hosts in the URL (the same syntax can also be used for IPv4 + connections): + +
+jdbc:mysql://address=(key1=value)[(key2=value)]...[,address=(key3=value)[(key4=value)]...]...[/[database]]» +[?propertyName1=propertyValue1[&propertyName2=propertyValue2]...] +
+ + Supported keys include: +
+ (protocol=tcp), or
+ (protocol=pipe) for named pipes on
+ Windows.
+
+ (path=
+ for named pipes.
+ path_to_pipe)
+ (host=
+ for TCP connections.
+ hostname)
+ (port=
+ for TCP connections.
+ port_number)
+ For example: +
+jdbc:mysql://address=(protocol=tcp)(host=localhost)(port=3306)/db +
+ Keys other than the four mentioned above are treated as + host-specific configuration properties, which allow per-host + overrides of any configuration property set for multi-host + connections (that is, when using failover, load balancing, or + replication). For example: + +
+# IPv6 Connection URL for a server failover setup: +jdbc:mysql//address=(protocol=tcp)(host=primaryhost)(port=3306),» +address=(protocol=tcp)(host=secondaryhost1)(port=3310)(user=test2)/test + +# IPv6 Connection URL for load balancing: +jdbc:mysql:loadbalance://address=(protocol=tcp)(host=localhost)(port=3306)(user=test1),» +address=(protocol=tcp)(host=localhost)(port=3310)(user=test2)/sakila + +# IPv6 Connection URL for server replication: +jdbc:mysql:replication://address=(protocol=tcp)(host=master)(port=3306)(user=test1),» +address=(protocol=tcp)(host=slave1)(port=3310)(user=test2)/test +
+ + Limit the overrides to user, password, network timeouts, and + statement and metadata cache sizes; the effects of other + per-host overrides are not defined. +
+ The ways to set the other configuration properties are the same + for IPv6 and IPv4 URLs; see + Setting Configuration Properties. +
+ Configuration properties define how Connector/J will make a
+ connection to a MySQL server. Unless otherwise noted, properties
+ can be set for a DataSource object or for a
+ Connection object.
+
+ Configuration properties can be set in one of the following + ways: +
+ Using the set*() methods on MySQL
+ implementations of java.sql.DataSource
+ (which is the preferred method when using implementations of
+ java.sql.DataSource):
+
+ com.mysql.jdbc.jdbc2.optional.MysqlDataSource
+
+ com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource
+
+ As a key/value pair in the
+ java.util.Properties instance passed to
+ DriverManager.getConnection() or
+ Driver.connect()
+
+ As a JDBC URL parameter in the URL given to
+ java.sql.DriverManager.getConnection(),
+ java.sql.Driver.connect() or the MySQL
+ implementations of the
+ javax.sql.DataSource
+ setURL() method. If you specify a
+ configuration property in the URL without providing a value
+ for it, nothing will be set; for example, adding
+ useServerPrepStmts alone to the URL does
+ not make Connector/J use server-side prepared statements;
+ you need to add useServerPrepStmts=true.
+
+ If the mechanism you use to configure a JDBC URL is
+ XML-based, use the XML character literal
+ & to separate configuration
+ parameters, as the ampersand is a reserved character for
+ XML.
+
+ The properties are listed in the following tables. +
Connection/Authentication. +
| Properties and Descriptions |
|---|
+ user + + + + ++ The user to connect as + + + + ++ Since version: all versions + |
+ password + + + + ++ The password to use when connecting + + + + ++ Since version: all versions + |
+ socketFactory + + + + ++ The name of the class that the driver should use for + creating socket connections to the server. This class + must implement the interface + 'com.mysql.jdbc.SocketFactory' and have public no-args + constructor. + + + + ++ Default: com.mysql.jdbc.StandardSocketFactory + + + + ++ Since version: 3.0.3 + |
+ connectTimeout + + + + ++ Timeout for socket connect (in milliseconds), with 0 + being no timeout. Only works on JDK-1.4 or newer. + Defaults to '0'. + + + + ++ Default: 0 + + + + ++ Since version: 3.0.1 + |
+ socketTimeout + + + + ++ Timeout on network socket operations (0, the default + means no timeout). + + + + ++ Default: 0 + + + + ++ Since version: 3.0.1 + |
+ connectionLifecycleInterceptors + + + + ++ A comma-delimited list of classes that implement + "com.mysql.jdbc.ConnectionLifecycleInterceptor" that + should notified of connection lifecycle events + (creation, destruction, commit, rollback, setCatalog + and setAutoCommit) and potentially alter the execution + of these commands. ConnectionLifecycleInterceptors are + "stackable", more than one interceptor may be + specified via the configuration property as a + comma-delimited list, with the interceptors executed + in order from left to right. + + + + ++ Since version: 5.1.4 + |
+ useConfigs + + + + ++ Load the comma-delimited list of configuration + properties before parsing the URL or applying + user-specified properties. These configurations are + explained in the 'Configurations' of the + documentation. + + + + ++ Since version: 3.1.5 + |
+ authenticationPlugins + + + + ++ Comma-delimited list of classes that implement + com.mysql.jdbc.AuthenticationPlugin and which will be + used for authentication unless disabled by + "disabledAuthenticationPlugins" property. + + + + ++ Since version: 5.1.19 + |
+ defaultAuthenticationPlugin + + + + ++ Name of a class implementing + com.mysql.jdbc.AuthenticationPlugin which will be used + as the default authentication plugin (see below). It + is an error to use a class which is not listed in + "authenticationPlugins" nor it is one of the built-in + plugins. It is an error to set as default a plugin + which was disabled with + "disabledAuthenticationPlugins" property. It is an + error to set this value to null or the empty string + (i.e. there must be at least a valid default + authentication plugin specified for the connection, + meeting all constraints listed above). + + + + ++ Default: + com.mysql.jdbc.authentication.MysqlNativePasswordPlugin + + + + ++ Since version: 5.1.19 + |
+ disabledAuthenticationPlugins + + + + ++ Comma-delimited list of classes implementing + com.mysql.jdbc.AuthenticationPlugin or mechanisms, + i.e. "mysql_native_password". The authentication + plugins or mechanisms listed will not be used for + authentication which will fail if it requires one of + them. It is an error to disable the default + authentication plugin (either the one named by + "defaultAuthenticationPlugin" property or the + hard-coded one if "defaultAuthenticationPlugin" + property is not set). + + + + ++ Since version: 5.1.19 + |
+ disconnectOnExpiredPasswords + + + + ++ If "disconnectOnExpiredPasswords" is set to "false" + and password is expired then server enters "sandbox" + mode and sends ERR(08001, ER_MUST_CHANGE_PASSWORD) for + all commands that are not needed to set a new password + until a new password is set. + + + + ++ Default: true + + + + ++ Since version: 5.1.23 + |
+ interactiveClient + + + + ++ Set the CLIENT_INTERACTIVE flag, which tells MySQL to + timeout connections based on INTERACTIVE_TIMEOUT + instead of WAIT_TIMEOUT + + + + ++ Default: false + + + + ++ Since version: 3.1.0 + |
+ localSocketAddress + + + + ++ Hostname or IP address given to explicitly configure + the interface that the driver will bind the client + side of the TCP/IP connection to when connecting. + + + + ++ Since version: 5.0.5 + |
+ propertiesTransform + + + + ++ An implementation of + com.mysql.jdbc.ConnectionPropertiesTransform that the + driver will use to modify URL properties passed to the + driver before attempting a connection + + + + ++ Since version: 3.1.4 + |
+ useCompression + + + + ++ Use zlib compression when communicating with the + server (true/false)? Defaults to 'false'. + + + + ++ Default: false + + + + ++ Since version: 3.0.17 + |
+
Networking. +
| Properties and Descriptions |
|---|
+ socksProxyHost + + + + ++ Name or IP address of SOCKS host to connect through. + + + + ++ Since version: 5.1.34 + |
+ socksProxyPort + + + + ++ Port of SOCKS server. + + + + ++ Default: 1080 + + + + ++ Since version: 5.1.34 + |
+ maxAllowedPacket + + + + ++ Maximum allowed packet size to send to server. If not + set, the value of system variable 'max_allowed_packet' + will be used to initialize this upon connecting. This + value will not take effect if set larger than the + value of 'max_allowed_packet'. Also, due to an + internal dependency with the property + "blobSendChunkSize", this setting has a minimum value + of "8203" if "useServerPrepStmts" is set to "true". + + + + ++ Default: -1 + + + + ++ Since version: 5.1.8 + |
+ tcpKeepAlive + + + + ++ If connecting using TCP/IP, should the driver set + SO_KEEPALIVE? + + + + ++ Default: true + + + + ++ Since version: 5.0.7 + |
+ tcpNoDelay + + + + ++ If connecting using TCP/IP, should the driver set + SO_TCP_NODELAY (disabling the Nagle Algorithm)? + + + + ++ Default: true + + + + ++ Since version: 5.0.7 + |
+ tcpRcvBuf + + + + ++ If connecting using TCP/IP, should the driver set + SO_RCV_BUF to the given value? The default value of + '0', means use the platform default value for this + property) + + + + ++ Default: 0 + + + + ++ Since version: 5.0.7 + |
+ tcpSndBuf + + + + ++ If connecting using TCP/IP, should the driver set + SO_SND_BUF to the given value? The default value of + '0', means use the platform default value for this + property) + + + + ++ Default: 0 + + + + ++ Since version: 5.0.7 + |
+ tcpTrafficClass + + + + ++ If connecting using TCP/IP, should the driver set + traffic class or type-of-service fields ?See the + documentation for java.net.Socket.setTrafficClass() + for more information. + + + + ++ Default: 0 + + + + ++ Since version: 5.0.7 + |
+
High Availability and Clustering. +
| Properties and Descriptions |
|---|
+ autoReconnect + + + + ++ Should the driver try to re-establish stale and/or + dead connections? If enabled the driver will throw an + exception for a queries issued on a stale or dead + connection, which belong to the current transaction, + but will attempt reconnect before the next query + issued on the connection in a new transaction. The use + of this feature is not recommended, because it has + side effects related to session state and data + consistency when applications don't handle + SQLExceptions properly, and is only designed to be + used when you are unable to configure your application + to handle SQLExceptions resulting from dead and stale + connections properly. Alternatively, as a last option, + investigate setting the MySQL server variable + "wait_timeout" to a high value, rather than the + default of 8 hours. + + + + ++ Default: false + + + + ++ Since version: 1.1 + |
+ autoReconnectForPools + + + + ++ Use a reconnection strategy appropriate for connection + pools (defaults to 'false') + + + + ++ Default: false + + + + ++ Since version: 3.1.3 + |
+ failOverReadOnly + + + + ++ When failing over in autoReconnect mode, should the + connection be set to 'read-only'? + + + + ++ Default: true + + + + ++ Since version: 3.0.12 + |
+ maxReconnects + + + + ++ Maximum number of reconnects to attempt if + autoReconnect is true, default is '3'. + + + + ++ Default: 3 + + + + ++ Since version: 1.1 + |
+ reconnectAtTxEnd + + + + ++ If autoReconnect is set to true, should the driver + attempt reconnections at the end of every transaction? + + + + ++ Default: false + + + + ++ Since version: 3.0.10 + |
+ retriesAllDown + + + + ++ When using loadbalancing or failover, the number of + times the driver should cycle through available hosts, + attempting to connect. Between cycles, the driver will + pause for 250ms if no servers are available. + + + + ++ Default: 120 + + + + ++ Since version: 5.1.6 + |
+ initialTimeout + + + + ++ If autoReconnect is enabled, the initial time to wait + between re-connect attempts (in seconds, defaults to + '2'). + + + + ++ Default: 2 + + + + ++ Since version: 1.1 + |
+ roundRobinLoadBalance + + + + ++ When autoReconnect is enabled, and failoverReadonly is + false, should we pick hosts to connect to on a + round-robin basis? + + + + ++ Default: false + + + + ++ Since version: 3.1.2 + |
+ queriesBeforeRetryMaster + + + + ++ Number of queries to issue before falling back to the + primary host when failed over (when using multi-host + failover). Whichever condition is met first, + 'queriesBeforeRetryMaster' or + 'secondsBeforeRetryMaster' will cause an attempt to be + made to reconnect to the primary host. Setting both + properties to 0 disables the automatic fall back to + the primary host at transaction boundaries. Defaults + to 50. + + + + ++ Default: 50 + + + + ++ Since version: 3.0.2 + |
+ secondsBeforeRetryMaster + + + + ++ How long should the driver wait, when failed over, + before attempting to reconnect to the primary host? + Whichever condition is met first, + 'queriesBeforeRetryMaster' or + 'secondsBeforeRetryMaster' will cause an attempt to be + made to reconnect to the master. Setting both + properties to 0 disables the automatic fall back to + the primary host at transaction boundaries. Time in + seconds, defaults to 30 + + + + ++ Default: 30 + + + + ++ Since version: 3.0.2 + |
+ allowMasterDownConnections + + + + ++ By default, a replication-aware connection will fail + to connect when configured master hosts are all + unavailable at initial connection. Setting this + property to 'true' allows to establish the initial + connection, by failing over to the slave servers, in + read-only state. It won't prevent subsequent failures + when switching back to the master hosts i.e. by + setting the replication connection to read/write + state. + + + + ++ Default: false + + + + ++ Since version: 5.1.27 + |
+ allowSlaveDownConnections + + + + ++ By default, a replication-aware connection will fail + to connect when configured slave hosts are all + unavailable at initial connection. Setting this + property to 'true' allows to establish the initial + connection. It won't prevent failures when switching + to slaves i.e. by setting the replication connection + to read-only state. The property + 'readFromMasterWhenNoSlaves' should be used for this + purpose. + + + + ++ Default: false + + + + ++ Since version: 5.1.38 + |
+ readFromMasterWhenNoSlaves + + + + ++ Replication-aware connections distribute load by using + the master hosts when in read/write state and by using + the slave hosts when in read-only state. If, when + setting the connection to read-only state, none of the + slave hosts are available, an SQLExeception is thrown + back. Setting this property to 'true' allows to fail + over to the master hosts, while setting the connection + state to read-only, when no slave hosts are available + at switch instant. + + + + ++ Default: false + + + + ++ Since version: 5.1.38 + |
+ replicationEnableJMX + + + + ++ Enables JMX-based management of load-balanced + connection groups, including live addition/removal of + hosts from load-balancing pool. + + + + ++ Default: false + + + + ++ Since version: 5.1.27 + |
+ selfDestructOnPingMaxOperations + + + + ++ =If set to a non-zero value, the driver will report + close the connection and report failure when + Connection.ping() or Connection.isValid(int) is called + if the connection's count of commands sent to the + server exceeds this value. + + + + ++ Default: 0 + + + + ++ Since version: 5.1.6 + |
+ selfDestructOnPingSecondsLifetime + + + + ++ If set to a non-zero value, the driver will report + close the connection and report failure when + Connection.ping() or Connection.isValid(int) is called + if the connection's lifetime exceeds this value. + + + + ++ Default: 0 + + + + ++ Since version: 5.1.6 + |
+ resourceId + + + + ++ A globally unique name that identifies the resource + that this datasource or connection is connected to, + used for XAResource.isSameRM() when the driver can't + determine this value based on hostnames used in the + URL + + + + ++ Since version: 5.0.1 + |
+
Security. +
| Properties and Descriptions |
|---|
+ allowMultiQueries + + + + ++ Allow the use of ';' to delimit multiple queries + during one statement (true/false), defaults to + 'false', and does not affect the addBatch() and + executeBatch() methods, which instead rely on + rewriteBatchStatements. + + + + ++ Default: false + + + + ++ Since version: 3.1.1 + |
+ useSSL + + + + ++ Use SSL when communicating with the server + (true/false), default is 'true' when connecting to + MySQL 5.5.45+, 5.6.26+ or 5.7.6+, otherwise default is + 'false' + + + + ++ Default: false + + + + ++ Since version: 3.0.2 + |
+ requireSSL + + + + ++ Require server support of SSL connection if + useSSL=true? (defaults to 'false'). + + + + ++ Default: false + + + + ++ Since version: 3.1.0 + |
+ verifyServerCertificate + + + + ++ If "useSSL" is set to "true", should the driver verify + the server's certificate? When using this feature, the + keystore parameters should be specified by the + "clientCertificateKeyStore*" properties, rather than + system properties. Default is 'false' when connecting + to MySQL 5.5.45+, 5.6.26+ or 5.7.6+ and "useSSL" was + not explicitly set to "true". Otherwise default is + 'true' + + + + ++ Default: true + + + + ++ Since version: 5.1.6 + |
+ clientCertificateKeyStoreUrl + + + + ++ URL to the client certificate KeyStore (if not + specified, use defaults) + + + + ++ Since version: 5.1.0 + |
+ clientCertificateKeyStoreType + + + + ++ KeyStore type for client certificates (NULL or empty + means use the default, which is "JKS". Standard + keystore types supported by the JVM are "JKS" and + "PKCS12", your environment may have more available + depending on what security products are installed and + available to the JVM. + + + + ++ Default: JKS + + + + ++ Since version: 5.1.0 + |
+ clientCertificateKeyStorePassword + + + + ++ Password for the client certificates KeyStore + + + + ++ Since version: 5.1.0 + |
+ trustCertificateKeyStoreUrl + + + + ++ URL to the trusted root certificate KeyStore (if not + specified, use defaults) + + + + ++ Since version: 5.1.0 + |
+ trustCertificateKeyStoreType + + + + ++ KeyStore type for trusted root certificates (NULL or + empty means use the default, which is "JKS". Standard + keystore types supported by the JVM are "JKS" and + "PKCS12", your environment may have more available + depending on what security products are installed and + available to the JVM. + + + + ++ Default: JKS + + + + ++ Since version: 5.1.0 + |
+ trustCertificateKeyStorePassword + + + + ++ Password for the trusted root certificates KeyStore + + + + ++ Since version: 5.1.0 + |
+ enabledSSLCipherSuites + + + + ++ If "useSSL" is set to "true", overrides the cipher + suites enabled for use on the underlying SSL sockets. + This may be required when using external JSSE + providers or to specify cipher suites compatible with + both MySQL server and used JVM. + + + + ++ Since version: 5.1.35 + |
+ allowLoadLocalInfile + + + + ++ Should the driver allow use of 'LOAD DATA LOCAL + INFILE...' (defaults to 'true'). + + + + ++ Default: true + + + + ++ Since version: 3.0.3 + |
+ allowUrlInLocalInfile + + + + ++ Should the driver allow URLs in 'LOAD DATA LOCAL + INFILE' statements? + + + + ++ Default: false + + + + ++ Since version: 3.1.4 + |
+ allowPublicKeyRetrieval + + + + ++ Allows special handshake roundtrip to get server RSA + public key directly from server. + + + + ++ Default: false + + + + ++ Since version: 5.1.31 + |
+ paranoid + + + + ++ Take measures to prevent exposure sensitive + information in error messages and clear data + structures holding sensitive data when possible? + (defaults to 'false') + + + + ++ Default: false + + + + ++ Since version: 3.0.1 + |
+ passwordCharacterEncoding + + + + ++ What character encoding is used for passwords? Leaving + this set to the default value (null), uses the value + set in "characterEncoding" if there is one, otherwise + uses UTF-8 as default encoding. If the password + contains non-ASCII characters, the password encoding + must match what server encoding was set to when the + password was created. For passwords in other character + encodings, the encoding will have to be specified with + this property (or with "characterEncoding"), as it's + not possible for the driver to auto-detect this. + + + + ++ Since version: 5.1.7 + |
+ serverRSAPublicKeyFile + + + + ++ File path to the server RSA public key file for + sha256_password authentication. If not specified, the + public key will be retrieved from the server. + + + + ++ Since version: 5.1.31 + |
+
Performance Extensions. +
| Properties and Descriptions |
|---|
+ callableStmtCacheSize + + + + ++ If 'cacheCallableStmts' is enabled, how many callable + statements should be cached? + + + + ++ Default: 100 + + + + ++ Since version: 3.1.2 + |
+ metadataCacheSize + + + + ++ The number of queries to cache ResultSetMetadata for + if cacheResultSetMetaData is set to 'true' (default + 50) + + + + ++ Default: 50 + + + + ++ Since version: 3.1.1 + |
+ useLocalSessionState + + + + ++ Should the driver refer to the internal values of + autocommit and transaction isolation that are set by + Connection.setAutoCommit() and + Connection.setTransactionIsolation() and transaction + state as maintained by the protocol, rather than + querying the database or blindly sending commands to + the database for commit() or rollback() method calls? + + + + ++ Default: false + + + + ++ Since version: 3.1.7 + |
+ useLocalTransactionState + + + + ++ Should the driver use the in-transaction state + provided by the MySQL protocol to determine if a + commit() or rollback() should actually be sent to the + database? + + + + ++ Default: false + + + + ++ Since version: 5.1.7 + |
+ prepStmtCacheSize + + + + ++ If prepared statement caching is enabled, how many + prepared statements should be cached? + + + + ++ Default: 25 + + + + ++ Since version: 3.0.10 + |
+ prepStmtCacheSqlLimit + + + + ++ If prepared statement caching is enabled, what's the + largest SQL the driver will cache the parsing for? + + + + ++ Default: 256 + + + + ++ Since version: 3.0.10 + |
+ parseInfoCacheFactory + + + + ++ Name of a class implementing + com.mysql.jdbc.CacheAdapterFactory, which will be used + to create caches for the parsed representation of + client-side prepared statements. + + + + ++ Default: com.mysql.jdbc.PerConnectionLRUFactory + + + + ++ Since version: 5.1.1 + |
+ serverConfigCacheFactory + + + + ++ Name of a class implementing + com.mysql.jdbc.CacheAdapterFactory<String, + Map<String, String>>, which will be used to + create caches for MySQL server configuration values + + + + ++ Default: com.mysql.jdbc.PerVmServerConfigCacheFactory + + + + ++ Since version: 5.1.1 + |
+ alwaysSendSetIsolation + + + + ++ Should the driver always communicate with the database + when Connection.setTransactionIsolation() is called? + If set to false, the driver will only communicate with + the database when the requested transaction isolation + is different than the whichever is newer, the last + value that was set via + Connection.setTransactionIsolation(), or the value + that was read from the server when the connection was + established. Note that useLocalSessionState=true will + force the same behavior as + alwaysSendSetIsolation=false, regardless of how + alwaysSendSetIsolation is set. + + + + ++ Default: true + + + + ++ Since version: 3.1.7 + |
+ maintainTimeStats + + + + ++ Should the driver maintain various internal timers to + enable idle time calculations as well as more verbose + error messages when the connection to the server + fails? Setting this property to false removes at least + two calls to System.getCurrentTimeMillis() per query. + + + + ++ Default: true + + + + ++ Since version: 3.1.9 + |
+ useCursorFetch + + + + ++ If connected to MySQL > 5.0.2, and setFetchSize() + > 0 on a statement, should that statement use + cursor-based fetching to retrieve rows? + + + + ++ Default: false + + + + ++ Since version: 5.0.0 + |
+ blobSendChunkSize + + + + ++ Chunk size to use when sending BLOB/CLOBs via + ServerPreparedStatements. Note that this value cannot + exceed the value of "maxAllowedPacket" and, if that is + the case, then this value will be corrected + automatically. + + + + ++ Default: 1048576 + + + + ++ Since version: 3.1.9 + |
+ cacheCallableStmts + + + + ++ Should the driver cache the parsing stage of + CallableStatements + + + + ++ Default: false + + + + ++ Since version: 3.1.2 + |
+ cachePrepStmts + + + + ++ Should the driver cache the parsing stage of + PreparedStatements of client-side prepared statements, + the "check" for suitability of server-side prepared + and server-side prepared statements themselves? + + + + ++ Default: false + + + + ++ Since version: 3.0.10 + |
+ cacheResultSetMetadata + + + + ++ Should the driver cache ResultSetMetaData for + Statements and PreparedStatements? (Req. JDK-1.4+, + true/false, default 'false') + + + + ++ Default: false + + + + ++ Since version: 3.1.1 + |
+ cacheServerConfiguration + + + + ++ Should the driver cache the results of 'SHOW + VARIABLES' and 'SHOW COLLATION' on a per-URL basis? + + + + ++ Default: false + + + + ++ Since version: 3.1.5 + |
+ defaultFetchSize + + + + ++ The driver will call setFetchSize(n) with this value + on all newly-created Statements + + + + ++ Default: 0 + + + + ++ Since version: 3.1.9 + |
+ dontCheckOnDuplicateKeyUpdateInSQL + + + + ++ Stops checking if every INSERT statement contains the + "ON DUPLICATE KEY UPDATE" clause. As a side effect, + obtaining the statement's generated keys information + will return a list where normally it wouldn't. Also be + aware that, in this case, the list of generated keys + returned may not be accurate. The effect of this + property is canceled if set simultaneously with + 'rewriteBatchedStatements=true'. + + + + ++ Default: false + + + + ++ Since version: 5.1.32 + |
+ dontTrackOpenResources + + + + ++ The JDBC specification requires the driver to + automatically track and close resources, however if + your application doesn't do a good job of explicitly + calling close() on statements or result sets, this can + cause memory leakage. Setting this property to true + relaxes this constraint, and can be more memory + efficient for some applications. Also the automatic + closing of the Statement and current ResultSet in + Statement.closeOnCompletion() and + Statement.getMoreResults + ([Statement.CLOSE_CURRENT_RESULT | + Statement.CLOSE_ALL_RESULTS]), respectively, ceases to + happen. This property automatically sets + holdResultsOpenOverStatementClose=true. + + + + ++ Default: false + + + + ++ Since version: 3.1.7 + |
+ dynamicCalendars + + + + ++ Should the driver retrieve the default calendar when + required, or cache it per connection/session? + + + + ++ Default: false + + + + ++ Since version: 3.1.5 + |
+ elideSetAutoCommits + + + + ++ If using MySQL-4.1 or newer, should the driver only + issue 'set autocommit=n' queries when the server's + state doesn't match the requested state by + Connection.setAutoCommit(boolean)? + + + + ++ Default: false + + + + ++ Since version: 3.1.3 + |
+ enableEscapeProcessing + + + + ++ Sets the default escape processing behavior for + Statement objects. The method + Statement.setEscapeProcessing() can be used to specify + the escape processing behavior for an individual + Statement object. Default escape processing behavior + in prepared statements must be defined with the + property 'processEscapeCodesForPrepStmts'. + + + + ++ Default: true + + + + ++ Since version: 5.1.37 + |
+ enableQueryTimeouts + + + + ++ When enabled, query timeouts set via + Statement.setQueryTimeout() use a shared + java.util.Timer instance for scheduling. Even if the + timeout doesn't expire before the query is processed, + there will be memory used by the TimerTask for the + given timeout which won't be reclaimed until the time + the timeout would have expired if it hadn't been + cancelled by the driver. High-load environments might + want to consider disabling this functionality. + + + + ++ Default: true + + + + ++ Since version: 5.0.6 + |
+ holdResultsOpenOverStatementClose + + + + ++ Should the driver close result sets on + Statement.close() as required by the JDBC + specification? + + + + ++ Default: false + + + + ++ Since version: 3.1.7 + |
+ largeRowSizeThreshold + + + + ++ What size result set row should the JDBC driver + consider "large", and thus use a more memory-efficient + way of representing the row internally? + + + + ++ Default: 2048 + + + + ++ Since version: 5.1.1 + |
+ loadBalanceStrategy + + + + ++ If using a load-balanced connection to connect to SQL + nodes in a MySQL Cluster/NDB configuration (by using + the URL prefix "jdbc:mysql:loadbalance://"), which + load balancing algorithm should the driver use: (1) + "random" - the driver will pick a random host for each + request. This tends to work better than round-robin, + as the randomness will somewhat account for spreading + loads where requests vary in response time, while + round-robin can sometimes lead to overloaded nodes if + there are variations in response times across the + workload. (2) "bestResponseTime" - the driver will + route the request to the host that had the best + response time for the previous transaction. + + + + ++ Default: random + + + + ++ Since version: 5.0.6 + |
+ locatorFetchBufferSize + + + + ++ If 'emulateLocators' is configured to 'true', what + size buffer should be used when fetching BLOB data for + getBinaryInputStream? + + + + ++ Default: 1048576 + + + + ++ Since version: 3.2.1 + |
+ readOnlyPropagatesToServer + + + + ++ Should the driver issue appropriate statements to + implicitly set the transaction access mode on server + side when Connection.setReadOnly() is called? Setting + this property to 'true' enables InnoDB read-only + potential optimizations but also requires an extra + roundtrip to set the right transaction state. Even if + this property is set to 'false', the driver will do + its best effort to prevent the execution of + database-state-changing queries. Requires minimum of + MySQL 5.6. + + + + ++ Default: true + + + + ++ Since version: 5.1.35 + |
+ rewriteBatchedStatements + + + + ++ Should the driver use multiqueries (irregardless of + the setting of "allowMultiQueries") as well as + rewriting of prepared statements for INSERT into + multi-value inserts when executeBatch() is called? + Notice that this has the potential for SQL injection + if using plain java.sql.Statements and your code + doesn't sanitize input correctly. Notice that for + prepared statements, server-side prepared statements + can not currently take advantage of this rewrite + option, and that if you don't specify stream lengths + when using PreparedStatement.set*Stream(), the driver + won't be able to determine the optimum number of + parameters per batch and you might receive an error + from the driver that the resultant packet is too + large. Statement.getGeneratedKeys() for these + rewritten statements only works when the entire batch + includes INSERT statements. Please be aware using + rewriteBatchedStatements=true with INSERT .. ON + DUPLICATE KEY UPDATE that for rewritten statement + server returns only one value as sum of all affected + (or found) rows in batch and it isn't possible to map + it correctly to initial statements; in this case + driver returns 0 as a result of each batch statement + if total count was 0, and the + Statement.SUCCESS_NO_INFO as a result of each batch + statement if total count was > 0. + + + + ++ Default: false + + + + ++ Since version: 3.1.13 + |
+ useDirectRowUnpack + + + + ++ Use newer result set row unpacking code that skips a + copy from network buffers to a MySQL packet instance + and instead reads directly into the result set row + data buffers. + + + + ++ Default: true + + + + ++ Since version: 5.1.1 + |
+ useDynamicCharsetInfo + + + + ++ Should the driver use a per-connection cache of + character set information queried from the server when + necessary, or use a built-in static mapping that is + more efficient, but isn't aware of custom character + sets or character sets implemented after the release + of the JDBC driver? + + + + ++ Default: true + + + + ++ Since version: 5.0.6 + |
+ useFastDateParsing + + + + ++ Use internal String->Date/Time/Timestamp conversion + routines to avoid excessive object creation? This is + part of the legacy date-time code, thus the property + has an effect only when "useLegacyDatetimeCode=true." + + + + ++ Default: true + + + + ++ Since version: 5.0.5 + |
+ useFastIntParsing + + + + ++ Use internal String->Integer conversion routines to + avoid excessive object creation? + + + + ++ Default: true + + + + ++ Since version: 3.1.4 + |
+ useJvmCharsetConverters + + + + ++ Always use the character encoding routines built into + the JVM, rather than using lookup tables for + single-byte character sets? + + + + ++ Default: false + + + + ++ Since version: 5.0.1 + |
+ useReadAheadInput + + + + ++ Use newer, optimized non-blocking, buffered input + stream when reading from the server? + + + + ++ Default: true + + + + ++ Since version: 3.1.5 + |
+
Debugging/Profiling. +
| Properties and Descriptions |
|---|
+ logger + + + + ++ The name of a class that implements + "com.mysql.jdbc.log.Log" that will be used to log + messages to. (default is + "com.mysql.jdbc.log.StandardLogger", which logs to + STDERR) + + + + ++ Default: com.mysql.jdbc.log.StandardLogger + + + + ++ Since version: 3.1.1 + |
+ gatherPerfMetrics + + + + ++ Should the driver gather performance metrics, and + report them via the configured logger every + 'reportMetricsIntervalMillis' milliseconds? + + + + ++ Default: false + + + + ++ Since version: 3.1.2 + |
+ profileSQL + + + + ++ Trace queries and their execution/fetch times to the + configured logger (true/false) defaults to 'false' + + + + ++ Default: false + + + + ++ Since version: 3.1.0 + |
+ profileSql + + + + ++ Deprecated, use 'profileSQL' instead. Trace queries + and their execution/fetch times on STDERR (true/false) + defaults to 'false' + + + + ++ Since version: 2.0.14 + |
+ reportMetricsIntervalMillis + + + + ++ If 'gatherPerfMetrics' is enabled, how often should + they be logged (in ms)? + + + + ++ Default: 30000 + + + + ++ Since version: 3.1.2 + |
+ maxQuerySizeToLog + + + + ++ Controls the maximum length/size of a query that will + get logged when profiling or tracing + + + + ++ Default: 2048 + + + + ++ Since version: 3.1.3 + |
+ packetDebugBufferSize + + + + ++ The maximum number of packets to retain when + 'enablePacketDebug' is true + + + + ++ Default: 20 + + + + ++ Since version: 3.1.3 + |
+ slowQueryThresholdMillis + + + + ++ If 'logSlowQueries' is enabled, how long should a + query (in ms) before it is logged as 'slow'? + + + + ++ Default: 2000 + + + + ++ Since version: 3.1.2 + |
+ slowQueryThresholdNanos + + + + ++ If 'useNanosForElapsedTime' is set to true, and this + property is set to a non-zero value, the driver will + use this threshold (in nanosecond units) to determine + if a query was slow. + + + + ++ Default: 0 + + + + ++ Since version: 5.0.7 + |
+ useUsageAdvisor + + + + ++ Should the driver issue 'usage' warnings advising + proper and efficient usage of JDBC and MySQL + Connector/J to the log (true/false, defaults to + 'false')? + + + + ++ Default: false + + + + ++ Since version: 3.1.1 + |
+ autoGenerateTestcaseScript + + + + ++ Should the driver dump the SQL it is executing, + including server-side prepared statements to STDERR? + + + + ++ Default: false + + + + ++ Since version: 3.1.9 + |
+ autoSlowLog + + + + ++ Instead of using slowQueryThreshold* to determine if a + query is slow enough to be logged, maintain statistics + that allow the driver to determine queries that are + outside the 99th percentile? + + + + ++ Default: true + + + + ++ Since version: 5.1.4 + |
+ clientInfoProvider + + + + ++ The name of a class that implements the + com.mysql.jdbc.JDBC4ClientInfoProvider interface in + order to support JDBC-4.0's + Connection.get/setClientInfo() methods + + + + ++ Default: com.mysql.jdbc.JDBC4CommentClientInfoProvider + + + + ++ Since version: 5.1.0 + |
+ dumpMetadataOnColumnNotFound + + + + ++ Should the driver dump the field-level metadata of a + result set into the exception message when + ResultSet.findColumn() fails? + + + + ++ Default: false + + + + ++ Since version: 3.1.13 + |
+ dumpQueriesOnException + + + + ++ Should the driver dump the contents of the query sent + to the server in the message for SQLExceptions? + + + + ++ Default: false + + + + ++ Since version: 3.1.3 + |
+ enablePacketDebug + + + + ++ When enabled, a ring-buffer of 'packetDebugBufferSize' + packets will be kept, and dumped when exceptions are + thrown in key areas in the driver's code + + + + ++ Default: false + + + + ++ Since version: 3.1.3 + |
+ explainSlowQueries + + + + ++ If 'logSlowQueries' is enabled, should the driver + automatically issue an 'EXPLAIN' on the server and + send the results to the configured log at a WARN + level? + + + + ++ Default: false + + + + ++ Since version: 3.1.2 + |
+ includeInnodbStatusInDeadlockExceptions + + + + ++ Include the output of "SHOW ENGINE INNODB STATUS" in + exception messages when deadlock exceptions are + detected? + + + + ++ Default: false + + + + ++ Since version: 5.0.7 + |
+ includeThreadDumpInDeadlockExceptions + + + + ++ Include a current Java thread dump in exception + messages when deadlock exceptions are detected? + + + + ++ Default: false + + + + ++ Since version: 5.1.15 + |
+ includeThreadNamesAsStatementComment + + + + ++ Include the name of the current thread as a comment + visible in "SHOW PROCESSLIST", or in Innodb deadlock + dumps, useful in correlation with + "includeInnodbStatusInDeadlockExceptions=true" and + "includeThreadDumpInDeadlockExceptions=true". + + + + ++ Default: false + + + + ++ Since version: 5.1.15 + |
+ logSlowQueries + + + + ++ Should queries that take longer than + 'slowQueryThresholdMillis' be logged? + + + + ++ Default: false + + + + ++ Since version: 3.1.2 + |
+ logXaCommands + + + + ++ Should the driver log XA commands sent by + MysqlXaConnection to the server, at the DEBUG level of + logging? + + + + ++ Default: false + + + + ++ Since version: 5.0.5 + |
+ profilerEventHandler + + + + ++ Name of a class that implements the interface + com.mysql.jdbc.profiler.ProfilerEventHandler that will + be used to handle profiling/tracing events. + + + + ++ Default: + com.mysql.jdbc.profiler.LoggingProfilerEventHandler + + + + ++ Since version: 5.1.6 + |
+ resultSetSizeThreshold + + + + ++ If the usage advisor is enabled, how many rows should + a result set contain before the driver warns that it + is suspiciously large? + + + + ++ Default: 100 + + + + ++ Since version: 5.0.5 + |
+ traceProtocol + + + + ++ Should trace-level network protocol be logged? + + + + ++ Default: false + + + + ++ Since version: 3.1.2 + |
+ useNanosForElapsedTime + + + + ++ For profiling/debugging functionality that measures + elapsed time, should the driver try to use nanoseconds + resolution if available (JDK >= 1.5)? + + + + ++ Default: false + + + + ++ Since version: 5.0.7 + |
+
Miscellaneous. +
| Properties and Descriptions |
|---|
+ useUnicode + + + + ++ Should the driver use Unicode character encodings when + handling strings? Should only be used when the driver + can't determine the character set mapping, or you are + trying to 'force' the driver to use a character set + that MySQL either doesn't natively support (such as + UTF-8), true/false, defaults to 'true' + + + + ++ Default: true + + + + ++ Since version: 1.1g + |
+ characterEncoding + + + + ++ If 'useUnicode' is set to true, what character + encoding should the driver use when dealing with + strings? (defaults is to 'autodetect') + + + + ++ Since version: 1.1g + |
+ characterSetResults + + + + ++ Character set to tell the server to return results as. + + + + ++ Since version: 3.0.13 + |
+ connectionAttributes + + + + ++ A comma-delimited list of user-defined key:value pairs + (in addition to standard MySQL-defined key:value + pairs) to be passed to MySQL Server for display as + connection attributes in the + PERFORMANCE_SCHEMA.SESSION_CONNECT_ATTRS table. + Example usage: + connectionAttributes=key1:value1,key2:value2 This + functionality is available for use with MySQL Server + version 5.6 or later only. Earlier versions of MySQL + Server do not support connection attributes, causing + this configuration option to be ignored. Setting + connectionAttributes=none will cause connection + attribute processing to be bypassed, for situations + where Connection creation/initialization speed is + critical. + + + + ++ Since version: 5.1.25 + |
+ connectionCollation + + + + ++ If set, tells the server to use this collation via + 'set collation_connection' + + + + ++ Since version: 3.0.13 + |
+ useBlobToStoreUTF8OutsideBMP + + + + ++ Tells the driver to treat [MEDIUM/LONG]BLOB columns as + [LONG]VARCHAR columns holding text encoded in UTF-8 + that has characters outside the BMP (4-byte + encodings), which MySQL server can't handle natively. + + + + ++ Default: false + + + + ++ Since version: 5.1.3 + |
+ utf8OutsideBmpExcludedColumnNamePattern + + + + ++ When "useBlobToStoreUTF8OutsideBMP" is set to "true", + column names matching the given regex will still be + treated as BLOBs unless they match the regex specified + for "utf8OutsideBmpIncludedColumnNamePattern". The + regex must follow the patterns used for the + java.util.regex package. + + + + ++ Since version: 5.1.3 + |
+ utf8OutsideBmpIncludedColumnNamePattern + + + + ++ Used to specify exclusion rules to + "utf8OutsideBmpExcludedColumnNamePattern". The regex + must follow the patterns used for the java.util.regex + package. + + + + ++ Since version: 5.1.3 + |
+ loadBalanceEnableJMX + + + + ++ Enables JMX-based management of load-balanced + connection groups, including live addition/removal of + hosts from load-balancing pool. + + + + ++ Default: false + + + + ++ Since version: 5.1.13 + |
+ sessionVariables + + + + ++ A comma-separated list of name/value pairs to be sent + as SET SESSION ... to the server when the driver + connects. + + + + ++ Since version: 3.1.8 + |
+ useColumnNamesInFindColumn + + + + ++ Prior to JDBC-4.0, the JDBC specification had a bug + related to what could be given as a "column name" to + ResultSet methods like findColumn(), or getters that + took a String property. JDBC-4.0 clarified "column + name" to mean the label, as given in an "AS" clause + and returned by ResultSetMetaData.getColumnLabel(), + and if no AS clause, the column name. Setting this + property to "true" will give behavior that is + congruent to JDBC-3.0 and earlier versions of the JDBC + specification, but which because of the specification + bug could give unexpected results. This property is + preferred over "useOldAliasMetadataBehavior" unless + you need the specific behavior that it provides with + respect to ResultSetMetadata. + + + + ++ Default: false + + + + ++ Since version: 5.1.7 + |
+ allowNanAndInf + + + + ++ Should the driver allow NaN or +/- INF values in + PreparedStatement.setDouble()? + + + + ++ Default: false + + + + ++ Since version: 3.1.5 + |
+ autoClosePStmtStreams + + + + ++ Should the driver automatically call .close() on + streams/readers passed as arguments via set*() + methods? + + + + ++ Default: false + + + + ++ Since version: 3.1.12 + |
+ autoDeserialize + + + + ++ Should the driver automatically detect and + de-serialize objects stored in BLOB fields? + + + + ++ Default: false + + + + ++ Since version: 3.1.5 + |
+ blobsAreStrings + + + + ++ Should the driver always treat BLOBs as Strings - + specifically to work around dubious metadata returned + by the server for GROUP BY clauses? + + + + ++ Default: false + + + + ++ Since version: 5.0.8 + |
+ cacheDefaultTimezone + + + + ++ Caches client's default time zone. This results in + better performance when dealing with time zone + conversions in Date and Time data types, however it + won't be aware of time zone changes if they happen at + runtime. + + + + ++ Default: true + + + + ++ Since version: 5.1.35 + |
+ capitalizeTypeNames + + + + ++ Capitalize type names in DatabaseMetaData? (usually + only useful when using WebObjects, true/false, + defaults to 'false') + + + + ++ Default: true + + + + ++ Since version: 2.0.7 + |
+ clobCharacterEncoding + + + + ++ The character encoding to use for sending and + retrieving TEXT, MEDIUMTEXT and LONGTEXT values + instead of the configured connection characterEncoding + + + + ++ Since version: 5.0.0 + |
+ clobberStreamingResults + + + + ++ This will cause a 'streaming' ResultSet to be + automatically closed, and any outstanding data still + streaming from the server to be discarded if another + query is executed before all the data has been read + from the server. + + + + ++ Default: false + + + + ++ Since version: 3.0.9 + |
+ compensateOnDuplicateKeyUpdateCounts + + + + ++ Should the driver compensate for the update counts of + "ON DUPLICATE KEY" INSERT statements (2 = 1, 0 = 1) + when using prepared statements? + + + + ++ Default: false + + + + ++ Since version: 5.1.7 + |
+ continueBatchOnError + + + + ++ Should the driver continue processing batch commands + if one statement fails. The JDBC spec allows either + way (defaults to 'true'). + + + + ++ Default: true + + + + ++ Since version: 3.0.3 + |
+ createDatabaseIfNotExist + + + + ++ Creates the database given in the URL if it doesn't + yet exist. Assumes the configured user has permissions + to create databases. + + + + ++ Default: false + + + + ++ Since version: 3.1.9 + |
+ detectCustomCollations + + + + ++ Should the driver detect custom charsets/collations + installed on server (true/false, defaults to 'false'). + If this option set to 'true' driver gets actual + charsets/collations from server each time connection + establishes. This could slow down connection + initialization significantly. + + + + ++ Default: false + + + + ++ Since version: 5.1.29 + |
+ emptyStringsConvertToZero + + + + ++ Should the driver allow conversions from empty string + fields to numeric values of '0'? + + + + ++ Default: true + + + + ++ Since version: 3.1.8 + |
+ emulateLocators + + + + ++ Should the driver emulate java.sql.Blobs with + locators? With this feature enabled, the driver will + delay loading the actual Blob data until the one of + the retrieval methods (getInputStream(), getBytes(), + and so forth) on the blob data stream has been + accessed. For this to work, you must use a column + alias with the value of the column to the actual name + of the Blob. The feature also has the following + restrictions: The SELECT that created the result set + must reference only one table, the table must have a + primary key; the SELECT must alias the original blob + column name, specified as a string, to an alternate + name; the SELECT must cover all columns that make up + the primary key. + + + + ++ Default: false + + + + ++ Since version: 3.1.0 + |
+ emulateUnsupportedPstmts + + + + ++ Should the driver detect prepared statements that are + not supported by the server, and replace them with + client-side emulated versions? + + + + ++ Default: true + + + + ++ Since version: 3.1.7 + |
+ exceptionInterceptors + + + + ++ Comma-delimited list of classes that implement + com.mysql.jdbc.ExceptionInterceptor. These classes + will be instantiated one per Connection instance, and + all SQLExceptions thrown by the driver will be allowed + to be intercepted by these interceptors, in a chained + fashion, with the first class listed as the head of + the chain. + + + + ++ Since version: 5.1.8 + |
+ functionsNeverReturnBlobs + + + + ++ Should the driver always treat data from functions + returning BLOBs as Strings - specifically to work + around dubious metadata returned by the server for + GROUP BY clauses? + + + + ++ Default: false + + + + ++ Since version: 5.0.8 + |
+ generateSimpleParameterMetadata + + + + ++ Should the driver generate simplified parameter + metadata for PreparedStatements when no metadata is + available either because the server couldn't support + preparing the statement, or server-side prepared + statements are disabled? + + + + ++ Default: false + + + + ++ Since version: 5.0.5 + |
+ getProceduresReturnsFunctions + + + + ++ Pre-JDBC4 DatabaseMetaData API has only the + getProcedures() and getProcedureColumns() methods, so + they return metadata info for both stored procedures + and functions. JDBC4 was extended with the + getFunctions() and getFunctionColumns() methods and + the expected behaviours of previous methods are not + well defined. For JDBC4 and higher, default 'true' + value of the option means that calls of + DatabaseMetaData.getProcedures() and + DatabaseMetaData.getProcedureColumns() return metadata + for both procedures and functions as before, keeping + backward compatibility. Setting this property to + 'false' decouples Connector/J from its pre-JDBC4 + behaviours for DatabaseMetaData.getProcedures() and + DatabaseMetaData.getProcedureColumns(), forcing them + to return metadata for procedures only. + + + + ++ Default: true + + + + ++ Since version: 5.1.26 + |
+ ignoreNonTxTables + + + + ++ Ignore non-transactional table warning for rollback? + (defaults to 'false'). + + + + ++ Default: false + + + + ++ Since version: 3.0.9 + |
+ jdbcCompliantTruncation + + + + ++ Should the driver throw java.sql.DataTruncation + exceptions when data is truncated as is required by + the JDBC specification when connected to a server that + supports warnings (MySQL 4.1.0 and newer)? This + property has no effect if the server sql-mode includes + STRICT_TRANS_TABLES. + + + + ++ Default: true + + + + ++ Since version: 3.1.2 + |
+ loadBalanceAutoCommitStatementRegex + + + + ++ When load-balancing is enabled for auto-commit + statements (via + loadBalanceAutoCommitStatementThreshold), the + statement counter will only increment when the SQL + matches the regular expression. By default, every + statement issued matches. + + + + ++ Since version: 5.1.15 + |
+ loadBalanceAutoCommitStatementThreshold + + + + ++ When auto-commit is enabled, the number of statements + which should be executed before triggering + load-balancing to rebalance. Default value of 0 causes + load-balanced connections to only rebalance when + exceptions are encountered, or auto-commit is disabled + and transactions are explicitly committed or rolled + back. + + + + ++ Default: 0 + + + + ++ Since version: 5.1.15 + |
+ loadBalanceBlacklistTimeout + + + + ++ Time in milliseconds between checks of servers which + are unavailable, by controlling how long a server + lives in the global blacklist. + + + + ++ Default: 0 + + + + ++ Since version: 5.1.0 + |
+ loadBalanceConnectionGroup + + + + ++ Logical group of load-balanced connections within a + classloader, used to manage different groups + independently. If not specified, live management of + load-balanced connections is disabled. + + + + ++ Since version: 5.1.13 + |
+ loadBalanceExceptionChecker + + + + ++ Fully-qualified class name of custom exception + checker. The class must implement + com.mysql.jdbc.LoadBalanceExceptionChecker interface, + and is used to inspect SQLExceptions and determine + whether they should trigger fail-over to another host + in a load-balanced deployment. + + + + ++ Default: + com.mysql.jdbc.StandardLoadBalanceExceptionChecker + + + + ++ Since version: 5.1.13 + |
+ loadBalancePingTimeout + + + + ++ Time in milliseconds to wait for ping response from + each of load-balanced physical connections when using + load-balanced Connection. + + + + ++ Default: 0 + + + + ++ Since version: 5.1.13 + |
+ loadBalanceSQLExceptionSubclassFailover + + + + ++ Comma-delimited list of classes/interfaces used by + default load-balanced exception checker to determine + whether a given SQLException should trigger failover. + The comparison is done using + Class.isInstance(SQLException) using the thrown + SQLException. + + + + ++ Since version: 5.1.13 + |
+ loadBalanceSQLStateFailover + + + + ++ Comma-delimited list of SQLState codes used by default + load-balanced exception checker to determine whether a + given SQLException should trigger failover. The + SQLState of a given SQLException is evaluated to + determine whether it begins with any value in the + comma-delimited list. + + + + ++ Since version: 5.1.13 + |
+ loadBalanceValidateConnectionOnSwapServer + + + + ++ Should the load-balanced Connection explicitly check + whether the connection is live when swapping to a new + physical connection at commit/rollback? + + + + ++ Default: false + + + + ++ Since version: 5.1.13 + |
+ maxRows + + + + ++ The maximum number of rows to return (0, the default + means return all rows). + + + + ++ Default: -1 + + + + ++ Since version: all versions + |
+ netTimeoutForStreamingResults + + + + ++ What value should the driver automatically set the + server setting 'net_write_timeout' to when the + streaming result sets feature is in use? (value has + unit of seconds, the value '0' means the driver will + not try and adjust this value) + + + + ++ Default: 600 + + + + ++ Since version: 5.1.0 + |
+ noAccessToProcedureBodies + + + + ++ When determining procedure parameter types for + CallableStatements, and the connected user can't + access procedure bodies through "SHOW CREATE + PROCEDURE" or select on mysql.proc should the driver + instead create basic metadata (all parameters reported + as IN VARCHARs, but allowing registerOutParameter() to + be called on them anyway) instead of throwing an + exception? + + + + ++ Default: false + + + + ++ Since version: 5.0.3 + |
+ noDatetimeStringSync + + + + ++ Don't ensure that + ResultSet.getDatetimeType().toString().equals(ResultSet.getString()) + + + + ++ Default: false + + + + ++ Since version: 3.1.7 + |
+ noTimezoneConversionForDateType + + + + ++ Don't convert DATE values using the server time zone + if 'useTimezone'='true' or + 'useLegacyDatetimeCode'='false' + + + + ++ Default: true + + + + ++ Since version: 5.1.35 + |
+ noTimezoneConversionForTimeType + + + + ++ Don't convert TIME values using the server time zone + if 'useTimezone'='true' + + + + ++ Default: false + + + + ++ Since version: 5.0.0 + |
+ nullCatalogMeansCurrent + + + + ++ When DatabaseMetadataMethods ask for a 'catalog' + parameter, does the value null mean use the current + catalog? (this is not JDBC-compliant, but follows + legacy behavior from earlier versions of the driver) + + + + ++ Default: true + + + + ++ Since version: 3.1.8 + |
+ nullNamePatternMatchesAll + + + + ++ Should DatabaseMetaData methods that accept *pattern + parameters treat null the same as '%' (this is not + JDBC-compliant, however older versions of the driver + accepted this departure from the specification) + + + + ++ Default: true + + + + ++ Since version: 3.1.8 + |
+ overrideSupportsIntegrityEnhancementFacility + + + + ++ Should the driver return "true" for + DatabaseMetaData.supportsIntegrityEnhancementFacility() + even if the database doesn't support it to workaround + applications that require this method to return "true" + to signal support of foreign keys, even though the SQL + specification states that this facility contains much + more than just foreign key support (one such + application being OpenOffice)? + + + + ++ Default: false + + + + ++ Since version: 3.1.12 + |
+ padCharsWithSpace + + + + ++ If a result set column has the CHAR type and the value + does not fill the amount of characters specified in + the DDL for the column, should the driver pad the + remaining characters with space (for ANSI compliance)? + + + + ++ Default: false + + + + ++ Since version: 5.0.6 + |
+ pedantic + + + + ++ Follow the JDBC spec to the letter. + + + + ++ Default: false + + + + ++ Since version: 3.0.0 + |
+ pinGlobalTxToPhysicalConnection + + + + ++ When using XAConnections, should the driver ensure + that operations on a given XID are always routed to + the same physical connection? This allows the + XAConnection to support "XA START ... JOIN" after "XA + END" has been called + + + + ++ Default: false + + + + ++ Since version: 5.0.1 + |
+ populateInsertRowWithDefaultValues + + + + ++ When using ResultSets that are CONCUR_UPDATABLE, + should the driver pre-populate the "insert" row with + default values from the DDL for the table used in the + query so those values are immediately available for + ResultSet accessors? This functionality requires a + call to the database for metadata each time a result + set of this type is created. If disabled (the + default), the default values will be populated by the + an internal call to refreshRow() which pulls back + default values and/or values changed by triggers. + + + + ++ Default: false + + + + ++ Since version: 5.0.5 + |
+ processEscapeCodesForPrepStmts + + + + ++ Should the driver process escape codes in queries that + are prepared? Default escape processing behavior in + non-prepared statements must be defined with the + property 'enableEscapeProcessing'. + + + + ++ Default: true + + + + ++ Since version: 3.1.12 + |
+ queryTimeoutKillsConnection + + + + ++ If the timeout given in Statement.setQueryTimeout() + expires, should the driver forcibly abort the + Connection instead of attempting to abort the query? + + + + ++ Default: false + + + + ++ Since version: 5.1.9 + |
+ relaxAutoCommit + + + + ++ If the version of MySQL the driver connects to does + not support transactions, still allow calls to + commit(), rollback() and setAutoCommit() (true/false, + defaults to 'false')? + + + + ++ Default: false + + + + ++ Since version: 2.0.13 + |
+ retainStatementAfterResultSetClose + + + + ++ Should the driver retain the Statement reference in a + ResultSet after ResultSet.close() has been called. + This is not JDBC-compliant after JDBC-4.0. + + + + ++ Default: false + + + + ++ Since version: 3.1.11 + |
+ rollbackOnPooledClose + + + + ++ Should the driver issue a rollback() when the logical + connection in a pool is closed? + + + + ++ Default: true + + + + ++ Since version: 3.0.15 + |
+ runningCTS13 + + + + ++ Enables workarounds for bugs in Sun's JDBC compliance + testsuite version 1.3 + + + + ++ Default: false + + + + ++ Since version: 3.1.7 + |
+ sendFractionalSeconds + + + + ++ Send fractional part from TIMESTAMP seconds. If set to + false, the nanoseconds value of TIMESTAMP values will + be truncated before sending any data to the server. + This option applies only to prepared statements, + callable statements or updatable result sets. + + + + ++ Default: true + + + + ++ Since version: 5.1.37 + |
+ serverTimezone + + + + ++ Override detection/mapping of time zone. Used when + time zone from server doesn't map to Java time zone + + + + ++ Since version: 3.0.2 + |
+ statementInterceptors + + + + ++ A comma-delimited list of classes that implement + "com.mysql.jdbc.StatementInterceptor" that should be + placed "in between" query execution to influence the + results. StatementInterceptors are "chainable", the + results returned by the "current" interceptor will be + passed on to the next in in the chain, from + left-to-right order, as specified in this property. + + + + ++ Since version: 5.1.1 + |
+ strictFloatingPoint + + + + ++ Used only in older versions of compliance test + + + + ++ Default: false + + + + ++ Since version: 3.0.0 + |
+ strictUpdates + + + + ++ Should the driver do strict checking (all primary keys + selected) of updatable result sets (true, false, + defaults to 'true')? + + + + ++ Default: true + + + + ++ Since version: 3.0.4 + |
+ tinyInt1isBit + + + + ++ Should the driver treat the datatype TINYINT(1) as the + BIT type (because the server silently converts BIT + -> TINYINT(1) when creating tables)? + + + + ++ Default: true + + + + ++ Since version: 3.0.16 + |
+ transformedBitIsBoolean + + + + ++ If the driver converts TINYINT(1) to a different type, + should it use BOOLEAN instead of BIT for future + compatibility with MySQL-5.0, as MySQL-5.0 has a BIT + type? + + + + ++ Default: false + + + + ++ Since version: 3.1.9 + |
+ treatUtilDateAsTimestamp + + + + ++ Should the driver treat java.util.Date as a TIMESTAMP + for the purposes of PreparedStatement.setObject()? + + + + ++ Default: true + + + + ++ Since version: 5.0.5 + |
+ ultraDevHack + + + + ++ Create PreparedStatements for prepareCall() when + required, because UltraDev is broken and issues a + prepareCall() for _all_ statements? (true/false, + defaults to 'false') + + + + ++ Default: false + + + + ++ Since version: 2.0.3 + |
+ useAffectedRows + + + + ++ Don't set the CLIENT_FOUND_ROWS flag when connecting + to the server (not JDBC-compliant, will break most + applications that rely on "found" rows vs. "affected + rows" for DML statements), but does cause "correct" + update counts from "INSERT ... ON DUPLICATE KEY + UPDATE" statements to be returned by the server. + + + + ++ Default: false + + + + ++ Since version: 5.1.7 + |
+ useGmtMillisForDatetimes + + + + ++ Convert between session time zone and GMT before + creating Date and Timestamp instances (value of + 'false' leads to legacy behavior, 'true' leads to more + JDBC-compliant behavior)? This is part of the legacy + date-time code, thus the property has an effect only + when "useLegacyDatetimeCode=true." + + + + ++ Default: false + + + + ++ Since version: 3.1.12 + |
+ useHostsInPrivileges + + + + ++ Add '@hostname' to users in + DatabaseMetaData.getColumn/TablePrivileges() + (true/false), defaults to 'true'. + + + + ++ Default: true + + + + ++ Since version: 3.0.2 + |
+ useInformationSchema + + + + ++ When connected to MySQL-5.0.7 or newer, should the + driver use the INFORMATION_SCHEMA to derive + information used by DatabaseMetaData? + + + + ++ Default: false + + + + ++ Since version: 5.0.0 + |
+ useJDBCCompliantTimezoneShift + + + + ++ Should the driver use JDBC-compliant rules when + converting TIME/TIMESTAMP/DATETIME values' time zone + information for those JDBC arguments which take a + java.util.Calendar argument? This is part of the + legacy date-time code, thus the property has an effect + only when "useLegacyDatetimeCode=true." + + + + ++ Default: false + + + + ++ Since version: 5.0.0 + |
+ useLegacyDatetimeCode + + + + ++ Use code for DATE/TIME/DATETIME/TIMESTAMP handling in + result sets and statements that consistently handles + time zone conversions from client to server and back + again, or use the legacy code for these datatypes that + has been in the driver for backwards-compatibility? + Setting this property to 'false' voids the effects of + "useTimezone," "useJDBCCompliantTimezoneShift," + "useGmtMillisForDatetimes," and "useFastDateParsing." + + + + ++ Default: true + + + + ++ Since version: 5.1.6 + |
+ useOldAliasMetadataBehavior + + + + ++ Should the driver use the legacy behavior for "AS" + clauses on columns and tables, and only return aliases + (if any) for ResultSetMetaData.getColumnName() or + ResultSetMetaData.getTableName() rather than the + original column/table name? In 5.0.x, the default + value was true. + + + + ++ Default: false + + + + ++ Since version: 5.0.4 + |
+ useOldUTF8Behavior + + + + ++ Use the UTF-8 behavior the driver did when + communicating with 4.0 and older servers + + + + ++ Default: false + + + + ++ Since version: 3.1.6 + |
+ useOnlyServerErrorMessages + + + + ++ Don't prepend 'standard' SQLState error messages to + error messages returned by the server. + + + + ++ Default: true + + + + ++ Since version: 3.0.15 + |
+ useSSPSCompatibleTimezoneShift + + + + ++ If migrating from an environment that was using + server-side prepared statements, and the configuration + property "useJDBCCompliantTimeZoneShift" set to + "true", use compatible behavior when not using + server-side prepared statements when sending TIMESTAMP + values to the MySQL server. + + + + ++ Default: false + + + + ++ Since version: 5.0.5 + |
+ useServerPrepStmts + + + + ++ Use server-side prepared statements if the server + supports them? + + + + ++ Default: false + + + + ++ Since version: 3.1.0 + |
+ useSqlStateCodes + + + + ++ Use SQL Standard state codes instead of 'legacy' + X/Open/SQL state codes (true/false), default is 'true' + + + + ++ Default: true + + + + ++ Since version: 3.1.3 + |
+ useStreamLengthsInPrepStmts + + + + ++ Honor stream length parameter in + PreparedStatement/ResultSet.setXXXStream() method + calls (true/false, defaults to 'true')? + + + + ++ Default: true + + + + ++ Since version: 3.0.2 + |
+ useTimezone + + + + ++ Convert time/date types between client and server time + zones (true/false, defaults to 'false')? This is part + of the legacy date-time code, thus the property has an + effect only when "useLegacyDatetimeCode=true." + + + + ++ Default: false + + + + ++ Since version: 3.0.2 + |
+ useUnbufferedInput + + + + ++ Don't use BufferedInputStream for reading data from + the server + + + + ++ Default: true + + + + ++ Since version: 3.0.11 + |
+ yearIsDateType + + + + ++ Should the JDBC driver treat the MySQL type "YEAR" as + a java.sql.Date, or as a SHORT? + + + + ++ Default: true + + + + ++ Since version: 3.1.9 + |
+ zeroDateTimeBehavior + + + + ++ What should happen when the driver encounters DATETIME + values that are composed entirely of zeros (used by + MySQL to represent invalid dates)? Valid values are + "exception", "round" and "convertToNull". + + + + ++ Default: exception + + + + ++ Since version: 3.1.4 + |
+
+ Connector/J also supports access to MySQL using named pipes on
+ Windows platforms with the
+ NamedPipeSocketFactory as a plugin-socket
+ factory. If you do not use a namedPipePath
+ property, the default of '\\.\pipe\MySQL' is
+ used. If you use the NamedPipeSocketFactory,
+ the host name and port number values in the JDBC URL are
+ ignored. To enable this feature, set the
+ socketFactory property:
+
+
+socketFactory=com.mysql.jdbc.NamedPipeSocketFactory +
+
+ Named pipes only work when connecting to a MySQL server on the + same physical machine where the JDBC driver is running. In + simple performance tests, named pipe access is between 30%-50% + faster than the standard TCP/IP access. However, this varies per + system, and named pipes are slower than TCP/IP in many Windows + configurations. +
+ To create your own socket factories, follow the example code in
+ com.mysql.jdbc.NamedPipeSocketFactory, or
+ com.mysql.jdbc.StandardSocketFactory.
+
+ The useConfigs connection option is
+ convenient shorthand for specifying combinations of options
+ for particular scenarios. The argument values you can use with
+ this option correspond to the names of
+ .properties files within the Connector/J
+ mysql-connector-java-
+ JAR file. For example, the Connector/J 5.1.9 driver includes
+ the following configuration properties files:
+ version-bin.jar
+$ unzip mysql-connector-java-5.1.19-bin.jar '*/configs/*' +Archive: mysql-connector-java-5.1.19-bin.jar + creating: com/mysql/jdbc/configs/ + inflating: com/mysql/jdbc/configs/3-0-Compat.properties + inflating: com/mysql/jdbc/configs/5-0-Compat.properties + inflating: com/mysql/jdbc/configs/clusterBase.properties + inflating: com/mysql/jdbc/configs/coldFusion.properties + inflating: com/mysql/jdbc/configs/fullDebug.properties + inflating: com/mysql/jdbc/configs/maxPerformance.properties + inflating: com/mysql/jdbc/configs/solarisMaxPerformance.properties +
+ To specify one of these combinations of options, specify
+ useConfigs=3-0-Compat,
+ useConfigs=maxPerformance, and so on. The
+ following sections show the options that are part of each
+ useConfigs setting. For the details of why
+ each one is included, see the comments in the
+ .properties files.
+
+emptyStringsConvertToZero=true +jdbcCompliantTruncation=false +noDatetimeStringSync=true +nullCatalogMeansCurrent=true +nullNamePatternMatchesAll=true +transformedBitIsBoolean=false +dontTrackOpenResources=true +zeroDateTimeBehavior=convertToNull +useServerPrepStmts=false +autoClosePStmtStreams=true +processEscapeCodesForPrepStmts=false +useFastDateParsing=false +populateInsertRowWithDefaultValues=false +useDirectRowUnpack=false +
+useDirectRowUnpack=false +
+autoReconnect=true +failOverReadOnly=false +roundRobinLoadBalance=true +
+useDynamicCharsetInfo=false +alwaysSendSetIsolation=false +useLocalSessionState=true +autoReconnect=true +
+profileSQL=true +gatherPerfMetrics=true +useUsageAdvisor=true +logSlowQueries=true +explainSlowQueries=true +
+cachePrepStmts=true +cacheCallableStmts=true +cacheServerConfiguration=true +useLocalSessionState=true +elideSetAutoCommits=true +alwaysSendSetIsolation=false +enableQueryTimeouts=false +
+useUnbufferedInput=false +useReadAheadInput=false +maintainTimeStats=false +
+ MySQL Connector/J, as a rigorous implementation of the + JDBC + API, passes all of the tests in the publicly available + version of Oracle's JDBC compliance test suite. The JDBC + specification is flexible on how certain functionality should be + implemented. This section gives details on an + interface-by-interface level about implementation decisions that + might affect how you code applications with MySQL Connector/J. +
+ BLOB +
+ Starting with Connector/J version 3.1.0, you can emulate
+ BLOBs with locators by adding the property
+ emulateLocators=true to your JDBC URL.
+ Using this method, the driver will delay loading the actual
+ BLOB data until you retrieve the other data and then use
+ retrieval methods (getInputStream(),
+ getBytes(), and so forth) on the BLOB
+ data stream.
+
+ You must use a column alias with the value of the column to + the actual name of the BLOB, for example: +
+SELECT id, 'data' as blob_data from blobtable +
+ You must also follow these rules: +
+ The SELECT must reference
+ only one table. The table must have a
+ primary key.
+
+ The SELECT must alias the
+ original BLOB column name, specified as a string, to an
+ alternate name.
+
+ The SELECT must cover all
+ columns that make up the primary key.
+
+ The BLOB implementation does not allow in-place modification
+ (they are copies, as reported by the
+ DatabaseMetaData.locatorsUpdateCopies()
+ method). Because of this, use the corresponding
+ PreparedStatement.setBlob() or
+ ResultSet.updateBlob() (in the case of
+ updatable result sets) methods to save changes back to the
+ database.
+
+ CallableStatement +
+ Starting with Connector/J 3.1.1, stored procedures are
+ supported when connecting to MySQL version 5.0 or newer
+ using the CallableStatement
+ interface. Currently, the
+ getParameterMetaData() method of
+ CallableStatement is not supported.
+
+ CLOB +
+ The CLOB implementation does not allow in-place modification
+ (they are copies, as reported by the
+ DatabaseMetaData.locatorsUpdateCopies()
+ method). Because of this, use the
+ PreparedStatement.setClob() method to
+ save changes back to the database. The JDBC API does not
+ have a ResultSet.updateClob() method.
+
+ Connection +
+ Unlike the pre-Connector/J JDBC driver
+ (MM.MySQL), the
+ isClosed() method does not ping the
+ server to determine if it is available. In accordance with
+ the JDBC specification, it only returns true if
+ closed() has been called on the
+ connection. If you need to determine if the connection is
+ still valid, issue a simple query, such as SELECT
+ 1. The driver will throw an exception if the
+ connection is no longer valid.
+
+ DatabaseMetaData +
+ Foreign key
+ information
+ (getImportedKeys()/getExportedKeys()
+ and getCrossReference()) is only
+ available from InnoDB tables.
+ The driver uses SHOW CREATE
+ TABLE to retrieve this information, so if any
+ other storage engines add support for foreign keys, the
+ driver would transparently support them as well.
+
+ PreparedStatement +
+ PreparedStatements are implemented by the driver, as MySQL
+ does not have a prepared statement feature. Because of this,
+ the driver does not implement
+ getParameterMetaData() or
+ getMetaData() as it would require the
+ driver to have a complete SQL parser in the client.
+
+ Starting with version 3.1.0 MySQL Connector/J, server-side + prepared statements and binary-encoded result sets are used + when the server supports them. +
+ Take care when using a server-side prepared statement with
+ large parameters that are
+ set using setBinaryStream(),
+ setAsciiStream(),
+ setUnicodeStream(),
+ setBlob(), or
+ setClob(). To re-execute the statement
+ with any large parameter changed to a nonlarge parameter,
+ call clearParameters() and set all
+ parameters again. The reason for this is as follows:
+
+ During both server-side prepared statements and
+ client-side emulation, large data is exchanged only when
+ PreparedStatement.execute() is
+ called.
+
+ Once that has been done, the stream used to read the + data on the client side is closed (as per the JDBC + spec), and cannot be read from again. +
+ If a parameter changes from large to nonlarge, the
+ driver must reset the server-side state of the prepared
+ statement to allow the parameter that is being changed
+ to take the place of the prior large value. This removes
+ all of the large data that has already been sent to the
+ server, thus requiring the data to be re-sent, using the
+ setBinaryStream(),
+ setAsciiStream(),
+ setUnicodeStream(),
+ setBlob() or
+ setClob() method.
+
+ Consequently, to change the type of a parameter to a
+ nonlarge one, you must call
+ clearParameters() and set all
+ parameters of the prepared statement again before it can be
+ re-executed.
+
+ ResultSet +
+ By default, ResultSets are completely retrieved and stored + in memory. In most cases this is the most efficient way to + operate and, due to the design of the MySQL network + protocol, is easier to implement. If you are working with + ResultSets that have a large number of rows or large values + and cannot allocate heap space in your JVM for the memory + required, you can tell the driver to stream the results back + one row at a time. +
+ To enable this functionality, create a
+ Statement instance in the following
+ manner:
+
+stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, + java.sql.ResultSet.CONCUR_READ_ONLY); +stmt.setFetchSize(Integer.MIN_VALUE); +
+ The combination of a forward-only, read-only result set,
+ with a fetch size of Integer.MIN_VALUE
+ serves as a signal to the driver to stream result sets
+ row-by-row. After this, any result sets created with the
+ statement will be retrieved row-by-row.
+
+ There are some caveats with this approach. You must read all + of the rows in the result set (or close it) before you can + issue any other queries on the connection, or an exception + will be thrown. +
+ The earliest the locks these statements hold can be released
+ (whether they be MyISAM table-level locks
+ or row-level locks in some other storage engine such as
+ InnoDB) is when the statement completes.
+
+ If the statement is within scope of a transaction, then + locks are released when the transaction completes (which + implies that the statement needs to complete first). As with + most other databases, statements are not complete until all + the results pending on the statement are read or the active + result set for the statement is closed. +
+ Therefore, if using streaming results, process them as + quickly as possible if you want to maintain concurrent + access to the tables referenced by the statement producing + the result set. +
+ ResultSetMetaData +
+ The isAutoIncrement() method only works
+ when using MySQL servers 4.0 and newer.
+
+ Statement +
+ When using versions of the JDBC driver earlier than 3.2.1,
+ and connected to server versions earlier than 5.0.3, the
+ setFetchSize() method has no effect,
+ other than to toggle result set streaming as described
+ above.
+
+ Connector/J 5.0.0 and later include support for both
+ Statement.cancel() and
+ Statement.setQueryTimeout(). Both require
+ MySQL 5.0.0 or newer server, and require a separate
+ connection to issue the
+ KILL QUERY
+ statement. In the case of
+ setQueryTimeout(), the implementation
+ creates an additional thread to handle the timeout
+ functionality.
+
+ Failures to cancel the statement for
+ setQueryTimeout() may manifest
+ themselves as RuntimeException rather
+ than failing silently, as there is currently no way to
+ unblock the thread that is executing the query being
+ cancelled due to timeout expiration and have it throw the
+ exception instead.
+
+ The MySQL statement
+ KILL QUERY
+ (which is what the driver uses to implement
+ Statement.cancel()) is
+ non-deterministic; thus, avoid the use of
+ Statement.cancel() if possible. If no
+ query is in process, the next query issued will be killed
+ by the server. This race condition is guarded against as
+ of Connector/J 5.1.18.
+
+ MySQL does not support SQL cursors, and the JDBC driver
+ doesn't emulate them, so setCursorName()
+ has no effect.
+
+ Connector/J 5.1.3 and later include two additional methods: +
+ setLocalInfileInputStream() sets an
+ InputStream instance that will be
+ used to send data to the MySQL server for a
+ LOAD DATA
+ LOCAL INFILE statement rather than a
+ FileInputStream or
+ URLInputStream that represents the
+ path given as an argument to the statement.
+
+ This stream will be read to completion upon execution of
+ a LOAD DATA
+ LOCAL INFILE statement, and will automatically
+ be closed by the driver, so it needs to be reset before
+ each call to execute*() that would
+ cause the MySQL server to request data to fulfill the
+ request for
+ LOAD DATA
+ LOCAL INFILE.
+
+ If this value is set to NULL, the
+ driver will revert to using a
+ FileInputStream or
+ URLInputStream as required.
+
+ getLocalInfileInputStream() returns
+ the InputStream instance that will be
+ used to send data in response to a
+ LOAD DATA
+ LOCAL INFILE statement.
+
+ This method returns NULL if no such
+ stream has been set using
+ setLocalInfileInputStream().
+
+ MySQL Connector/J is flexible in the way it handles conversions + between MySQL data types and Java data types. +
+ In general, any MySQL data type can be converted to a
+ java.lang.String, and any numeric type can be
+ converted to any of the Java numeric types, although round-off,
+ overflow, or loss of precision may occur.
+
+ All TEXT types return
+ Types.LONGVARCHAR with different
+ getPrecision() values (65535, 255,
+ 16777215, and 2147483647 respectively) with
+ getColumnType() returning
+ -1. This behavior is intentional even
+ though TINYTEXT does not fall, regarding to
+ its size, within the LONGVARCHAR category.
+ This is to avoid different handling inside the same base type.
+ And getColumnType() returns
+ -1 because the internal server handling is
+ of type TEXT, which is similar to
+ BLOB.
+
+ Also note that getColumnTypeName() will
+ return VARCHAR even though
+ getColumnType() returns
+ Types.LONGVARCHAR, because
+ VARCHAR is the designated column
+ database-specific name for this type.
+
+ Starting with Connector/J 3.1.0, the JDBC driver issues warnings
+ or throws DataTruncation exceptions as is
+ required by the JDBC specification unless the connection was
+ configured not to do so by using the property
+ jdbcCompliantTruncation and setting it to
+ false.
+
+ The conversions that are always guaranteed to work are listed in + the following table. The first column lists one or more MySQL + data types, and the second column lists one or more Java types + to which the MySQL types can be converted. +
Table 5.1 Connection Properties - Miscellaneous
| These MySQL Data Types | Can always be converted to these Java types |
|---|---|
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 |
DATE, TIME, DATETIME, TIMESTAMP | java.lang.String, java.sql.Date, java.sql.Timestamp |
+ Round-off, overflow or loss of precision may occur if you + choose a Java numeric data type that has less precision or + capacity than the MySQL data type you are converting to/from. +
+ The ResultSet.getObject() method uses the
+ type conversions between MySQL and Java types, following the
+ JDBC specification where appropriate. The value returned by
+ ResultSetMetaData.GetColumnClassName() is
+ also shown below. For more information on the JDBC types, see
+ the reference on the
+ java.sql.Types
+ class.
+
Table 5.2 MySQL Types to Java Types for ResultSet.getObject()
| MySQL Type Name | Return value of GetColumnClassName | Returned as Java Class |
|---|---|---|
BIT(1) (new in MySQL-5.0) | BIT | java.lang.Boolean |
BIT( > 1) (new in MySQL-5.0) | BIT | byte[] |
TINYINT | TINYINT | java.lang.Boolean if the configuration property
+ tinyInt1isBit is set to
+ true (the default) and the storage
+ size is 1, or java.lang.Integer
+ if not. |
BOOL, BOOLEAN | TINYINT | See TINYINT, above as these are aliases for
+ TINYINT(1), currently. |
SMALLINT[(M)] [UNSIGNED] | SMALLINT [UNSIGNED] | java.lang.Integer (regardless if
+ UNSIGNED or not) |
MEDIUMINT[(M)] [UNSIGNED] | MEDIUMINT [UNSIGNED] | java.lang.Integer, if UNSIGNED
+ java.lang.Long (C/J 3.1 and
+ earlier), or java.lang.Integer
+ for C/J 5.0 and later |
INT,INTEGER[(M)] [UNSIGNED] | INTEGER [UNSIGNED] | java.lang.Integer, if UNSIGNED
+ java.lang.Long |
BIGINT[(M)] [UNSIGNED] | BIGINT [UNSIGNED] | java.lang.Long, if UNSIGNED
+ java.math.BigInteger |
FLOAT[(M,D)] | FLOAT | java.lang.Float |
DOUBLE[(M,B)] | DOUBLE | java.lang.Double |
DECIMAL[(M[,D])] | DECIMAL | java.math.BigDecimal |
DATE | DATE | java.sql.Date |
DATETIME | DATETIME | java.sql.Timestamp |
TIMESTAMP[(M)] | TIMESTAMP | java.sql.Timestamp |
TIME | TIME | java.sql.Time |
YEAR[(2|4)] | YEAR | If yearIsDateType configuration property is set to
+ false, then the returned object type
+ is java.sql.Short. If set to
+ true (the default), then the returned
+ object is of type java.sql.Date
+ with the date
+
+
+ set to January 1st, at midnight. |
CHAR(M) | CHAR | java.lang.String (unless the character set for
+ the column is BINARY, then
+ byte[] is returned. |
VARCHAR(M) [BINARY] | VARCHAR | java.lang.String (unless the character set for
+ the column is BINARY, then
+ byte[] is returned. |
BINARY(M) | BINARY | byte[] |
VARBINARY(M) | VARBINARY | byte[] |
TINYBLOB | TINYBLOB | byte[] |
TINYTEXT | VARCHAR | java.lang.String |
BLOB | BLOB | byte[] |
TEXT | VARCHAR | java.lang.String |
MEDIUMBLOB | MEDIUMBLOB | byte[] |
MEDIUMTEXT | VARCHAR | java.lang.String |
LONGBLOB | LONGBLOB | byte[] |
LONGTEXT | VARCHAR | java.lang.String |
ENUM('value1','value2',...) | CHAR | java.lang.String |
SET('value1','value2',...) | CHAR | java.lang.String |
+ All strings sent from the JDBC driver to the server are
+ converted automatically from native Java Unicode form to the
+ client character encoding, including all queries sent using
+ Statement.execute(),
+ Statement.executeUpdate(),
+ Statement.executeQuery() as well as all
+ PreparedStatement and
+ CallableStatement parameters with
+ the exclusion of parameters set using
+ setBytes(),
+ setBinaryStream(),
+ setAsciiStream(),
+ setUnicodeStream() and
+ setBlob().
+
+ In MySQL Server 4.1 and higher, Connector/J supports a single
+ character encoding between client and server, and any number of
+ character encodings for data returned by the server to the
+ client in ResultSets.
+
+ Prior to MySQL Server 4.1, Connector/J supported a single
+ character encoding per connection, which could either be
+ automatically detected from the server configuration, or could
+ be configured by the user through the
+ useUnicode and
+ characterEncoding properties.
+
+ The character encoding between client and server is
+ automatically detected upon connection. You specify the encoding
+ on the server using the
+ character_set_server for server
+ versions 4.1.0 and newer, and character_set
+ system variable for server versions older than 4.1.0. The driver
+ automatically uses the encoding specified by the server. For
+ more information, see Server Character Set and Collation.
+
+ For example, to use 4-byte UTF-8 character sets with
+ Connector/J, configure the MySQL server with
+ character_set_server=utf8mb4,
+ and leave characterEncoding out of the
+ Connector/J connection string. Connector/J will then autodetect
+ the UTF-8 setting.
+
+ To override the automatically detected encoding on the client
+ side, use the characterEncoding property
+ in the URL used to connect to the server.
+
+ To allow multiple character sets to be sent from the client, use
+ the UTF-8 encoding, either by configuring
+ utf8 as the default server character set, or
+ by configuring the JDBC driver to use UTF-8 through the
+ characterEncoding property.
+
+ When specifying character encodings on the client side, use + Java-style names. The following table lists MySQL character set + names and the corresponding Java-style names: +
Table 5.3 MySQL to Java Encoding Name Translations
| MySQL Character Set Name | Java-Style Character Encoding Name |
|---|---|
ascii | US-ASCII |
big5 | Big5 |
gbk | GBK |
sjis | SJIS (or Cp932 or MS932 for MySQL Server < 4.1.11) |
cp932 | Cp932 or MS932 (MySQL Server > 4.1.11) |
gb2312 | EUC_CN |
ujis | EUC_JP |
euckr | EUC_KR |
latin1 | Cp1252 |
latin2 | ISO8859_2 |
greek | ISO8859_7 |
hebrew | ISO8859_8 |
cp866 | Cp866 |
tis620 | TIS620 |
cp1250 | Cp1250 |
cp1251 | Cp1251 |
cp1257 | Cp1257 |
macroman | MacRoman |
macce | MacCentralEurope |
utf8 | UTF-8 |
ucs2 | UnicodeBig |
+ Do not issue the query set names with
+ Connector/J, as the driver will not detect that the character
+ set has changed, and will continue to use the character set
+ detected during the initial connection setup.
+
+ SSL in MySQL Connector/J encrypts all data (other than the + initial handshake) between the JDBC driver and the server. There + is a performance penalty for enabling SSL, the severity of which + depends on multiple factors including (but not limited to) the + size of the query, the amount of data returned, the server + hardware, the SSL library used, the network bandwidth, and so + on. +
+ For SSL support to work, you must have the following: +
+ A JDK that includes JSSE (Java Secure Sockets Extension), + like JDK-1.4.1 or newer. SSL does not currently work with a + JDK that you can add JSSE to, like JDK-1.2.x or JDK-1.3.x + due to the following JSSE bug: + http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4273544 +
+ A MySQL server that supports SSL and has been compiled and + configured to do so, which is MySQL 4.0.4 or later. For more + information, see + Building MySQL with Support for Secure Connections. +
+ A client certificate (covered later in this section) +
+ The system works through two Java truststore files, one file
+ contains the certificate information for the server
+ (truststore in the examples below). The
+ other file contains the certificate for the client
+ (keystore in the examples below). All Java
+ truststore files are password protected by supplying a suitable
+ password to the keytool when you create the
+ files. You need the file names and associated passwords to
+ create an SSL connection.
+
+ You will first need to import the MySQL server CA Certificate
+ into a Java truststore. A sample MySQL server CA Certificate is
+ located in the SSL subdirectory of the
+ MySQL source distribution. This is what SSL will use to
+ determine if you are communicating with a secure MySQL server.
+ Alternatively, use the CA Certificate that you have generated or
+ been provided with by your SSL provider.
+
+ To use Java's keytool to create a truststore
+ in the current directory , and import the server's CA
+ certificate (cacert.pem), you can do the
+ following (assuming that keytool is in your
+ path. The keytool is typically located in the
+ bin subdirectory of your JDK or JRE):
+
+shell> keytool -import -alias mysqlServerCACert \ + -file cacert.pem -keystore truststore +
+ Enter the password when prompted for the keystore file. + Interaction with keytool looks like this: +
+Enter keystore password: ********* +Owner: EMAILADDRESS=walrus@example.com, CN=Walrus, + O=My Company, L=Orenburg, ST=Some-State, C=RU +Issuer: EMAILADDRESS=walrus@example.com, CN=Walrus, + O=My Company, L=Orenburg, ST=Some-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 +
+ You then have two options: either import the client certificate + that matches the CA certificate you just imported, or create a + new client certificate. +
+ Importing an existing certificate requires the certificate to be + in DER format. You can use openssl to convert + an existing certificate into the new format. For example: +
+shell> openssl x509 -outform DER -in client-cert.pem -out client.cert +
+ Now import the converted certificate into your keystore using + keytool: +
+shell> keytool -import -file client.cert -keystore keystore -alias mysqlClientCertificate +
+ To generate your own client certificate, use
+ keytool to create a suitable certificate and
+ add it to the keystore file:
+
+shell> keytool -genkey -keyalg rsa \ + -alias mysqlClientCertificate -keystore keystore +
+ Keytool will prompt you for the following information, and
+ create a keystore named keystore in the
+ current directory.
+
+ Respond with information that is appropriate for your situation: +
+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]: My Company +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=My Company, + L=Flossmoor, ST=IL, C=US> correct? + [no]: y + +Enter key password for <mysqlClientCertificate> + (RETURN if same as keystore password): +
+ Finally, to get JSSE to use the keystore and truststore that you
+ have generated, you need to set the following system properties
+ when you start your JVM, replacing
+ path_to_keystore_file with the full
+ path to the keystore file you created,
+ path_to_truststore_file with the path
+ to the truststore file you created, and using the appropriate
+ password values for each property. You can do this either on the
+ command line:
+
+-Djavax.net.ssl.keyStore=path_to_keystore_file+-Djavax.net.ssl.keyStorePassword=password+-Djavax.net.ssl.trustStore=path_to_truststore_file+-Djavax.net.ssl.trustStorePassword=password+
+ Or you can set the values directly within the application: +
+System.setProperty("javax.net.ssl.keyStore","path_to_keystore_file");
+System.setProperty("javax.net.ssl.keyStorePassword","password");
+System.setProperty("javax.net.ssl.trustStore","path_to_truststore_file");
+System.setProperty("javax.net.ssl.trustStorePassword","password");
+
+ You will also need to set useSSL to
+ true in your connection parameters for MySQL
+ Connector/J, either by adding useSSL=true to
+ your URL, or by setting the property useSSL
+ to true in the
+ java.util.Properties instance you pass to
+ DriverManager.getConnection().
+
+ You can test that SSL is working by turning on JSSE debugging + (as detailed below), and look for the following key events: +
+...
+*** 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 provides debugging (to stdout) when you
+ set the following system property:
+ -Djavax.net.debug=all This will tell you what
+ keystores and truststores are being used, as well as what is
+ going on during the SSL handshake and certificate exchange. It
+ will be helpful when trying to determine what is not working
+ when trying to get an SSL connection to happen.
+
+ Java applications using Connector/J 5.1.21 and higher can + connect to MySQL servers that use the pluggable authentication + module (PAM) authentication scheme. +
+ For PAM authentication to work, you must have the following: +
+ A MySQL server that supports PAM authentication: a + commercial distribution of MySQL 5.5.16 or higher. See + The PAM Authentication Plugin for more + information. Connector/J implements the same cleartext + authentication method as in + The Cleartext Client-Side Authentication Plugin. +
+ SSL capability, as explained in + Section 5.5, “Connecting Securely Using SSL”. Because + the PAM authentication scheme sends the original password to + the server, the connection to the server must be encrypted. +
+ PAM authentication support is enabled by default in Connector/J + 5.1.21 and up, so no extra configuration is needed. +
+ To disable the PAM authentication feature, specify
+ mysql_clear_password (the method) or
+ com.mysql.jdbc.authentication.MysqlClearPasswordPlugin
+ (the class name) in the comma-separated list of arguments for
+ the disabledAuthenticationPlugins connection
+ option. See
+ Section 5.1, “Driver/Datasource Class Names, URL Syntax and Configuration Properties
+ for Connector/J”
+ for details about that connection option.
+
+ See + Section 8.3, “Configuring Master/Slave Replication with Connector/J” + for details on the topic. +
+ The table below provides a mapping of the MySQL error numbers to
+ JDBC SQLState values.
+
Table 5.4 Mapping of MySQL Error Numbers to SQLStates
| MySQL Error Number | MySQL Error Name | Legacy (X/Open) SQLState | SQL Standard SQLState |
|---|---|---|---|
| 1022 | ER_DUP_KEY | 23000 | 23000 |
| 1037 | ER_OUTOFMEMORY | S1001 | HY001 |
| 1038 | ER_OUT_OF_SORTMEMORY | S1001 | HY001 |
| 1040 | ER_CON_COUNT_ERROR | 08004 | 08004 |
| 1042 | ER_BAD_HOST_ERROR | 08004 | 08S01 |
| 1043 | ER_HANDSHAKE_ERROR | 08004 | 08S01 |
| 1044 | ER_DBACCESS_DENIED_ERROR | 42000 | 42000 |
| 1045 | ER_ACCESS_DENIED_ERROR | 28000 | 28000 |
| 1046 | ER_NO_DB_ERROR | 3D000 | 3D000 |
| 1047 | ER_UNKNOWN_COM_ERROR | 08S01 | 08S01 |
| 1048 | ER_BAD_NULL_ERROR | 23000 | 23000 |
| 1049 | ER_BAD_DB_ERROR | 42000 | 42000 |
| 1050 | ER_TABLE_EXISTS_ERROR | 42S01 | 42S01 |
| 1051 | ER_BAD_TABLE_ERROR | 42S02 | 42S02 |
| 1052 | ER_NON_UNIQ_ERROR | 23000 | 23000 |
| 1053 | ER_SERVER_SHUTDOWN | 08S01 | 08S01 |
| 1054 | ER_BAD_FIELD_ERROR | S0022 | 42S22 |
| 1055 | ER_WRONG_FIELD_WITH_GROUP | S1009 | 42000 |
| 1056 | ER_WRONG_GROUP_FIELD | S1009 | 42000 |
| 1057 | ER_WRONG_SUM_SELECT | S1009 | 42000 |
| 1058 | ER_WRONG_VALUE_COUNT | 21S01 | 21S01 |
| 1059 | ER_TOO_LONG_IDENT | S1009 | 42000 |
| 1060 | ER_DUP_FIELDNAME | S1009 | 42S21 |
| 1061 | ER_DUP_KEYNAME | S1009 | 42000 |
| 1062 | ER_DUP_ENTRY | S1009 | 23000 |
| 1063 | ER_WRONG_FIELD_SPEC | S1009 | 42000 |
| 1064 | ER_PARSE_ERROR | 42000 | 42000 |
| 1065 | ER_EMPTY_QUERY | 42000 | 42000 |
| 1066 | ER_NONUNIQ_TABLE | S1009 | 42000 |
| 1067 | ER_INVALID_DEFAULT | S1009 | 42000 |
| 1068 | ER_MULTIPLE_PRI_KEY | S1009 | 42000 |
| 1069 | ER_TOO_MANY_KEYS | S1009 | 42000 |
| 1070 | ER_TOO_MANY_KEY_PARTS | S1009 | 42000 |
| 1071 | ER_TOO_LONG_KEY | S1009 | 42000 |
| 1072 | ER_KEY_COLUMN_DOES_NOT_EXITS | S1009 | 42000 |
| 1073 | ER_BLOB_USED_AS_KEY | S1009 | 42000 |
| 1074 | ER_TOO_BIG_FIELDLENGTH | S1009 | 42000 |
| 1075 | ER_WRONG_AUTO_KEY | S1009 | 42000 |
| 1080 | ER_FORCING_CLOSE | 08S01 | 08S01 |
| 1081 | ER_IPSOCK_ERROR | 08S01 | 08S01 |
| 1082 | ER_NO_SUCH_INDEX | S1009 | 42S12 |
| 1083 | ER_WRONG_FIELD_TERMINATORS | S1009 | 42000 |
| 1084 | ER_BLOBS_AND_NO_TERMINATED | S1009 | 42000 |
| 1090 | ER_CANT_REMOVE_ALL_FIELDS | 42000 | 42000 |
| 1091 | ER_CANT_DROP_FIELD_OR_KEY | 42000 | 42000 |
| 1101 | ER_BLOB_CANT_HAVE_DEFAULT | 42000 | 42000 |
| 1102 | ER_WRONG_DB_NAME | 42000 | 42000 |
| 1103 | ER_WRONG_TABLE_NAME | 42000 | 42000 |
| 1104 | ER_TOO_BIG_SELECT | 42000 | 42000 |
| 1106 | ER_UNKNOWN_PROCEDURE | 42000 | 42000 |
| 1107 | ER_WRONG_PARAMCOUNT_TO_PROCEDURE | 42000 | 42000 |
| 1109 | ER_UNKNOWN_TABLE | 42S02 | 42S02 |
| 1110 | ER_FIELD_SPECIFIED_TWICE | 42000 | 42000 |
| 1112 | ER_UNSUPPORTED_EXTENSION | 42000 | 42000 |
| 1113 | ER_TABLE_MUST_HAVE_COLUMNS | 42000 | 42000 |
| 1115 | ER_UNKNOWN_CHARACTER_SET | 42000 | 42000 |
| 1118 | ER_TOO_BIG_ROWSIZE | 42000 | 42000 |
| 1120 | ER_WRONG_OUTER_JOIN | 42000 | 42000 |
| 1121 | ER_NULL_COLUMN_IN_INDEX | 42000 | 42000 |
| 1129 | ER_HOST_IS_BLOCKED | 08004 | HY000 |
| 1130 | ER_HOST_NOT_PRIVILEGED | 08004 | HY000 |
| 1131 | ER_PASSWORD_ANONYMOUS_USER | 42000 | 42000 |
| 1132 | ER_PASSWORD_NOT_ALLOWED | 42000 | 42000 |
| 1133 | ER_PASSWORD_NO_MATCH | 42000 | 42000 |
| 1136 | ER_WRONG_VALUE_COUNT_ON_ROW | 21S01 | 21S01 |
| 1138 | ER_INVALID_USE_OF_NULL | S1000 | 42000 |
| 1139 | ER_REGEXP_ERROR | 42000 | 42000 |
| 1140 | ER_MIX_OF_GROUP_FUNC_AND_FIELDS | 42000 | 42000 |
| 1141 | ER_NONEXISTING_GRANT | 42000 | 42000 |
| 1142 | ER_TABLEACCESS_DENIED_ERROR | 42000 | 42000 |
| 1143 | ER_COLUMNACCESS_DENIED_ERROR | 42000 | 42000 |
| 1144 | ER_ILLEGAL_GRANT_FOR_TABLE | 42000 | 42000 |
| 1145 | ER_GRANT_WRONG_HOST_OR_USER | 42000 | 42000 |
| 1146 | ER_NO_SUCH_TABLE | 42S02 | 42S02 |
| 1147 | ER_NONEXISTING_TABLE_GRANT | 42000 | 42000 |
| 1148 | ER_NOT_ALLOWED_COMMAND | 42000 | 42000 |
| 1149 | ER_SYNTAX_ERROR | 42000 | 42000 |
| 1152 | ER_ABORTING_CONNECTION | 08S01 | 08S01 |
| 1153 | ER_NET_PACKET_TOO_LARGE | 08S01 | 08S01 |
| 1154 | ER_NET_READ_ERROR_FROM_PIPE | 08S01 | 08S01 |
| 1155 | ER_NET_FCNTL_ERROR | 08S01 | 08S01 |
| 1156 | ER_NET_PACKETS_OUT_OF_ORDER | 08S01 | 08S01 |
| 1157 | ER_NET_UNCOMPRESS_ERROR | 08S01 | 08S01 |
| 1158 | ER_NET_READ_ERROR | 08S01 | 08S01 |
| 1159 | ER_NET_READ_INTERRUPTED | 08S01 | 08S01 |
| 1160 | ER_NET_ERROR_ON_WRITE | 08S01 | 08S01 |
| 1161 | ER_NET_WRITE_INTERRUPTED | 08S01 | 08S01 |
| 1162 | ER_TOO_LONG_STRING | 42000 | 42000 |
| 1163 | ER_TABLE_CANT_HANDLE_BLOB | 42000 | 42000 |
| 1164 | ER_TABLE_CANT_HANDLE_AUTO_INCREMENT | 42000 | 42000 |
| 1166 | ER_WRONG_COLUMN_NAME | 42000 | 42000 |
| 1167 | ER_WRONG_KEY_COLUMN | 42000 | 42000 |
| 1169 | ER_DUP_UNIQUE | 23000 | 23000 |
| 1170 | ER_BLOB_KEY_WITHOUT_LENGTH | 42000 | 42000 |
| 1171 | ER_PRIMARY_CANT_HAVE_NULL | 42000 | 42000 |
| 1172 | ER_TOO_MANY_ROWS | 42000 | 42000 |
| 1173 | ER_REQUIRES_PRIMARY_KEY | 42000 | 42000 |
| 1176 | ER_KEY_DOES_NOT_EXITS | 42000 | 42000 |
| 1177 | ER_CHECK_NO_SUCH_TABLE | 42000 | 42000 |
| 1178 | ER_CHECK_NOT_IMPLEMENTED | 42000 | 42000 |
| 1179 | ER_CANT_DO_THIS_DURING_AN_TRANSACTION | 25000 | 25000 |
| 1184 | ER_NEW_ABORTING_CONNECTION | 08S01 | 08S01 |
| 1189 | ER_MASTER_NET_READ | 08S01 | 08S01 |
| 1190 | ER_MASTER_NET_WRITE | 08S01 | 08S01 |
| 1203 | ER_TOO_MANY_USER_CONNECTIONS | 42000 | 42000 |
| 1205 | ER_LOCK_WAIT_TIMEOUT | 40001 | 40001 |
| 1207 | ER_READ_ONLY_TRANSACTION | 25000 | 25000 |
| 1211 | ER_NO_PERMISSION_TO_CREATE_USER | 42000 | 42000 |
| 1213 | ER_LOCK_DEADLOCK | 40001 | 40001 |
| 1216 | ER_NO_REFERENCED_ROW | 23000 | 23000 |
| 1217 | ER_ROW_IS_REFERENCED | 23000 | 23000 |
| 1218 | ER_CONNECT_TO_MASTER | 08S01 | 08S01 |
| 1222 | ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT | 21000 | 21000 |
| 1226 | ER_USER_LIMIT_REACHED | 42000 | 42000 |
| 1227 | ER_SPECIFIC_ACCESS_DENIED_ERROR | 42000 | 42000 |
| 1230 | ER_NO_DEFAULT | 42000 | 42000 |
| 1231 | ER_WRONG_VALUE_FOR_VAR | 42000 | 42000 |
| 1232 | ER_WRONG_TYPE_FOR_VAR | 42000 | 42000 |
| 1234 | ER_CANT_USE_OPTION_HERE | 42000 | 42000 |
| 1235 | ER_NOT_SUPPORTED_YET | 42000 | 42000 |
| 1239 | ER_WRONG_FK_DEF | 42000 | 42000 |
| 1241 | ER_OPERAND_COLUMNS | 21000 | 21000 |
| 1242 | ER_SUBQUERY_NO_1_ROW | 21000 | 21000 |
| 1247 | ER_ILLEGAL_REFERENCE | 42S22 | 42S22 |
| 1248 | ER_DERIVED_MUST_HAVE_ALIAS | 42000 | 42000 |
| 1249 | ER_SELECT_REDUCED | 01000 | 01000 |
| 1250 | ER_TABLENAME_NOT_ALLOWED_HERE | 42000 | 42000 |
| 1251 | ER_NOT_SUPPORTED_AUTH_MODE | 08004 | 08004 |
| 1252 | ER_SPATIAL_CANT_HAVE_NULL | 42000 | 42000 |
| 1253 | ER_COLLATION_CHARSET_MISMATCH | 42000 | 42000 |
| 1261 | ER_WARN_TOO_FEW_RECORDS | 01000 | 01000 |
| 1262 | ER_WARN_TOO_MANY_RECORDS | 01000 | 01000 |
| 1263 | ER_WARN_NULL_TO_NOTNULL | S1000 | 01000 |
| 1264 | ER_WARN_DATA_OUT_OF_RANGE | 01000 | 01000 |
| 1265 | ER_WARN_DATA_TRUNCATED | 01000 | 01000 |
| 1280 | ER_WRONG_NAME_FOR_INDEX | 42000 | 42000 |
| 1281 | ER_WRONG_NAME_FOR_CATALOG | 42000 | 42000 |
| 1286 | ER_UNKNOWN_STORAGE_ENGINE | 42000 | 42000 |
| 1292 | ER_TRUNCATED_WRONG_VALUE | 22007 | 22007 |
| 1303 | ER_SP_NO_RECURSIVE_CREATE | S1000 | 2F003 |
| 1304 | ER_SP_ALREADY_EXISTS | 42000 | 42000 |
| 1305 | ER_SP_DOES_NOT_EXIST | 42000 | 42000 |
| 1308 | ER_SP_LILABEL_MISMATCH | 42000 | 42000 |
| 1309 | ER_SP_LABEL_REDEFINE | 42000 | 42000 |
| 1310 | ER_SP_LABEL_MISMATCH | 42000 | 42000 |
| 1311 | ER_SP_UNINIT_VAR | 01000 | 01000 |
| 1312 | ER_SP_BADSELECT | 0A000 | 0A000 |
| 1313 | ER_SP_BADRETURN | 42000 | 42000 |
| 1314 | ER_SP_BADSTATEMENT | 0A000 | 0A000 |
| 1315 | ER_UPDATE_LOG_DEPRECATED_IGNORED | 42000 | 42000 |
| 1316 | ER_UPDATE_LOG_DEPRECATED_TRANSLATED | 42000 | 42000 |
| 1317 | ER_QUERY_INTERRUPTED | S1000 | 70100 |
| 1318 | ER_SP_WRONG_NO_OF_ARGS | 42000 | 42000 |
| 1319 | ER_SP_COND_MISMATCH | 42000 | 42000 |
| 1320 | ER_SP_NORETURN | 42000 | 42000 |
| 1321 | ER_SP_NORETURNEND | S1000 | 2F005 |
| 1322 | ER_SP_BAD_CURSOR_QUERY | 42000 | 42000 |
| 1323 | ER_SP_BAD_CURSOR_SELECT | 42000 | 42000 |
| 1324 | ER_SP_CURSOR_MISMATCH | 42000 | 42000 |
| 1325 | ER_SP_CURSOR_ALREADY_OPEN | 24000 | 24000 |
| 1326 | ER_SP_CURSOR_NOT_OPEN | 24000 | 24000 |
| 1327 | ER_SP_UNDECLARED_VAR | 42000 | 42000 |
| 1329 | ER_SP_FETCH_NO_DATA | S1000 | 02000 |
| 1330 | ER_SP_DUP_PARAM | 42000 | 42000 |
| 1331 | ER_SP_DUP_VAR | 42000 | 42000 |
| 1332 | ER_SP_DUP_COND | 42000 | 42000 |
| 1333 | ER_SP_DUP_CURS | 42000 | 42000 |
| 1335 | ER_SP_SUBSELECT_NYI | 0A000 | 0A000 |
| 1336 | ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG | 0A000 | 0A000 |
| 1337 | ER_SP_VARCOND_AFTER_CURSHNDLR | 42000 | 42000 |
| 1338 | ER_SP_CURSOR_AFTER_HANDLER | 42000 | 42000 |
| 1339 | ER_SP_CASE_NOT_FOUND | S1000 | 20000 |
| 1365 | ER_DIVISION_BY_ZERO | 22012 | 22012 |
| 1367 | ER_ILLEGAL_VALUE_FOR_TYPE | 22007 | 22007 |
| 1370 | ER_PROCACCESS_DENIED_ERROR | 42000 | 42000 |
| 1397 | ER_XAER_NOTA | S1000 | XAE04 |
| 1398 | ER_XAER_INVAL | S1000 | XAE05 |
| 1399 | ER_XAER_RMFAIL | S1000 | XAE07 |
| 1400 | ER_XAER_OUTSIDE | S1000 | XAE09 |
| 1401 | ER_XA_RMERR | S1000 | XAE03 |
| 1402 | ER_XA_RBROLLBACK | S1000 | XA100 |
| 1403 | ER_NONEXISTING_PROC_GRANT | 42000 | 42000 |
| 1406 | ER_DATA_TOO_LONG | 22001 | 22001 |
| 1407 | ER_SP_BAD_SQLSTATE | 42000 | 42000 |
| 1410 | ER_CANT_CREATE_USER_WITH_GRANT | 42000 | 42000 |
| 1413 | ER_SP_DUP_HANDLER | 42000 | 42000 |
| 1414 | ER_SP_NOT_VAR_ARG | 42000 | 42000 |
| 1415 | ER_SP_NO_RETSET | 0A000 | 0A000 |
| 1416 | ER_CANT_CREATE_GEOMETRY_OBJECT | 22003 | 22003 |
| 1425 | ER_TOO_BIG_SCALE | 42000 | 42000 |
| 1426 | ER_TOO_BIG_PRECISION | 42000 | 42000 |
| 1427 | ER_M_BIGGER_THAN_D | 42000 | 42000 |
| 1437 | ER_TOO_LONG_BODY | 42000 | 42000 |
| 1439 | ER_TOO_BIG_DISPLAYWIDTH | 42000 | 42000 |
| 1440 | ER_XAER_DUPID | S1000 | XAE08 |
| 1441 | ER_DATETIME_FUNCTION_OVERFLOW | 22008 | 22008 |
| 1451 | ER_ROW_IS_REFERENCED_2 | 23000 | 23000 |
| 1452 | ER_NO_REFERENCED_ROW_2 | 23000 | 23000 |
| 1453 | ER_SP_BAD_VAR_SHADOW | 42000 | 42000 |
| 1458 | ER_SP_WRONG_NAME | 42000 | 42000 |
| 1460 | ER_SP_NO_AGGREGATE | 42000 | 42000 |
| 1461 | ER_MAX_PREPARED_STMT_COUNT_REACHED | 42000 | 42000 |
| 1463 | ER_NON_GROUPING_FIELD_USED | 42000 | 42000 |
| 1557 | ER_FOREIGN_DUPLICATE_KEY | 23000 | 23000 |
| 1568 | ER_CANT_CHANGE_TX_ISOLATION | S1000 | 25001 |
| 1582 | ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT | 42000 | 42000 |
| 1583 | ER_WRONG_PARAMETERS_TO_NATIVE_FCT | 42000 | 42000 |
| 1584 | ER_WRONG_PARAMETERS_TO_STORED_FCT | 42000 | 42000 |
| 1586 | ER_DUP_ENTRY_WITH_KEY_NAME | 23000 | 23000 |
| 1613 | ER_XA_RBTIMEOUT | S1000 | XA106 |
| 1614 | ER_XA_RBDEADLOCK | S1000 | XA102 |
| 1630 | ER_FUNC_INEXISTENT_NAME_COLLISION | 42000 | 42000 |
| 1641 | ER_DUP_SIGNAL_SET | 42000 | 42000 |
| 1642 | ER_SIGNAL_WARN | 01000 | 01000 |
| 1643 | ER_SIGNAL_NOT_FOUND | S1000 | 02000 |
| 1645 | ER_RESIGNAL_WITHOUT_ACTIVE_HANDLER | S1000 | 0K000 |
| 1687 | ER_SPATIAL_MUST_HAVE_GEOM_COL | 42000 | 42000 |
| 1690 | ER_DATA_OUT_OF_RANGE | 22003 | 22003 |
| 1698 | ER_ACCESS_DENIED_NO_PASSWORD_ERROR | 28000 | 28000 |
| 1701 | ER_TRUNCATE_ILLEGAL_FK | 42000 | 42000 |
| 1758 | ER_DA_INVALID_CONDITION_NUMBER | 35000 | 35000 |
| 1761 | ER_FOREIGN_DUPLICATE_KEY_WITH_CHILD_INFO | 23000 | 23000 |
| 1762 | ER_FOREIGN_DUPLICATE_KEY_WITHOUT_CHILD_INFO | 23000 | 23000 |
| 1792 | ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION | S1000 | 25006 |
| 1845 | ER_ALTER_OPERATION_NOT_SUPPORTED | 0A000 | 0A000 |
| 1846 | ER_ALTER_OPERATION_NOT_SUPPORTED_REASON | 0A000 | 0A000 |
| 1859 | ER_DUP_UNKNOWN_IN_INDEX | 23000 | 23000 |
| 1873 | ER_ACCESS_DENIED_CHANGE_USER_ERROR | 28000 | 28000 |
| 1887 | ER_GET_STACKED_DA_WITHOUT_ACTIVE_HANDLER | S1000 | 0Z002 |
| 1903 | ER_INVALID_ARGUMENT_FOR_LOGARITHM | S1000 | 2201E |
Table of Contents
+ This section provides some general JDBC background. +
+ When you are using JDBC outside of an application server, the
+ DriverManager class manages the establishment
+ of connections.
+
+ Specify to the DriverManager which JDBC
+ drivers to try to make Connections with. The easiest way to do
+ this is to use Class.forName() on the class
+ that implements the java.sql.Driver
+ interface. With MySQL Connector/J, the name of this class is
+ com.mysql.jdbc.Driver. With this method, you
+ could use an external configuration file to supply the driver
+ class name and driver parameters to use when connecting to a
+ database.
+
+ The following section of Java code shows how you might register
+ MySQL Connector/J from the main() method of
+ your application. If testing this code, first read the
+ installation section at
+ Chapter 3, Connector/J Installation, to make sure you have
+ connector installed correctly and the
+ CLASSPATH set up. Also, ensure that MySQL is
+ configured to accept external TCP/IP connections.
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+
+// Notice, do not import com.mysql.jdbc.*
+// or you will have problems!
+
+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
+ }
+ }
+}
+
+ After the driver has been registered with the
+ DriverManager, you can obtain a
+ Connection instance that is connected to a
+ particular database by calling
+ DriverManager.getConnection():
+
Example 6.1 Connector/J: Obtaining a connection from the
+ DriverManager
+ If you have not already done so, please review the portion of
+ Section 6.1, “Connecting to MySQL Using the JDBC DriverManager
+ Interface”
+ above before working with the example below.
+
+ This example shows how you can obtain a
+ Connection instance from the
+ DriverManager. There are a few different
+ signatures for the getConnection()
+ method. Consult the API documentation that comes with your JDK
+ for more specific information on how to use them.
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+
+Connection conn = null;
+...
+try {
+ conn =
+ DriverManager.getConnection("jdbc:mysql://localhost/test?" +
+ "user=minty&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());
+}
+
+ Once a Connection is established, it
+ can be used to create Statement and
+ PreparedStatement objects, as well as
+ retrieve metadata about the database. This is explained in the
+ following sections.
+
+ Statement objects allow you to execute
+ basic SQL queries and retrieve the results through the
+ ResultSet class, which is described later.
+
+ To create a Statement instance, you call
+ the createStatement() method on the
+ Connection object you have retrieved using
+ one of the DriverManager.getConnection() or
+ DataSource.getConnection() methods described
+ earlier.
+
+ Once you have a Statement instance, you
+ can execute a SELECT query by
+ calling the executeQuery(String) method
+ with the SQL you want to use.
+
+ To update data in the database, use the
+ executeUpdate(String SQL) method. This
+ method returns the number of rows matched by the update
+ statement, not the number of rows that were modified.
+
+ If you do not know ahead of time whether the SQL statement will
+ be a SELECT or an
+ UPDATE/INSERT,
+ then you can use the execute(String SQL)
+ method. This method will return true if the SQL query was a
+ SELECT, or false if it was an
+ UPDATE,
+ INSERT, or
+ DELETE statement. If the
+ statement was a SELECT query, you
+ can retrieve the results by calling the
+ getResultSet() method. If the statement was
+ an UPDATE,
+ INSERT, or
+ DELETE statement, you can
+ retrieve the affected rows count by calling
+ getUpdateCount() on the
+ Statement instance.
+
Example 6.2 Connector/J: Using java.sql.Statement to execute a
+ SELECT query
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.sql.ResultSet;
+
+// assume that conn is an already created JDBC connection (see previous examples)
+
+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 ....
+}
+catch (SQLException ex){
+ // handle any errors
+ System.out.println("SQLException: " + ex.getMessage());
+ System.out.println("SQLState: " + ex.getSQLState());
+ System.out.println("VendorError: " + ex.getErrorCode());
+}
+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;
+ }
+}
+
+ Starting with MySQL server version 5.0 when used with
+ Connector/J 3.1.1 or newer, the
+ java.sql.CallableStatement interface is
+ fully implemented with the exception of the
+ getParameterMetaData() method.
+
+ For more information on MySQL stored procedures, please refer to + Using Stored Routines (Procedures and Functions). +
+ Connector/J exposes stored procedure functionality through
+ JDBC's CallableStatement interface.
+
+ Current versions of MySQL server do not return enough
+ information for the JDBC driver to provide result set metadata
+ for callable statements. This means that when using
+ CallableStatement,
+ ResultSetMetaData may return
+ NULL.
+
+ The following example shows a stored procedure that returns the
+ value of inOutParam incremented by 1, and the
+ string passed in using inputParam as a
+ ResultSet:
+
+
Example 6.3 Connector/J: Calling Stored Procedures
+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
+
+
+ To use the demoSp procedure with Connector/J,
+ follow these steps:
+
+ Prepare the callable statement by using
+ Connection.prepareCall().
+
+ Notice that you have to use JDBC escape syntax, and that the + parentheses surrounding the parameter placeholders are not + optional: +
Example 6.4 Connector/J: Using Connection.prepareCall()
+import 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() is an
+ expensive method, due to the metadata retrieval that the
+ driver performs to support output parameters. For
+ performance reasons, minimize unnecessary calls to
+ Connection.prepareCall() by reusing
+ CallableStatement instances in your
+ code.
+
+ Register the output parameters (if any exist) +
+ To retrieve the values of output parameters (parameters
+ specified as OUT or
+ INOUT when you created the stored
+ procedure), JDBC requires that they be specified before
+ statement execution using the various
+ registerOutputParameter() methods in
+ the CallableStatement interface:
+
+
Example 6.5 Connector/J: Registering output parameters
+import 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, and
+// uses the type 'INTEGER' for values returned from
+// getObject()
+//
+
+cStmt.registerOutParameter(2, Types.INTEGER);
+
+//
+// Registers the named parameter 'inOutParam', and
+// uses the type 'INTEGER' for values returned from
+// getObject()
+//
+
+cStmt.registerOutParameter("inOutParam", Types.INTEGER);
+...
+
+
+ Set the input parameters (if any exist) +
+ Input and in/out parameters are set as for
+ PreparedStatement objects. However,
+ CallableStatement also supports
+ setting parameters by name:
+
+
Example 6.6 Connector/J: Setting CallableStatement input
+ parameters
+...
+
+ //
+ // 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);
+
+...
+
+
+ Execute the CallableStatement, and
+ retrieve any result sets or output parameters.
+
+ Although CallableStatement supports
+ calling any of the Statement execute
+ methods (executeUpdate(),
+ executeQuery() or
+ execute()), the most flexible method to
+ call is execute(), as you do not need
+ to know ahead of time if the stored procedure returns result
+ sets:
+
+
Example 6.7 Connector/J: Retrieving results and output parameter values
+...
+
+ 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(2); // index-based
+
+ outputValue = cStmt.getInt("inOutParam"); // name-based
+
+...
+
+
+ Before version 3.0 of the JDBC API, there was no standard way of
+ retrieving key values from databases that supported auto
+ increment or identity columns. With older JDBC drivers for
+ MySQL, you could always use a MySQL-specific method on the
+ Statement interface, or issue the query
+ SELECT LAST_INSERT_ID() after issuing an
+ INSERT to a table that had an
+ AUTO_INCREMENT key. Using the MySQL-specific
+ method call isn't portable, and issuing a
+ SELECT to get the
+ AUTO_INCREMENT key's value requires another
+ round-trip to the database, which isn't as efficient as
+ possible. The following code snippets demonstrate the three
+ different ways to retrieve AUTO_INCREMENT
+ values. First, we demonstrate the use of the new JDBC 3.0 method
+ getGeneratedKeys() which is now the
+ preferred method to use if you need to retrieve
+ AUTO_INCREMENT keys and have access to JDBC
+ 3.0. The second example shows how you can retrieve the same
+ value using a standard SELECT
+ LAST_INSERT_ID() query. The final example shows how
+ updatable result sets can retrieve the
+ AUTO_INCREMENT value when using the
+ insertRow() method.
+
Example 6.8 Connector/J: Retrieving AUTO_INCREMENT column values
+ using Statement.getGeneratedKeys()
+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();
+
+ //
+ // 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
+ }
+
+ 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
+ }
+ }
+}
+Example 6.9 Connector/J: Retrieving AUTO_INCREMENT column values
+ using SELECT LAST_INSERT_ID()
+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
+ }
+
+ 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
+ }
+ }
+}
+Example 6.10 Connector/J: Retrieving AUTO_INCREMENT column values
+ in Updatable ResultSets
+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");
+
+ 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
+ }
+ }
+}
++ Running the preceding example code should produce the following + output: +
+Key returned from getGeneratedKeys(): 1 +Key returned from SELECT LAST_INSERT_ID(): 1 +Key returned for inserted row: 1 +
+ At times, it can be tricky to use the SELECT
+ LAST_INSERT_ID() query, as that function's value is
+ scoped to a connection. So, if some other query happens on the
+ same connection, the value is overwritten. On the other hand,
+ the getGeneratedKeys() method is scoped by
+ the Statement instance, so it can be used
+ even if other queries happen on the same connection, but not on
+ the same Statement instance.
+
+ Connection pooling is a technique of creating and managing a pool + of connections that are ready for use by any + thread that needs them. + Connection pooling can greatly increase the performance of your + Java application, while reducing overall resource usage. +
+ Most applications only need a thread to have access to a JDBC + connection when they are actively processing a + transaction, which often + takes only milliseconds to complete. When not processing a + transaction, the connection sits idle. Connection pooling enables + the idle connection to be used by some other thread to do useful + work. +
+ In practice, when a thread needs to do work against a MySQL or + other database with JDBC, it requests a connection from the pool. + When the thread is finished using the connection, it returns it to + the pool, so that it can be used by any other threads. +
+ When the connection is loaned out from the pool, it is used
+ exclusively by the thread that requested it. From a programming
+ point of view, it is the same as if your thread called
+ DriverManager.getConnection() every time it
+ needed a JDBC connection. With connection pooling, your thread may
+ end up using either a new connection or an already-existing
+ connection.
+
+ The main benefits to connection pooling are: +
+ Reduced connection creation time. +
+ Although this is not usually an issue with the quick + connection setup that MySQL offers compared to other + databases, creating new JDBC connections still incurs + networking and JDBC driver overhead that will be avoided if + connections are recycled. +
+ Simplified programming model. +
+ When using connection pooling, each individual thread can act + as though it has created its own JDBC connection, allowing you + to use straightforward JDBC programming techniques. +
+ Controlled resource usage. +
+ If you create a new connection every time a thread needs one + rather than using connection pooling, your application's + resource usage can be wasteful, and it could lead to + unpredictable behaviors for your application when it is under + a heavy load. +
+ The concept of connection pooling in JDBC has been standardized + through the JDBC 2.0 Optional interfaces, and all major + application servers have implementations of these APIs that work + with MySQL Connector/J. +
+ Generally, you configure a connection pool in your application + server configuration files, and access it through the Java Naming + and Directory Interface (JNDI). The following code shows how you + might use a connection pool from an application deployed in a J2EE + application server: + +
Example 7.1 Connector/J: Using a connection pool with a J2EE application server
+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 permits 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;
+ }
+ }
+ }
+}
+
+
+ As shown in the example above, after obtaining the JNDI
+ InitialContext, and looking up the
+ DataSource, the rest of the code follows
+ familiar JDBC conventions.
+
+ When using connection pooling, always make sure that connections, + and anything created by them (such as statements or result sets) + are closed. This rule applies no matter what happens in your code + (exceptions, flow-of-control, and so forth). When these objects + are closed, they can be re-used; otherwise, they will be stranded, + which means that the MySQL server resources they represent (such + as buffers, locks, or sockets) are tied up for some time, or in + the worst case can be tied up forever. +
+ Each connection to MySQL has overhead (memory, CPU, context + switches, and so forth) on both the client and server side. Every + connection limits how many resources there are available to your + application as well as the MySQL server. Many of these resources + will be used whether or not the connection is actually doing any + useful work! Connection pools can be tuned to maximize + performance, while keeping resource utilization below the point + where your application will start to fail rather than just run + slower. +
+ The optimal size for the connection pool depends on anticipated + load and average database transaction time. In practice, the + optimal connection pool size can be smaller than you might expect. + If you take Oracle's Java Petstore blueprint application for + example, a connection pool of 15-20 connections can serve a + relatively moderate load (600 concurrent users) using MySQL and + Tomcat with acceptable response times. +
+ To correctly size a connection pool for your application, create + load test scripts with tools such as Apache JMeter or The Grinder, + and load test your application. +
+ An easy way to determine a starting point is to configure your + connection pool's maximum number of connections to be unbounded, + run a load test, and measure the largest amount of concurrently + used connections. You can then work backward from there to + determine what values of minimum and maximum pooled connections + give the best performance for your particular application. +
+ MySQL Connector/J can validate the connection by executing a + lightweight ping against a server. In the case of load-balanced + connections, this is performed against all active pooled internal + connections that are retained. This is beneficial to Java + applications using connection pools, as the pool can use this + feature to validate connections. Depending on your connection pool + and configuration, this validation can be carried out at different + times: +
+ Before the pool returns a connection to the application. +
+ When the application returns a connection to the pool. +
+ During periodic checks of idle connections. +
+ To use this feature, specify a validation query in your connection
+ pool that starts with /* ping */. Note that the
+ syntax must be exactly as specified. This will cause the driver
+ send a ping to the server and return a dummy lightweight result
+ set. When using a ReplicationConnection or
+ LoadBalancedConnection, the ping will be sent
+ across all active connections.
+
+ It is critical that the syntax be specified correctly. The syntax + needs to be exact for reasons of efficiency, as this test is done + for every statement that is executed: +
+
+protected static final String PING_MARKER = "/* ping */";
+...
+if (sql.charAt(0) == '/') {
+if (sql.startsWith(PING_MARKER)) {
+doPingInstead();
+...
+
++ None of the following snippets will work, because the ping syntax + is sensitive to whitespace, capitalization, and placement: +
+sql = "/* PING */ SELECT 1"; +sql = "SELECT 1 /* ping*/"; +sql = "/*ping*/ SELECT 1"; +sql = " /* ping */ SELECT 1"; +sql = "/*to ping or not to ping*/ SELECT 1"; +
+ All of the previous statements will issue a normal
+ SELECT statement and will
+ not be transformed into the
+ lightweight ping. Further, for load-balanced connections, the
+ statement will be executed against one connection in the internal
+ pool, rather than validating each underlying physical connection.
+ This results in the non-active physical connections assuming a
+ stale state, and they may die. If Connector/J then re-balances, it
+ might select a dead connection, resulting in an exception being
+ passed to the application. To help prevent this, you can use
+ loadBalanceValidateConnectionOnSwapServer to
+ validate the connection before use.
+
+ If your Connector/J deployment uses a connection pool that allows
+ you to specify a validation query, take advantage of it, but
+ ensure that the query starts exactly with
+ /* ping */. This is particularly important if
+ you are using the load-balancing or replication-aware features of
+ Connector/J, as it will help keep alive connections which
+ otherwise will go stale and die, causing problems later.
+
Table of Contents
+ The following sections discuss a number of topics that involve + multi-host connections, namely, server load-balancing, failover, + and replication. +
+ Developers should know the following things about multi-host + connections that are managed through Connector/J: + +
+ Each multi-host connection is a wrapper of the underlying + physical connections. +
+ Each of the underlying physical connections has its own + session. Sessions cannot be tracked, shared, or copied, + given the MySQL architecture. +
+ Every switch between physical connections means a switch + between sessions. +
+ Within a transaction boundary, there are no switches between + physical connections. Beyond a transaction boundary, there + is no guarantee that a switch does not occur. +
+ If an application reuses session-scope data (for example, + variables, SSPs) beyond a transaction boundary, failures + are possible, as a switch between the physical connections + (which is also a switch between sessions) might occur. + Therefore, the application should re-prepare the session + data and also restart the last transaction in case of an + exception, or it should re-prepare session data for each + new transaction if it does not want to deal with exception + handling. +
+
+ MySQL Connector/J supports server failover. A failover happens
+ when connection-related errors occur for an underlying, active
+ connection. The connection errors are, by default, propagated to
+ the client, which has to handle them by, for example, recreating
+ the working objects (Statement,
+ ResultSet, etc.) and restarting the
+ processes. Sometimes, the driver might eventually fall back to
+ the original host automatically before the client application
+ continues to run, in which case the host switch is transparent
+ and the client application will not even notice it.
+
+
+ A connection using failover support works just like a standard + connection: the client does not experience any disruptions in + the failover process. This means the client can rely on the same + connection instance even if two successive statements might be + executed on two different physical hosts. However, this does not + mean the client does not have to deal with the exception that + triggered the server switch. +
+ The failover is configured at the initial setup stage of the + server connection by the connection URL (see explanations for + its format + here): + +
+jdbc:mysql://[primary host][:port],[secondary host 1][:port][,[secondary host 2][:port]]...[/[database]]» +[?propertyName1=propertyValue1[&propertyName2=propertyValue2]...] +
+
+ The host list in the connection URL comprises of two types of + hosts, the primary and the secondary. When starting a new + connection, the driver always tries to connect to the primary + host first and, if required, fails over to the secondary hosts + on the list sequentially when communication problems are + experienced. Even if the initial connection to the primary host + fails and the driver gets connected to a secondary host, the + primary host never loses its special status: for example, it can + be configured with an access mode distinct from those of the + secondary hosts, and it can be put on a higher priority when a + host is to be picked during a failover process. +
+ The failover support is configured by the following connection + properties (their functions are explained in the paragraphs + below): + +
+ failOverReadOnly
+
+ secondsBeforeRetryMaster
+
+ queriesBeforeRetryMaster
+
+ retriesAllDown
+
+ autoReconnect
+
+ autoReconnectForPools
+
+
+ As with any standard connection, the initial connection to the
+ primary host is in read/write mode. However, if the driver fails
+ to establish the initial connection to the primary host and it
+ automatically switches to the next host on the list, the access
+ mode now depends on the value of the property
+ failOverReadOnly, which is
+ “true” by default. The same happens if the driver
+ is initially connected to the primary host and, because of some
+ connection failure, it fails over to a secondary host. Every
+ time the connection falls back to the primary host, its access
+ mode will be read/write, irrespective of whether or not the
+ primary host has been connected to before. The connection access
+ mode can be changed any time at runtime by calling the
+ method Connection.setReadOnly(boolean), which
+ partially overrides the property
+ failOverReadOnly. When
+ failOverReadOnly=false and the access mode is
+ explicitly set to either true or false, it becomes the mode for
+ every connection after a host switch, no matter what host type
+ are we connected to; but, if
+ failOverReadOnly=true, changing the access
+ mode to read/write is only possible if the driver is connecting
+ to the primary host; however, even if the access mode cannot be
+ changed for the current connection, the driver remembers the
+ client's last intention and, when falling back to the primary
+ host, that is the mode that will be used. For an illustration,
+ see the following successions of events with a two-host
+ connection.
+
+
+ Sequence A, with failOverReadOnly=true:
+
+
+ Connects to primary host in read/write mode +
+ Sets
+ Connection.setReadOnly(true);
+ primary host now in read-only mode
+
+ Failover event; connects to secondary host in + read-only mode +
+ Sets
+ Connection.setReadOnly(false);
+ secondary host remains in read-only mode
+
+ Falls back to primary host; connection now in + read/write mode +
+
+ Sequence B, with failOverReadOnly=false
+
+ Connects to primary host in read/write mode +
+ Sets Connection.setReadOnly(true);
+ primary host now in read-only mode
+
+ Failover event; connects to secondary host in + read-only mode +
+ Set Connection.setReadOnly(false);
+ connection to secondary host switches to read/write
+ mode
+
+ Falls back to primary host; connection now in + read/write mode +
+
+ The difference between the two scenarios is in step 4: the + access mode for the secondary host in sequence A does not change + at that step, but the driver remembers and uses the set mode + when falling back to the primary host, which would be read-only + otherwise; but in sequence B, the access mode for the secondary + host changes immediately. +
+ As already mentioned, the primary host is special in the
+ failover arrangement when it comes to the host's access mode.
+ Additionally, the driver tries to fall back to the primary host
+ as soon as possible by default, even if no communication
+ exception occurs. Two properties,
+ secondsBeforeRetryMaster and
+ queriesBeforeRetryMaster, determine when the
+ driver is ready to retry a reconnection to the primary host (the
+ Master in the property names stands for the
+ primary host of our connection URL, which is not necessarily a
+ master host in a replication setup; the naming was maintained
+ for back compatibility with Connector/J versions prior to
+ 5.1.35):
+
+
+ secondsBeforeRetryMaster determines how
+ much time the driver waits before trying to fall back to
+ the primary host
+
+ queriesBeforeRetryMaster determines the
+ number of queries that are executed before the driver
+ tries to fall back to the primary host. Note that for the
+ driver, each call to a
+ Statement.execute*() method increments
+ the query execution counter; therefore, when calls are
+ made to Statement.executeBatch() or if
+ allowMultiQueries or
+ rewriteBatchStatements are enabled, the
+ driver may not have an accurate count of the actual number
+ of queries executed on the server. Also, the driver calls
+ the Statement.execute*() methods
+ internally in several occasions. All these mean you can
+ only use queriesBeforeRetryMaster only
+ as a coarse specification for when to fall back to the
+ primary host.
+
+
+ In general, an attempt to fallback to the primary host is made
+ when at least one of the conditions specified by the two
+ properties is met, and the attempt always takes place at
+ transaction boundaries. However, if auto-commit is turned off,
+ the check happens only when the method
+ Connection.commit() or
+ Connection.rollback() is called. The
+ automatic fallback to the primary host can be turned off by
+ setting simultaneously
+ secondsBeforeRetryMaster and
+ queriesBeforeRetryMaster to “0”.
+ Setting only one of the properties to “0” only
+ disables one part of the check.
+
+ When establishing a new connection or when a failover event
+ occurs, the driver tries to connect successively to the next
+ candidate on the host list. When the end of the list has been
+ reached, it restarts all over again from the beginning of the
+ list; however, the primary host is skipped over, if (a) NOT all
+ the secondary hosts have already been tested at least once, AND
+ (b) the fallback conditions defined by
+ secondsBeforeRetryMaster and
+ queriesBeforeRetryMaster are not yet
+ fulfilled. Each run-through of the whole host list, (which is
+ not necessarily completed at the end of the host list) counts as
+ a single connection attempt. The driver tries as many connection
+ attempts as specified by the value of the property
+ retriesAllDown.
+
+ Although not recommended, you can make the driver perform
+ failovers without invalidating the active
+ Statement or ResultSet
+ instances by setting either the parameter
+ autoReconnect or
+ autoReconnectForPools to
+ true. This allows the client to continue
+ using the same object instances after a failover event, without
+ taking any exceptional measures. This, however, may lead to
+ unexpected results: for example, if the driver is connected to
+ the primary host with read/write access mode and it fails-over
+ to a secondary host in real-only mode, further attempts to issue
+ data-changing queries will result in errors, and the client will
+ not be aware of that. This limitation is particularly relevant
+ when using data streaming: after the failover, the
+ ResultSet looks to be alright, but the
+ underlying connection may have changed already, and no backing
+ cursor is available anymore.
+
+ Connector/J has long provided an effective means to distribute + read/write load across multiple MySQL server instances for + Cluster or master-master replication deployments. Starting with + Connector/J 5.1.3, you can now dynamically configure + load-balanced connections, with no service outage. In-process + transactions are not lost, and no application exceptions are + generated if any application is trying to use that particular + server instance. +
+ The load balancing is configured at the initial setup stage of + the server connection by the following connection URL, which has + a similar format as + the general URL + for MySQL connection, but a specialized scheme: + +
+jdbc:mysql:loadbalance://[host1][:port],[host2][:port][,[host3][:port]]...[/[database]] » +[?propertyName1=propertyValue1[&propertyName2=propertyValue2]...] +
+
+ There are two configuration properties associated with this + functionality: +
+ loadBalanceConnectionGroup – This
+ provides the ability to group connections from different
+ sources. This allows you to manage these JDBC sources within
+ a single class loader in any combination you choose. If they
+ use the same configuration, and you want to manage them as a
+ logical single group, give them the same name. This is the
+ key property for management: if you do not define a name
+ (string) for loadBalanceConnectionGroup,
+ you cannot manage the connections. All load-balanced
+ connections sharing the same
+ loadBalanceConnectionGroup value,
+ regardless of how the application creates them, will be
+ managed together.
+
+ loadBalanceEnableJMX – The ability to
+ manage the connections is exposed when you define a
+ loadBalanceConnectionGroup; but if you
+ want to manage this externally, enable JMX by setting this
+ property to true. This enables a JMX
+ implementation, which exposes the management and monitoring
+ operations of a connection group. Further, start your
+ application with the
+ -Dcom.sun.management.jmxremote JVM flag.
+ You can then perform connect and perform operations using a
+ JMX client such as jconsole.
+
+ Once a connection has been made using the correct connection + properties, a number of monitoring properties are available: +
+ Current active host count. +
+ Current active physical connection count. +
+ Current active logical connection count. +
+ Total logical connections created. +
+ Total transaction count. +
+ The following management operations can also be performed: +
+ Add host. +
+ Remove host. +
+ The JMX interface,
+ com.mysql.jdbc.jmx.LoadBalanceConnectionGroupManagerMBean,
+ has the following methods:
+
+ int getActiveHostCount(String group);
+
+ int getTotalHostCount(String group);
+
+ long getTotalLogicalConnectionCount(String
+ group);
+
+ long getActiveLogicalConnectionCount(String
+ group);
+
+ long getActivePhysicalConnectionCount(String
+ group);
+
+ long getTotalPhysicalConnectionCount(String
+ group);
+
+ long getTotalTransactionCount(String
+ group);
+
+ void removeHost(String group, String host) throws
+ SQLException;
+
+ void stopNewConnectionsToHost(String group, String
+ host) throws SQLException;
+
+ void addHost(String group, String host, boolean
+ forExisting);
+
+ String getActiveHostsList(String group);
+
+ String getRegisteredConnectionGroups();
+
+ The getRegisteredConnectionGroups() method
+ returns the names of all connection groups defined in that class
+ loader.
+
+ You can test this setup with the following code: +
+
+public class Test {
+
+ private static String URL = "jdbc:mysql:loadbalance://" +
+ "localhost:3306,localhost:3310/test?" +
+ "loadBalanceConnectionGroup=first&loadBalanceEnableJMX=true";
+
+ public static void main(String[] args) throws Exception {
+ new Thread(new Repeater()).start();
+ new Thread(new Repeater()).start();
+ new Thread(new Repeater()).start();
+ }
+
+ static Connection getNewConnection() throws SQLException, ClassNotFoundException {
+ Class.forName("com.mysql.jdbc.Driver");
+ return DriverManager.getConnection(URL, "root", "");
+ }
+
+ static void executeSimpleTransaction(Connection c, int conn, int trans){
+ try {
+ c.setAutoCommit(false);
+ Statement s = c.createStatement();
+ s.executeQuery("SELECT SLEEP(1) /* Connection: " + conn + ", transaction: " + trans + " */");
+ c.commit();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static class Repeater implements Runnable {
+ public void run() {
+ for(int i=0; i < 100; i++){
+ try {
+ Connection c = getNewConnection();
+ for(int j=0; j < 10; j++){
+ executeSimpleTransaction(c, i, j);
+ Thread.sleep(Math.round(100 * Math.random()));
+ }
+ c.close();
+ Thread.sleep(100);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+}
+
+
+ After compiling, the application can be started with the
+ -Dcom.sun.management.jmxremote flag, to
+ enable remote management. jconsole can then
+ be started. The Test main class will be
+ listed by jconsole. Select this and click
+ . You can then navigate to the
+ com.mysql.jdbc.jmx.LoadBalanceConnectionGroupManager
+ bean. At this point, you can click on various operations and
+ examine the returned result.
+
+ If you now had an additional instance of MySQL running on port
+ 3309, you could ensure that Connector/J starts using it by using
+ the addHost(), which is exposed in
+ jconsole. Note that these operations can be
+ performed dynamically without having to stop the application
+ running.
+
+ For further information on the combination of load balancing and + failover, see + Section 8.4, “Advanced Load-balancing and Failover Configuration”. +
+ This section describe a number of features of Connector/J's + support for replication-aware deployments. + + +
+ The replication is configured at the initial setup stage of the + server connection by the connection URL, which has a similar + format as the + general URL for MySQL connection, but a specialized + scheme: + +
+jdbc:mysql:replication://[master host][:port],[slave host 1][:port][,[slave host 2][:port]]...[/[database]] » +[?propertyName1=propertyValue1[&propertyName2=propertyValue2]...] +
+
+ Users may specify the property
+ allowMasterDownConnections=true to allow
+ Connection objects to be created even though
+ no master hosts are reachable. Such
+ Connection objects report they are read-only,
+ and isMasterConnection() returns false for
+ them. The Connection tests for available
+ master hosts when
+ Connection.setReadOnly(false) is called,
+ throwing an SQLException if it cannot establish a connection to
+ a master, or switching to a master connection if the host is
+ available.
+
+ For Connector/J 5.1.38 and later, users may specify the
+ property allowSlavesDownConnections=true to
+ allow Connection objects to be created even
+ though no slave hosts are reachable. A
+ Connection then, at runtime, tests for
+ available slave hosts when
+ Connection.setReadOnly(true) is called (see
+ explanation for the method below), throwing an SQLException if
+ it cannot establish a connection to a slave, unless the property
+ readFromMasterWhenNoSlaves is set
+ to be “true” (see below for a description of the
+ property).
+
+ Connector/J 3.1.7 and higher includes a variant of the driver
+ that will automatically send queries to a read/write master, or
+ a failover or round-robin loadbalanced set of slaves based on
+ the state of Connection.getReadOnly().
+
+ An application signals that it wants a transaction to be
+ read-only by calling
+ Connection.setReadOnly(true). The
+ replication-aware connection will use one of the slave
+ connections, which are load-balanced per slave host using a
+ round-robin scheme. A given connection is sticky to a slave
+ until a transaction boundary command (a commit or rollback) is
+ issued, or until the slave is removed from service. For
+ Connector/J 5.1.38 and later, after calling
+ Connection.setReadOnly(true), if you want to
+ allow connection to a master when no slaves are available, set
+ the property
+ readFromMasterWhenNoSlaves to
+ “true.” Notice that the master host will be used in
+ read-only state in those cases, as if it is a slave host. Also
+ notice that setting
+ readFromMasterWhenNoSlaves=true
+ might result in an extra load for the master host in a
+ transparent manner.
+
+ If you have a write transaction, or if you have a read that is
+ time-sensitive (remember, replication in MySQL is asynchronous),
+ set the connection to be not read-only, by calling
+ Connection.setReadOnly(false) and the driver
+ will ensure that further calls are sent to the master MySQL
+ server. The driver takes care of propagating the current state
+ of autocommit, isolation level, and catalog between all of the
+ connections that it uses to accomplish this load balancing
+ functionality.
+
+ To enable this functionality, use the
+ com.mysql.jdbc.ReplicationDriver class when
+ configuring your application server's connection pool or when
+ creating an instance of a JDBC driver for your standalone
+ application. Because it accepts the same URL format as the
+ standard MySQL JDBC driver, ReplicationDriver
+ does not currently work with
+ java.sql.DriverManager-based connection
+ creation unless it is the only MySQL JDBC driver registered with
+ the DriverManager .
+
+ Here is a short example of how
+ ReplicationDriver might be used in a
+ standalone application:
+
+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:replication://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 FROM alt_table");
+
+ .......
+ }
+}
++ Consider using the Load Balancing JDBC Pool + (lbpool) tool, which provides a wrapper + around the standard JDBC driver and enables you to use DB + connection pools that includes checks for system failures and + uneven load distribution. For more information, see + Load + Balancing JDBC Driver for MySQL (mysql-lbpool). +
+ Since Connector/J 5.1.27, multi-master replication topographies + are supported. +
+ The connection URL for replication discussed earlier (i.e., in
+ the format of
+ jdbc:mysql:replication://master,slave1,slave2,slave3/test)
+ assumes that the first (and only the first) host is the master.
+ Supporting deployments with an arbitrary number of masters and
+ slaves requires a different URL syntax for specifying the hosts
+ and the properties for specific hosts, which is just an
+ expansion of the URL syntax discussed in
+ IPv6 Connections with the
+ property type=[master|slave]; for example:
+
+
jdbc:mysql://address=(type=master)(host=master1host),address=(type=master)(host=master2host),address=(type=slave)(host=slave1host)/database
+
+ Connector/J uses a load-balanced connection internally for
+ management of the master connections, which means that
+ ReplicationConnection, when configured to use
+ multiple masters, exposes the same options to balance load
+ across master hosts as described in
+ Section 8.2, “Configuring Load Balancing with Connector/J”.
+
+ Since Connector/J 5.1.28, live management of replication host + (single or multi-master) topographies is also supported. This + enables users to promote slaves for Java applications without + requiring an application restart. +
+ The replication hosts are most effectively managed in the
+ context of a replication connection group. A
+ ReplicationConnectionGroup class represents a logical grouping
+ of connections which can be managed together. There may be one
+ or more such replication connection groups in a given Java class
+ loader (there can be an application with two different JDBC
+ resources needing to be managed independently). This key class
+ exposes host management methods for replication connections, and
+ ReplicationConnection objects register
+ themselves with the appropriate
+ ReplicationConnectionGroup if a value for the
+ new replicationConnectionGroup property is
+ specified. The ReplicationConnectionGroup
+ object tracks these connections until they are closed, and it is
+ used to manipulate the hosts associated with these connections.
+
+ Some important methods related to host management include: + +
+ getMasterHosts(): Returns a collection
+ of strings representing the hosts configured as masters
+
+ getSlaveHosts(): Returns a collection
+ of strings representing the hosts configured as slaves
+
+ addSlaveHost(String host): Adds new
+ host to pool of possible slave hosts for selection at
+ start of new read-only workload
+
+ promoteSlaveToMaster(String host):
+ Removes the host from the pool of potential slaves for
+ future read-only processes (existing read-only process is
+ allowed to continue to completion) and adds the host to
+ the pool of potential master hosts
+
+ removeSlaveHost(String host, boolean
+ closeGently): Removes the host (host name match
+ must be exact) from the list of configured slaves; if
+ closeGently is false, existing
+ connections which have this host as currently active will
+ be closed hardly (application should expect exceptions)
+
+ removeMasterHost(String host, boolean
+ closeGently): Same as
+ removeSlaveHost(), but removes the host
+ from the list of configured masters
+
+
+ Some useful management metrics include: + +
+ getConnectionCountWithHostAsSlave(String
+ host): Returns the number of
+ ReplicationConnection objects that have the given host
+ configured as a possible slave
+
+ getConnectionCountWithHostAsMaster(String
+ host): Returns the number of
+ ReplicationConnection objects that have the given host
+ configured as a possible master
+
+ getNumberOfSlavesAdded(): Returns the
+ number of times a slave host has been dynamically added to
+ the group pool
+
+ getNumberOfSlavesRemoved(): Returns the
+ number of times a slave host has been dynamically removed
+ from the group pool
+
+ getNumberOfSlavePromotions(): Returns
+ the number of times a slave host has been promoted to a
+ master
+
+ getTotalConnectionCount(): Returns the
+ number of ReplicationConnection objects which have been
+ registered with this group
+
+ getActiveConnectionCount(): Returns the
+ number of ReplicationConnection objects currently being
+ managed by this group
+
+
+ com.mysql.jdbc.ReplicationConnectionGroupManager
+ provides access to the replication connection groups, together
+ with some utility methods.
+
+
+ getConnectionGroup(String groupName):
+ Returns the ReplicationConnectionGroup
+ object matching the groupName provided
+
+
+ The other methods in
+ ReplicationConnectionGroupManager mirror
+ those of ReplicationConnectionGroup, except
+ that the first argument is a String group name. These methods
+ will operate on all matching ReplicationConnectionGroups, which
+ are helpful for removing a server from service and have it
+ decommissioned across all possible
+ ReplicationConnectionGroups.
+
+ These methods might be useful for in-JVM management of + replication hosts if an application triggers topography changes. + For managing host configurations from outside the JVM, JMX can + be used. +
+ When Connector/J is started with
+ replicationEnableJMX=true and a value set for
+ the property replicationConnectionGroup, a
+ JMX MBean will be registered, allowing manipulation of
+ replication hosts by a JMX client. The MBean interface is
+ defined in
+ com.mysql.jdbc.jmx.ReplicationGroupManagerMBean,
+ and leverages the
+ ReplicationConnectionGroupManager static
+ methods:
+
+ public abstract void addSlaveHost(String groupFilter, String host) throws SQLException; + public abstract void removeSlaveHost(String groupFilter, String host) throws SQLException; + public abstract void promoteSlaveToMaster(String groupFilter, String host) throws SQLException; + public abstract void removeMasterHost(String groupFilter, String host) throws SQLException; + public abstract String getMasterHostsList(String group); + public abstract String getSlaveHostsList(String group); + public abstract String getRegisteredConnectionGroups(); + public abstract int getActiveMasterHostCount(String group); + public abstract int getActiveSlaveHostCount(String group); + public abstract int getSlavePromotionCount(String group); + public abstract long getTotalLogicalConnectionCount(String group); + public abstract long getActiveLogicalConnectionCount(String group); +
+ Connector/J provides a useful load-balancing implementation for
+ MySQL Cluster or multi-master deployments, as explained in
+ Section 8.2, “Configuring Load Balancing with Connector/J”
+ and
+ Support for Multiple-Master Replication Topographies.
+ As of Connector/J 5.1.12, this same implementation is used for
+ balancing load between read-only slaves with
+ ReplicationDriver.
+
+ When trying to balance workload between multiple servers, the + driver has to determine when it is safe to swap servers, doing + so in the middle of a transaction, for example, could cause + problems. It is important not to lose state information. For + this reason, Connector/J will only try to pick a new server when + one of the following happens: +
+ At transaction boundaries (transactions are explicitly + committed or rolled back). +
+ A communication exception (SQL State starting with "08") is + encountered. +
+ When a SQLException matches conditions
+ defined by user, using the extension points defined by the
+ loadBalanceSQLStateFailover,
+ loadBalanceSQLExceptionSubclassFailover
+ or loadBalanceExceptionChecker
+ properties.
+
+ The third condition revolves around three new properties
+ introduced with Connector/J 5.1.13. It allows you to control
+ which SQLExceptions trigger failover.
+
+ loadBalanceExceptionChecker - The
+ loadBalanceExceptionChecker property is
+ really the key. This takes a fully-qualified class name
+ which implements the new
+ com.mysql.jdbc.LoadBalanceExceptionChecker
+ interface. This interface is very simple, and you only need
+ to implement the following method:
+
+public boolean shouldExceptionTriggerFailover(SQLException ex) +
+ A SQLException is passed in, and a
+ boolean returned. A value of true
+ triggers a failover, false does not.
+
+ You can use this to implement your own custom logic. An + example where this might be useful is when dealing with + transient errors when using MySQL Cluster, where certain + buffers may become overloaded. The following code snippet + illustrates this: +
+
+public class NdbLoadBalanceExceptionChecker
+ extends StandardLoadBalanceExceptionChecker {
+
+ public boolean shouldExceptionTriggerFailover(SQLException ex) {
+ return super.shouldExceptionTriggerFailover(ex)
+ || checkNdbException(ex);
+ }
+
+ private boolean checkNdbException(SQLException ex){
+ // Have to parse the message since most NDB errors
+ // are mapped to the same DEMC.
+ return (ex.getMessage().startsWith("Lock wait timeout exceeded") ||
+ (ex.getMessage().startsWith("Got temporary error")
+ && ex.getMessage().endsWith("from NDB")));
+ }
+}
+
+
+ The code above extends
+ com.mysql.jdbc.StandardLoadBalanceExceptionChecker,
+ which is the default implementation. There are a few
+ convenient shortcuts built into this, for those who want to
+ have some level of control using properties, without writing
+ Java code. This default implementation uses the two
+ remaining properties:
+ loadBalanceSQLStateFailover and
+ loadBalanceSQLExceptionSubclassFailover.
+
+ loadBalanceSQLStateFailover - allows you
+ to define a comma-delimited list of
+ SQLState code prefixes, against which a
+ SQLException is compared. If the prefix
+ matches, failover is triggered. So, for example, the
+ following would trigger a failover if a given
+ SQLException starts with "00", or is
+ "12345":
+
+loadBalanceSQLStateFailover=00,12345 +
+ loadBalanceSQLExceptionSubclassFailover -
+ can be used in conjunction with
+ loadBalanceSQLStateFailover or on its
+ own. If you want certain subclasses of
+ SQLException to trigger failover, simply
+ provide a comma-delimited list of fully-qualified class or
+ interface names to check against. For example, if you want
+ all SQLTransientConnectionExceptions to
+ trigger failover, you would specify:
+
+loadBalanceSQLExceptionSubclassFailover=java.sql.SQLTransientConnectionException +
+ While the three failover conditions enumerated earlier suit most
+ situations, if autocommit is enabled,
+ Connector/J never re-balances, and continues using the same
+ physical connection. This can be problematic, particularly when
+ load-balancing is being used to distribute read-only load across
+ multiple slaves. However, Connector/J can be configured to
+ re-balance after a certain number of statements are executed,
+ when autocommit is enabled. This
+ functionality is dependent upon the following properties:
+
+ loadBalanceAutoCommitStatementThreshold
+ – defines the number of matching statements which will
+ trigger the driver to potentially swap physical server
+ connections. The default value, 0, retains the behavior that
+ connections with autocommit enabled are
+ never balanced.
+
+ loadBalanceAutoCommitStatementRegex –
+ the regular expression against which statements must match.
+ The default value, blank, matches all statements. So, for
+ example, using the following properties will cause
+ Connector/J to re-balance after every third statement that
+ contains the string “test”:
+
+loadBalanceAutoCommitStatementThreshold=3 +loadBalanceAutoCommitStatementRegex=.*test.* +
+ loadBalanceAutoCommitStatementRegex can
+ prove useful in a number of situations. Your application may
+ use temporary tables, server-side session state variables,
+ or connection state, where letting the driver arbitrarily
+ swap physical connections before processing is complete
+ could cause data loss or other problems. This allows you to
+ identify a trigger statement that is only executed when it
+ is safe to swap physical connections.
+
+ An interceptor is a software design pattern that provides a + transparent way to extend or modify some aspect of a program, + similar to a user exit. No recompiling is required. With + Connector/J, the interceptors are enabled and disabled by updating + the connection string to refer to different sets of interceptor + classes that you instantiate. +
+ The connection properties that control the interceptors are + explained in + Section 5.1, “Driver/Datasource Class Names, URL Syntax and Configuration Properties + for Connector/J”: +
+ connectionLifecycleInterceptors, where you
+ specify the fully qualified names of classes that implement
+ the
+ com.mysql.jdbc.ConnectionLifecycleInterceptor
+ interface. In these kinds of interceptor classes, you might
+ log events such as rollbacks, measure the time between
+ transaction start and end, or count events such as calls to
+ setAutoCommit().
+
+ exceptionInterceptors, where you specify
+ the fully qualified names of classes that implement the
+ com.mysql.jdbc.ExceptionInterceptor
+ interface. In these kinds of interceptor classes, you might
+ add extra diagnostic information to exceptions that can have
+ multiple causes or indicate a problem with server settings.
+ Because exceptionInterceptors classes are
+ only called when handling a SQLException
+ thrown from Connector/J code, they can be used even in
+ production deployments without substantial performance
+ overhead.
+
+ statementInterceptors, where you specify
+ the fully qualified names of classes that implement the
+ com.mysql.jdbc.StatementInterceptorV2
+ interface. In these kinds of interceptor classes, you might
+ change or augment the processing done by certain kinds of
+ statements, such as automatically checking for queried data in
+ a memcached server, rewriting slow queries,
+ logging information about statement execution, or route
+ requests to remote servers.
+
+ The following instructions are based on the instructions for + Tomcat-5.x, available at + http://tomcat.apache.org/tomcat-5.5-doc/jndi-datasource-examples-howto.html + which is current at the time this document was written. +
+ First, install the .jar file that comes with
+ Connector/J in $CATALINA_HOME/common/lib so
+ that it is available to all applications installed in the
+ container.
+
+ Next, configure the JNDI DataSource by adding a declaration
+ resource to $CATALINA_HOME/conf/server.xml in
+ the context that defines your web application:
+
+ <Context ....> + + ... + + <Resource name="jdbc/MySQLDB" + auth="Container" + type="javax.sql.DataSource"/> + + <ResourceParams name="jdbc/MySQLDB"> + <parameter> + <name>factory</name> + <value>org.apache.commons.dbcp.BasicDataSourceFactory</value> + </parameter> + + <parameter> + <name>maxActive</name> + <value>10</value> + </parameter> + + <parameter> + <name>maxIdle</name> + <value>5</value> + </parameter> + + <parameter> + <name>validationQuery</name> + <value>SELECT 1</value> + </parameter> + + <parameter> + <name>testOnBorrow</name> + <value>true</value> + </parameter> + + <parameter> + <name>testWhileIdle</name> + <value>true</value> + </parameter> + + <parameter> + <name>timeBetweenEvictionRunsMillis</name> + <value>10000</value> + </parameter> + + <parameter> + <name>minEvictableIdleTimeMillis</name> + <value>60000</value> + </parameter> + + <parameter> + <name>username</name> + <value>someuser</value> + </parameter> + + <parameter> + <name>password</name> + <value>somepass</value> + </parameter> + + <parameter> + <name>driverClassName</name> + <value>com.mysql.jdbc.Driver</value> + </parameter> + + <parameter> + <name>url</name> + <value>jdbc:mysql://localhost:3306/test</value> + </parameter> + + </ResourceParams> +</Context> +
+ Note that Connector/J 5.1.3 introduced a facility whereby, rather
+ than use a validationQuery value of
+ SELECT 1, it is possible to use
+ validationQuery with a value set to /*
+ ping */. This sends a ping to the server which then
+ returns a fake result set. This is a lighter weight solution. It
+ also has the advantage that if using
+ ReplicationConnection or
+ LoadBalancedConnection type connections, the
+ ping will be sent across all active connections. The following XML
+ snippet illustrates how to select this option:
+
+ +<parameter> + <name>validationQuery</name> + <value>/* ping */</value> +</parameter> + +
+ Note that /* ping */ has to be specified
+ exactly.
+
+ In general, follow the installation instructions that come with + your version of Tomcat, as the way you configure datasources in + Tomcat changes from time to time, and if you use the wrong syntax + in your XML file, you will most likely end up with an exception + similar to the following: +
+Error: java.sql.SQLException: Cannot load JDBC driver class 'null ' SQL +state: null +
+ Note that the auto-loading of drivers having the
+ META-INF/service/java.sql.Driver class in
+ JDBC 4.0 and above causes an improper undeployment of the
+ Connector/J driver in Tomcat on Windows. Namely, the Connector/J
+ jar remains locked. This is an initialization problem that is not
+ related to the driver. The possible workarounds, if viable, are as
+ follows: use "antiResourceLocking=true" as a
+ Tomcat Context attribute, or remove the
+ META-INF/ directory.
+
+ These instructions cover JBoss-4.x. To make the JDBC driver
+ classes available to the application server, copy the
+ .jar file that comes with Connector/J to the
+ lib directory for your server configuration
+ (which is usually called default). Then, in
+ the same configuration directory, in the subdirectory named
+ deploy, create a datasource configuration file that ends with
+ -ds.xml, which tells JBoss to deploy this file
+ as a JDBC Datasource. The file should have the following contents:
+
+<datasources> + <local-tx-datasource> + + <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> + + <max-pool-size>20</max-pool-size> + + <idle-timeout-minutes>5</idle-timeout-minutes> + + <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> +
Table of Contents
+ The Spring Framework is a Java-based application framework + designed for assisting in application design by providing a way to + configure components. The technique used by Spring is a well known + design pattern called Dependency Injection (see + Inversion + of Control Containers and the Dependency Injection + pattern). This article will focus on Java-oriented access + to MySQL databases with Spring 2.0. For those wondering, there is + a .NET port of Spring appropriately named Spring.NET. +
+ Spring is not only a system for configuring components, but also + includes support for aspect oriented programming (AOP). This is + one of the main benefits and the foundation for Spring's resource + and transaction management. Spring also provides utilities for + integrating resource management with JDBC and Hibernate. +
+ For the examples in this section the MySQL world sample database + will be used. The first task is to set up a MySQL data source + through Spring. Components within Spring use the + “bean” terminology. For example, to configure a + connection to a MySQL server supporting the world sample database, + you might use: +
+ +<util:map id="dbProps"> + <entry key="db.driver" value="com.mysql.jdbc.Driver"/> + <entry key="db.jdbcurl" value="jdbc:mysql://localhost/world"/> + <entry key="db.username" value="myuser"/> + <entry key="db.password" value="mypass"/> +</util:map> + +
+ In the above example, we are assigning values to properties that + will be used in the configuration. For the datasource + configuration: +
+
+<bean id="dataSource"
+ class="org.springframework.jdbc.datasource.DriverManagerDataSource">
+ <property name="driverClassName" value="${db.driver}"/>
+ <property name="url" value="${db.jdbcurl}"/>
+ <property name="username" value="${db.username}"/>
+ <property name="password" value="${db.password}"/>
+</bean>
+
++ The placeholders are used to provide values for properties of this + bean. This means that you can specify all the properties of the + configuration in one place instead of entering the values for each + property on each bean. We do, however, need one more bean to pull + this all together. The last bean is responsible for actually + replacing the placeholders with the property values. +
+ +<bean + class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> + <property name="properties" ref="dbProps"/> +</bean> + +
+ Now that we have our MySQL data source configured and ready to go, + we write some Java code to access it. The example below will + retrieve three random cities and their corresponding country using + the data source we configured with Spring. +
+// Create a new application context. this processes the Spring config
+ApplicationContext ctx =
+ new ClassPathXmlApplicationContext("ex1appContext.xml");
+// Retrieve the data source from the application context
+ DataSource ds = (DataSource) ctx.getBean("dataSource");
+// Open a database connection using Spring's DataSourceUtils
+Connection c = DataSourceUtils.getConnection(ds);
+try {
+ // retrieve a list of three random cities
+ PreparedStatement ps = c.prepareStatement(
+ "select City.Name as 'City', Country.Name as 'Country' " +
+ "from City inner join Country on City.CountryCode = Country.Code " +
+ "order by rand() limit 3");
+ ResultSet rs = ps.executeQuery();
+ while(rs.next()) {
+ String city = rs.getString("City");
+ String country = rs.getString("Country");
+ System.out.printf("The city %s is in %s%n", city, country);
+ }
+} catch (SQLException ex) {
+ // something has failed and we print a stack trace to analyse the error
+ ex.printStackTrace();
+ // ignore failure closing connection
+ try { c.close(); } catch (SQLException e) { }
+} finally {
+ // properly release our connection
+ DataSourceUtils.releaseConnection(c, ds);
+}
++ This is very similar to normal JDBC access to MySQL with the main + difference being that we are using DataSourceUtils instead of the + DriverManager to create the connection. +
+ While it may seem like a small difference, the implications are + somewhat far reaching. Spring manages this resource in a way + similar to a container managed data source in a J2EE application + server. When a connection is opened, it can be subsequently + accessed in other parts of the code if it is synchronized with a + transaction. This makes it possible to treat different parts of + your application as transactional instead of passing around a + database connection. +
+ Spring makes extensive use of the Template method design pattern
+ (see
+ Template
+ Method Pattern). Our immediate focus will be on the
+ JdbcTemplate and related classes,
+ specifically NamedParameterJdbcTemplate. The
+ template classes handle obtaining and releasing a connection for
+ data access when one is needed.
+
+ The next example shows how to use
+ NamedParameterJdbcTemplate inside of a DAO
+ (Data Access Object) class to retrieve a random city given a
+ country code.
+
+public class Ex2JdbcDao {
+ /**
+ * Data source reference which will be provided by Spring.
+ */
+ private DataSource dataSource;
+
+ /**
+ * Our query to find a random city given a country code. Notice
+ * the ":country" parameter toward the end. This is called a
+ * named parameter.
+ */
+ private String queryString = "select Name from City " +
+ "where CountryCode = :country order by rand() limit 1";
+
+ /**
+ * Retrieve a random city using Spring JDBC access classes.
+ */
+ public String getRandomCityByCountryCode(String cntryCode) {
+ // A template that permits using queries with named parameters
+ NamedParameterJdbcTemplate template =
+ new NamedParameterJdbcTemplate(dataSource);
+ // A java.util.Map is used to provide values for the parameters
+ Map params = new HashMap();
+ params.put("country", cntryCode);
+ // We query for an Object and specify what class we are expecting
+ return (String)template.queryForObject(queryString, params, String.class);
+ }
+
+ /**
+ * A JavaBean setter-style method to allow Spring to inject the data source.
+ * @param dataSource
+ */
+ public void setDataSource(DataSource dataSource) {
+ this.dataSource = dataSource;
+ }
+}
+
+ The focus in the above code is on the
+ getRandomCityByCountryCode() method. We
+ pass a country code and use the
+ NamedParameterJdbcTemplate to query for a
+ city. The country code is placed in a Map with the key
+ "country", which is the parameter is named in the SQL query.
+
+ To access this code, you need to configure it with Spring by + providing a reference to the data source. +
+ +<bean id="dao" class="code.Ex2JdbcDao"> + <property name="dataSource" ref="dataSource"/> +</bean> + +
+ At this point, we can just grab a reference to the DAO from
+ Spring and call
+ getRandomCityByCountryCode().
+
+ // Create the application context
+ ApplicationContext ctx =
+ new ClassPathXmlApplicationContext("ex2appContext.xml");
+ // Obtain a reference to our DAO
+ Ex2JdbcDao dao = (Ex2JdbcDao) ctx.getBean("dao");
+
+ String countryCode = "USA";
+
+ // Find a few random cities in the US
+ for(int i = 0; i < 4; ++i)
+ System.out.printf("A random city in %s is %s%n", countryCode,
+ dao.getRandomCityByCountryCode(countryCode));
+
+ This example shows how to use Spring's JDBC classes to
+ completely abstract away the use of traditional JDBC classes
+ including Connection and
+ PreparedStatement.
+
+ You might be wondering how we can add transactions into our code + if we do not deal directly with the JDBC classes. Spring + provides a transaction management package that not only replaces + JDBC transaction management, but also enables declarative + transaction management (configuration instead of code). +
+ To use transactional database access, we will need to change the + storage engine of the tables in the world database. The + downloaded script explicitly creates MyISAM tables which do not + support transactional semantics. The InnoDB storage engine does + support transactions and this is what we will be using. We can + change the storage engine with the following statements. +
+ALTER TABLE City ENGINE=InnoDB; +ALTER TABLE Country ENGINE=InnoDB; +ALTER TABLE CountryLanguage ENGINE=InnoDB; +
+ A good programming practice emphasized by Spring is separating + interfaces and implementations. What this means is that we can + create a Java interface and only use the operations on this + interface without any internal knowledge of what the actual + implementation is. We will let Spring manage the implementation + and with this it will manage the transactions for our + implementation. +
+ First you create a simple interface: +
+public interface Ex3Dao {
+ Integer createCity(String name, String countryCode,
+ String district, Integer population);
+}
++ This interface contains one method that will create a new city + record in the database and return the id of the new record. Next + you need to create an implementation of this interface. +
+public class Ex3DaoImpl implements Ex3Dao {
+ protected DataSource dataSource;
+ protected SqlUpdate updateQuery;
+ protected SqlFunction idQuery;
+
+ public Integer createCity(String name, String countryCode,
+ String district, Integer population) {
+ updateQuery.update(new Object[] { name, countryCode,
+ district, population });
+ return getLastId();
+ }
+
+ protected Integer getLastId() {
+ return idQuery.run();
+ }
+}
++ You can see that we only operate on abstract query objects here + and do not deal directly with the JDBC API. Also, this is the + complete implementation. All of our transaction management will + be dealt with in the configuration. To get the configuration + started, we need to create the DAO. +
+ +<bean id="dao" class="code.Ex3DaoImpl"> + <property name="dataSource" ref="dataSource"/> + <property name="updateQuery">...</property> + <property name="idQuery">...</property> +</bean> + +
+ Now you need to set up the transaction configuration. The first
+ thing you must do is create transaction manager to manage the
+ data source and a specification of what transaction properties
+ are required for the dao methods.
+
+ +<bean id="transactionManager" + class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> + <property name="dataSource" ref="dataSource"/> +</bean> + +<tx:advice id="txAdvice" transaction-manager="transactionManager"> + <tx:attributes> + <tx:method name="*"/> + </tx:attributes> +</tx:advice> + +
+ The preceding code creates a transaction manager that handles
+ transactions for the data source provided to it. The
+ txAdvice uses this transaction manager and
+ the attributes specify to create a transaction for all methods.
+ Finally you need to apply this advice with an AOP pointcut.
+
+ +<aop:config> + <aop:pointcut id="daoMethods" + expression="execution(* code.Ex3Dao.*(..))"/> + <aop:advisor advice-ref="txAdvice" pointcut-ref="daoMethods"/> +</aop:config> + +
+ This basically says that all methods called on the
+ Ex3Dao interface will be wrapped in a
+ transaction. To make use of this, you only have to retrieve the
+ dao from the application context and call a
+ method on the dao instance.
+
+Ex3Dao dao = (Ex3Dao) ctx.getBean("dao");
+Integer id = dao.createCity(name, countryCode, district, pop);
++ We can verify from this that there is no transaction management + happening in our Java code and it is all configured with Spring. + This is a very powerful notion and regarded as one of the most + beneficial features of Spring. +
+ In many situations, such as web applications, there will be a
+ large number of small database transactions. When this is the
+ case, it usually makes sense to create a pool of database
+ connections available for web requests as needed. Although MySQL
+ does not spawn an extra process when a connection is made, there
+ is still a small amount of overhead to create and set up the
+ connection. Pooling of connections also alleviates problems such
+ as collecting large amounts of sockets in the
+ TIME_WAIT state.
+
+ Setting up pooling of MySQL connections with Spring is as simple
+ as changing the data source configuration in the application
+ context. There are a number of configurations that we can use.
+ The first example is based on the
+ Jakarta
+ Commons DBCP library. The example below replaces the
+ source configuration that was based on
+ DriverManagerDataSource with DBCP's
+ BasicDataSource.
+
+
+<bean id="dataSource" destroy-method="close"
+ class="org.apache.commons.dbcp.BasicDataSource">
+ <property name="driverClassName" value="${db.driver}"/>
+ <property name="url" value="${db.jdbcurl}"/>
+ <property name="username" value="${db.username}"/>
+ <property name="password" value="${db.password}"/>
+ <property name="initialSize" value="3"/>
+</bean>
+
+
+ The configuration of the two solutions is very similar. The
+ difference is that DBCP will pool connections to the database
+ instead of creating a new connection every time one is
+ requested. We have also set a parameter here called
+ initialSize. This tells DBCP that we want
+ three connections in the pool when it is created.
+
+ Another way to configure connection pooling is to configure a
+ data source in our J2EE application server. Using JBoss as an
+ example, you can set up the MySQL connection pool by creating a
+ file called mysql-local-ds.xml and placing
+ it in the server/default/deploy directory in JBoss. Once we have
+ this setup, we can use JNDI to look it up. With Spring, this
+ lookup is very simple. The data source configuration looks like
+ this.
+
+ +<jee:jndi-lookup id="dataSource" jndi-name="java:MySQL_DS"/> + +
Table of Contents
+ This section explains how to use MySQL Connector/J with GlassFish ™ + Server Open Source Edition 3.0.1. GlassFish can be downloaded from + the + GlassFish + website. +
+ Once GlassFish is installed, make sure it can access MySQL Connector/J. To do
+ this, copy the MySQL Connector/J jar file to the
+
+ directory. For example, copy
+ domain-dir/libmysql-connector-java-5.1.30-bin.jar to
+ C:\.
+ Restart the GlassFish Application Server. For more information,
+ see “Integrating the JDBC Driver” in
+ GlassFish Server Open Source Edition Administration
+ Guide, available at
+ GlassFish
+ Server Documentation.
+ glassfish-install-path\domains\domain-name\lib
+ You are now ready to create JDBC Connection Pools and JDBC + Resources. +
+ Creating a Connection Pool +
+ In the GlassFish Administration Console, using the navigation + tree navigate to Resources, + JDBC, Connection + Pools. +
+ In the JDBC Connection Pools frame click + . You will enter a two step wizard. +
+ In the Name field under General
+ Settings enter the name for the connection pool,
+ for example enter MySQLConnPool.
+
+ In the Resource Type field, select
+ javax.sql.DataSource from the drop-down
+ listbox.
+
+ In the Database Vendor field, select
+ MySQL from the drop-down listbox. Click
+ to go to the next page of the
+ wizard.
+
+ You can accept the default settings for General Settings, Pool + Settings and Transactions for this example. Scroll down to + Additional Properties. +
+ In Additional Properties you will need to ensure the following + properties are set: +
+ ServerName - The server
+ to connect to. For local testing this will be
+ localhost.
+
+ User - The user name with + which to connect to MySQL. +
+ Password - The + corresponding password for the user. +
+ DatabaseName - The
+ database to connect to, for example the sample MySQL
+ database World.
+
+ Click to exit the wizard. You + will be taken to the JDBC Connection + Pools page where all current connection pools, + including the one you just created, will be displayed. +
+ In the JDBC Connection Pools frame click + on the connection pool you just created. Here, you can review + and edit information about the connection pool. Because + Connector/J does not support optimized validation queries, go + to the Advanced tab, and under Connection + Validation, configure the following settings: + +
+ Connection Validation - + select Required. +
+ Validation Method - + select table from the drop-down + menu. +
+ Table Name - enter
+ DUAL.
+
+
+ To test your connection pool click the + button at the top of the frame. A + message will be displayed confirming correct operation or + otherwise. If an error message is received recheck the + previous steps, and ensure that MySQL Connector/J has been correctly copied + into the previously specified location. +
+ Now that you have created a connection pool you will also need to + create a JDBC Resource (data source) for use by your application. +
+ Creating a JDBC Resource +
+ Your Java application will usually reference a data source object + to establish a connection with the database. This needs to be + created first using the following procedure. +
+ Using the navigation tree in the GlassFish Administration + Console, navigate to Resources, + JDBC, JDBC + Resources. A list of resources will be displayed in + the JDBC Resources frame. +
+ Click . The New JDBC + Resource frame will be displayed. +
+ In the JNDI Name field, enter the JNDI
+ name that will be used to access this resource, for example
+ enter jdbc/MySQLDataSource.
+
+ In the Pool Name field, select a + connection pool you want this resource to use from the + drop-down listbox. +
+ Optionally, you can enter a description into the + Description field. +
+ Additional properties can be added if required. +
+ Click to create the new JDBC + resource. The JDBC Resources frame will + list all available JDBC Resources. +
+ This section shows how to deploy a simple JSP application on + GlassFish, that connects to a MySQL database. +
+ This example assumes you have already set up a suitable
+ Connection Pool and JDBC Resource, as explained in the preceding
+ sections. It is also assumed you have a sample database
+ installed, such as world.
+
+ The main application code, index.jsp is
+ presented here:
+
+
+<%@ page import="java.sql.*, javax.sql.*, java.io.*, javax.naming.*" %>
+<html>
+<head><title>Hello world from JSP</title></head>
+<body>
+<%
+ InitialContext ctx;
+ DataSource ds;
+ Connection conn;
+ Statement stmt;
+ ResultSet rs;
+
+ try {
+ ctx = new InitialContext();
+ ds = (DataSource) ctx.lookup("java:comp/env/jdbc/MySQLDataSource");
+ //ds = (DataSource) ctx.lookup("jdbc/MySQLDataSource");
+ conn = ds.getConnection();
+ stmt = conn.createStatement();
+ rs = stmt.executeQuery("SELECT * FROM Country");
+
+ while(rs.next()) {
+%>
+ <h3>Name: <%= rs.getString("Name") %></h3>
+ <h3>Population: <%= rs.getString("Population") %></h3>
+<%
+ }
+ }
+ catch (SQLException se) {
+%>
+ <%= se.getMessage() %>
+<%
+ }
+ catch (NamingException ne) {
+%>
+ <%= ne.getMessage() %>
+<%
+ }
+%>
+</body>
+</html>
+
+
+ In addition two XML files are required:
+ web.xml, and
+ sun-web.xml. There may be other files
+ present, such as classes and images. These files are organized
+ into the directory structure as follows:
+
+index.jsp +WEB-INF + | + - web.xml + - sun-web.xml +
+ The code for web.xml is:
+
+ +<?xml version="1.0" encoding="UTF-8"?> +<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> + <display-name>HelloWebApp</display-name> + <distributable/> + <resource-ref> + <res-ref-name>jdbc/MySQLDataSource</res-ref-name> + <res-type>javax.sql.DataSource</res-type> + <res-auth>Container</res-auth> + <res-sharing-scope>Shareable</res-sharing-scope> + </resource-ref> +</web-app> + +
+ The code for sun-web.xml is:
+
+ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE sun-web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Application Server 8.1 Servlet 2.4//EN" "http://www.sun.com/software/appserver/dtds/sun-web-app_2_4-1.dtd"> +<sun-web-app> + <context-root>HelloWebApp</context-root> + <resource-ref> + <res-ref-name>jdbc/MySQLDataSource</res-ref-name> + <jndi-name>jdbc/MySQLDataSource</jndi-name> + </resource-ref> +</sun-web-app> + +
+ These XML files illustrate a very important aspect of running
+ JDBC applications on GlassFish. On GlassFish it is important to
+ map the string specified for a JDBC resource to its JNDI name,
+ as set up in the GlassFish administration console. In this
+ example, the JNDI name for the JDBC resource, as specified in
+ the GlassFish Administration console when creating the JDBC
+ Resource, was jdbc/MySQLDataSource. This must
+ be mapped to the name given in the application. In this example
+ the name specified in the application,
+ jdbc/MySQLDataSource, and the JNDI name,
+ happen to be the same, but this does not necessarily have to be
+ the case. Note that the XML element <res-ref-name> is used
+ to specify the name as used in the application source code, and
+ this is mapped to the JNDI name specified using the
+ <jndi-name> element, in the file
+ sun-web.xml. The resource also has to be
+ created in the web.xml file, although the
+ mapping of the resource to a JNDI name takes place in the
+ sun-web.xml file.
+
+ If you do not have this mapping set up correctly in the XML + files you will not be able to lookup the data source using a + JNDI lookup string such as: +
+ds = (DataSource) ctx.lookup("java:comp/env/jdbc/MySQLDataSource");
++ You will still be able to access the data source directly using: +
+ds = (DataSource) ctx.lookup("jdbc/MySQLDataSource");
++ With the source files in place, in the correct directory + structure, you are ready to deploy the application: +
+ In the navigation tree, navigate to + Applications - the + Applications frame will be displayed. + Click . +
+ You can now deploy an application packaged into a single WAR + file from a remote client, or you can choose a packaged file + or directory that is locally accessible to the server. If + you are simply testing an application locally you can simply + point GlassFish at the directory that contains your + application, without needing to package the application into + a WAR file. +
+ Now select the application type from the
+ Type drop-down listbox, which in this
+ example is Web application.
+
+ Click OK. +
+ Now, when you navigate to the Applications
+ frame, you will have the option to Launch,
+ Redeploy, or Restart
+ your application. You can test your application by clicking
+ Launch. The application will connection to
+ the MySQL database and display the Name and Population of
+ countries in the Country table.
+
+ This section describes a simple servlet that can be used in the
+ GlassFish environment to access a MySQL database. As with the
+ previous section, this example assumes the sample database
+ world is installed.
+
+ The project is set up with the following directory structure: +
+index.html +WEB-INF + | + - web.xml + - sun-web.xml + - classes + | + - HelloWebServlet.java + - HelloWebServlet.class +
+ The code for the servlet, located in
+ HelloWebServlet.java, is as follows:
+
+
+import javax.servlet.http.*;
+import javax.servlet.*;
+import java.io.*;
+import java.sql.*;
+import javax.sql.*;
+import javax.naming.*;
+
+public class HelloWebServlet extends HttpServlet {
+
+ InitialContext ctx = null;
+ DataSource ds = null;
+ Connection conn = null;
+ PreparedStatement ps = null;
+ ResultSet rs = null;
+
+ String sql = "SELECT Name, Population FROM Country WHERE Name=?";
+
+ public void init () throws ServletException {
+ try {
+ ctx = new InitialContext();
+ ds = (DataSource) ctx.lookup("java:comp/env/jdbc/MySQLDataSource");
+ conn = ds.getConnection();
+ ps = conn.prepareStatement(sql);
+ }
+ catch (SQLException se) {
+ System.out.println("SQLException: "+se.getMessage());
+ }
+ catch (NamingException ne) {
+ System.out.println("NamingException: "+ne.getMessage());
+ }
+ }
+
+ public void destroy () {
+ try {
+ if (rs != null)
+ rs.close();
+ if (ps != null)
+ ps.close();
+ if (conn != null)
+ conn.close();
+ if (ctx != null)
+ ctx.close();
+ }
+ catch (SQLException se) {
+ System.out.println("SQLException: "+se.getMessage());
+ }
+ catch (NamingException ne) {
+ System.out.println("NamingException: "+ne.getMessage());
+ }
+ }
+
+ public void doPost(HttpServletRequest req, HttpServletResponse resp){
+ try {
+ String country_name = req.getParameter("country_name");
+ resp.setContentType("text/html");
+ PrintWriter writer = resp.getWriter();
+ writer.println("<html><body>");
+ writer.println("<p>Country: "+country_name+"</p>");
+ ps.setString(1, country_name);
+ rs = ps.executeQuery();
+ if (!rs.next()){
+ writer.println("<p>Country does not exist!</p>");
+ }
+ else {
+ rs.beforeFirst();
+ while(rs.next()) {
+ writer.println("<p>Name: "+rs.getString("Name")+"</p>");
+ writer.println("<p>Population: "+rs.getString("Population")+"</p>");
+ }
+ }
+ writer.println("</body></html>");
+ writer.close();
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void doGet(HttpServletRequest req, HttpServletResponse resp){
+ try {
+ resp.setContentType("text/html");
+ PrintWriter writer = resp.getWriter();
+ writer.println("<html><body>");
+ writer.println("<p>Hello from servlet doGet()</p>");
+ writer.println("</body></html>");
+ writer.close();
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
+
+
+ In the preceding code a basic doGet() method
+ is implemented, but is not used in the example. The code to
+ establish the connection with the database is as shown in the
+ previous example,
+ Section 13.1, “A Simple JSP Application with GlassFish, Connector/J and MySQL”,
+ and is most conveniently located in the servlet
+ init() method. The corresponding freeing of
+ resources is located in the destroy method. The main
+ functionality of the servlet is located in the
+ doPost() method. If the user enters into the
+ input form a country name that can be located in the database,
+ the population of the country is returned. The code is invoked
+ using a POST action associated with the input form. The form is
+ defined in the file index.html:
+
+ +<html> + <head><title>HelloWebServlet</title></head> + + <body> + <h1>HelloWebServlet</h1> + + <p>Please enter country name:</p> + + <form action="HelloWebServlet" method="POST"> + <input type="text" name="country_name" length="50" /> + <input type="submit" value="Submit" /> + </form> + + </body> +</html> + +
+ The XML files web.xml and
+ sun-web.xml are as for the example in the
+ preceding section,
+ Section 13.1, “A Simple JSP Application with GlassFish, Connector/J and MySQL”,
+ no additional changes are required.
+
+ When compiling the Java source code, you will need to specify
+ the path to the file javaee.jar. On
+ Windows, this can be done as follows:
+
+shell> javac -classpath c:\glassfishv3\glassfish\lib\javaee.jar HelloWebServlet.java +
+ Once the code is correctly located within its directory + structure, and compiled, the application can be deployed in + GlassFish. This is done in exactly the same way as described in + the preceding section, + Section 13.1, “A Simple JSP Application with GlassFish, Connector/J and MySQL”. +
+ Once deployed the application can be launched from within the + GlassFish Administration Console. Enter a country name such as + “England”, and the application will return + “Country does not exist!”. Enter + “France”, and the application will return a + population of 59225700. +
+ MySQL Fabric is a system for managing a farm of MySQL servers (and + other components). Fabric provides an extensible and easy to use + system for managing a MySQL deployment for sharding and + high-availability. +
+ For more information on MySQL Fabric, see + MySQL Fabric. For instructions on how to use + Connector/J with MySQL Fabric, see + Using Connector/J with MySQL Fabric. +
+ This section explains the symptoms and resolutions for the most + commonly encountered issues with applications using MySQL + Connector/J. +
Questions
15.1: + When I try to connect to the database with MySQL + Connector/J, I get the following exception: +
+SQLException: Server configuration denies access to data source +SQLState: 08001 +VendorError: 0 +
+ What is going on? I can connect just fine with the MySQL + command-line client. +
15.2: + My application throws an SQLException 'No Suitable Driver'. + Why is this happening? +
15.3: + I'm trying to use MySQL Connector/J in an applet or + application and I get an exception similar to: +
+SQLException: Cannot connect to MySQL server on host:3306. +Is there a MySQL server running on the machine/port you +are trying to connect to? + +(java.security.AccessControlException) +SQLState: 08S01 +VendorError: 0 +
15.4: + I have a servlet/application that works fine for a day, and + then stops working overnight +
15.5: + I'm trying to use JDBC 2.0 updatable result sets, and I get + an exception saying my result set is not updatable. +
15.6: + I cannot connect to the MySQL server using Connector/J, and + I'm sure the connection parameters are correct. +
15.7: + I am trying to connect to my MySQL server within my + application, but I get the following error and stack trace: +
+java.net.SocketException +MESSAGE: Software caused connection abort: recv failed + +STACKTRACE: + +java.net.SocketException: Software caused connection abort: recv failed +at java.net.SocketInputStream.socketRead0(Native Method) +at java.net.SocketInputStream.read(Unknown Source) +at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:1392) +at com.mysql.jdbc.MysqlIO.readPacket(MysqlIO.java:1414) +at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:625) +at com.mysql.jdbc.Connection.createNewIO(Connection.java:1926) +at com.mysql.jdbc.Connection.<init>(Connection.java:452) +at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:411) +
15.8: + My application is deployed through JBoss and I am using + transactions to handle the statements on the MySQL database. + Under heavy loads, I am getting an error and stack trace, + but these only occur after a fixed period of heavy activity. +
15.9:
+ When using gcj, a
+ java.io.CharConversionException exception
+ is raised when working with certain character sequences.
+
15.10:
+ Updating a table that contains a
+ primary key that is
+ either FLOAT or compound
+ primary key that uses FLOAT
+ fails to update the table and raises an exception.
+
15.11:
+ You get an
+ ER_NET_PACKET_TOO_LARGE
+ exception, even though the binary blob size you want to
+ insert using JDBC is safely below the
+ max_allowed_packet size.
+
15.12: + What should you do if you receive error messages similar to + the following: “Communications link failure – Last + packet sent to the server was X ms ago”? +
15.13:
+ Why does Connector/J not reconnect to MySQL and re-issue the
+ statement after a communication failure, instead of throwing
+ an Exception, even though I use the
+ autoReconnect connection string option?
+
15.14: + How can I use 3-byte UTF8 with Connector/J? +
15.15:
+ How can I use 4-byte UTF8, utf8mb4 with
+ Connector/J?
+
15.16:
+ Using useServerPrepStmts=false and
+ certain character encodings can lead to corruption when
+ inserting BLOBs. How can this be avoided?
+
Questions and Answers
15.1: + When I try to connect to the database with MySQL + Connector/J, I get the following exception: +
+SQLException: Server configuration denies access to data source +SQLState: 08001 +VendorError: 0 +
+ What is going on? I can connect just fine with the MySQL + command-line client. +
+ MySQL Connector/J must use TCP/IP sockets to connect to + MySQL, as Java does not support Unix Domain Sockets. + Therefore, when MySQL Connector/J connects to MySQL, the + security manager in MySQL server will use its grant tables + to determine whether the connection is permitted. +
+ You must add the necessary security credentials to the MySQL
+ server for this to happen, using the
+ GRANT statement to your MySQL
+ Server. See GRANT Syntax, for more information.
+
+ Testing your connectivity with the
+ mysql command-line client will not work
+ unless you add the "host" flag, and use something other
+ than localhost for the host. The
+ mysql command-line client will use Unix
+ domain sockets if you use the special host name
+ localhost. If you are testing
+ connectivity to localhost, use
+ 127.0.0.1 as the host name instead.
+
+ Changing privileges and permissions improperly in MySQL + can potentially cause your server installation to not have + optimal security properties. +
15.2: + My application throws an SQLException 'No Suitable Driver'. + Why is this happening? +
+ There are three possible causes for this error: +
+ The Connector/J driver is not in your
+ CLASSPATH, see
+ Chapter 3, Connector/J Installation.
+
+ The format of your connection URL is incorrect, or you + are referencing the wrong JDBC driver. +
+ When using DriverManager, the
+ jdbc.drivers system property has not
+ been populated with the location of the Connector/J
+ driver.
+
15.3: + I'm trying to use MySQL Connector/J in an applet or + application and I get an exception similar to: +
+SQLException: Cannot connect to MySQL server on host:3306. +Is there a MySQL server running on the machine/port you +are trying to connect to? + +(java.security.AccessControlException) +SQLState: 08S01 +VendorError: 0 +
+ Either you're running an Applet, your MySQL server has been + installed with the "skip-networking" option set, or your + MySQL server has a firewall sitting in front of it. +
+ Applets can only make network connections back to the + machine that runs the web server that served the .class + files for the applet. This means that MySQL must run on the + same machine (or you must have some sort of port + re-direction) for this to work. This also means that you + will not be able to test applets from your local file + system, you must always deploy them to a web server. +
+ MySQL Connector/J can only communicate with MySQL using + TCP/IP, as Java does not support Unix domain sockets. TCP/IP + communication with MySQL might be affected if MySQL was + started with the "skip-networking" flag, or if it is + firewalled. +
+ If MySQL has been started with the "skip-networking" option
+ set (the Debian Linux package of MySQL server does this for
+ example), you need to comment it out in the file
+ /etc/mysql/my.cnf or
+ /etc/my.cnf. Of course your
+ my.cnf file might also exist in the
+ data directory of your MySQL server, or
+ anywhere else (depending on how MySQL was compiled for your
+ system). Binaries created by us always look in
+ /etc/my.cnf and
+ .
+ If your MySQL server has been firewalled, you will need to
+ have the firewall configured to allow TCP/IP connections
+ from the host where your Java code is running to the MySQL
+ server on the port that MySQL is listening to (by default,
+ 3306).
+ datadir/my.cnf
15.4: + I have a servlet/application that works fine for a day, and + then stops working overnight +
+ MySQL closes connections after 8 hours of inactivity. You
+ either need to use a connection pool that handles stale
+ connections or use the autoReconnect
+ parameter (see
+ Section 5.1, “Driver/Datasource Class Names, URL Syntax and Configuration Properties
+ for Connector/J”).
+
+ Also, catch SQLExceptions in your
+ application and deal with them, rather than propagating them
+ all the way until your application exits. This is just good
+ programming practice. MySQL Connector/J will set the
+ SQLState (see
+ java.sql.SQLException.getSQLState() in
+ your API docs) to 08S01 when it
+ encounters network-connectivity issues during the processing
+ of a query. Attempt to reconnect to MySQL at this point.
+
+ The following (simplistic) example shows what code that can + handle these exceptions might look like: +
+
Example 15.1 Connector/J: Example of transaction with retry logic
+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 transactional 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 40001 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) || "40001".equals(sqlState)) {
+ retryCount -= 1;
+ } 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));
+}
+
+
+ Use of the autoReconnect option is not
+ recommended because there is no safe method of
+ reconnecting to the MySQL server without risking some
+ corruption of the connection state or database state
+ information. Instead, use a connection pool, which will
+ enable your application to connect to the MySQL server
+ using an available connection from the pool. The
+ autoReconnect facility is deprecated, and
+ may be removed in a future release.
+
15.5: + I'm trying to use JDBC 2.0 updatable result sets, and I get + an exception saying my result set is not updatable. +
+ Because MySQL does not have row identifiers, MySQL + Connector/J can only update result sets that have come from + queries on tables that have at least one + primary key, the + query must select every primary key column, and the query + can only span one table (that is, no joins). This is + outlined in the JDBC specification. +
+ Note that this issue only occurs when using updatable result
+ sets, and is caused because Connector/J is unable to
+ guarantee that it can identify the correct rows within the
+ result set to be updated without having a unique reference
+ to each row. There is no requirement to have a unique field
+ on a table if you are using
+ UPDATE or
+ DELETE statements on a table
+ where you can individually specify the criteria to be
+ matched using a WHERE clause.
+
15.6: + I cannot connect to the MySQL server using Connector/J, and + I'm sure the connection parameters are correct. +
+ Make sure that the
+ skip-networking option has
+ not been enabled on your server. Connector/J must be able to
+ communicate with your server over TCP/IP; named sockets are
+ not supported. Also ensure that you are not filtering
+ connections through a firewall or other network security
+ system. For more information, see
+ Can't connect to [local] MySQL server.
+
15.7: + I am trying to connect to my MySQL server within my + application, but I get the following error and stack trace: +
+java.net.SocketException +MESSAGE: Software caused connection abort: recv failed + +STACKTRACE: + +java.net.SocketException: Software caused connection abort: recv failed +at java.net.SocketInputStream.socketRead0(Native Method) +at java.net.SocketInputStream.read(Unknown Source) +at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:1392) +at com.mysql.jdbc.MysqlIO.readPacket(MysqlIO.java:1414) +at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:625) +at com.mysql.jdbc.Connection.createNewIO(Connection.java:1926) +at com.mysql.jdbc.Connection.<init>(Connection.java:452) +at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:411) +
+ The error probably indicates that you are using a older + version of the Connector/J JDBC driver (2.0.14 or 3.0.x) and + you are trying to connect to a MySQL server with version + 4.1x or newer. The older drivers are not compatible with 4.1 + or newer of MySQL as they do not support the newer + authentication mechanisms. +
+ It is likely that the older version of the Connector/J
+ driver exists within your application directory or your
+ CLASSPATH includes the older Connector/J
+ package.
+
15.8: + My application is deployed through JBoss and I am using + transactions to handle the statements on the MySQL database. + Under heavy loads, I am getting an error and stack trace, + but these only occur after a fixed period of heavy activity. +
+ This is a JBoss, not Connector/J, issue and is connected to + the use of transactions. Under heavy loads the time taken + for transactions to complete can increase, and the error is + caused because you have exceeded the predefined timeout. +
+ You can increase the timeout value by setting the
+ TransactionTimeout attribute to the
+ TransactionManagerService within the
+ /conf/jboss-service.xml file
+ (pre-4.0.3) or /deploy/jta-service.xml
+ for JBoss 4.0.3 or later. See
+ TransactionTimeout
+ within the JBoss wiki for more information.
+
15.9:
+ When using gcj, a
+ java.io.CharConversionException exception
+ is raised when working with certain character sequences.
+
+ This is a known issue with gcj which
+ raises an exception when it reaches an unknown character or
+ one it cannot convert. Add
+ useJvmCharsetConverters=true to your
+ connection string to force character conversion outside of
+ the gcj libraries, or try a different
+ JDK.
+
15.10:
+ Updating a table that contains a
+ primary key that is
+ either FLOAT or compound
+ primary key that uses FLOAT
+ fails to update the table and raises an exception.
+
+ Connector/J adds conditions to the WHERE
+ clause during an UPDATE to
+ check the old values of the primary key. If there is no
+ match, then Connector/J considers this a failure condition
+ and raises an exception.
+
+ The problem is that rounding differences between supplied + values and the values stored in the database may mean that + the values never match, and hence the update fails. The + issue will affect all queries, not just those from + Connector/J. +
+ To prevent this issue, use a primary key that does not use
+ FLOAT. If you have to use a
+ floating point column in your primary key, use
+ DOUBLE or
+ DECIMAL types in place of
+ FLOAT.
+
15.11:
+ You get an
+ ER_NET_PACKET_TOO_LARGE
+ exception, even though the binary blob size you want to
+ insert using JDBC is safely below the
+ max_allowed_packet size.
+
+ This is because the hexEscapeBlock()
+ method in
+ com.mysql.jdbc.PreparedStatement.streamToBytes()
+ may almost double the size of your data.
+
15.12: + What should you do if you receive error messages similar to + the following: “Communications link failure – Last + packet sent to the server was X ms ago”? +
+ Generally speaking, this error suggests that the network + connection has been closed. There can be several root + causes: +
+ Firewalls or routers may clamp down on idle connections + (the MySQL client/server protocol does not ping). +
+ The MySQL Server may be closing idle connections that
+ exceed the wait_timeout or
+ interactive_timeout threshold.
+
+ To help troubleshoot these issues, the following tips can be + used. If a recent (5.1.13+) version of Connector/J is used, + you will see an improved level of information compared to + earlier versions. Older versions simply display the last + time a packet was sent to the server, which is frequently 0 + ms ago. This is of limited use, as it may be that a packet + was just sent, while a packet from the server has not been + received for several hours. Knowing the period of time since + Connector/J last received a packet from the server is useful + information, so if this is not displayed in your exception + message, it is recommended that you update Connector/J. +
+ Further, if the time a packet was last sent/received exceeds
+ the wait_timeout or
+ interactive_timeout threshold, this is
+ noted in the exception message.
+
+ Although network connections can be volatile, the following + can be helpful in avoiding problems: +
+ Ensure connections are valid when used from the
+ connection pool. Use a query that starts with
+ /* ping */ to execute a lightweight
+ ping instead of full query. Note, the syntax of the ping
+ needs to be exactly as specified here.
+
+ Minimize the duration a connection object is left idle + while other application logic is executed. +
+ Explicitly validate the connection before using it if + the connection has been left idle for an extended period + of time. +
+ Ensure that wait_timeout and
+ interactive_timeout are set
+ sufficiently high.
+
+ Ensure that tcpKeepalive is enabled.
+
+ Ensure that any configurable firewall or router timeout + settings allow for the maximum expected connection idle + time. +
+ Do not expect to be able to reuse a connection without + problems, if it has being lying idle for a period. If a + connection is to be reused after being idle for any length + of time, ensure that you explicitly test it before reusing + it. +
15.13:
+ Why does Connector/J not reconnect to MySQL and re-issue the
+ statement after a communication failure, instead of throwing
+ an Exception, even though I use the
+ autoReconnect connection string option?
+
+ There are several reasons for this. The first is + transactional integrity. The MySQL Reference Manual states + that “there is no safe method of reconnecting to the + MySQL server without risking some corruption of the + connection state or database state information”. + Consider the following series of statements for example: +
+ +conn.createStatement().execute( + "UPDATE checking_account SET balance = balance - 1000.00 WHERE customer='Smith'"); +conn.createStatement().execute( + "UPDATE savings_account SET balance = balance + 1000.00 WHERE customer='Smith'"); +conn.commit(); + +
+ Consider the case where the connection to the server fails
+ after the UPDATE to
+ checking_account. If no exception is
+ thrown, and the application never learns about the problem,
+ it will continue executing. However, the server did not
+ commit the first transaction in this case, so that will get
+ rolled back. But execution continues with the next
+ transaction, and increases the
+ savings_account balance by 1000. The
+ application did not receive an exception, so it continued
+ regardless, eventually committing the second transaction, as
+ the commit only applies to the changes made in the new
+ connection. Rather than a transfer taking place, a deposit
+ was made in this example.
+
+ Note that running with autocommit enabled
+ does not solve this problem. When Connector/J encounters a
+ communication problem, there is no means to determine
+ whether the server processed the currently executing
+ statement or not. The following theoretical states are
+ equally possible:
+
+ The server never received the statement, and therefore + no related processing occurred on the server. +
+ The server received the statement, executed it in full, + but the response was not received by the client. +
+ If you are running with autocommit
+ enabled, it is not possible to guarantee the state of data
+ on the server when a communication exception is encountered.
+ The statement may have reached the server, or it may not.
+ All you know is that communication failed at some point,
+ before the client received confirmation (or data) from the
+ server. This does not only affect
+ autocommit statements though. If the
+ communication problem occurred during
+ Connection.commit(), the question arises
+ of whether the transaction was committed on the server
+ before the communication failed, or whether the server
+ received the commit request at all.
+
+ The second reason for the generation of exceptions is that + transaction-scoped contextual data may be vulnerable, for + example: +
+ Temporary tables. +
+ User-defined variables. +
+ Server-side prepared statements. +
+ These items are lost when a connection fails, and if the + connection silently reconnects without generating an + exception, this could be detrimental to the correct + execution of your application. +
+ In summary, communication errors generate conditions that + may well be unsafe for Connector/J to simply ignore by + silently reconnecting. It is necessary for the application + to be notified. It is then for the application developer to + decide how to proceed in the event of connection errors and + failures. +
15.14: + How can I use 3-byte UTF8 with Connector/J? +
+ To use 3-byte UTF8 with Connector/J set
+ characterEncoding=utf8 and set
+ useUnicode=true in the connection string.
+
15.15:
+ How can I use 4-byte UTF8, utf8mb4 with
+ Connector/J?
+
+ To use 4-byte UTF8 with Connector/J configure the MySQL
+ server with character_set_server=utf8mb4.
+ Connector/J will then use that setting as long as
+ characterEncoding has not been set in the
+ connection string. This is equivalent to autodetection of
+ the character set.
+
15.16:
+ Using useServerPrepStmts=false and
+ certain character encodings can lead to corruption when
+ inserting BLOBs. How can this be avoided?
+
+ When using certain character encodings, such as SJIS, CP932, + and BIG5, it is possible that BLOB data contains characters + that can be interpreted as control characters, for example, + backslash, '\'. This can lead to corrupted data when + inserting BLOBs into the database. There are two things that + need to be done to avoid this: +
+ Set the connection string option
+ useServerPrepStmts to
+ true.
+
+ Set SQL_MODE to
+ NO_BACKSLASH_ESCAPES.
+
+ The following are some known issues and limitations for MySQL + Connector/J: +
+ When Connector/J retrieves timestamps for a daylight saving
+ time (DST) switch day using the
+ getTimeStamp() method on the result set,
+ some of the returned values might be wrong. The errors can be
+ avoided by using the following connection options when
+ connecting to a database:
+
+
+ useTimezone=true + useLegacyDatetimeCode=false + serverTimezone=UTC +
+
+ Oracle provides assistance to the user community by means of its + mailing lists. For Connector/J related issues, you can get help + from experienced users by using the MySQL and Java mailing list. + Archives and subscription information is available online at + http://lists.mysql.com/java. +
+ For information about subscribing to MySQL mailing lists or to + browse list archives, visit + http://lists.mysql.com/. See + MySQL Mailing Lists. +
+ Community support from experienced users is also available + through the JDBC + Forum. You may also find help from other users in the + other MySQL Forums, located at + http://forums.mysql.com. See + MySQL Community Support at the MySQL Forums. +
+ The normal place to report bugs is + http://bugs.mysql.com/, which is the address for + our bugs database. This database is public, and can be browsed + and searched by anyone. If you log in to the system, you will + also be able to enter new reports. +
+ If you find a sensitive security bug in MySQL Server, please let
+ us know immediately by sending an email message to
+ <secalert_us@oracle.com>. Exception: Support
+ customers should report all problems, including security bugs,
+ to Oracle Support at http://support.oracle.com/.
+
+ Writing a good bug report takes patience, but doing it right the + first time saves time both for us and for yourself. A good bug + report, containing a full test case for the bug, makes it very + likely that we will fix the bug in the next release. +
+ This section will help you write your report correctly so that + you do not waste your time doing things that may not help us + much or at all. +
+ If you have a repeatable bug report, please report it to the + bugs database at http://bugs.mysql.com/. Any bug + that we are able to repeat has a high chance of being fixed in + the next MySQL release. +
+ To report other problems, you can use one of the MySQL mailing + lists. +
+ Remember that it is possible for us to respond to a message + containing too much information, but not to one containing too + little. People often omit facts because they think they know the + cause of a problem and assume that some details do not matter. +
+ A good principle is this: If you are in doubt about stating + something, state it. It is faster and less troublesome to write + a couple more lines in your report than to wait longer for the + answer if we must ask you to provide information that was + missing from the initial report. +
+ The most common errors made in bug reports are (a) not including + the version number of Connector/J or MySQL used, and (b) not + fully describing the platform on which Connector/J is installed + (including the JVM version, and the platform type and version + number that MySQL itself is installed on). +
+ This is highly relevant information, and in 99 cases out of 100, + the bug report is useless without it. Very often we get + questions like, “Why doesn't this work for me?” + Then we find that the feature requested wasn't implemented in + that MySQL version, or that a bug described in a report has + already been fixed in newer MySQL versions. +
+ Sometimes the error is platform-dependent; in such cases, it is + next to impossible for us to fix anything without knowing the + operating system and the version number of the platform. +
+ If at all possible, create a repeatable, standalone testcase + that doesn't involve any third-party classes. +
+ To streamline this process, we ship a base class for testcases
+ with Connector/J, named
+ 'com.mysql.jdbc.util.BaseBugReport'. To
+ create a testcase for Connector/J using this class, create your
+ own class that inherits from
+ com.mysql.jdbc.util.BaseBugReport and
+ override the methods setUp(),
+ tearDown() and
+ runTest().
+
+ In the setUp() method, create code that
+ creates your tables, and populates them with any data needed to
+ demonstrate the bug.
+
+ In the runTest() method, create code that
+ demonstrates the bug using the tables and data you created in
+ the setUp method.
+
+ In the tearDown() method, drop any tables
+ you created in the setUp() method.
+
+ In any of the above three methods, use one of the variants of
+ the getConnection() method to create a JDBC
+ connection to MySQL:
+
+ getConnection() - Provides a connection
+ to the JDBC URL specified in getUrl().
+ If a connection already exists, that connection is returned,
+ otherwise a new connection is created.
+
+ getNewConnection() - Use this if you
+ need to get a new connection for your bug report (that is,
+ there is more than one connection involved).
+
+ getConnection(String url) - Returns a
+ connection using the given URL.
+
+ getConnection(String url, Properties
+ props) - Returns a connection using the given URL
+ and properties.
+
+ If you need to use a JDBC URL that is different from
+ 'jdbc:mysql:///test', override the method
+ getUrl() as well.
+
+ Use the assertTrue(boolean expression) and
+ assertTrue(String failureMessage, boolean
+ expression) methods to create conditions that must be
+ met in your testcase demonstrating the behavior you are
+ expecting (vs. the behavior you are observing, which is why you
+ are most likely filing a bug report).
+
+ Finally, create a main() method that
+ creates a new instance of your testcase, and calls the
+ run method:
+
+public static void main(String[] args) throws Exception {
+ new MyBugReport().run();
+ }
++ Once you have finished your testcase, and have verified that it + demonstrates the bug you are reporting, upload it with your bug + report to http://bugs.mysql.com/. +