%PDF-1.5 %���� ºaâÚÎΞ-ÌE1ÍØÄ÷{òò2ÿ ÛÖ^ÔÀá TÎ{¦?§®¥kuµùÕ5sLOšuY
| Server IP : 122.154.253.140 / Your IP : 216.73.216.185 Web Server : Microsoft-IIS/7.5 System : Windows NT SERVER02 6.1 build 7601 (Windows Server 2008 R2 Standard Edition Service Pack 1) i586 User : IUSR ( 0) PHP Version : 5.6.31 Disable Function : NONE MySQL : ON | cURL : ON | WGET : OFF | Perl : OFF | Python : OFF | Sudo : OFF | Pkexec : OFF Directory : C:/Program Files (x86)/MySQL/Connector.J 5.1/docs/ |
Upload File : |
<html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>MySQL Connector/J Developer Guide</title><link rel="stylesheet" type="text/css" href="mvl.css"><meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
<script language="javascript" type="text/javascript">
function addOnload(theFunc)
{
var previous = window.onload;
if (typeof window.onload != 'function')
{
window.onload = theFunc;
}
else
{
window.onload = function()
{
previous();
theFunc();
}
}
}
addOnload(function()
{
var base = new Date(1449031775*1000);
var now = new Date();
var diff = ((now-base)/1000)/(24*3600);
if (diff > 90) {
var nodes = document.getElementsByClassName('titlepage');
nodes[0].innerHTML = '<p style="border: 5px #ff0000 solid; padding: 5px; margin 5px">' +
'This copy of the manual is more than 90 days old. We encourage you to download a ' +
'new version from <a href="http://dev.mysql.com">dev.mysql.com/doc</a>.</p>' + nodes[0].innerHTML;
}
});
</script>
<noscript></noscript>
</head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div lang="en" class="book"><div class="titlepage"><div><div><h1 class="title"><a name="connector-j"></a>MySQL Connector/J Developer Guide</h1></div><div><div class="abstract"><p class="title"><b>Abstract</b></p><p>
This manual describes how to install, configure, and develop
database applications using MySQL Connector/J, the JDBC driver
for communicating with MySQL servers.
</p><p>
For notes detailing the changes in each release of Connector/J,
see <a class="ulink" href="http://dev.mysql.com/doc/relnotes/connector-j/en/" target="_top">MySQL
Connector/J Release Notes</a>.
</p><p>
For legal information, see the <a class="link" href="#legalnotice" title="Legal Notices">Legal
Notices</a>.
</p><p>
For help with using MySQL, please visit either the
<a class="ulink" href="http://forums.mysql.com" target="_top">MySQL Forums</a> or
<a class="ulink" href="http://lists.mysql.com" target="_top">MySQL Mailing Lists</a>,
where you can discuss your issues with other MySQL users.
</p><p>
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 <a class="ulink" href="http://dev.mysql.com/doc" target="_top">MySQL
Documentation Library</a>.
</p><p>
Document generated on:
2015-12-02
(revision: 45718)
</p></div></div></div><hr></div><div class="toc"><p><b>Table of Contents</b></p><dl class="toc"><dt><span class="preface"><a href="#preface">Preface and Legal Notices</a></span></dt><dt><span class="chapter"><a href="#connector-j-overview">1 Overview of MySQL Connector/J</a></span></dt><dt><span class="chapter"><a href="#connector-j-versions">2 Connector/J Versions</a></span></dt><dd><dl><dt><span class="section"><a href="#connector-j-change-history">2.1 Connector/J Release Notes and Change History</a></span></dt><dt><span class="section"><a href="#connector-j-versions-java">2.2 Java Versions Supported</a></span></dt></dl></dd><dt><span class="chapter"><a href="#connector-j-installing">3 Connector/J Installation</a></span></dt><dd><dl><dt><span class="section"><a href="#connector-j-binary-installation">3.1 Installing Connector/J from a Binary Distribution</a></span></dt><dt><span class="section"><a href="#connector-j-installing-classpath">3.2 Installing the Driver and Configuring the <code class="literal">CLASSPATH</code></a></span></dt><dt><span class="section"><a href="#connector-j-installing-upgrading">3.3 Upgrading from an Older Version</a></span></dt><dd><dl><dt><span class="section"><a href="#connector-j-installing-upgrading-5-1">3.3.1 Upgrading to MySQL Connector/J 5.1.x</a></span></dt><dt><span class="section"><a href="#connector-j-installing-upgrading-issues">3.3.2 JDBC-Specific Issues When Upgrading to MySQL Server 4.1 or Newer</a></span></dt><dt><span class="section"><a href="#connector-j-installing-upgrading-3-0-to-3-1">3.3.3 Upgrading from MySQL Connector/J 3.0 to 3.1</a></span></dt></dl></dd><dt><span class="section"><a href="#connector-j-installing-source">3.4 Installing from Source</a></span></dt><dt><span class="section"><a href="#connector-j-testing">3.5 Testing Connector/J</a></span></dt></dl></dd><dt><span class="chapter"><a href="#connector-j-examples">4 Connector/J Examples</a></span></dt><dt><span class="chapter"><a href="#connector-j-reference">5 Connector/J (JDBC) Reference</a></span></dt><dd><dl><dt><span class="section"><a href="#connector-j-reference-configuration-properties">5.1 Driver/Datasource Class Names, URL Syntax and Configuration Properties
for Connector/J</a></span></dt><dd><dl><dt><span class="section"><a href="#connector-j-useconfigs">5.1.1 Properties Files for the <code class="literal">useConfigs</code> Option</a></span></dt></dl></dd><dt><span class="section"><a href="#connector-j-reference-implementation-notes">5.2 JDBC API Implementation Notes</a></span></dt><dt><span class="section"><a href="#connector-j-reference-type-conversions">5.3 Java, JDBC and MySQL Types</a></span></dt><dt><span class="section"><a href="#connector-j-reference-charsets">5.4 Using Character Sets and Unicode</a></span></dt><dt><span class="section"><a href="#connector-j-reference-using-ssl">5.5 Connecting Securely Using SSL</a></span></dt><dt><span class="section"><a href="#connector-j-using-pam">5.6 Connecting Using PAM Authentication</a></span></dt><dt><span class="section"><a href="#connector-j-reference-replication-connection">5.7 Using Master/Slave Replication with ReplicationConnection</a></span></dt><dt><span class="section"><a href="#connector-j-reference-error-sqlstates">5.8 Mapping MySQL Error Numbers to JDBC SQLState Codes</a></span></dt></dl></dd><dt><span class="chapter"><a href="#connector-j-usagenotes-basic">6 JDBC Concepts</a></span></dt><dd><dl><dt><span class="section"><a href="#connector-j-usagenotes-connect-drivermanager">6.1 Connecting to MySQL Using the JDBC <code class="literal">DriverManager</code>
Interface</a></span></dt><dt><span class="section"><a href="#connector-j-usagenotes-statements">6.2 Using JDBC <code class="literal">Statement</code> Objects to Execute SQL</a></span></dt><dt><span class="section"><a href="#connector-j-usagenotes-statements-callable">6.3 Using JDBC <code class="literal">CallableStatements</code> to Execute Stored
Procedures</a></span></dt><dt><span class="section"><a href="#connector-j-usagenotes-last-insert-id">6.4 Retrieving <code class="literal">AUTO_INCREMENT</code> Column Values through JDBC</a></span></dt></dl></dd><dt><span class="chapter"><a href="#connector-j-usagenotes-j2ee-concepts-connection-pooling">7 Connection Pooling with Connector/J</a></span></dt><dt><span class="chapter"><a href="#connector-j-multi-host-connections">8 Multi-Host Connections</a></span></dt><dd><dl><dt><span class="section"><a href="#connector-j-config-failover">8.1 Configuring Server Failover</a></span></dt><dt><span class="section"><a href="#connector-j-usagenotes-j2ee-concepts-managing-load-balanced-connections">8.2 Configuring Load Balancing with Connector/J</a></span></dt><dt><span class="section"><a href="#connector-j-master-slave-replication-connection">8.3 Configuring Master/Slave Replication with Connector/J</a></span></dt><dt><span class="section"><a href="#connector-j-usagenotes-j2ee-concepts-load-balancing-failover">8.4 Advanced Load-balancing and Failover Configuration</a></span></dt></dl></dd><dt><span class="chapter"><a href="#connector-j-interceptors">9 Using the Connector/J Interceptor Classes</a></span></dt><dt><span class="chapter"><a href="#connector-j-usagenotes-tomcat">10 Using Connector/J with Tomcat</a></span></dt><dt><span class="chapter"><a href="#connector-j-usagenotes-jboss">11 Using Connector/J with JBoss</a></span></dt><dt><span class="chapter"><a href="#connector-j-usagenotes-spring-config">12 Using Connector/J with Spring</a></span></dt><dd><dl><dt><span class="section"><a href="#connector-j-usagenotes-spring-config-jdbctemplate">12.1 Using <code class="classname">JdbcTemplate</code></a></span></dt><dt><span class="section"><a href="#connector-j-usagenotes-spring-config-transactional">12.2 Transactional JDBC Access</a></span></dt><dt><span class="section"><a href="#connector-j-usagenotes-spring-config-connpooling">12.3 Connection Pooling with Spring</a></span></dt></dl></dd><dt><span class="chapter"><a href="#connector-j-usagenotes-glassfish-config">13 Using Connector/J with GlassFish</a></span></dt><dd><dl><dt><span class="section"><a href="#connector-j-usagenotes-glassfish-config-jsp">13.1 A Simple JSP Application with GlassFish, Connector/J and MySQL</a></span></dt><dt><span class="section"><a href="#connector-j-usagenotes-glassfish-config-servlet">13.2 A Simple Servlet with GlassFish, Connector/J and MySQL</a></span></dt></dl></dd><dt><span class="chapter"><a href="#connector-j-usagenotes-fabric">14 Using Connector/J with MySQL Fabric</a></span></dt><dt><span class="chapter"><a href="#connector-j-usagenotes-troubleshooting">15 Troubleshooting Connector/J Applications</a></span></dt><dt><span class="chapter"><a href="#connector-j-usagenotes-known-issues-limitations">16 Known Issues and Limitations</a></span></dt><dt><span class="chapter"><a href="#connector-j-support">17 Connector/J Support</a></span></dt><dd><dl><dt><span class="section"><a href="#connector-j-support-community">17.1 Connector/J Community Support</a></span></dt><dt><span class="section"><a href="#connector-j-support-bug-report">17.2 How to Report Connector/J Bugs or Problems</a></span></dt></dl></dd><dt><span class="appendix"><a href="#connector-j-third-party-licenses">A Licenses for Third-Party Components</a></span></dt><dd><dl><dt><span class="section"><a href="#license-ant-contrib">A.1 Ant-Contrib License</a></span></dt><dt><span class="section"><a href="#license-c3p0-0-91">A.2 c3p0 JDBC Library License</a></span></dt><dt><span class="section"><a href="#license-gnu-lgpl-2-1">A.3 GNU Lesser General Public License Version 2.1, February 1999</a></span></dt><dt><span class="section"><a href="#license-jboss-common-jdbc-wrapper">A.4 jboss-common-jdbc-wrapper.jar License</a></span></dt><dt><span class="section"><a href="#license-nanoxml">A.5 NanoXML License</a></span></dt><dt><span class="section"><a href="#license-rox-jar">A.6 rox.jar License</a></span></dt><dt><span class="section"><a href="#license-slf4j">A.7 Simple Logging Facade for Java (SLF4J) License</a></span></dt><dt><span class="section"><a href="#license-unicode-data-files">A.8 Unicode Data Files</a></span></dt></dl></dd></dl></div><div class="preface"><div class="titlepage"><div><div><h1 class="title"><a name="preface"></a>Preface and Legal Notices</h1></div></div></div><p>
This manual describes how to install, configure, and develop
database applications using MySQL Connector/J, the JDBC driver for
communicating with MySQL servers.
</p><div class="simplesect"><div class="titlepage"><div><div class="simple"><h2 class="title" style="clear: both"><a name="legalnotice"></a>Legal Notices</h2></div></div></div><p>
Copyright © 1998, 2015, Oracle and/or its affiliates. All
rights reserved.
</p><p>
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.
</p><p>
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.
</p><p>
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:
</p><p>
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.
</p><p>
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.
</p><p>
Oracle and Java are registered trademarks of Oracle and/or its
affiliates. Other names may be trademarks of their respective
owners.
</p><p>
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.
</p><p>
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.
</p><p class="legal-head">Documentation Accessibility</p><p>
For information about Oracle's commitment to accessibility, visit
the Oracle Accessibility Program website at
<a class="ulink" href="http://www.oracle.com/pls/topic/lookup?ctx=acc&id=docacc" target="_top">http://www.oracle.com/pls/topic/lookup?ctx=acc&id=docacc</a>.
</p><p class="legal-subhead">Access to Oracle Support</p><p>
Oracle customers that have purchased support have access to
electronic support through My Oracle Support. For information,
visit
<a class="ulink" href="http://www.oracle.com/pls/topic/lookup?ctx=acc&id=info" target="_top">http://www.oracle.com/pls/topic/lookup?ctx=acc&id=info</a>
or visit
<a class="ulink" href="http://www.oracle.com/pls/topic/lookup?ctx=acc&id=trs" target="_top">http://www.oracle.com/pls/topic/lookup?ctx=acc&id=trs</a>
if you are hearing impaired.
</p><p>
This documentation is NOT distributed under a GPL license. Use of
this documentation is subject to the following terms:
</p><p>
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.
</p></div></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="connector-j-overview"></a>Chapter 1 Overview of MySQL Connector/J</h1></div></div></div><a class="indexterm" name="idm139688241586992"></a><p>
MySQL provides connectivity for client applications developed in
the Java programming language with MySQL Connector/J, a driver
that implements the
<a class="ulink" href="http://www.oracle.com/technetwork/java/javase/jdbc/index.html" target="_top">Java
Database Connectivity (JDBC) API</a>.
</p><p>
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 <a class="xref" href="#connector-j-versions" title="Chapter 2 Connector/J Versions">Chapter 2, <i>Connector/J Versions</i></a>). 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.
</p><p>
For large-scale programs that use common design patterns of data
access, consider using one of the popular persistence frameworks
such as <a class="ulink" href="http://www.hibernate.org/" target="_top">Hibernate</a>,
<a class="ulink" href="http://www.springframework.org/" target="_top">Spring's JDBC
templates</a> or <a class="ulink" href="http://ibatis.apache.org/" target="_top">Ibatis
SQL Maps</a> to reduce the amount of JDBC code for you to
debug, tune, secure, and maintain.
</p><h2><a name="idm139688241579856"></a>Key Topics</h2><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
For help with connection strings, connection options, and
setting up your connection through JDBC, see
<a class="xref" href="#connector-j-reference-configuration-properties" title="5.1 Driver/Datasource Class Names, URL Syntax and Configuration Properties for Connector/J">Section 5.1, “Driver/Datasource Class Names, URL Syntax and Configuration Properties
for Connector/J”</a>.
</p></li></ul></div></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="connector-j-versions"></a>Chapter 2 Connector/J Versions</h1></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl class="toc"><dt><span class="section"><a href="#connector-j-change-history">2.1 Connector/J Release Notes and Change History</a></span></dt><dt><span class="section"><a href="#connector-j-versions-java">2.2 Java Versions Supported</a></span></dt></dl></div><a class="indexterm" name="idm139688241576048"></a><p>
There are currently four versions of MySQL Connector/J available:
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
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 <code class="literal">java.time</code> package, support for
JDBC-4.x XML processing, support for per connection client
information, and support for the
<a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/char.html" target="_top"><code class="literal">NCHAR</code></a>,
<a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/char.html" target="_top"><code class="literal">NVARCHAR</code></a> and
<code class="literal">NCLOB</code> data types. This release also
includes all bug fixes up to and including Connector/J 5.0.6.
</p></li><li class="listitem"><p>
Connector/J 5.0 provides support for all the functionality
offered by Connector/J 3.1 and includes distributed
transaction (XA) support.
</p></li><li class="listitem"><p>
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.
</p></li><li class="listitem"><p>
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.
</p></li></ul></div><p>
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:
</p><p>
</p><div class="table"><a name="idm139688241564496"></a><p class="title"><b>Table 2.1 Summary of Connector/J Versions</b></p><div class="table-contents"><table summary="Summary of Connector/J Versions" border="1"><colgroup><col><col><col><col><col></colgroup><thead><tr><th scope="col">Connector/J version</th><th scope="col">Driver Type</th><th scope="col">JDBC version</th><th scope="col">MySQL Server version</th><th scope="col">Status</th></tr></thead><tbody><tr><td scope="row">5.1</td><td>4</td><td>3.0, 4.0, 4.1, 4.2</td><td>4.1, 5.0, 5.1, 5.5, 5.6, 5.7</td><td>Recommended version</td></tr><tr><td scope="row">5.0</td><td>4</td><td>3.0</td><td>4.1, 5.0</td><td>Released version</td></tr><tr><td scope="row">3.1</td><td>4</td><td>3.0</td><td>4.1, 5.0</td><td>Obsolete</td></tr><tr><td scope="row">3.0</td><td>4</td><td>3.0</td><td>3.x, 4.1</td><td>Obsolete</td></tr></tbody></table></div></div><p><br class="table-break">
</p><p>
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.
</p><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="connector-j-change-history"></a>2.1 Connector/J Release Notes and Change History</h2></div></div></div><p>
For details of new features and bug fixes in each Connector/J
release, see the
<a class="ulink" href="http://dev.mysql.com/doc/relnotes/connector-j/en/" target="_top">MySQL
Connector/J Release Notes</a>.
</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="connector-j-versions-java"></a>2.2 Java Versions Supported</h2></div></div></div><p>
The following table summarizes what version of Java RTE is
required to use Connector/J with Java applications, and what
version of JDK is required to build Connector/J source code:
</p><p>
</p><div class="table"><a name="idm139688236006912"></a><p class="title"><b>Table 2.2 Summary of Java Versions Required by Connector/J</b></p><div class="table-contents"><table summary="Summary of Java Versions Required by Connector/J" border="1"><colgroup><col><col><col></colgroup><thead><tr><th scope="col">Connector/J version</th><th scope="col">Java RTE required</th><th scope="col">JDK required (to build source code)</th></tr></thead><tbody><tr><td scope="row">5.1</td><td>1.5.x, 1.6.x, 1.7.x, 1.8.x</td><td>1.6.x and 1.5.x</td></tr><tr><td scope="row">5.0</td><td>1.3.x, 1.4.x, 1.5.x, 1.6.x</td><td>1.4.2, 1.5.x, 1.6.x</td></tr><tr><td scope="row">3.1</td><td>1.2.x, 1.3.x, 1.4.x, 1.5.x, 1.6.x</td><td>1.4.2, 1.5.x, 1.6.x</td></tr><tr><td scope="row">3.0</td><td>1.2.x, 1.3.x, 1.4.x, 1.5.x, 1.6.x</td><td>1.4.2, 1.5.x, 1.6.x</td></tr></tbody></table></div></div><p><br class="table-break">
</p><p>
If you are building Connector/J from source code using the
source distribution (see
<a class="xref" href="#connector-j-installing-source" title="3.4 Installing from Source">Section 3.4, “Installing from Source”</a>), 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
<span class="emphasis"><em>AND</em></span> JDK-1.5.x installed to be able to build
the source code.
</p><p>
Java 1.7 support requires Connector/J 5.1.21 and higher.
</p><p>
Several JDBC 4.1 methods were implemented for the first time in
Connector/J 5.1.21.
</p><p>
Because of the implementation of
<code class="classname">java.sql.Savepoint</code>, 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
<code class="option">-Xverify:none</code> option to the Java runtime). This
is because the class verifier will try to load the class
definition for <code class="classname">java.sql.Savepoint</code> even
though it is not accessed by the driver unless you actually use
savepoint functionality.
</p><p>
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
<code class="classname">java.util.LinkedHashMap</code>, which was first
available in JDK-1.4.0.
</p><p>
MySQL Connector/J does not support JDK-1.1.x or JDK-1.0.x.
</p></div></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="connector-j-installing"></a>Chapter 3 Connector/J Installation</h1></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl class="toc"><dt><span class="section"><a href="#connector-j-binary-installation">3.1 Installing Connector/J from a Binary Distribution</a></span></dt><dt><span class="section"><a href="#connector-j-installing-classpath">3.2 Installing the Driver and Configuring the <code class="literal">CLASSPATH</code></a></span></dt><dt><span class="section"><a href="#connector-j-installing-upgrading">3.3 Upgrading from an Older Version</a></span></dt><dd><dl><dt><span class="section"><a href="#connector-j-installing-upgrading-5-1">3.3.1 Upgrading to MySQL Connector/J 5.1.x</a></span></dt><dt><span class="section"><a href="#connector-j-installing-upgrading-issues">3.3.2 JDBC-Specific Issues When Upgrading to MySQL Server 4.1 or Newer</a></span></dt><dt><span class="section"><a href="#connector-j-installing-upgrading-3-0-to-3-1">3.3.3 Upgrading from MySQL Connector/J 3.0 to 3.1</a></span></dt></dl></dd><dt><span class="section"><a href="#connector-j-installing-source">3.4 Installing from Source</a></span></dt><dt><span class="section"><a href="#connector-j-testing">3.5 Testing Connector/J</a></span></dt></dl></div><p>
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
<code class="literal">CLASSPATH</code>.
</p><p>
If you are upgrading from a previous version, read the upgrade
information in <a class="xref" href="#connector-j-installing-upgrading" title="3.3 Upgrading from an Older Version">Section 3.3, “Upgrading from an Older Version”</a>
before continuing.
</p><p>
Connector/J is also available as part of the Maven project. For
more information and to download the Connector/J JAR files, see
the
<a class="ulink" href="http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22mysql%22%20AND%20a%3A%22mysql-connector-java%22" target="_top">Maven
repository</a>.
</p><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="connector-j-binary-installation"></a>3.1 Installing Connector/J from a Binary Distribution</h2></div></div></div><p>
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
<code class="literal">CLASSPATH</code> (see
<a class="xref" href="#connector-j-installing-classpath" title="3.2 Installing the Driver and Configuring the CLASSPATH">Section 3.2, “Installing the Driver and Configuring the <code class="literal">CLASSPATH</code>”</a>).
</p><p>
MySQL Connector/J is distributed as a <code class="literal">.zip</code> or
<code class="literal">.tar.gz</code> archive containing the sources, the
class files, and the JAR archive named
<code class="filename">mysql-connector-java-<em class="replaceable"><code>version</code></em>-bin.jar</code>.
</p><p>
Starting with Connector/J 3.1.9, the <code class="filename">.class</code>
files that constitute the JAR files are only included as part of
the driver JAR file.
</p><p>
Starting with Connector/J 3.1.8, the archive also includes a
debug build of the driver in a file named
<code class="filename">mysql-connector-java-<em class="replaceable"><code>version</code></em>-bin-g.jar</code>.
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
<code class="filename">src/lib/aspectjrt.jar</code> file that comes with
the Connector/J distribution.
</p><p>
Use the appropriate graphical or command-line utility to extract
the distribution (for example, WinZip for the .zip archive, and
<span class="command"><strong>tar</strong></span> 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.
</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="connector-j-installing-classpath"></a>3.2 Installing the Driver and Configuring the <code class="literal">CLASSPATH</code></h2></div></div></div><a class="indexterm" name="idm139688235972416"></a><p>
Once you have extracted the distribution archive, you can
install the driver by placing
<code class="filename">mysql-connector-java-<em class="replaceable"><code>version</code></em>-bin.jar
</code>in your classpath, either by adding the full path to
it to your <code class="literal">CLASSPATH</code> environment variable, or
by directly specifying it with the command line switch
<code class="literal">-cp</code> when starting the JVM.
</p><p>
To use the driver with the JDBC
<code class="literal">DriverManager</code>, use
<code class="literal">com.mysql.jdbc.Driver</code> as the class that
implements <code class="classname">java.sql.Driver</code>.
</p><p>
You can set the <code class="literal">CLASSPATH</code> environment
variable under Unix, Linux, or OS X either locally for a user
within their <code class="literal">.profile</code>,
<code class="literal">.login</code> or other login file. You can also set
it globally by editing the global
<code class="literal">/etc/profile</code> file.
</p><p>
For example, add the Connector/J driver to your
<code class="literal">CLASSPATH</code> using one of the following forms,
depending on your command shell:
</p><pre class="programlisting">
# Bourne-compatible shell (sh, ksh, bash, zsh):
shell> export CLASSPATH=/path/mysql-connector-java-<em class="replaceable"><code>ver</code></em>-bin.jar:$CLASSPATH
# C shell (csh, tcsh):
shell> setenv CLASSPATH /path/mysql-connector-java-<em class="replaceable"><code>ver</code></em>-bin.jar:$CLASSPATH
</pre><p>
For Windows platforms, you set the environment variable through
the System Control Panel.
</p><p>
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
<code class="literal">CLASSPATH</code> environment variable. For
configuration examples for some J2EE application servers, see
<a class="xref" href="#connector-j-usagenotes-j2ee-concepts-connection-pooling" title="Chapter 7 Connection Pooling with Connector/J">Chapter 7, <i>Connection Pooling with Connector/J</i></a>,
<a class="xref" href="#connector-j-usagenotes-j2ee-concepts-managing-load-balanced-connections" title="8.2 Configuring Load Balancing with Connector/J">Section 8.2, “Configuring Load Balancing with Connector/J”</a>,
and
<a class="xref" href="#connector-j-usagenotes-j2ee-concepts-load-balancing-failover" title="8.4 Advanced Load-balancing and Failover Configuration">Section 8.4, “Advanced Load-balancing and Failover Configuration”</a>.
However, the authoritative source for JDBC connection pool
configuration information for your particular application server
is the documentation for that application server.
</p><p>
If you are developing servlets or JSPs, and your application
server is J2EE-compliant, you can put the driver's
<code class="literal">.jar</code> file in the
<code class="filename">WEB-INF/lib</code> subdirectory of your webapp, as
this is a standard location for third party class libraries in
J2EE web applications.
</p><p>
You can also use the <code class="classname">MysqlDataSource</code> or
<code class="classname">MysqlConnectionPoolDataSource</code> classes in
the <code class="literal">com.mysql.jdbc.jdbc2.optional</code> package, if
your J2EE application server supports or requires them. Starting
with Connector/J 5.0.0, the
<code class="literal">javax.sql.XADataSource</code> interface is
implemented using the
<code class="literal">com.mysql.jdbc.jdbc2.optional.MysqlXADataSource</code>
class, which supports XA distributed transactions when used in
combination with MySQL server version 5.0 and later.
</p><p>
The various <code class="classname">MysqlDataSource</code> classes
support the following parameters (through standard set
mutators):
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
<code class="literal">user</code>
</p></li><li class="listitem"><p>
<code class="literal">password</code>
</p></li><li class="listitem"><p>
<code class="literal">serverName</code> (see the previous section
about failover hosts)
</p></li><li class="listitem"><p>
<code class="literal">databaseName</code>
</p></li><li class="listitem"><p>
<code class="literal">port</code>
</p></li></ul></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="connector-j-installing-upgrading"></a>3.3 Upgrading from an Older Version</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="section"><a href="#connector-j-installing-upgrading-5-1">3.3.1 Upgrading to MySQL Connector/J 5.1.x</a></span></dt><dt><span class="section"><a href="#connector-j-installing-upgrading-issues">3.3.2 JDBC-Specific Issues When Upgrading to MySQL Server 4.1 or Newer</a></span></dt><dt><span class="section"><a href="#connector-j-installing-upgrading-3-0-to-3-1">3.3.3 Upgrading from MySQL Connector/J 3.0 to 3.1</a></span></dt></dl></div><p>
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.
</p><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="connector-j-installing-upgrading-5-1"></a>3.3.1 Upgrading to MySQL Connector/J 5.1.x</h3></div></div></div><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
In Connector/J 5.0.x and earlier, the alias for a table in
a <a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/select.html" target="_top"><code class="literal">SELECT</code></a> statement is
returned when accessing the result set metadata using
<code class="function">ResultSetMetaData.getColumnName()</code>.
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.
</p><p>
The JDBC-compliant behavior is designed to let API users
reconstruct the DML statement based on the metadata within
<code class="literal">ResultSet</code> and
<code class="literal">ResultSetMetaData</code>.
</p><p>
You can get the alias for a column in a result set by
calling
<code class="function">ResultSetMetaData.getColumnLabel()</code>.
To use the old noncompliant behavior with
<code class="function">ResultSetMetaData.getColumnName()</code>,
use the <code class="option">useOldAliasMetadataBehavior</code>
option and set the value to <code class="literal">true</code>.
</p><p>
In Connector/J 5.0.x, the default value of
<code class="option">useOldAliasMetadataBehavior</code> was
<code class="literal">true</code>, but in Connector/J 5.1 this was
changed to a default value of <code class="literal">false</code>.
</p></li></ul></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="connector-j-installing-upgrading-issues"></a>3.3.2 JDBC-Specific Issues When Upgrading to MySQL Server 4.1 or Newer</h3></div></div></div><a class="indexterm" name="idm139688235927920"></a><a class="indexterm" name="idm139688235926528"></a><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
<span class="emphasis"><em>Using the UTF-8 Character Encoding</em></span> -
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 <code class="literal">latin1</code> tables on the
server.
</p><p>
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:
</p><p>
<code class="computeroutput">useOldUTF8Behavior=true</code>
</p></li><li class="listitem"><p>
<span class="emphasis"><em>Server-side Prepared Statements</em></span> -
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:
</p><p>
<code class="computeroutput">useServerPrepStmts=false</code>
</p></li></ul></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="connector-j-installing-upgrading-3-0-to-3-1"></a>3.3.3 Upgrading from MySQL Connector/J 3.0 to 3.1</h3></div></div></div><p>
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, <code class="literal">SQLState</code> codes returned in
error messages by the server and various performance
enhancements that can be enabled or disabled using
configuration properties.
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
<span class="bold"><strong>Unicode Character Sets</strong></span>:
See the next section, as well as
<a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/charset.html" target="_top">Character Set Support</a>, for information on this MySQL
feature. If you have something misconfigured, it will
usually show up as an error with a message similar to
<code class="literal">Illegal mix of collations</code>.
</p></li><li class="listitem"><p>
<span class="bold"><strong>Server-side Prepared
Statements</strong></span>: 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).
</p><p>
Starting with version 3.1.7, the driver scans SQL you are
preparing using all variants of
<code class="literal">Connection.prepareStatement()</code> 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
<code class="literal">emulateUnsupportedPstmts=false</code> in your
JDBC URL.
</p><p>
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
<code class="literal">useServerPrepStmts=false</code>.
</p></li><li class="listitem"><p>
<span class="bold"><strong>Datetimes</strong></span> with all-zero
components (<code class="literal">0000-00-00 ...</code>): These
values cannot be represented reliably in Java. Connector/J
3.0.x always converted them to <code class="literal">NULL</code>
when being read from a ResultSet.
</p><p>
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
<code class="literal">zeroDateTimeBehavior</code> configuration
property. The permissible values are:
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
<code class="literal">exception</code> (the default), which
throws an SQLException with an SQLState of
<code class="literal">S1009</code>.
</p></li><li class="listitem"><p>
<code class="literal">convertToNull</code>, which returns
<code class="literal">NULL</code> instead of the date.
</p></li><li class="listitem"><p>
<code class="literal">round</code>, which rounds the date to the
nearest closest value which is
<code class="literal">0001-01-01</code>.
</p></li></ul></div><p>
Starting with Connector/J 3.1.7,
<code class="literal">ResultSet.getString()</code> can be decoupled
from this behavior using
<code class="literal">noDatetimeStringSync=true</code> (the default
value is <code class="literal">false</code>) 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
<code class="literal">noDatetimeStringSync</code> and
<code class="literal">useTimezone</code> at the same time.
</p></li><li class="listitem"><p>
<span class="bold"><strong>New SQLState Codes</strong></span>:
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 <code class="literal">useSqlStateCodes=false</code>.
</p></li><li class="listitem"><p>
<span class="bold"><strong><code class="literal">ResultSet.getString()</code></strong></span>:
Calling <code class="literal">ResultSet.getString()</code> on a
<a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/blob.html" target="_top"><code class="literal">BLOB</code></a> column will now return
the address of the <code class="literal">byte[]</code> array that
represents it, instead of a <code class="literal">String</code>
representation of the <a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/blob.html" target="_top"><code class="literal">BLOB</code></a>.
<a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/blob.html" target="_top"><code class="literal">BLOB</code></a> values have no
character set, so they cannot be converted to
<code class="literal">java.lang.String</code>s without data loss or
corruption.
</p><p>
To store strings in MySQL with LOB behavior, use one of
the <a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/blob.html" target="_top"><code class="literal">TEXT</code></a> types, which the
driver will treat as a <code class="literal">java.sql.Clob</code>.
</p></li><li class="listitem"><p>
<span class="bold"><strong>Debug builds</strong></span>: Starting
with Connector/J 3.1.8 a debug build of the driver in a
file named
<code class="filename">mysql-connector-java-<em class="replaceable"><code>version</code></em>-bin-g.jar</code>
is shipped alongside the normal binary jar file that is
named
<code class="filename">mysql-connector-java-<em class="replaceable"><code>version</code></em>-bin.jar</code>.
</p><p>
Starting with Connector/J 3.1.9, we do not ship the
<code class="literal">.class</code> files unbundled, they are only
available in the JAR archives that ship with the driver.
</p><p>
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
<code class="filename">src/lib/aspectjrt.jar</code> file that comes
with the Connector/J distribution.
</p></li></ul></div></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="connector-j-installing-source"></a>3.4 Installing from Source</h2></div></div></div><div class="caution" style="margin-left: 0.5in; margin-right: 0.5in;"><div class="admon-title">Caution</div><p>
To just get MySQL Connector/J up and running on your system,
install Connector/J
<a class="link" href="#connector-j-binary-installation" title="3.1 Installing Connector/J from a Binary Distribution">using a
standard binary release distribution</a>. Instructions in
this section is only for users who, for various reasons, want
to compile Connector/J from source.
</p></div><p>
The requirements and steps for installing from source
Connector/J <a class="link" href="#connector-j-installing-5.1.37" title="Installing Connector/J 5.1.37 or later from source">5.1.37
or later</a>,
<a class="link" href="#connector-j-installing-5.1.34" title="Installing Connector/J 5.1.34 to 5.1.36 from source">5.1.34 to
5.1.36</a>, and
<a class="link" href="#connector-j-installing-5.1.33" title="Installing Connector/J 5.1.33 or earlier from the source tree">5.1.33 or
earlier</a> are different; check the section below that is
relevant for the version you want.
</p><p><a name="connector-j-installing-5.1.37"></a><b>Installing Connector/J 5.1.37 or later from source. </b>
To install MySQL Connector/J from its source tree on GitHub,
you need to have the following software on your system:
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
A Git client, to check out the sources from our GitHub
repository (available from
<a class="ulink" href="http://git-scm.com/downloads" target="_top">http://git-scm.com/downloads</a>).
</p></li><li class="listitem"><p>
Apache Ant version 1.8.2 or newer (available from
<a class="ulink" href="http://ant.apache.org/" target="_top">http://ant.apache.org/</a>).
</p></li><li class="listitem"><p>
JDK 1.8.x <span class="emphasis"><em>AND</em></span> JDK 1.5.x.
</p></li><li class="listitem"><p>
JRE 1.6.x (optional)
</p></li><li class="listitem"><p>
JUnit libraries (available from
<a class="ulink" href="https://github.com/junit-team/junit/wiki/Download-and-Install" target="_top">https://github.com/junit-team/junit/wiki/Download-and-Install</a>).
</p></li><li class="listitem"><p>
The required <code class="filename">.jar</code> files from the
Hibernate ORM 4.1 or 4.2 Final release bundle, which is
available at
<a class="ulink" href="http://sourceforge.net/projects/hibernate/files/hibernate4/" target="_top">http://sourceforge.net/projects/hibernate/files/hibernate4/</a>.
</p></li></ul></div><p>
To check out and compile MySQL Connector/J, follow these steps:
</p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>
Check out the code from the source code repository for MySQL
Connector/J located on GitHub at
<a class="ulink" href="https://github.com/mysql/mysql-connector-j" target="_top">https://github.com/mysql/mysql-connector-j</a>;
for the latest release of the Connector/J 5.1 series, use
the following command:
</p><pre class="programlisting">
shell> <strong class="userinput"><code>git clone https://github.com/mysql/mysql-connector-j.git </code></strong>
</pre><p>
To check out a release other than the latest one, use the
<code class="option">--branch</code> option to specify the revision tag
for it:
</p><pre class="programlisting">
shell> <strong class="userinput"><code>git clone --branch 5.1.<em class="replaceable"><code>xx</code></em> https://github.com/mysql/mysql-connector-j.git </code></strong>
</pre><p>
</p><p>
Under the current directory, the commands create a
<code class="filename">mysql-connector-j</code> subdirectory , which
contains the code you want.
</p></li><li class="listitem"><p>
Make sure that you have both JDK 1.8.x
<span class="emphasis"><em>AND</em></span> 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.
</p></li><li class="listitem"><p>
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 <code class="literal">com.mysql.jdbc.java6.rtjar</code>,
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.
</p></li><li class="listitem"><p>
Place the required <code class="filename">junit.jar</code> file in a
separate directory—for example,
<code class="filename">/home/username/ant-extralibs</code>.
</p></li><li class="listitem"><p>
In the same directory for extra libraries described in the
last step, create a directory named
<code class="filename">hibernate4</code>, and put under it all the
<code class="filename">.jar</code> files you can find under the
<code class="filename">/lib/required/</code> folder in the Hibernate
ORM 4 Final release bundle.
</p></li><li class="listitem"><p>
Change your current working directory to the
<code class="filename">mysql-connector-j</code> directory created in
step 1 above.
</p></li><li class="listitem"><p>
In the directory, create a file named
<code class="filename">build.properties</code> 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
<code class="filename">rt.jar</code> of your JRE 1.6.x (optional),
and the location of the extra libraries. The file should
contain the following property settings, with the
<span class="quote">“<span class="quote"><em class="replaceable"><code>path_to_*</code></em></span>”</span> parts
replaced by the appropriate filepaths:
</p><pre class="programlisting">
com.mysql.jdbc.jdk8=<em class="replaceable"><code>path_to_jdk_1.8</code></em>
com.mysql.jdbc.jdk5=<em class="replaceable"><code>path_to_jdk_1.5</code></em>
com.mysql.jdbc.java6.rtjar=<em class="replaceable"><code>path_to_rt.jar_under_jre_1.6</code></em>/rt.jar
com.mysql.jdbc.extra.libs=<em class="replaceable"><code>path_to_folder_for_extra_libraries</code></em>
</pre><p>
Alternatively, you can set the values of those properties
through the Ant <code class="option">-D</code> options.
</p></li><li class="listitem"><p>
Issue the following command to compile the driver and create
a <code class="filename">.jar</code> file for Connector/J:
</p><pre class="programlisting">
shell> <strong class="userinput"><code>ant dist</code></strong>
</pre><p>
This creates a <code class="filename">build</code> directory in the
current directory, where all the build output goes. A
directory is created under the <code class="filename">build</code>
directory, whose name includes the version number of the
release you are building. That directory contains the
sources, the compiled <code class="filename">.class</code> files, and
a <code class="filename">.jar</code> file for deployment. For more
information and other possible targets, including those that
create a fully packaged distribution, issue the following
command:
</p><pre class="programlisting">
shell> <strong class="userinput"><code>ant -projecthelp</code></strong>
</pre></li><li class="listitem"><p>
Install the newly created <code class="filename">.jar</code> file for
the JDBC driver as you would install a binary
<code class="filename">.jar</code> file you download from MySQL by
following the instructions given in
<a class="xref" href="#connector-j-installing-classpath" title="3.2 Installing the Driver and Configuring the CLASSPATH">Section 3.2, “Installing the Driver and Configuring the <code class="literal">CLASSPATH</code>”</a>.
</p></li></ol></div><p>
Note that a package containing both the binary and source code
for Connector/J 5.1 can also be found at
<a class="ulink" href="http://dev.mysql.com/downloads/connector/j/5.1.html" target="_top">
Connector/J 5.1 Download</a>.
</p><p><a name="connector-j-installing-5.1.34"></a><b>Installing Connector/J 5.1.34 to 5.1.36 from source. </b>
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:
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
A Git client, to check out the sources from our GitHub
repository (available from
<a class="ulink" href="http://git-scm.com/downloads" target="_top">http://git-scm.com/downloads</a>).
</p></li><li class="listitem"><p>
Apache Ant version 1.8.2 or newer (available from
<a class="ulink" href="http://ant.apache.org/" target="_top">http://ant.apache.org/</a>).
</p></li><li class="listitem"><p>
JDK 1.6.x <span class="emphasis"><em>AND</em></span> JDK 1.5.x.
</p></li><li class="listitem"><p>
JUnit libraries (available from
<a class="ulink" href="https://github.com/junit-team/junit/wiki/Download-and-Install" target="_top">https://github.com/junit-team/junit/wiki/Download-and-Install</a>).
</p></li><li class="listitem"><p>
The required <code class="filename">.jar</code> files from the
Hibernate ORM 4.1 or 4.2 Final release bundle, which is
available at
<a class="ulink" href="http://sourceforge.net/projects/hibernate/files/hibernate4/" target="_top">http://sourceforge.net/projects/hibernate/files/hibernate4/</a>.
</p></li></ul></div><p>
To check out and compile MySQL Connector/J, follow these steps:
</p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>
Check out the code from the source code repository for MySQL
Connector/J located on GitHub at
<a class="ulink" href="https://github.com/mysql/mysql-connector-j" target="_top">https://github.com/mysql/mysql-connector-j</a>,
using the <code class="option">--branch</code> option to specify the
revision tag for release 5.1.<em class="replaceable"><code>xx</code></em>:
</p><pre class="programlisting">
shell> <strong class="userinput"><code>git clone --branch 5.1.<em class="replaceable"><code>xx</code></em> https://github.com/mysql/mysql-connector-j.git </code></strong>
</pre><p>
</p><p>
Under the current directory, the commands create a
<code class="filename">mysql-connector-j</code> subdirectory , which
contains the code you want.
</p></li><li class="listitem"><p>
Make sure that you have both JDK 1.6.x
<span class="emphasis"><em>AND</em></span> 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.
</p></li><li class="listitem"><p>
Place the required <code class="filename">junit.jar</code> file in a
separate directory—for example,
<code class="filename">/home/username/ant-extralibs</code>.
</p></li><li class="listitem"><p>
In the same directory for extra libraries described in the
last step, create a directory named
<code class="filename">hibernate4</code>, and put under it all the
<code class="filename">.jar</code> files you can find under the
<code class="filename">/lib/required/</code> folder in the Hibernate
ORM 4 Final release bundle.
</p></li><li class="listitem"><p>
Change your current working directory to the
<code class="filename">mysql-connector-j</code> directory created in
step 1 above.
</p></li><li class="listitem"><p>
In the directory, create a file named
<code class="filename">build.properties</code> 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
<span class="quote">“<span class="quote"><em class="replaceable"><code>path_to_*</code></em></span>”</span> parts
replaced by the appropriate filepaths:
</p><pre class="programlisting">
com.mysql.jdbc.jdk5=<em class="replaceable"><code>path_to_jdk_1.5</code></em>
com.mysql.jdbc.jdk6=<em class="replaceable"><code>path_to_jdk_1.6</code></em>
com.mysql.jdbc.extra.libs=<em class="replaceable"><code>path_to_folder_for_extra_libraries</code></em>
</pre><p>
Alternatively, you can set the values of those properties
through the Ant <code class="option">-D</code> options.
</p></li><li class="listitem"><p>
Issue the following command to compile the driver and create
a <code class="filename">.jar</code> file for Connector/J:
</p><pre class="programlisting">
shell> <strong class="userinput"><code>ant dist</code></strong>
</pre><p>
This creates a <code class="filename">build</code> directory in the
current directory, where all the build output goes. A
directory is created under the <code class="filename">build</code>
directory, whose name includes the version number of the
release you are building. That directory contains the
sources, the compiled <code class="filename">.class</code> files, and
a <code class="filename">.jar</code> file for deployment. For more
information and other possible targets, including those that
create a fully packaged distribution, issue the following
command:
</p><pre class="programlisting">
shell> <strong class="userinput"><code>ant -projecthelp</code></strong>
</pre></li><li class="listitem"><p>
Install the newly created <code class="filename">.jar</code> file for
the JDBC driver as you would install a binary
<code class="filename">.jar</code> file you download from MySQL by
following the instructions given in
<a class="xref" href="#connector-j-installing-classpath" title="3.2 Installing the Driver and Configuring the CLASSPATH">Section 3.2, “Installing the Driver and Configuring the <code class="literal">CLASSPATH</code>”</a>.
</p></li></ol></div><p><a name="connector-j-installing-5.1.33"></a><b>Installing Connector/J 5.1.33 or earlier from the source tree. </b>
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:
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
A Git client, to check out the source code from our GitHub
repository (available from
<a class="ulink" href="http://git-scm.com/downloads" target="_top">http://git-scm.com/downloads</a>).
</p></li><li class="listitem"><p>
Apache Ant version 1.7 or newer (available from
<a class="ulink" href="http://ant.apache.org/" target="_top">http://ant.apache.org/</a>).
</p></li><li class="listitem"><p>
JDK 1.6.x <span class="emphasis"><em>AND</em></span> JDK 1.5.x. Refer to
<a class="xref" href="#connector-j-versions-java" title="2.2 Java Versions Supported">Section 2.2, “Java Versions Supported”</a> for the version
of Java you need to build or run any Connector/J release.
</p></li><li class="listitem"><p>
The Ant Contrib (version 1.03b is available from
<a class="ulink" href="http://sourceforge.net/projects/ant-contrib/files/ant-contrib/1.0b3/" target="_top">http://sourceforge.net/projects/ant-contrib/files/ant-contrib/1.0b3/</a>)
and JUnit (available from
<a class="ulink" href="https://github.com/junit-team/junit/wiki/Download-and-Install" target="_top">https://github.com/junit-team/junit/wiki/Download-and-Install</a>)
libraries.
</p></li></ul></div><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
The required <code class="filename">.jar</code> files from the
Hibernate ORM 4.1 or 4.2 Final release bundle, which is
available at
<a class="ulink" href="http://sourceforge.net/projects/hibernate/files/hibernate4/" target="_top">http://sourceforge.net/projects/hibernate/files/hibernate4/</a>.
</p></li></ul></div><p>
To check out and compile a specific branch of MySQL Connector/J,
follow these steps:
</p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>
Check out the code from the source code repository for MySQL
Connector/J located on GitHub at
<a class="ulink" href="https://github.com/mysql/mysql-connector-j" target="_top">https://github.com/mysql/mysql-connector-j</a>,
using the <code class="option">--branch</code> option to specify the
revision tag for release 5.1.<em class="replaceable"><code>xx</code></em>:
</p><pre class="programlisting">
shell> <strong class="userinput"><code>git clone --branch 5.1.<em class="replaceable"><code>xx</code></em> https://github.com/mysql/mysql-connector-j.git </code></strong>
</pre><p>
</p><p>
Under the current directory, the commands create a
<code class="filename">mysql-connector-j</code> subdirectory , which
contains the code you want.
</p></li><li class="listitem"><p>
To build Connector/J 5.1, make sure that you have both JDK
1.6.x <span class="emphasis"><em>AND</em></span> 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 <code class="literal">JAVA_HOME</code> environment variable to
the path to the JDK 1.5.x installation.
</p></li><li class="listitem"><p>
Place the required <code class="filename">ant-contrib.jar</code> file
(in exactly that name, without the version number in it;
rename the <code class="filename">jar</code> file if needed) and
<code class="filename">junit.jar</code> file in a separate
directory—for example,
<code class="filename">/home/username/ant-extralibs</code>.
</p></li><li class="listitem"><p>
In the same directory for extra libraries described in the
last step, create a directory named
<code class="filename">hibernate4</code>, and put under it all the
<code class="filename">.jar</code> files you can find under the
<code class="filename">/lib/required/</code> folder in the Hibernate
ORM 4 Final release bundle.
</p></li><li class="listitem"><p>
Change your current working directory to the
<code class="filename">mysql-connector-j</code> directory created in
step 1 above.
</p></li><li class="listitem"><p>
In the directory, create a file named
<code class="filename">build.properties</code> to indicate to Ant the
locations of the Javac and <code class="filename">rt.jar</code> 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
<span class="quote">“<span class="quote"><em class="replaceable"><code>path_to_*</code></em></span>”</span> parts
replaced by the appropriate filepaths:
</p><pre class="programlisting">
com.mysql.jdbc.java6.javac=<em class="replaceable"><code>path_to_javac_1.6</code></em>/javac
com.mysql.jdbc.java6.rtjar=<em class="replaceable"><code>path_to_rt.jar_under_jdk_1.6</code></em>/rt.jar
com.mysql.jdbc.extra.libs=<em class="replaceable"><code>path_to_folder_for_extra_libraries</code></em>
</pre><p>
Alternatively, you can set the values of those properties
through the Ant <code class="option">-D</code> options.
</p></li><li class="listitem"><p>
Issue the following command to compile the driver and create
a <code class="filename">.jar</code> file for Connector/J:
</p><pre class="programlisting">
shell> <strong class="userinput"><code>ant dist</code></strong>
</pre><p>
This creates a <code class="filename">build</code> directory in the
current directory, where all the build output goes. A
directory is created under the <code class="filename">build</code>
directory, whose name includes the version number of the
release you are building. That directory contains the
sources, the compiled <code class="filename">.class</code> files, and
a <code class="filename">.jar</code> file for deployment. For more
information and other possible targets, including those that
create a fully packaged distribution, issue the following
command:
</p><pre class="programlisting">
shell> <strong class="userinput"><code>ant -projecthelp</code></strong>
</pre></li><li class="listitem"><p>
Install the newly created <code class="filename">.jar</code> file for
the JDBC driver as you would install a binary
<code class="filename">.jar</code> file you download from MySQL by
following the instructions given in
<a class="xref" href="#connector-j-installing-classpath" title="3.2 Installing the Driver and Configuring the CLASSPATH">Section 3.2, “Installing the Driver and Configuring the <code class="literal">CLASSPATH</code>”</a>.
</p></li></ol></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="connector-j-testing"></a>3.5 Testing Connector/J</h2></div></div></div><p>
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:
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
<span class="emphasis"><em>Functional or unit tests:</em></span> Classes
from the package <code class="classname">testsuite.simple</code>.
Include test code for the main features of the
Connector/J.
</p></li><li class="listitem"><p>
<span class="emphasis"><em>Performance tests:</em></span> Classes from the
package <code class="classname">testsuite.perf</code>. Include
test code to make measurements for the performance of
Connector/J.
</p></li><li class="listitem"><p>
<span class="emphasis"><em>Fabric tests:</em></span> Classes from the
package <code class="classname">testsuite.fabric</code>. 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,
<code class="filename">build.xml</code>.
</p></li><li class="listitem"><p>
<span class="emphasis"><em>Regression tests:</em></span> Classes from the
package <code class="classname">testsuite.regression</code>.
Includes code for testing bug and regression fixes.
</p></li></ul></div><p>
</p><p>
The bundled Ant build file contains targets like
<code class="literal">test</code> and <code class="literal">test-multijvm</code>,
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
<a class="xref" href="#connector-j-installing-source" title="3.4 Installing from Source">Section 3.4, “Installing from Source”</a>, a number of the
tests also require the File System Service Provider 1.2 for the
Java Naming and Directory Interface (JNDI), available at
<a class="ulink" href="http://www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloads-java-plat-419418.html" target="_top">http://www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloads-java-plat-419418.html</a>)—place
the jar files downloaded from there into the
<code class="filename">lib</code> directory or in the directory pointed
to by the property <code class="literal">com.mysql.jdbc.extra.libs</code>.
</p><p>
To run the test using Ant, in addition to the properties
required for <a class="xref" href="#connector-j-installing-source" title="3.4 Installing from Source">Section 3.4, “Installing from Source”</a>,
you must set the following properties in the
<code class="filename">build.properties</code> file or through the Ant
<code class="option">-D</code> options:
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
<code class="literal">com.mysql.jdbc.testsuite.url</code>: it
specifies the JDBC URL for connection to a MySQL test
server; see
<a class="xref" href="#connector-j-reference-configuration-properties" title="5.1 Driver/Datasource Class Names, URL Syntax and Configuration Properties for Connector/J">Section 5.1, “Driver/Datasource Class Names, URL Syntax and Configuration Properties
for Connector/J”</a>.
</p></li><li class="listitem"><p>
<code class="literal">com.mysql.jdbc.testsuite.jvm</code>: 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 <code class="literal">com.mysql.jdbc.jdk8</code> (for
5.1.36 and earlier, supplied with the property
<code class="literal">com.mysql.jdbc.jdk6</code>). If the property
is not set, the JVM supplied with
<code class="literal">com.mysql.jdbc.jdk5</code> will be used to run
test cases for JDBC 3.0 and the one supplied with
<code class="literal">com.mysql.jdbc.jdk8</code> (for 5.1.36 and
earlier, supplied with the property
<code class="literal">com.mysql.jdbc.jdk6</code>) will be used to
run test cases for JDBC 4.0 and later.
</p></li></ul></div><p>
</p><p>
After setting these parameters, run the tests with Ant in the
following ways:
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
Building the <code class="literal">test</code> target with
<code class="literal">ant test</code> 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 <code class="literal">test</code> variable; for
example:
</p><pre class="programlisting">
shell > <strong class="userinput"><code>ant -Dtest=testsuite.simple.StringUtilsTest test</code></strong></pre><p>
You can also run individual tests in a test case by
specifying the names of the corresponding methods in the
<code class="literal">methods</code> variable, separating multiple
methods by commas; for example:
</p><pre class="programlisting">
shell > <strong class="userinput"><code>ant -Dtest=testsuite.simple.StringUtilsTest -Dmethods=testIndexOfIgnoreCase,testGetBytes test</code></strong>
</pre><p>
</p></li><li class="listitem"><p>
Building the <code class="literal">test-multijvm</code> target with
<code class="literal">ant test-multijvm</code> 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:
</p><pre class="programlisting">
com.mysql.jdbc.testsuite.jvm.1=<strong class="userinput"><code>path_to_Java_7</code></strong>
com.mysql.jdbc.testsuite.jvm.2=<strong class="userinput"><code>path_to_Java_8</code></strong>
com.mysql.jdbc.testsuite.url.1=<strong class="userinput"><code>URL_to_1st_server</code></strong>
com.mysql.jdbc.testsuite.url.2=<strong class="userinput"><code>URL_to_2nd_server</code></strong>
com.mysql.jdbc.testsuite.url.3=<strong class="userinput"><code>URL_to_3rd_server</code></strong></pre><p>
</p><p>
Unlike the target <code class="literal">test</code>, the target
<code class="literal">test-multijvm</code> only recognizes the
properties
<code class="literal">com.mysql.jdbc.testsuite.jvm.<strong class="userinput"><code>N</code></strong></code>
and
<code class="literal">com.mysql.jdbc.testsuite.url.<strong class="userinput"><code>N</code></strong></code>,
where <strong class="userinput"><code>N</code></strong> is a numeric suffice; the
same properties without the suffices are ignored by
<code class="literal">test-multijvm</code>. As with the target
<code class="literal">test</code>, if any of the
<code class="literal">com.mysql.jdbc.testsuite.jvm.<strong class="userinput"><code>N</code></strong></code>
settings points to Java 5, then Ant relies on the property
<code class="literal">com.mysql.jdbc.jdk8</code> to run the tests
specific to JDBC 4.0 and later.
</p><p>
You can choose to run individual test cases or specific
tests by using the <code class="literal">test</code> or
<code class="literal">methods</code> property, as explained in the
last bullet for the target <code class="literal">test</code>. Each
test is run once per possible combination of JVMs and
server instances (that is, 6 times in total for in this
example).
</p><p>
When a test for a certain JVM-server combination has
failed, <code class="literal">test-multijvm</code> does not throw an
error, but moves on to the next combination, until all
tests for all combinations are finished.
</p></li></ul></div><p>
</p><p>
While the test results are partially reported by the console,
complete reports in HTML and XML formats are provided:
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
For results of <code class="literal">test</code>: view the HTML
report by opening
<code class="filename">build/junit/unitregress/report/index.html</code>.
XML version of the reports are located in the folder
<code class="filename">build/junit/unitregress</code>.
</p></li><li class="listitem"><p>
For results of <code class="literal">test-multijvm</code>: view the
HTML report for each JVM-server combination by opening
<code class="filename">build/junit/MySQL<em class="replaceable"><code>N</code></em>.<em class="replaceable"><code>server_version</code></em>/<em class="replaceable"><code>operating_system_version</code></em>/<em class="replaceable"><code>jvm-version</code></em>/unitregress/report/index.html</code>.
XML version of the reports are located in the folder
<code class="filename">build/junit/MySQL<em class="replaceable"><code>N</code></em>.<em class="replaceable"><code>server_version</code></em>/<em class="replaceable"><code>operating_system_version</code></em>/<em class="replaceable"><code>jvm-version</code></em>/unitregress</code>.
</p></li></ul></div><p>
</p></div></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="connector-j-examples"></a>Chapter 4 Connector/J Examples</h1></div></div></div><a class="indexterm" name="idm139688235679360"></a><p>
Examples of using Connector/J are located throughout this
document. This section provides a summary and links to these
examples.
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
<a class="xref" href="#connector-j-examples-connection-drivermanager" title="Example 6.1 Connector/J: Obtaining a connection from the DriverManager">Example 6.1, “Connector/J: Obtaining a connection from the
<code class="literal">DriverManager</code>”</a>
</p></li><li class="listitem"><p>
<a class="xref" href="#connector-j-examples-execute-select" title="Example 6.2 Connector/J: Using java.sql.Statement to execute a SELECT query">Example 6.2, “Connector/J: Using java.sql.Statement to execute a
<code class="literal">SELECT</code> query”</a>
</p></li><li class="listitem"><p>
<a class="xref" href="#connector-j-examples-stored-procedure" title="Example 6.3 Connector/J: Calling Stored Procedures">Example 6.3, “Connector/J: Calling Stored Procedures”</a>
</p></li><li class="listitem"><p>
<a class="xref" href="#connector-j-examples-preparecall" title="Example 6.4 Connector/J: Using Connection.prepareCall()">Example 6.4, “Connector/J: Using <code class="literal">Connection.prepareCall()</code>”</a>
</p></li><li class="listitem"><p>
<a class="xref" href="#connector-j-examples-output-param" title="Example 6.5 Connector/J: Registering output parameters">Example 6.5, “Connector/J: Registering output parameters”</a>
</p></li><li class="listitem"><p>
<a class="xref" href="#connector-j-examples-callablestatement" title="Example 6.6 Connector/J: Setting CallableStatement input parameters">Example 6.6, “Connector/J: Setting <code class="literal">CallableStatement</code> input
parameters”</a>
</p></li><li class="listitem"><p>
<a class="xref" href="#connector-j-examples-retrieving-results-params" title="Example 6.7 Connector/J: Retrieving results and output parameter values">Example 6.7, “Connector/J: Retrieving results and output parameter values”</a>
</p></li><li class="listitem"><p>
<a class="xref" href="#connector-j-examples-autoincrement-getgeneratedkeys" title="Example 6.8 Connector/J: Retrieving AUTO_INCREMENT column values using Statement.getGeneratedKeys()">Example 6.8, “Connector/J: Retrieving <code class="literal">AUTO_INCREMENT</code> column values
using <code class="literal">Statement.getGeneratedKeys()</code>”</a>
</p></li><li class="listitem"><p>
<a class="xref" href="#connector-j-examples-autoincrement-select" title="Example 6.9 Connector/J: Retrieving AUTO_INCREMENT column values using SELECT LAST_INSERT_ID()">Example 6.9, “Connector/J: Retrieving <code class="literal">AUTO_INCREMENT</code> column values
using <code class="literal">SELECT LAST_INSERT_ID()</code>”</a>
</p></li><li class="listitem"><p>
<a class="xref" href="#connector-j-examples-autoincrement-updateable-resultsets" title="Example 6.10 Connector/J: Retrieving AUTO_INCREMENT column values in Updatable ResultSets">Example 6.10, “Connector/J: Retrieving <code class="literal">AUTO_INCREMENT</code> column values
in <code class="literal">Updatable ResultSets</code>”</a>
</p></li><li class="listitem"><p>
<a class="xref" href="#connector-j-examples-connectionpool-j2ee" title="Example 7.1 Connector/J: Using a connection pool with a J2EE application server">Example 7.1, “Connector/J: Using a connection pool with a J2EE application server”</a>
</p></li><li class="listitem"><p>
<a class="xref" href="#connector-j-examples-transaction-retry" title="Example 15.1 Connector/J: Example of transaction with retry logic">Example 15.1, “Connector/J: Example of transaction with retry logic”</a>
</p></li></ul></div></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="connector-j-reference"></a>Chapter 5 Connector/J (JDBC) Reference</h1></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl class="toc"><dt><span class="section"><a href="#connector-j-reference-configuration-properties">5.1 Driver/Datasource Class Names, URL Syntax and Configuration Properties
for Connector/J</a></span></dt><dd><dl><dt><span class="section"><a href="#connector-j-useconfigs">5.1.1 Properties Files for the <code class="literal">useConfigs</code> Option</a></span></dt></dl></dd><dt><span class="section"><a href="#connector-j-reference-implementation-notes">5.2 JDBC API Implementation Notes</a></span></dt><dt><span class="section"><a href="#connector-j-reference-type-conversions">5.3 Java, JDBC and MySQL Types</a></span></dt><dt><span class="section"><a href="#connector-j-reference-charsets">5.4 Using Character Sets and Unicode</a></span></dt><dt><span class="section"><a href="#connector-j-reference-using-ssl">5.5 Connecting Securely Using SSL</a></span></dt><dt><span class="section"><a href="#connector-j-using-pam">5.6 Connecting Using PAM Authentication</a></span></dt><dt><span class="section"><a href="#connector-j-reference-replication-connection">5.7 Using Master/Slave Replication with ReplicationConnection</a></span></dt><dt><span class="section"><a href="#connector-j-reference-error-sqlstates">5.8 Mapping MySQL Error Numbers to JDBC SQLState Codes</a></span></dt></dl></div><p>
This section of the manual contains reference material for MySQL
Connector/J.
</p><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="connector-j-reference-configuration-properties"></a>5.1 Driver/Datasource Class Names, URL Syntax and Configuration Properties
for Connector/J</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="section"><a href="#connector-j-useconfigs">5.1.1 Properties Files for the <code class="literal">useConfigs</code> Option</a></span></dt></dl></div><a class="indexterm" name="idm139688235659120"></a><a class="indexterm" name="idm139688235657728"></a><p>
The name of the class that implements
<code class="literal">java.sql.Driver</code> in MySQL Connector/J is
<code class="literal">com.mysql.jdbc.Driver</code>. The
<code class="literal">org.gjt.mm.mysql.Driver</code> 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.
</p><h3><a name="connector-j-reference-url-format"></a>JDBC URL Format</h3><p>
The general format for a JDBC URL for connecting to a MySQL
server is as follows, with items in square brackets ([ ]) being
optional:
</p><pre class="programlisting">
jdbc:mysql://[<em class="replaceable"><code>host1</code></em>][:<em class="replaceable"><code>port1</code></em>][,[<em class="replaceable"><code>host2</code></em>][:<em class="replaceable"><code>port2</code></em>]]...[/[<em class="replaceable"><code>database</code></em>]] »
[?<em class="replaceable"><code>propertyName1</code></em>=<em class="replaceable"><code>propertyValue1</code></em>[&<em class="replaceable"><code>propertyName2</code></em>=<em class="replaceable"><code>propertyValue2</code></em>]...]
</pre><p>
Here is a simple example for a connection URL:
</p><pre class="programlisting">
jdbc:mysql://localhost:3306/sakila?profileSQL=true
</pre><p>
Supply multiple hosts for a server failover setup (see
<a class="xref" href="#connector-j-multi-host-connections" title="Chapter 8 Multi-Host Connections">Chapter 8, <i>Multi-Host Connections</i></a> for
details):
</p><pre class="programlisting">
# Connection URL for a server failover setup:
jdbc:mysql//primaryhost,secondaryhost1,secondaryhost2/test</pre><p>
There are specialized URL schemes for configuring Connector/J's
multi-host functions like load balancing and replication; here
are some examples (see
<a class="xref" href="#connector-j-multi-host-connections" title="Chapter 8 Multi-Host Connections">Chapter 8, <i>Multi-Host Connections</i></a> for
details):
</p><pre class="programlisting">
# 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
</pre><p>
</p><h3><a name="idm139688235643664"></a>Host and Port</h3><p>
If no hosts are not specified, the host name defaults to
<code class="literal">127.0.0.1</code>. If the port for a host is not
specified, it defaults to <code class="literal">3306</code>, the default
port number for MySQL servers.
</p><h3><a name="idm139688235641152"></a>Initial Database for Connection</h3><p>
If the database is not specified, the connection is made with no
default database. In this case, either call the
<code class="function">setCatalog()</code> method on the Connection
instance, or fully specify table names using the database name
(that is, <code class="literal">SELECT
<em class="replaceable"><code>dbname</code></em>.<em class="replaceable"><code>tablename</code></em>.<em class="replaceable"><code>colname</code></em>
FROM dbname.tablename...</code>) 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.
</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><div class="admon-title">Note</div><p>
Always use the <code class="literal">Connection.setCatalog()</code>
method to specify the desired database in JDBC applications,
rather than the <code class="literal">USE
<em class="replaceable"><code>database</code></em></code> statement.
</p></div><h3><a name="connector-j-reference-ipv6-url"></a>IPv6 Connections</h3><a class="indexterm" name="idm139688235633968"></a><p>
For IPv6 connections, use this alternative syntax to specify
hosts in the URL (the same syntax can also be used for IPv4
connections):
</p><pre class="programlisting">
jdbc:mysql://address=(<em class="replaceable"><code>key1</code></em>=<em class="replaceable"><code>value</code></em>)[(<em class="replaceable"><code>key2</code></em>=<em class="replaceable"><code>value</code></em>)]...[,address=(key3=value)[(key4=value)]...]...[/[<em class="replaceable"><code>database</code></em>]]»
[?<em class="replaceable"><code>propertyName1</code></em>=<em class="replaceable"><code>propertyValue1</code></em>[&<em class="replaceable"><code>propertyName2</code></em>=<em class="replaceable"><code>propertyValue2</code></em>]...]
</pre><p>
Supported keys include:
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
<code class="literal">(protocol=tcp)</code>, or
<code class="literal">(protocol=pipe)</code> for named pipes on
Windows.
</p></li><li class="listitem"><p>
<code class="literal">(path=<em class="replaceable"><code>path_to_pipe</code></em>)</code>
for named pipes.
</p></li><li class="listitem"><p>
<code class="literal">(host=<em class="replaceable"><code>hostname</code></em>)</code>
for TCP connections.
</p></li><li class="listitem"><p>
<code class="literal">(port=<em class="replaceable"><code>port_number</code></em>)</code>
for TCP connections.
</p></li></ul></div><p>
For example:
</p><pre class="programlisting">
jdbc:mysql://address=(protocol=tcp)(host=localhost)(port=3306)/db
</pre><p>
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:
</p><pre class="programlisting">
# 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
</pre><p>
Limit the overrides to user, password, network timeouts, and
statement and metadata cache sizes; the effects of other
per-host overrides are not defined.
</p><p>
The ways to set the other configuration properties are the same
for IPv6 and IPv4 URLs; see
<a class="xref" href="#connector-j-reference-set-config" title="Setting Configuration Properties">Setting Configuration Properties</a>.
</p><p></p><h3><a name="connector-j-reference-set-config"></a>Setting Configuration Properties</h3><p>
Configuration properties define how Connector/J will make a
connection to a MySQL server. Unless otherwise noted, properties
can be set for a <code class="literal">DataSource</code> object or for a
<code class="literal">Connection</code> object.
</p><p>
Configuration properties can be set in one of the following
ways:
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
Using the <code class="literal">set*()</code> methods on MySQL
implementations of <code class="literal">java.sql.DataSource</code>
(which is the preferred method when using implementations of
<code class="literal">java.sql.DataSource</code>):
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
<code class="literal">com.mysql.jdbc.jdbc2.optional.MysqlDataSource</code>
</p></li><li class="listitem"><p>
<code class="literal">com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource</code>
</p></li></ul></div></li><li class="listitem"><p>
As a key/value pair in the
<code class="literal">java.util.Properties</code> instance passed to
<code class="literal">DriverManager.getConnection()</code> or
<code class="literal">Driver.connect()</code>
</p></li><li class="listitem"><p>
As a JDBC URL parameter in the URL given to
<code class="literal">java.sql.DriverManager.getConnection()</code>,
<code class="literal">java.sql.Driver.connect()</code> or the MySQL
implementations of the
<code class="literal">javax.sql.DataSource</code>
<code class="function">setURL()</code> method. If you specify a
configuration property in the URL without providing a value
for it, nothing will be set; for example, adding
<code class="literal">useServerPrepStmts</code> alone to the URL does
not make Connector/J use server-side prepared statements;
you need to add <code class="literal">useServerPrepStmts=true</code>.
</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><div class="admon-title">Note</div><p>
If the mechanism you use to configure a JDBC URL is
XML-based, use the XML character literal
<code class="literal">&amp;</code> to separate configuration
parameters, as the ampersand is a reserved character for
XML.
</p></div></li></ul></div><p>
The properties are listed in the following tables.
</p><p><b>Connection/Authentication. </b>
</p><div class="informaltable"><table summary="This table lists Connector/J Connection/Authentication
connection properties." border="1"><colgroup><col class="Properties"></colgroup><thead><tr><th scope="col"><span class="bold"><strong>Properties and Descriptions</strong></span></th></tr></thead><tbody><tr><td scope="row"><p>
<span class="strong"><strong>user</strong></span>
</p>
<p>
The user to connect as
</p>
<p>
Since version: all versions
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>password</strong></span>
</p>
<p>
The password to use when connecting
</p>
<p>
Since version: all versions
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>socketFactory</strong></span>
</p>
<p>
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.
</p>
<p>
Default: com.mysql.jdbc.StandardSocketFactory
</p>
<p>
Since version: 3.0.3
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>connectTimeout</strong></span>
</p>
<p>
Timeout for socket connect (in milliseconds), with 0
being no timeout. Only works on JDK-1.4 or newer.
Defaults to '0'.
</p>
<p>
Default: 0
</p>
<p>
Since version: 3.0.1
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>socketTimeout</strong></span>
</p>
<p>
Timeout on network socket operations (0, the default
means no timeout).
</p>
<p>
Default: 0
</p>
<p>
Since version: 3.0.1
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>connectionLifecycleInterceptors</strong></span>
</p>
<p>
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.
</p>
<p>
Since version: 5.1.4
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>useConfigs</strong></span>
</p>
<p>
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.
</p>
<p>
Since version: 3.1.5
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>authenticationPlugins</strong></span>
</p>
<p>
Comma-delimited list of classes that implement
com.mysql.jdbc.AuthenticationPlugin and which will be
used for authentication unless disabled by
"disabledAuthenticationPlugins" property.
</p>
<p>
Since version: 5.1.19
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>defaultAuthenticationPlugin</strong></span>
</p>
<p>
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).
</p>
<p>
Default:
com.mysql.jdbc.authentication.MysqlNativePasswordPlugin
</p>
<p>
Since version: 5.1.19
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>disabledAuthenticationPlugins</strong></span>
</p>
<p>
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).
</p>
<p>
Since version: 5.1.19
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>disconnectOnExpiredPasswords</strong></span>
</p>
<p>
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.
</p>
<p>
Default: true
</p>
<p>
Since version: 5.1.23
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>interactiveClient</strong></span>
</p>
<p>
Set the CLIENT_INTERACTIVE flag, which tells MySQL to
timeout connections based on INTERACTIVE_TIMEOUT
instead of WAIT_TIMEOUT
</p>
<p>
Default: false
</p>
<p>
Since version: 3.1.0
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>localSocketAddress</strong></span>
</p>
<p>
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.
</p>
<p>
Since version: 5.0.5
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>propertiesTransform</strong></span>
</p>
<p>
An implementation of
com.mysql.jdbc.ConnectionPropertiesTransform that the
driver will use to modify URL properties passed to the
driver before attempting a connection
</p>
<p>
Since version: 3.1.4
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>useCompression</strong></span>
</p>
<p>
Use zlib compression when communicating with the
server (true/false)? Defaults to 'false'.
</p>
<p>
Default: false
</p>
<p>
Since version: 3.0.17
</p></td></tr></tbody></table></div><p>
</p><p><b>Networking. </b>
</p><div class="informaltable"><table summary="This table lists Connector/J Networking connection
properties." border="1"><colgroup><col class="Properties"></colgroup><thead><tr><th scope="col"><span class="bold"><strong>Properties and Descriptions</strong></span></th></tr></thead><tbody><tr><td scope="row"><p>
<span class="strong"><strong>socksProxyHost</strong></span>
</p>
<p>
Name or IP address of SOCKS host to connect through.
</p>
<p>
Since version: 5.1.34
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>socksProxyPort</strong></span>
</p>
<p>
Port of SOCKS server.
</p>
<p>
Default: 1080
</p>
<p>
Since version: 5.1.34
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>maxAllowedPacket</strong></span>
</p>
<p>
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".
</p>
<p>
Default: -1
</p>
<p>
Since version: 5.1.8
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>tcpKeepAlive</strong></span>
</p>
<p>
If connecting using TCP/IP, should the driver set
SO_KEEPALIVE?
</p>
<p>
Default: true
</p>
<p>
Since version: 5.0.7
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>tcpNoDelay</strong></span>
</p>
<p>
If connecting using TCP/IP, should the driver set
SO_TCP_NODELAY (disabling the Nagle Algorithm)?
</p>
<p>
Default: true
</p>
<p>
Since version: 5.0.7
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>tcpRcvBuf</strong></span>
</p>
<p>
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)
</p>
<p>
Default: 0
</p>
<p>
Since version: 5.0.7
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>tcpSndBuf</strong></span>
</p>
<p>
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)
</p>
<p>
Default: 0
</p>
<p>
Since version: 5.0.7
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>tcpTrafficClass</strong></span>
</p>
<p>
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.
</p>
<p>
Default: 0
</p>
<p>
Since version: 5.0.7
</p></td></tr></tbody></table></div><p>
</p><p><b>High Availability and Clustering. </b>
</p><div class="informaltable"><table summary="This table lists Connector/J High Availability and
Clustering connection properties." border="1"><colgroup><col class="Properties"></colgroup><thead><tr><th scope="col"><span class="bold"><strong>Properties and Descriptions</strong></span></th></tr></thead><tbody><tr><td scope="row"><p>
<span class="strong"><strong>autoReconnect</strong></span>
</p>
<p>
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.
</p>
<p>
Default: false
</p>
<p>
Since version: 1.1
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>autoReconnectForPools</strong></span>
</p>
<p>
Use a reconnection strategy appropriate for connection
pools (defaults to 'false')
</p>
<p>
Default: false
</p>
<p>
Since version: 3.1.3
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>failOverReadOnly</strong></span>
</p>
<p>
When failing over in autoReconnect mode, should the
connection be set to 'read-only'?
</p>
<p>
Default: true
</p>
<p>
Since version: 3.0.12
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>maxReconnects</strong></span>
</p>
<p>
Maximum number of reconnects to attempt if
autoReconnect is true, default is '3'.
</p>
<p>
Default: 3
</p>
<p>
Since version: 1.1
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>reconnectAtTxEnd</strong></span>
</p>
<p>
If autoReconnect is set to true, should the driver
attempt reconnections at the end of every transaction?
</p>
<p>
Default: false
</p>
<p>
Since version: 3.0.10
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>retriesAllDown</strong></span>
</p>
<p>
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.
</p>
<p>
Default: 120
</p>
<p>
Since version: 5.1.6
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>initialTimeout</strong></span>
</p>
<p>
If autoReconnect is enabled, the initial time to wait
between re-connect attempts (in seconds, defaults to
'2').
</p>
<p>
Default: 2
</p>
<p>
Since version: 1.1
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>roundRobinLoadBalance</strong></span>
</p>
<p>
When autoReconnect is enabled, and failoverReadonly is
false, should we pick hosts to connect to on a
round-robin basis?
</p>
<p>
Default: false
</p>
<p>
Since version: 3.1.2
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>queriesBeforeRetryMaster</strong></span>
</p>
<p>
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.
</p>
<p>
Default: 50
</p>
<p>
Since version: 3.0.2
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>secondsBeforeRetryMaster</strong></span>
</p>
<p>
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
</p>
<p>
Default: 30
</p>
<p>
Since version: 3.0.2
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>allowMasterDownConnections</strong></span>
</p>
<p>
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.
</p>
<p>
Default: false
</p>
<p>
Since version: 5.1.27
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>allowSlaveDownConnections</strong></span>
</p>
<p>
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.
</p>
<p>
Default: false
</p>
<p>
Since version: 5.1.38
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>readFromMasterWhenNoSlaves</strong></span>
</p>
<p>
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.
</p>
<p>
Default: false
</p>
<p>
Since version: 5.1.38
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>replicationEnableJMX</strong></span>
</p>
<p>
Enables JMX-based management of load-balanced
connection groups, including live addition/removal of
hosts from load-balancing pool.
</p>
<p>
Default: false
</p>
<p>
Since version: 5.1.27
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>selfDestructOnPingMaxOperations</strong></span>
</p>
<p>
=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.
</p>
<p>
Default: 0
</p>
<p>
Since version: 5.1.6
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>selfDestructOnPingSecondsLifetime</strong></span>
</p>
<p>
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.
</p>
<p>
Default: 0
</p>
<p>
Since version: 5.1.6
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>resourceId</strong></span>
</p>
<p>
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
</p>
<p>
Since version: 5.0.1
</p></td></tr></tbody></table></div><p>
</p><p><b>Security. </b>
</p><div class="informaltable"><table summary="This table lists Connector/J Security connection
properties." border="1"><colgroup><col class="Properties"></colgroup><thead><tr><th scope="col"><span class="bold"><strong>Properties and Descriptions</strong></span></th></tr></thead><tbody><tr><td scope="row"><p>
<span class="strong"><strong>allowMultiQueries</strong></span>
</p>
<p>
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.
</p>
<p>
Default: false
</p>
<p>
Since version: 3.1.1
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>useSSL</strong></span>
</p>
<p>
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'
</p>
<p>
Default: false
</p>
<p>
Since version: 3.0.2
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>requireSSL</strong></span>
</p>
<p>
Require server support of SSL connection if
useSSL=true? (defaults to 'false').
</p>
<p>
Default: false
</p>
<p>
Since version: 3.1.0
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>verifyServerCertificate</strong></span>
</p>
<p>
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'
</p>
<p>
Default: true
</p>
<p>
Since version: 5.1.6
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>clientCertificateKeyStoreUrl</strong></span>
</p>
<p>
URL to the client certificate KeyStore (if not
specified, use defaults)
</p>
<p>
Since version: 5.1.0
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>clientCertificateKeyStoreType</strong></span>
</p>
<p>
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.
</p>
<p>
Default: JKS
</p>
<p>
Since version: 5.1.0
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>clientCertificateKeyStorePassword</strong></span>
</p>
<p>
Password for the client certificates KeyStore
</p>
<p>
Since version: 5.1.0
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>trustCertificateKeyStoreUrl</strong></span>
</p>
<p>
URL to the trusted root certificate KeyStore (if not
specified, use defaults)
</p>
<p>
Since version: 5.1.0
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>trustCertificateKeyStoreType</strong></span>
</p>
<p>
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.
</p>
<p>
Default: JKS
</p>
<p>
Since version: 5.1.0
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>trustCertificateKeyStorePassword</strong></span>
</p>
<p>
Password for the trusted root certificates KeyStore
</p>
<p>
Since version: 5.1.0
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>enabledSSLCipherSuites</strong></span>
</p>
<p>
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.
</p>
<p>
Since version: 5.1.35
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>allowLoadLocalInfile</strong></span>
</p>
<p>
Should the driver allow use of 'LOAD DATA LOCAL
INFILE...' (defaults to 'true').
</p>
<p>
Default: true
</p>
<p>
Since version: 3.0.3
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>allowUrlInLocalInfile</strong></span>
</p>
<p>
Should the driver allow URLs in 'LOAD DATA LOCAL
INFILE' statements?
</p>
<p>
Default: false
</p>
<p>
Since version: 3.1.4
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>allowPublicKeyRetrieval</strong></span>
</p>
<p>
Allows special handshake roundtrip to get server RSA
public key directly from server.
</p>
<p>
Default: false
</p>
<p>
Since version: 5.1.31
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>paranoid</strong></span>
</p>
<p>
Take measures to prevent exposure sensitive
information in error messages and clear data
structures holding sensitive data when possible?
(defaults to 'false')
</p>
<p>
Default: false
</p>
<p>
Since version: 3.0.1
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>passwordCharacterEncoding</strong></span>
</p>
<p>
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.
</p>
<p>
Since version: 5.1.7
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>serverRSAPublicKeyFile</strong></span>
</p>
<p>
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.
</p>
<p>
Since version: 5.1.31
</p></td></tr></tbody></table></div><p>
</p><p><b>Performance Extensions. </b>
</p><div class="informaltable"><table summary="This table lists Connector/J Performance Extensions
connection properties." border="1"><colgroup><col class="Properties"></colgroup><thead><tr><th scope="col"><span class="bold"><strong>Properties and Descriptions</strong></span></th></tr></thead><tbody><tr><td scope="row"><p>
<span class="strong"><strong>callableStmtCacheSize</strong></span>
</p>
<p>
If 'cacheCallableStmts' is enabled, how many callable
statements should be cached?
</p>
<p>
Default: 100
</p>
<p>
Since version: 3.1.2
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>metadataCacheSize</strong></span>
</p>
<p>
The number of queries to cache ResultSetMetadata for
if cacheResultSetMetaData is set to 'true' (default
50)
</p>
<p>
Default: 50
</p>
<p>
Since version: 3.1.1
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>useLocalSessionState</strong></span>
</p>
<p>
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?
</p>
<p>
Default: false
</p>
<p>
Since version: 3.1.7
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>useLocalTransactionState</strong></span>
</p>
<p>
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?
</p>
<p>
Default: false
</p>
<p>
Since version: 5.1.7
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>prepStmtCacheSize</strong></span>
</p>
<p>
If prepared statement caching is enabled, how many
prepared statements should be cached?
</p>
<p>
Default: 25
</p>
<p>
Since version: 3.0.10
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>prepStmtCacheSqlLimit</strong></span>
</p>
<p>
If prepared statement caching is enabled, what's the
largest SQL the driver will cache the parsing for?
</p>
<p>
Default: 256
</p>
<p>
Since version: 3.0.10
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>parseInfoCacheFactory</strong></span>
</p>
<p>
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.
</p>
<p>
Default: com.mysql.jdbc.PerConnectionLRUFactory
</p>
<p>
Since version: 5.1.1
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>serverConfigCacheFactory</strong></span>
</p>
<p>
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
</p>
<p>
Default: com.mysql.jdbc.PerVmServerConfigCacheFactory
</p>
<p>
Since version: 5.1.1
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>alwaysSendSetIsolation</strong></span>
</p>
<p>
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.
</p>
<p>
Default: true
</p>
<p>
Since version: 3.1.7
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>maintainTimeStats</strong></span>
</p>
<p>
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.
</p>
<p>
Default: true
</p>
<p>
Since version: 3.1.9
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>useCursorFetch</strong></span>
</p>
<p>
If connected to MySQL > 5.0.2, and setFetchSize()
> 0 on a statement, should that statement use
cursor-based fetching to retrieve rows?
</p>
<p>
Default: false
</p>
<p>
Since version: 5.0.0
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>blobSendChunkSize</strong></span>
</p>
<p>
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.
</p>
<p>
Default: 1048576
</p>
<p>
Since version: 3.1.9
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>cacheCallableStmts</strong></span>
</p>
<p>
Should the driver cache the parsing stage of
CallableStatements
</p>
<p>
Default: false
</p>
<p>
Since version: 3.1.2
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>cachePrepStmts</strong></span>
</p>
<p>
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?
</p>
<p>
Default: false
</p>
<p>
Since version: 3.0.10
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>cacheResultSetMetadata</strong></span>
</p>
<p>
Should the driver cache ResultSetMetaData for
Statements and PreparedStatements? (Req. JDK-1.4+,
true/false, default 'false')
</p>
<p>
Default: false
</p>
<p>
Since version: 3.1.1
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>cacheServerConfiguration</strong></span>
</p>
<p>
Should the driver cache the results of 'SHOW
VARIABLES' and 'SHOW COLLATION' on a per-URL basis?
</p>
<p>
Default: false
</p>
<p>
Since version: 3.1.5
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>defaultFetchSize</strong></span>
</p>
<p>
The driver will call setFetchSize(n) with this value
on all newly-created Statements
</p>
<p>
Default: 0
</p>
<p>
Since version: 3.1.9
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>dontCheckOnDuplicateKeyUpdateInSQL</strong></span>
</p>
<p>
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'.
</p>
<p>
Default: false
</p>
<p>
Since version: 5.1.32
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>dontTrackOpenResources</strong></span>
</p>
<p>
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.
</p>
<p>
Default: false
</p>
<p>
Since version: 3.1.7
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>dynamicCalendars</strong></span>
</p>
<p>
Should the driver retrieve the default calendar when
required, or cache it per connection/session?
</p>
<p>
Default: false
</p>
<p>
Since version: 3.1.5
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>elideSetAutoCommits</strong></span>
</p>
<p>
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)?
</p>
<p>
Default: false
</p>
<p>
Since version: 3.1.3
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>enableEscapeProcessing</strong></span>
</p>
<p>
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'.
</p>
<p>
Default: true
</p>
<p>
Since version: 5.1.37
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>enableQueryTimeouts</strong></span>
</p>
<p>
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.
</p>
<p>
Default: true
</p>
<p>
Since version: 5.0.6
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>holdResultsOpenOverStatementClose</strong></span>
</p>
<p>
Should the driver close result sets on
Statement.close() as required by the JDBC
specification?
</p>
<p>
Default: false
</p>
<p>
Since version: 3.1.7
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>largeRowSizeThreshold</strong></span>
</p>
<p>
What size result set row should the JDBC driver
consider "large", and thus use a more memory-efficient
way of representing the row internally?
</p>
<p>
Default: 2048
</p>
<p>
Since version: 5.1.1
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>loadBalanceStrategy</strong></span>
</p>
<p>
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.
</p>
<p>
Default: random
</p>
<p>
Since version: 5.0.6
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>locatorFetchBufferSize</strong></span>
</p>
<p>
If 'emulateLocators' is configured to 'true', what
size buffer should be used when fetching BLOB data for
getBinaryInputStream?
</p>
<p>
Default: 1048576
</p>
<p>
Since version: 3.2.1
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>readOnlyPropagatesToServer</strong></span>
</p>
<p>
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.
</p>
<p>
Default: true
</p>
<p>
Since version: 5.1.35
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>rewriteBatchedStatements</strong></span>
</p>
<p>
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.
</p>
<p>
Default: false
</p>
<p>
Since version: 3.1.13
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>useDirectRowUnpack</strong></span>
</p>
<p>
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.
</p>
<p>
Default: true
</p>
<p>
Since version: 5.1.1
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>useDynamicCharsetInfo</strong></span>
</p>
<p>
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?
</p>
<p>
Default: true
</p>
<p>
Since version: 5.0.6
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>useFastDateParsing</strong></span>
</p>
<p>
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."
</p>
<p>
Default: true
</p>
<p>
Since version: 5.0.5
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>useFastIntParsing</strong></span>
</p>
<p>
Use internal String->Integer conversion routines to
avoid excessive object creation?
</p>
<p>
Default: true
</p>
<p>
Since version: 3.1.4
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>useJvmCharsetConverters</strong></span>
</p>
<p>
Always use the character encoding routines built into
the JVM, rather than using lookup tables for
single-byte character sets?
</p>
<p>
Default: false
</p>
<p>
Since version: 5.0.1
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>useReadAheadInput</strong></span>
</p>
<p>
Use newer, optimized non-blocking, buffered input
stream when reading from the server?
</p>
<p>
Default: true
</p>
<p>
Since version: 3.1.5
</p></td></tr></tbody></table></div><p>
</p><p><b>Debugging/Profiling. </b>
</p><div class="informaltable"><table summary="This table lists Connector/J Debugging/Profiling
connection properties." border="1"><colgroup><col class="Properties"></colgroup><thead><tr><th scope="col"><span class="bold"><strong>Properties and Descriptions</strong></span></th></tr></thead><tbody><tr><td scope="row"><p>
<span class="strong"><strong>logger</strong></span>
</p>
<p>
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)
</p>
<p>
Default: com.mysql.jdbc.log.StandardLogger
</p>
<p>
Since version: 3.1.1
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>gatherPerfMetrics</strong></span>
</p>
<p>
Should the driver gather performance metrics, and
report them via the configured logger every
'reportMetricsIntervalMillis' milliseconds?
</p>
<p>
Default: false
</p>
<p>
Since version: 3.1.2
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>profileSQL</strong></span>
</p>
<p>
Trace queries and their execution/fetch times to the
configured logger (true/false) defaults to 'false'
</p>
<p>
Default: false
</p>
<p>
Since version: 3.1.0
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>profileSql</strong></span>
</p>
<p>
Deprecated, use 'profileSQL' instead. Trace queries
and their execution/fetch times on STDERR (true/false)
defaults to 'false'
</p>
<p>
Since version: 2.0.14
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>reportMetricsIntervalMillis</strong></span>
</p>
<p>
If 'gatherPerfMetrics' is enabled, how often should
they be logged (in ms)?
</p>
<p>
Default: 30000
</p>
<p>
Since version: 3.1.2
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>maxQuerySizeToLog</strong></span>
</p>
<p>
Controls the maximum length/size of a query that will
get logged when profiling or tracing
</p>
<p>
Default: 2048
</p>
<p>
Since version: 3.1.3
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>packetDebugBufferSize</strong></span>
</p>
<p>
The maximum number of packets to retain when
'enablePacketDebug' is true
</p>
<p>
Default: 20
</p>
<p>
Since version: 3.1.3
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>slowQueryThresholdMillis</strong></span>
</p>
<p>
If 'logSlowQueries' is enabled, how long should a
query (in ms) before it is logged as 'slow'?
</p>
<p>
Default: 2000
</p>
<p>
Since version: 3.1.2
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>slowQueryThresholdNanos</strong></span>
</p>
<p>
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.
</p>
<p>
Default: 0
</p>
<p>
Since version: 5.0.7
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>useUsageAdvisor</strong></span>
</p>
<p>
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')?
</p>
<p>
Default: false
</p>
<p>
Since version: 3.1.1
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>autoGenerateTestcaseScript</strong></span>
</p>
<p>
Should the driver dump the SQL it is executing,
including server-side prepared statements to STDERR?
</p>
<p>
Default: false
</p>
<p>
Since version: 3.1.9
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>autoSlowLog</strong></span>
</p>
<p>
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?
</p>
<p>
Default: true
</p>
<p>
Since version: 5.1.4
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>clientInfoProvider</strong></span>
</p>
<p>
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
</p>
<p>
Default: com.mysql.jdbc.JDBC4CommentClientInfoProvider
</p>
<p>
Since version: 5.1.0
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>dumpMetadataOnColumnNotFound</strong></span>
</p>
<p>
Should the driver dump the field-level metadata of a
result set into the exception message when
ResultSet.findColumn() fails?
</p>
<p>
Default: false
</p>
<p>
Since version: 3.1.13
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>dumpQueriesOnException</strong></span>
</p>
<p>
Should the driver dump the contents of the query sent
to the server in the message for SQLExceptions?
</p>
<p>
Default: false
</p>
<p>
Since version: 3.1.3
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>enablePacketDebug</strong></span>
</p>
<p>
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
</p>
<p>
Default: false
</p>
<p>
Since version: 3.1.3
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>explainSlowQueries</strong></span>
</p>
<p>
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?
</p>
<p>
Default: false
</p>
<p>
Since version: 3.1.2
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>includeInnodbStatusInDeadlockExceptions</strong></span>
</p>
<p>
Include the output of "SHOW ENGINE INNODB STATUS" in
exception messages when deadlock exceptions are
detected?
</p>
<p>
Default: false
</p>
<p>
Since version: 5.0.7
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>includeThreadDumpInDeadlockExceptions</strong></span>
</p>
<p>
Include a current Java thread dump in exception
messages when deadlock exceptions are detected?
</p>
<p>
Default: false
</p>
<p>
Since version: 5.1.15
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>includeThreadNamesAsStatementComment</strong></span>
</p>
<p>
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".
</p>
<p>
Default: false
</p>
<p>
Since version: 5.1.15
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>logSlowQueries</strong></span>
</p>
<p>
Should queries that take longer than
'slowQueryThresholdMillis' be logged?
</p>
<p>
Default: false
</p>
<p>
Since version: 3.1.2
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>logXaCommands</strong></span>
</p>
<p>
Should the driver log XA commands sent by
MysqlXaConnection to the server, at the DEBUG level of
logging?
</p>
<p>
Default: false
</p>
<p>
Since version: 5.0.5
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>profilerEventHandler</strong></span>
</p>
<p>
Name of a class that implements the interface
com.mysql.jdbc.profiler.ProfilerEventHandler that will
be used to handle profiling/tracing events.
</p>
<p>
Default:
com.mysql.jdbc.profiler.LoggingProfilerEventHandler
</p>
<p>
Since version: 5.1.6
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>resultSetSizeThreshold</strong></span>
</p>
<p>
If the usage advisor is enabled, how many rows should
a result set contain before the driver warns that it
is suspiciously large?
</p>
<p>
Default: 100
</p>
<p>
Since version: 5.0.5
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>traceProtocol</strong></span>
</p>
<p>
Should trace-level network protocol be logged?
</p>
<p>
Default: false
</p>
<p>
Since version: 3.1.2
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>useNanosForElapsedTime</strong></span>
</p>
<p>
For profiling/debugging functionality that measures
elapsed time, should the driver try to use nanoseconds
resolution if available (JDK >= 1.5)?
</p>
<p>
Default: false
</p>
<p>
Since version: 5.0.7
</p></td></tr></tbody></table></div><p>
</p><p><b>Miscellaneous. </b>
</p><div class="informaltable"><table summary="This table lists Connector/J Miscellaneous connection
properties." border="1"><colgroup><col class="Properties"></colgroup><thead><tr><th scope="col"><span class="bold"><strong>Properties and Descriptions</strong></span></th></tr></thead><tbody><tr><td scope="row"><p>
<span class="strong"><strong>useUnicode</strong></span>
</p>
<p>
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'
</p>
<p>
Default: true
</p>
<p>
Since version: 1.1g
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>characterEncoding</strong></span>
</p>
<p>
If 'useUnicode' is set to true, what character
encoding should the driver use when dealing with
strings? (defaults is to 'autodetect')
</p>
<p>
Since version: 1.1g
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>characterSetResults</strong></span>
</p>
<p>
Character set to tell the server to return results as.
</p>
<p>
Since version: 3.0.13
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>connectionAttributes</strong></span>
</p>
<p>
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.
</p>
<p>
Since version: 5.1.25
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>connectionCollation</strong></span>
</p>
<p>
If set, tells the server to use this collation via
'set collation_connection'
</p>
<p>
Since version: 3.0.13
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>useBlobToStoreUTF8OutsideBMP</strong></span>
</p>
<p>
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.
</p>
<p>
Default: false
</p>
<p>
Since version: 5.1.3
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>utf8OutsideBmpExcludedColumnNamePattern</strong></span>
</p>
<p>
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.
</p>
<p>
Since version: 5.1.3
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>utf8OutsideBmpIncludedColumnNamePattern</strong></span>
</p>
<p>
Used to specify exclusion rules to
"utf8OutsideBmpExcludedColumnNamePattern". The regex
must follow the patterns used for the java.util.regex
package.
</p>
<p>
Since version: 5.1.3
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>loadBalanceEnableJMX</strong></span>
</p>
<p>
Enables JMX-based management of load-balanced
connection groups, including live addition/removal of
hosts from load-balancing pool.
</p>
<p>
Default: false
</p>
<p>
Since version: 5.1.13
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>sessionVariables</strong></span>
</p>
<p>
A comma-separated list of name/value pairs to be sent
as SET SESSION ... to the server when the driver
connects.
</p>
<p>
Since version: 3.1.8
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>useColumnNamesInFindColumn</strong></span>
</p>
<p>
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.
</p>
<p>
Default: false
</p>
<p>
Since version: 5.1.7
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>allowNanAndInf</strong></span>
</p>
<p>
Should the driver allow NaN or +/- INF values in
PreparedStatement.setDouble()?
</p>
<p>
Default: false
</p>
<p>
Since version: 3.1.5
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>autoClosePStmtStreams</strong></span>
</p>
<p>
Should the driver automatically call .close() on
streams/readers passed as arguments via set*()
methods?
</p>
<p>
Default: false
</p>
<p>
Since version: 3.1.12
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>autoDeserialize</strong></span>
</p>
<p>
Should the driver automatically detect and
de-serialize objects stored in BLOB fields?
</p>
<p>
Default: false
</p>
<p>
Since version: 3.1.5
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>blobsAreStrings</strong></span>
</p>
<p>
Should the driver always treat BLOBs as Strings -
specifically to work around dubious metadata returned
by the server for GROUP BY clauses?
</p>
<p>
Default: false
</p>
<p>
Since version: 5.0.8
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>cacheDefaultTimezone</strong></span>
</p>
<p>
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.
</p>
<p>
Default: true
</p>
<p>
Since version: 5.1.35
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>capitalizeTypeNames</strong></span>
</p>
<p>
Capitalize type names in DatabaseMetaData? (usually
only useful when using WebObjects, true/false,
defaults to 'false')
</p>
<p>
Default: true
</p>
<p>
Since version: 2.0.7
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>clobCharacterEncoding</strong></span>
</p>
<p>
The character encoding to use for sending and
retrieving TEXT, MEDIUMTEXT and LONGTEXT values
instead of the configured connection characterEncoding
</p>
<p>
Since version: 5.0.0
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>clobberStreamingResults</strong></span>
</p>
<p>
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.
</p>
<p>
Default: false
</p>
<p>
Since version: 3.0.9
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>compensateOnDuplicateKeyUpdateCounts</strong></span>
</p>
<p>
Should the driver compensate for the update counts of
"ON DUPLICATE KEY" INSERT statements (2 = 1, 0 = 1)
when using prepared statements?
</p>
<p>
Default: false
</p>
<p>
Since version: 5.1.7
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>continueBatchOnError</strong></span>
</p>
<p>
Should the driver continue processing batch commands
if one statement fails. The JDBC spec allows either
way (defaults to 'true').
</p>
<p>
Default: true
</p>
<p>
Since version: 3.0.3
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>createDatabaseIfNotExist</strong></span>
</p>
<p>
Creates the database given in the URL if it doesn't
yet exist. Assumes the configured user has permissions
to create databases.
</p>
<p>
Default: false
</p>
<p>
Since version: 3.1.9
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>detectCustomCollations</strong></span>
</p>
<p>
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.
</p>
<p>
Default: false
</p>
<p>
Since version: 5.1.29
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>emptyStringsConvertToZero</strong></span>
</p>
<p>
Should the driver allow conversions from empty string
fields to numeric values of '0'?
</p>
<p>
Default: true
</p>
<p>
Since version: 3.1.8
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>emulateLocators</strong></span>
</p>
<p>
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.
</p>
<p>
Default: false
</p>
<p>
Since version: 3.1.0
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>emulateUnsupportedPstmts</strong></span>
</p>
<p>
Should the driver detect prepared statements that are
not supported by the server, and replace them with
client-side emulated versions?
</p>
<p>
Default: true
</p>
<p>
Since version: 3.1.7
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>exceptionInterceptors</strong></span>
</p>
<p>
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.
</p>
<p>
Since version: 5.1.8
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>functionsNeverReturnBlobs</strong></span>
</p>
<p>
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?
</p>
<p>
Default: false
</p>
<p>
Since version: 5.0.8
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>generateSimpleParameterMetadata</strong></span>
</p>
<p>
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?
</p>
<p>
Default: false
</p>
<p>
Since version: 5.0.5
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>getProceduresReturnsFunctions</strong></span>
</p>
<p>
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.
</p>
<p>
Default: true
</p>
<p>
Since version: 5.1.26
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>ignoreNonTxTables</strong></span>
</p>
<p>
Ignore non-transactional table warning for rollback?
(defaults to 'false').
</p>
<p>
Default: false
</p>
<p>
Since version: 3.0.9
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>jdbcCompliantTruncation</strong></span>
</p>
<p>
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.
</p>
<p>
Default: true
</p>
<p>
Since version: 3.1.2
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>loadBalanceAutoCommitStatementRegex</strong></span>
</p>
<p>
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.
</p>
<p>
Since version: 5.1.15
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>loadBalanceAutoCommitStatementThreshold</strong></span>
</p>
<p>
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.
</p>
<p>
Default: 0
</p>
<p>
Since version: 5.1.15
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>loadBalanceBlacklistTimeout</strong></span>
</p>
<p>
Time in milliseconds between checks of servers which
are unavailable, by controlling how long a server
lives in the global blacklist.
</p>
<p>
Default: 0
</p>
<p>
Since version: 5.1.0
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>loadBalanceConnectionGroup</strong></span>
</p>
<p>
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.
</p>
<p>
Since version: 5.1.13
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>loadBalanceExceptionChecker</strong></span>
</p>
<p>
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.
</p>
<p>
Default:
com.mysql.jdbc.StandardLoadBalanceExceptionChecker
</p>
<p>
Since version: 5.1.13
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>loadBalancePingTimeout</strong></span>
</p>
<p>
Time in milliseconds to wait for ping response from
each of load-balanced physical connections when using
load-balanced Connection.
</p>
<p>
Default: 0
</p>
<p>
Since version: 5.1.13
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>loadBalanceSQLExceptionSubclassFailover</strong></span>
</p>
<p>
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.
</p>
<p>
Since version: 5.1.13
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>loadBalanceSQLStateFailover</strong></span>
</p>
<p>
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.
</p>
<p>
Since version: 5.1.13
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>loadBalanceValidateConnectionOnSwapServer</strong></span>
</p>
<p>
Should the load-balanced Connection explicitly check
whether the connection is live when swapping to a new
physical connection at commit/rollback?
</p>
<p>
Default: false
</p>
<p>
Since version: 5.1.13
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>maxRows</strong></span>
</p>
<p>
The maximum number of rows to return (0, the default
means return all rows).
</p>
<p>
Default: -1
</p>
<p>
Since version: all versions
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>netTimeoutForStreamingResults</strong></span>
</p>
<p>
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)
</p>
<p>
Default: 600
</p>
<p>
Since version: 5.1.0
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>noAccessToProcedureBodies</strong></span>
</p>
<p>
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?
</p>
<p>
Default: false
</p>
<p>
Since version: 5.0.3
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>noDatetimeStringSync</strong></span>
</p>
<p>
Don't ensure that
ResultSet.getDatetimeType().toString().equals(ResultSet.getString())
</p>
<p>
Default: false
</p>
<p>
Since version: 3.1.7
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>noTimezoneConversionForDateType</strong></span>
</p>
<p>
Don't convert DATE values using the server time zone
if 'useTimezone'='true' or
'useLegacyDatetimeCode'='false'
</p>
<p>
Default: true
</p>
<p>
Since version: 5.1.35
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>noTimezoneConversionForTimeType</strong></span>
</p>
<p>
Don't convert TIME values using the server time zone
if 'useTimezone'='true'
</p>
<p>
Default: false
</p>
<p>
Since version: 5.0.0
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>nullCatalogMeansCurrent</strong></span>
</p>
<p>
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)
</p>
<p>
Default: true
</p>
<p>
Since version: 3.1.8
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>nullNamePatternMatchesAll</strong></span>
</p>
<p>
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)
</p>
<p>
Default: true
</p>
<p>
Since version: 3.1.8
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>overrideSupportsIntegrityEnhancementFacility</strong></span>
</p>
<p>
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)?
</p>
<p>
Default: false
</p>
<p>
Since version: 3.1.12
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>padCharsWithSpace</strong></span>
</p>
<p>
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)?
</p>
<p>
Default: false
</p>
<p>
Since version: 5.0.6
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>pedantic</strong></span>
</p>
<p>
Follow the JDBC spec to the letter.
</p>
<p>
Default: false
</p>
<p>
Since version: 3.0.0
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>pinGlobalTxToPhysicalConnection</strong></span>
</p>
<p>
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
</p>
<p>
Default: false
</p>
<p>
Since version: 5.0.1
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>populateInsertRowWithDefaultValues</strong></span>
</p>
<p>
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.
</p>
<p>
Default: false
</p>
<p>
Since version: 5.0.5
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>processEscapeCodesForPrepStmts</strong></span>
</p>
<p>
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'.
</p>
<p>
Default: true
</p>
<p>
Since version: 3.1.12
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>queryTimeoutKillsConnection</strong></span>
</p>
<p>
If the timeout given in Statement.setQueryTimeout()
expires, should the driver forcibly abort the
Connection instead of attempting to abort the query?
</p>
<p>
Default: false
</p>
<p>
Since version: 5.1.9
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>relaxAutoCommit</strong></span>
</p>
<p>
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')?
</p>
<p>
Default: false
</p>
<p>
Since version: 2.0.13
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>retainStatementAfterResultSetClose</strong></span>
</p>
<p>
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.
</p>
<p>
Default: false
</p>
<p>
Since version: 3.1.11
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>rollbackOnPooledClose</strong></span>
</p>
<p>
Should the driver issue a rollback() when the logical
connection in a pool is closed?
</p>
<p>
Default: true
</p>
<p>
Since version: 3.0.15
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>runningCTS13</strong></span>
</p>
<p>
Enables workarounds for bugs in Sun's JDBC compliance
testsuite version 1.3
</p>
<p>
Default: false
</p>
<p>
Since version: 3.1.7
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>sendFractionalSeconds</strong></span>
</p>
<p>
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.
</p>
<p>
Default: true
</p>
<p>
Since version: 5.1.37
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>serverTimezone</strong></span>
</p>
<p>
Override detection/mapping of time zone. Used when
time zone from server doesn't map to Java time zone
</p>
<p>
Since version: 3.0.2
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>statementInterceptors</strong></span>
</p>
<p>
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.
</p>
<p>
Since version: 5.1.1
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>strictFloatingPoint</strong></span>
</p>
<p>
Used only in older versions of compliance test
</p>
<p>
Default: false
</p>
<p>
Since version: 3.0.0
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>strictUpdates</strong></span>
</p>
<p>
Should the driver do strict checking (all primary keys
selected) of updatable result sets (true, false,
defaults to 'true')?
</p>
<p>
Default: true
</p>
<p>
Since version: 3.0.4
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>tinyInt1isBit</strong></span>
</p>
<p>
Should the driver treat the datatype TINYINT(1) as the
BIT type (because the server silently converts BIT
-> TINYINT(1) when creating tables)?
</p>
<p>
Default: true
</p>
<p>
Since version: 3.0.16
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>transformedBitIsBoolean</strong></span>
</p>
<p>
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?
</p>
<p>
Default: false
</p>
<p>
Since version: 3.1.9
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>treatUtilDateAsTimestamp</strong></span>
</p>
<p>
Should the driver treat java.util.Date as a TIMESTAMP
for the purposes of PreparedStatement.setObject()?
</p>
<p>
Default: true
</p>
<p>
Since version: 5.0.5
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>ultraDevHack</strong></span>
</p>
<p>
Create PreparedStatements for prepareCall() when
required, because UltraDev is broken and issues a
prepareCall() for _all_ statements? (true/false,
defaults to 'false')
</p>
<p>
Default: false
</p>
<p>
Since version: 2.0.3
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>useAffectedRows</strong></span>
</p>
<p>
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.
</p>
<p>
Default: false
</p>
<p>
Since version: 5.1.7
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>useGmtMillisForDatetimes</strong></span>
</p>
<p>
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."
</p>
<p>
Default: false
</p>
<p>
Since version: 3.1.12
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>useHostsInPrivileges</strong></span>
</p>
<p>
Add '@hostname' to users in
DatabaseMetaData.getColumn/TablePrivileges()
(true/false), defaults to 'true'.
</p>
<p>
Default: true
</p>
<p>
Since version: 3.0.2
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>useInformationSchema</strong></span>
</p>
<p>
When connected to MySQL-5.0.7 or newer, should the
driver use the INFORMATION_SCHEMA to derive
information used by DatabaseMetaData?
</p>
<p>
Default: false
</p>
<p>
Since version: 5.0.0
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>useJDBCCompliantTimezoneShift</strong></span>
</p>
<p>
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."
</p>
<p>
Default: false
</p>
<p>
Since version: 5.0.0
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>useLegacyDatetimeCode</strong></span>
</p>
<p>
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."
</p>
<p>
Default: true
</p>
<p>
Since version: 5.1.6
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>useOldAliasMetadataBehavior</strong></span>
</p>
<p>
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.
</p>
<p>
Default: false
</p>
<p>
Since version: 5.0.4
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>useOldUTF8Behavior</strong></span>
</p>
<p>
Use the UTF-8 behavior the driver did when
communicating with 4.0 and older servers
</p>
<p>
Default: false
</p>
<p>
Since version: 3.1.6
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>useOnlyServerErrorMessages</strong></span>
</p>
<p>
Don't prepend 'standard' SQLState error messages to
error messages returned by the server.
</p>
<p>
Default: true
</p>
<p>
Since version: 3.0.15
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>useSSPSCompatibleTimezoneShift</strong></span>
</p>
<p>
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.
</p>
<p>
Default: false
</p>
<p>
Since version: 5.0.5
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>useServerPrepStmts</strong></span>
</p>
<p>
Use server-side prepared statements if the server
supports them?
</p>
<p>
Default: false
</p>
<p>
Since version: 3.1.0
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>useSqlStateCodes</strong></span>
</p>
<p>
Use SQL Standard state codes instead of 'legacy'
X/Open/SQL state codes (true/false), default is 'true'
</p>
<p>
Default: true
</p>
<p>
Since version: 3.1.3
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>useStreamLengthsInPrepStmts</strong></span>
</p>
<p>
Honor stream length parameter in
PreparedStatement/ResultSet.setXXXStream() method
calls (true/false, defaults to 'true')?
</p>
<p>
Default: true
</p>
<p>
Since version: 3.0.2
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>useTimezone</strong></span>
</p>
<p>
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."
</p>
<p>
Default: false
</p>
<p>
Since version: 3.0.2
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>useUnbufferedInput</strong></span>
</p>
<p>
Don't use BufferedInputStream for reading data from
the server
</p>
<p>
Default: true
</p>
<p>
Since version: 3.0.11
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>yearIsDateType</strong></span>
</p>
<p>
Should the JDBC driver treat the MySQL type "YEAR" as
a java.sql.Date, or as a SHORT?
</p>
<p>
Default: true
</p>
<p>
Since version: 3.1.9
</p></td></tr><tr><td scope="row"><p>
<span class="strong"><strong>zeroDateTimeBehavior</strong></span>
</p>
<p>
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".
</p>
<p>
Default: exception
</p>
<p>
Since version: 3.1.4
</p></td></tr></tbody></table></div><p>
</p><p>
Connector/J also supports access to MySQL using named pipes on
Windows platforms with the
<code class="literal">NamedPipeSocketFactory</code> as a plugin-socket
factory. If you do not use a <code class="literal">namedPipePath</code>
property, the default of <code class="literal">'\\.\pipe\MySQL'</code> is
used. If you use the <code class="literal">NamedPipeSocketFactory</code>,
the host name and port number values in the JDBC URL are
ignored. To enable this feature, set the
<code class="literal">socketFactory</code> property:
</p><pre class="programlisting">
socketFactory=com.mysql.jdbc.NamedPipeSocketFactory
</pre><p>
</p><p>
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.
</p><p>
To create your own socket factories, follow the example code in
<code class="classname">com.mysql.jdbc.NamedPipeSocketFactory</code>, or
<code class="classname">com.mysql.jdbc.StandardSocketFactory</code>.
</p><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="connector-j-useconfigs"></a>5.1.1 Properties Files for the <code class="literal">useConfigs</code> Option</h3></div></div></div><a class="indexterm" name="idm139688234923136"></a><p>
The <code class="literal">useConfigs</code> 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
<code class="filename">.properties</code> files within the Connector/J
<code class="filename">mysql-connector-java-<em class="replaceable"><code>version</code></em>-bin.jar</code>
JAR file. For example, the Connector/J 5.1.9 driver includes
the following configuration properties files:
</p><pre class="programlisting">
$ 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
</pre><p>
To specify one of these combinations of options, specify
<code class="literal">useConfigs=3-0-Compat</code>,
<code class="literal">useConfigs=maxPerformance</code>, and so on. The
following sections show the options that are part of each
<code class="literal">useConfigs</code> setting. For the details of why
each one is included, see the comments in the
<code class="filename">.properties</code> files.
</p><h4><a name="idm139688234914672"></a>3-0-Compat</h4><pre class="programlisting">
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
</pre><h4><a name="idm139688234912560"></a>5-0-Compat</h4><pre class="programlisting">
useDirectRowUnpack=false
</pre><h4><a name="idm139688234911312"></a>clusterBase</h4><pre class="programlisting">
autoReconnect=true
failOverReadOnly=false
roundRobinLoadBalance=true
</pre><h4><a name="idm139688234909984"></a>coldFusion</h4><pre class="programlisting">
useDynamicCharsetInfo=false
alwaysSendSetIsolation=false
useLocalSessionState=true
autoReconnect=true
</pre><h4><a name="idm139688234908624"></a>fullDebug</h4><pre class="programlisting">
profileSQL=true
gatherPerfMetrics=true
useUsageAdvisor=true
logSlowQueries=true
explainSlowQueries=true
</pre><h4><a name="idm139688234907248"></a>maxPerformance</h4><pre class="programlisting">
cachePrepStmts=true
cacheCallableStmts=true
cacheServerConfiguration=true
useLocalSessionState=true
elideSetAutoCommits=true
alwaysSendSetIsolation=false
enableQueryTimeouts=false
</pre><h4><a name="idm139688234905808"></a>solarisMaxPerformance</h4><pre class="programlisting">
useUnbufferedInput=false
useReadAheadInput=false
maintainTimeStats=false
</pre></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="connector-j-reference-implementation-notes"></a>5.2 JDBC API Implementation Notes</h2></div></div></div><a class="indexterm" name="idm139688234903328"></a><p>
MySQL Connector/J, as a rigorous implementation of the
<a class="ulink" href="http://www.oracle.com/technetwork/java/javase/jdbc/index.html" target="_top">JDBC
API</a>, 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.
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
<span class="bold"><strong>BLOB</strong></span>
</p><p>
Starting with Connector/J version 3.1.0, you can emulate
BLOBs with locators by adding the property
<code class="literal">emulateLocators=true</code> 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 (<code class="function">getInputStream()</code>,
<code class="function">getBytes()</code>, and so forth) on the BLOB
data stream.
</p><p>
You must use a column alias with the value of the column to
the actual name of the BLOB, for example:
</p><pre class="programlisting">
SELECT id, 'data' as blob_data from blobtable
</pre><p>
You must also follow these rules:
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
The <a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/select.html" target="_top"><code class="literal">SELECT</code></a> must reference
only one table. The table must have a
<a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/glossary.html#glos_primary_key" target="_top">primary key</a>.
</p></li><li class="listitem"><p>
The <a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/select.html" target="_top"><code class="literal">SELECT</code></a> must alias the
original BLOB column name, specified as a string, to an
alternate name.
</p></li><li class="listitem"><p>
The <a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/select.html" target="_top"><code class="literal">SELECT</code></a> must cover all
columns that make up the primary key.
</p></li></ul></div><p>
The BLOB implementation does not allow in-place modification
(they are copies, as reported by the
<code class="literal">DatabaseMetaData.locatorsUpdateCopies()</code>
method). Because of this, use the corresponding
<code class="literal">PreparedStatement.setBlob()</code> or
<code class="literal">ResultSet.updateBlob()</code> (in the case of
updatable result sets) methods to save changes back to the
database.
</p></li><li class="listitem"><p>
<span class="bold"><strong>CallableStatement</strong></span>
</p><p>
Starting with Connector/J 3.1.1, stored procedures are
supported when connecting to MySQL version 5.0 or newer
using the <code class="classname">CallableStatement</code>
interface. Currently, the
<code class="function">getParameterMetaData()</code> method of
<code class="classname">CallableStatement</code> is not supported.
</p></li><li class="listitem"><p>
<span class="bold"><strong>CLOB</strong></span>
</p><p>
The CLOB implementation does not allow in-place modification
(they are copies, as reported by the
<code class="literal">DatabaseMetaData.locatorsUpdateCopies()</code>
method). Because of this, use the
<code class="literal">PreparedStatement.setClob()</code> method to
save changes back to the database. The JDBC API does not
have a <code class="literal">ResultSet.updateClob()</code> method.
</p></li><li class="listitem"><p>
<span class="bold"><strong>Connection</strong></span>
</p><p>
Unlike the pre-Connector/J JDBC driver
(<code class="literal">MM.MySQL</code>), the
<code class="function">isClosed()</code> method does not ping the
server to determine if it is available. In accordance with
the JDBC specification, it only returns true if
<code class="function">closed()</code> has been called on the
connection. If you need to determine if the connection is
still valid, issue a simple query, such as <code class="literal">SELECT
1</code>. The driver will throw an exception if the
connection is no longer valid.
</p></li><li class="listitem"><p>
<span class="bold"><strong>DatabaseMetaData</strong></span>
</p><p>
<a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/glossary.html#glos_foreign_key" target="_top">Foreign key</a>
information
(<code class="function">getImportedKeys()</code>/<code class="function">getExportedKeys()</code>
and <code class="function">getCrossReference()</code>) is only
available from <a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/innodb-storage-engine.html" target="_top"><code class="literal">InnoDB</code></a> tables.
The driver uses <a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/show-create-table.html" target="_top"><code class="literal">SHOW CREATE
TABLE</code></a> to retrieve this information, so if any
other storage engines add support for foreign keys, the
driver would transparently support them as well.
</p></li><li class="listitem"><p>
<span class="bold"><strong>PreparedStatement</strong></span>
</p><p>
PreparedStatements are implemented by the driver, as MySQL
does not have a prepared statement feature. Because of this,
the driver does not implement
<code class="function">getParameterMetaData()</code> or
<code class="function">getMetaData()</code> as it would require the
driver to have a complete SQL parser in the client.
</p><p>
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.
</p><p>
Take care when using a server-side prepared statement with
<span class="bold"><strong>large</strong></span> parameters that are
set using <code class="function">setBinaryStream()</code>,
<code class="function">setAsciiStream()</code>,
<code class="function">setUnicodeStream()</code>,
<code class="function">setBlob()</code>, or
<code class="function">setClob()</code>. To re-execute the statement
with any large parameter changed to a nonlarge parameter,
call <code class="function">clearParameters()</code> and set all
parameters again. The reason for this is as follows:
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
During both server-side prepared statements and
client-side emulation, large data is exchanged only when
<code class="literal">PreparedStatement.execute()</code> is
called.
</p></li></ul></div><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
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.
</p></li></ul></div><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
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
<code class="function">setBinaryStream()</code>,
<code class="function">setAsciiStream()</code>,
<code class="function">setUnicodeStream()</code>,
<code class="function">setBlob()</code> or
<code class="function">setClob()</code> method.
</p></li></ul></div><p>
Consequently, to change the type of a parameter to a
nonlarge one, you must call
<code class="function">clearParameters()</code> and set all
parameters of the prepared statement again before it can be
re-executed.
</p></li><li class="listitem"><p>
<span class="bold"><strong>ResultSet</strong></span>
</p><p>
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.
</p><p>
To enable this functionality, create a
<code class="literal">Statement</code> instance in the following
manner:
</p><pre class="programlisting">
stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,
java.sql.ResultSet.CONCUR_READ_ONLY);
stmt.setFetchSize(Integer.MIN_VALUE);
</pre><p>
The combination of a forward-only, read-only result set,
with a fetch size of <code class="literal">Integer.MIN_VALUE</code>
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.
</p><p>
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.
</p><p>
The earliest the locks these statements hold can be released
(whether they be <code class="literal">MyISAM</code> table-level locks
or row-level locks in some other storage engine such as
<code class="literal">InnoDB</code>) is when the statement completes.
</p><p>
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.
</p><p>
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.
</p></li><li class="listitem"><p>
<span class="bold"><strong>ResultSetMetaData</strong></span>
</p><p>
The <code class="function">isAutoIncrement()</code> method only works
when using MySQL servers 4.0 and newer.
</p></li><li class="listitem"><p>
<span class="bold"><strong>Statement</strong></span>
</p><p>
When using versions of the JDBC driver earlier than 3.2.1,
and connected to server versions earlier than 5.0.3, the
<code class="function">setFetchSize()</code> method has no effect,
other than to toggle result set streaming as described
above.
</p><p>
Connector/J 5.0.0 and later include support for both
<code class="literal">Statement.cancel()</code> and
<code class="literal">Statement.setQueryTimeout()</code>. Both require
MySQL 5.0.0 or newer server, and require a separate
connection to issue the
<a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/kill.html" target="_top"><code class="literal">KILL QUERY</code></a>
statement. In the case of
<code class="function">setQueryTimeout()</code>, the implementation
creates an additional thread to handle the timeout
functionality.
</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><div class="admon-title">Note</div><p>
Failures to cancel the statement for
<code class="function">setQueryTimeout()</code> may manifest
themselves as <code class="literal">RuntimeException</code> 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.
</p></div><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><div class="admon-title">Note</div><p>
The MySQL statement
<a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/kill.html" target="_top"><code class="literal">KILL QUERY</code></a>
(which is what the driver uses to implement
<code class="literal">Statement.cancel()</code>) is
non-deterministic; thus, avoid the use of
<code class="literal">Statement.cancel()</code> 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.
</p></div><p>
MySQL does not support SQL cursors, and the JDBC driver
doesn't emulate them, so <code class="literal">setCursorName()</code>
has no effect.
</p><p>
Connector/J 5.1.3 and later include two additional methods:
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
<code class="function">setLocalInfileInputStream()</code> sets an
<code class="literal">InputStream</code> instance that will be
used to send data to the MySQL server for a
<a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/load-data.html" target="_top"><code class="literal">LOAD DATA
LOCAL INFILE</code></a> statement rather than a
<code class="literal">FileInputStream</code> or
<code class="literal">URLInputStream</code> that represents the
path given as an argument to the statement.
</p><p>
This stream will be read to completion upon execution of
a <a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/load-data.html" target="_top"><code class="literal">LOAD DATA
LOCAL INFILE</code></a> statement, and will automatically
be closed by the driver, so it needs to be reset before
each call to <code class="literal">execute*()</code> that would
cause the MySQL server to request data to fulfill the
request for
<a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/load-data.html" target="_top"><code class="literal">LOAD DATA
LOCAL INFILE</code></a>.
</p><p>
If this value is set to <code class="literal">NULL</code>, the
driver will revert to using a
<code class="literal">FileInputStream</code> or
<code class="literal">URLInputStream</code> as required.
</p></li><li class="listitem"><p>
<code class="function">getLocalInfileInputStream()</code> returns
the <code class="literal">InputStream</code> instance that will be
used to send data in response to a
<a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/load-data.html" target="_top"><code class="literal">LOAD DATA
LOCAL INFILE</code></a> statement.
</p><p>
This method returns <code class="literal">NULL</code> if no such
stream has been set using
<code class="function">setLocalInfileInputStream()</code>.
</p></li></ul></div></li></ul></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="connector-j-reference-type-conversions"></a>5.3 Java, JDBC and MySQL Types</h2></div></div></div><a class="indexterm" name="idm139688234805408"></a><p>
MySQL Connector/J is flexible in the way it handles conversions
between MySQL data types and Java data types.
</p><p>
In general, any MySQL data type can be converted to a
<code class="literal">java.lang.String</code>, and any numeric type can be
converted to any of the Java numeric types, although round-off,
overflow, or loss of precision may occur.
</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><div class="admon-title">Note</div><p>
All <code class="literal">TEXT</code> types return
<code class="literal">Types.LONGVARCHAR</code> with different
<code class="literal">getPrecision()</code> values (65535, 255,
16777215, and 2147483647 respectively) with
<code class="literal">getColumnType()</code> returning
<code class="literal">-1</code>. This behavior is intentional even
though <code class="literal">TINYTEXT</code> does not fall, regarding to
its size, within the <code class="literal">LONGVARCHAR</code> category.
This is to avoid different handling inside the same base type.
And <code class="literal">getColumnType()</code> returns
<code class="literal">-1</code> because the internal server handling is
of type <code class="literal">TEXT</code>, which is similar to
<code class="literal">BLOB</code>.
</p><p>
Also note that <code class="literal">getColumnTypeName()</code> will
return <code class="literal">VARCHAR</code> even though
<code class="literal">getColumnType()</code> returns
<code class="literal">Types.LONGVARCHAR</code>, because
<code class="literal">VARCHAR</code> is the designated column
database-specific name for this type.
</p></div><p>
Starting with Connector/J 3.1.0, the JDBC driver issues warnings
or throws <code class="literal">DataTruncation</code> exceptions as is
required by the JDBC specification unless the connection was
configured not to do so by using the property
<code class="literal">jdbcCompliantTruncation</code> and setting it to
<code class="literal">false</code>.
</p><p>
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.
</p><div class="table"><a name="idm139688234787040"></a><p class="title"><b>Table 5.1 Connection Properties - Miscellaneous</b></p><div class="table-contents"><table summary="Connection Properties - Miscellaneous" border="1"><colgroup><col><col></colgroup><thead><tr><th scope="col">These MySQL Data Types</th><th scope="col">Can always be converted to these Java types</th></tr></thead><tbody><tr><td scope="row"><code class="literal">CHAR, VARCHAR, BLOB, TEXT, ENUM, and SET</code></td><td><code class="literal">java.lang.String, java.io.InputStream, java.io.Reader,
java.sql.Blob, java.sql.Clob</code></td></tr><tr><td scope="row"><code class="literal">FLOAT, REAL, DOUBLE PRECISION, NUMERIC, DECIMAL, TINYINT,
SMALLINT, MEDIUMINT, INTEGER, BIGINT</code></td><td><code class="literal">java.lang.String, java.lang.Short, java.lang.Integer,
java.lang.Long, java.lang.Double,
java.math.BigDecimal</code></td></tr><tr><td scope="row"><code class="literal">DATE, TIME, DATETIME, TIMESTAMP</code></td><td><code class="literal">java.lang.String, java.sql.Date, java.sql.Timestamp</code></td></tr></tbody></table></div></div><br class="table-break"><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><div class="admon-title">Note</div><p>
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.
</p></div><p>
The <code class="classname">ResultSet.getObject()</code> method uses the
type conversions between MySQL and Java types, following the
JDBC specification where appropriate. The value returned by
<code class="classname">ResultSetMetaData.GetColumnClassName()</code> is
also shown below. For more information on the JDBC types, see
the reference on the
<a class="ulink" href="http://docs.oracle.com/javase/8/docs/api/java/sql/Types.html" target="_top">java.sql.Types</a>
class.
</p><div class="table"><a name="idm139688234773504"></a><p class="title"><b>Table 5.2 MySQL Types to Java Types for ResultSet.getObject()</b></p><div class="table-contents"><table summary="MySQL Types to Java Types for ResultSet.getObject()" border="1"><colgroup><col><col><col></colgroup><thead><tr><th scope="col">MySQL Type Name</th><th scope="col">Return value of <code class="literal">GetColumnClassName</code></th><th scope="col">Returned as Java Class</th></tr></thead><tbody><tr><td scope="row"><code class="literal">BIT(1)</code> (new in MySQL-5.0)</td><td><code class="literal">BIT</code></td><td><code class="classname">java.lang.Boolean</code></td></tr><tr><td scope="row"><code class="literal">BIT( > 1)</code> (new in MySQL-5.0)</td><td><code class="literal">BIT</code></td><td><code class="classname">byte[]</code></td></tr><tr><td scope="row"><code class="literal">TINYINT</code></td><td><code class="literal">TINYINT</code></td><td><code class="classname">java.lang.Boolean</code> if the configuration property
<code class="literal">tinyInt1isBit</code> is set to
<code class="literal">true</code> (the default) and the storage
size is 1, or <code class="classname">java.lang.Integer</code>
if not.</td></tr><tr><td scope="row"><code class="literal">BOOL</code>, <code class="literal">BOOLEAN</code></td><td><code class="literal">TINYINT</code></td><td>See <code class="literal">TINYINT</code>, above as these are aliases for
<code class="literal">TINYINT(1)</code>, currently.</td></tr><tr><td scope="row"><code class="literal">SMALLINT[(M)] [UNSIGNED]</code></td><td><code class="literal">SMALLINT [UNSIGNED]</code></td><td><code class="classname">java.lang.Integer</code> (regardless if
<code class="literal">UNSIGNED</code> or not)</td></tr><tr><td scope="row"><code class="literal">MEDIUMINT[(M)] [UNSIGNED]</code></td><td><code class="literal">MEDIUMINT [UNSIGNED]</code></td><td><code class="classname">java.lang.Integer,</code> if <code class="literal">UNSIGNED</code>
<code class="classname">java.lang.Long</code> (C/J 3.1 and
earlier), or <code class="classname">java.lang.Integer</code>
for C/J 5.0 and later</td></tr><tr><td scope="row"><code class="literal">INT,INTEGER[(M)] [UNSIGNED]</code></td><td><code class="literal">INTEGER [UNSIGNED]</code></td><td><code class="classname">java.lang.Integer</code>, if <code class="literal">UNSIGNED</code>
<code class="classname">java.lang.Long</code></td></tr><tr><td scope="row"><code class="literal">BIGINT[(M)] [UNSIGNED]</code></td><td><code class="literal">BIGINT [UNSIGNED]</code></td><td><code class="classname">java.lang.Long</code>, if UNSIGNED
<code class="classname">java.math.BigInteger</code></td></tr><tr><td scope="row"><code class="literal">FLOAT[(M,D)]</code></td><td><code class="literal">FLOAT</code></td><td><code class="classname">java.lang.Float</code></td></tr><tr><td scope="row"><code class="literal">DOUBLE[(M,B)]</code></td><td><code class="literal">DOUBLE</code></td><td><code class="classname">java.lang.Double</code></td></tr><tr><td scope="row"><code class="literal">DECIMAL[(M[,D])]</code></td><td><code class="literal">DECIMAL</code></td><td><code class="classname">java.math.BigDecimal</code></td></tr><tr><td scope="row"><code class="literal">DATE</code></td><td><code class="literal">DATE</code></td><td><code class="classname">java.sql.Date</code></td></tr><tr><td scope="row"><code class="literal">DATETIME</code></td><td><code class="literal">DATETIME</code></td><td><code class="classname">java.sql.Timestamp</code></td></tr><tr><td scope="row"><code class="literal">TIMESTAMP[(M)]</code></td><td><code class="literal">TIMESTAMP</code></td><td><code class="classname">java.sql.Timestamp</code></td></tr><tr><td scope="row"><code class="literal">TIME</code></td><td><code class="literal">TIME</code></td><td><code class="classname">java.sql.Time</code></td></tr><tr><td scope="row"><code class="literal">YEAR[(2|4)]</code></td><td><code class="literal">YEAR</code></td><td>If <code class="literal">yearIsDateType</code> configuration property is set to
<code class="literal">false</code>, then the returned object type
is <code class="classname">java.sql.Short</code>. If set to
<code class="literal">true</code> (the default), then the returned
object is of type <code class="classname">java.sql.Date</code>
with the date
set to January 1st, at midnight.</td></tr><tr><td scope="row"><code class="literal">CHAR(M)</code></td><td><code class="literal">CHAR</code></td><td><code class="classname">java.lang.String</code> (unless the character set for
the column is <code class="literal">BINARY</code>, then
<code class="classname">byte[]</code> is returned.</td></tr><tr><td scope="row"><code class="literal">VARCHAR(M) [BINARY]</code></td><td><code class="literal">VARCHAR</code></td><td><code class="classname">java.lang.String</code> (unless the character set for
the column is <code class="literal">BINARY</code>, then
<code class="classname">byte[]</code> is returned.</td></tr><tr><td scope="row"><code class="literal">BINARY(M)</code></td><td><code class="literal">BINARY</code></td><td><code class="classname">byte[]</code></td></tr><tr><td scope="row"><code class="literal">VARBINARY(M)</code></td><td><code class="literal">VARBINARY</code></td><td><code class="classname">byte[]</code></td></tr><tr><td scope="row"><code class="literal">TINYBLOB</code></td><td><code class="literal">TINYBLOB</code></td><td><code class="classname">byte[]</code></td></tr><tr><td scope="row"><code class="literal">TINYTEXT</code></td><td><code class="literal">VARCHAR</code></td><td><code class="classname">java.lang.String</code></td></tr><tr><td scope="row"><code class="literal">BLOB</code></td><td><code class="literal">BLOB</code></td><td><code class="classname">byte[]</code></td></tr><tr><td scope="row"><code class="literal">TEXT</code></td><td><code class="literal">VARCHAR</code></td><td><code class="classname">java.lang.String</code></td></tr><tr><td scope="row"><code class="literal">MEDIUMBLOB</code></td><td><code class="literal">MEDIUMBLOB</code></td><td><code class="classname">byte[]</code></td></tr><tr><td scope="row"><code class="literal">MEDIUMTEXT</code></td><td><code class="literal">VARCHAR</code></td><td><code class="classname">java.lang.String</code></td></tr><tr><td scope="row"><code class="literal">LONGBLOB</code></td><td><code class="literal">LONGBLOB</code></td><td><code class="classname">byte[]</code></td></tr><tr><td scope="row"><code class="literal">LONGTEXT</code></td><td><code class="literal">VARCHAR</code></td><td><code class="classname">java.lang.String</code></td></tr><tr><td scope="row"><code class="literal">ENUM('value1','value2',...)</code></td><td><code class="literal">CHAR</code></td><td><code class="classname">java.lang.String</code></td></tr><tr><td scope="row"><code class="literal">SET('value1','value2',...)</code></td><td><code class="literal">CHAR</code></td><td><code class="classname">java.lang.String</code></td></tr></tbody></table></div></div><br class="table-break"></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="connector-j-reference-charsets"></a>5.4 Using Character Sets and Unicode</h2></div></div></div><a class="indexterm" name="idm139688234682192"></a><a class="indexterm" name="idm139688234680800"></a><a class="indexterm" name="idm139688234679408"></a><p>
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
<code class="literal">Statement.execute()</code>,
<code class="literal">Statement.executeUpdate()</code>,
<code class="literal">Statement.executeQuery()</code> as well as all
<code class="interfacename">PreparedStatement</code> and
<code class="interfacename">CallableStatement</code> parameters with
the exclusion of parameters set using
<code class="function">setBytes()</code>,
<code class="function">setBinaryStream()</code>,
<code class="function">setAsciiStream()</code>,
<code class="function">setUnicodeStream()</code> and
<code class="function">setBlob()</code>.
</p><h3><a name="idm139688234671568"></a>Number of Encodings Per Connection</h3><p>
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 <code class="classname">ResultSets</code>.
</p><p>
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
<em class="parameter"><code>useUnicode</code></em> and
<em class="parameter"><code>characterEncoding</code></em> properties.
</p><h3><a name="idm139688234668032"></a>Setting the Character Encoding</h3><p>
The character encoding between client and server is
automatically detected upon connection. You specify the encoding
on the server using the
<a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_character_set_server" target="_top"><code class="literal">character_set_server</code></a> for server
versions 4.1.0 and newer, and <code class="literal">character_set</code>
system variable for server versions older than 4.1.0. The driver
automatically uses the encoding specified by the server. For
more information, see <a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/charset-server.html" target="_top">Server Character Set and Collation</a>.
</p><p>
For example, to use 4-byte UTF-8 character sets with
Connector/J, configure the MySQL server with
<a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_character_set_server" target="_top"><code class="literal">character_set_server=utf8mb4</code></a>,
and leave <code class="literal">characterEncoding</code> out of the
Connector/J connection string. Connector/J will then autodetect
the UTF-8 setting.
</p><p>
To override the automatically detected encoding on the client
side, use the <em class="parameter"><code>characterEncoding</code></em> property
in the URL used to connect to the server.
</p><p>
To allow multiple character sets to be sent from the client, use
the UTF-8 encoding, either by configuring
<code class="literal">utf8</code> as the default server character set, or
by configuring the JDBC driver to use UTF-8 through the
<code class="literal">characterEncoding</code> property.
</p><p>
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:
</p><div class="table"><a name="idm139688234658112"></a><p class="title"><b>Table 5.3 MySQL to Java Encoding Name Translations</b></p><div class="table-contents"><table summary="MySQL to Java Encoding Name Translations" border="1"><colgroup><col><col></colgroup><thead><tr><th scope="col">MySQL Character Set Name</th><th scope="col">Java-Style Character Encoding Name</th></tr></thead><tbody><tr><td scope="row"><code class="literal">ascii</code></td><td><code class="literal">US-ASCII</code></td></tr><tr><td scope="row"><code class="literal">big5</code></td><td><code class="literal">Big5</code></td></tr><tr><td scope="row"><code class="literal">gbk</code></td><td><code class="literal">GBK</code></td></tr><tr><td scope="row"><code class="literal">sjis</code></td><td><code class="literal">SJIS (or Cp932 or MS932 for MySQL Server < 4.1.11)</code></td></tr><tr><td scope="row"><code class="literal">cp932</code></td><td><code class="literal">Cp932 or MS932 (MySQL Server > 4.1.11)</code></td></tr><tr><td scope="row"><code class="literal">gb2312</code></td><td><code class="literal">EUC_CN</code></td></tr><tr><td scope="row"><code class="literal">ujis</code></td><td><code class="literal">EUC_JP</code></td></tr><tr><td scope="row"><code class="literal">euckr</code></td><td><code class="literal">EUC_KR</code></td></tr><tr><td scope="row"><code class="literal">latin1</code></td><td><code class="literal">Cp1252</code></td></tr><tr><td scope="row"><code class="literal">latin2</code></td><td><code class="literal">ISO8859_2</code></td></tr><tr><td scope="row"><code class="literal">greek</code></td><td><code class="literal">ISO8859_7</code></td></tr><tr><td scope="row"><code class="literal">hebrew</code></td><td><code class="literal">ISO8859_8</code></td></tr><tr><td scope="row"><code class="literal">cp866</code></td><td><code class="literal">Cp866</code></td></tr><tr><td scope="row"><code class="literal">tis620</code></td><td><code class="literal">TIS620</code></td></tr><tr><td scope="row"><code class="literal">cp1250</code></td><td><code class="literal">Cp1250</code></td></tr><tr><td scope="row"><code class="literal">cp1251</code></td><td><code class="literal">Cp1251</code></td></tr><tr><td scope="row"><code class="literal">cp1257</code></td><td><code class="literal">Cp1257</code></td></tr><tr><td scope="row"><code class="literal">macroman</code></td><td><code class="literal">MacRoman</code></td></tr><tr><td scope="row"><code class="literal">macce</code></td><td><code class="literal">MacCentralEurope</code></td></tr><tr><td scope="row"><code class="literal">utf8</code></td><td><code class="literal">UTF-8</code></td></tr><tr><td scope="row"><code class="literal">ucs2</code></td><td><code class="literal">UnicodeBig</code></td></tr></tbody></table></div></div><br class="table-break"><div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;"><div class="admon-title">Warning</div><p>
Do not issue the query <code class="literal">set names</code> 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.
</p></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="connector-j-reference-using-ssl"></a>5.5 Connecting Securely Using SSL</h2></div></div></div><a class="indexterm" name="idm139688234611360"></a><p>
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.
</p><p>
For SSL support to work, you must have the following:
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
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:
<a class="ulink" href="http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4273544" target="_top">http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4273544</a>
</p></li><li class="listitem"><p>
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
<a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/building-with-ssl-support.html" target="_top">Building MySQL with SSL Support</a>.
</p></li><li class="listitem"><p>
A client certificate (covered later in this section)
</p></li></ul></div><p>
The system works through two Java truststore files, one file
contains the certificate information for the server
(<code class="filename">truststore</code> in the examples below). The
other file contains the certificate for the client
(<code class="filename">keystore</code> in the examples below). All Java
truststore files are password protected by supplying a suitable
password to the <span class="command"><strong>keytool</strong></span> when you create the
files. You need the file names and associated passwords to
create an SSL connection.
</p><p>
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 <code class="filename">SSL</code> 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.
</p><p>
To use Java's <span class="command"><strong>keytool</strong></span> to create a truststore
in the current directory , and import the server's CA
certificate (<code class="filename">cacert.pem</code>), you can do the
following (assuming that <span class="command"><strong>keytool</strong></span> is in your
path. The <span class="command"><strong>keytool</strong></span> is typically located in the
<code class="filename">bin</code> subdirectory of your JDK or JRE):
</p><pre class="programlisting">
shell> keytool -import -alias mysqlServerCACert \
-file cacert.pem -keystore truststore
</pre><p>
Enter the password when prompted for the keystore file.
Interaction with <span class="command"><strong>keytool</strong></span> looks like this:
</p><pre class="programlisting">
Enter keystore password: *********
Owner: EMAILADDRESS=walrus@example.com, CN=Walrus,
O=MySQL AB, L=Orenburg, ST=Some-State, C=RU
Issuer: EMAILADDRESS=walrus@example.com, CN=Walrus,
O=MySQL AB, L=Orenburg, ST=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
</pre><p>
You then have two options: either import the client certificate
that matches the CA certificate you just imported, or create a
new client certificate.
</p><p>
Importing an existing certificate requires the certificate to be
in DER format. You can use <span class="command"><strong>openssl</strong></span> to convert
an existing certificate into the new format. For example:
</p><pre class="programlisting">
shell> openssl x509 -outform DER -in client-cert.pem -out client.cert
</pre><p>
Now import the converted certificate into your keystore using
<span class="command"><strong>keytool</strong></span>:
</p><pre class="programlisting">
shell> keytool -import -file client.cert -keystore keystore -alias mysqlClientCertificate
</pre><p>
To generate your own client certificate, use
<span class="command"><strong>keytool</strong></span> to create a suitable certificate and
add it to the <code class="filename">keystore</code> file:
</p><pre class="programlisting">
shell> keytool -genkey -keyalg rsa \
-alias mysqlClientCertificate -keystore keystore
</pre><p>
Keytool will prompt you for the following information, and
create a keystore named <code class="filename">keystore</code> in the
current directory.
</p><p>
Respond with information that is appropriate for your situation:
</p><pre class="programlisting">
Enter keystore password: *********
What is your first and last name?
[Unknown]: Matthews
What is the name of your organizational unit?
[Unknown]: Software Development
What is the name of your organization?
[Unknown]: MySQL AB
What is the name of your City or Locality?
[Unknown]: Flossmoor
What is the name of your State or Province?
[Unknown]: IL
What is the two-letter country code for this unit?
[Unknown]: US
Is <CN=Matthews, OU=Software Development, O=MySQL AB,
L=Flossmoor, ST=IL, C=US> correct?
[no]: y
Enter key password for <mysqlClientCertificate>
(RETURN if same as keystore password):
</pre><p>
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
<em class="replaceable"><code>path_to_keystore_file</code></em> with the full
path to the keystore file you created,
<em class="replaceable"><code>path_to_truststore_file</code></em> 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:
</p><pre class="programlisting">
-Djavax.net.ssl.keyStore=<em class="replaceable"><code>path_to_keystore_file</code></em>
-Djavax.net.ssl.keyStorePassword=<em class="replaceable"><code>password</code></em>
-Djavax.net.ssl.trustStore=<em class="replaceable"><code>path_to_truststore_file</code></em>
-Djavax.net.ssl.trustStorePassword=<em class="replaceable"><code>password</code></em>
</pre><p>
Or you can set the values directly within the application:
</p><pre class="programlisting">
System.setProperty("javax.net.ssl.keyStore","<em class="replaceable"><code>path_to_keystore_file</code></em>");
System.setProperty("javax.net.ssl.keyStorePassword","<em class="replaceable"><code>password</code></em>");
System.setProperty("javax.net.ssl.trustStore","<em class="replaceable"><code>path_to_truststore_file</code></em>");
System.setProperty("javax.net.ssl.trustStorePassword","<em class="replaceable"><code>password</code></em>");
</pre><p>
You will also need to set <code class="literal">useSSL</code> to
<code class="literal">true</code> in your connection parameters for MySQL
Connector/J, either by adding <code class="literal">useSSL=true</code> to
your URL, or by setting the property <code class="literal">useSSL</code>
to <code class="literal">true</code> in the
<code class="classname">java.util.Properties</code> instance you pass to
<code class="literal">DriverManager.getConnection()</code>.
</p><p>
You can test that SSL is working by turning on JSSE debugging
(as detailed below), and look for the following key events:
</p><pre class="programlisting">
...
*** 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
...
</pre><p>
JSSE provides debugging (to <code class="literal">stdout</code>) when you
set the following system property:
<code class="literal">-Djavax.net.debug=all</code> 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.
</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="connector-j-using-pam"></a>5.6 Connecting Using PAM Authentication</h2></div></div></div><a class="indexterm" name="idm139688234565440"></a><p>
Java applications using Connector/J 5.1.21 and higher can
connect to MySQL servers that use the pluggable authentication
module (PAM) authentication scheme.
</p><p>
For PAM authentication to work, you must have the following:
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
A MySQL server that supports PAM authentication: a
commercial distribution of MySQL 5.5.16 or higher. See
<a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/pam-authentication-plugin.html" target="_top">The PAM Authentication Plugin</a> for more
information. Connector/J implements the same cleartext
authentication method as in
<a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/cleartext-authentication-plugin.html" target="_top">The Cleartext Client-Side Authentication Plugin</a>.
</p></li><li class="listitem"><p>
SSL capability, as explained in
<a class="xref" href="#connector-j-reference-using-ssl" title="5.5 Connecting Securely Using SSL">Section 5.5, “Connecting Securely Using SSL”</a>. Because
the PAM authentication scheme sends the original password to
the server, the connection to the server must be encrypted.
</p></li></ul></div><p>
PAM authentication support is enabled by default in Connector/J
5.1.21 and up, so no extra configuration is needed.
</p><p>
To disable the PAM authentication feature, specify
<code class="literal">mysql_clear_password</code> (the method) or
<code class="literal">com.mysql.jdbc.authentication.MysqlClearPasswordPlugin</code>
(the class name) in the comma-separated list of arguments for
the <code class="literal">disabledAuthenticationPlugins</code> connection
option. See
<a class="xref" href="#connector-j-reference-configuration-properties" title="5.1 Driver/Datasource Class Names, URL Syntax and Configuration Properties for Connector/J">Section 5.1, “Driver/Datasource Class Names, URL Syntax and Configuration Properties
for Connector/J”</a>
for details about that connection option.
</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="connector-j-reference-replication-connection"></a>5.7 Using Master/Slave Replication with ReplicationConnection</h2></div></div></div><p>
See
<a class="xref" href="#connector-j-master-slave-replication-connection" title="8.3 Configuring Master/Slave Replication with Connector/J">Section 8.3, “Configuring Master/Slave Replication with Connector/J”</a>
for details on the topic.
</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="connector-j-reference-error-sqlstates"></a>5.8 Mapping MySQL Error Numbers to JDBC SQLState Codes</h2></div></div></div><a class="indexterm" name="idm139688234552048"></a><a class="indexterm" name="idm139688234551040"></a><a class="indexterm" name="idm139688234550032"></a><a class="indexterm" name="idm139688234548640"></a><a class="indexterm" name="idm139688234547248"></a><a class="indexterm" name="idm139688234546240"></a><a class="indexterm" name="idm139688234545232"></a><a class="indexterm" name="idm139688234544224"></a><a class="indexterm" name="idm139688234543216"></a><a class="indexterm" name="idm139688234542208"></a><a class="indexterm" name="idm139688234541200"></a><a class="indexterm" name="idm139688234540192"></a><a class="indexterm" name="idm139688234539184"></a><a class="indexterm" name="idm139688234538176"></a><a class="indexterm" name="idm139688234537168"></a><a class="indexterm" name="idm139688234536160"></a><a class="indexterm" name="idm139688234535152"></a><a class="indexterm" name="idm139688234534144"></a><a class="indexterm" name="idm139688234533136"></a><a class="indexterm" name="idm139688234532128"></a><a class="indexterm" name="idm139688234531120"></a><a class="indexterm" name="idm139688234530112"></a><a class="indexterm" name="idm139688234529104"></a><a class="indexterm" name="idm139688234528096"></a><a class="indexterm" name="idm139688234527088"></a><a class="indexterm" name="idm139688234526080"></a><a class="indexterm" name="idm139688234525072"></a><a class="indexterm" name="idm139688234524064"></a><a class="indexterm" name="idm139688234523056"></a><a class="indexterm" name="idm139688234522048"></a><a class="indexterm" name="idm139688234521040"></a><a class="indexterm" name="idm139688234520032"></a><a class="indexterm" name="idm139688234519024"></a><a class="indexterm" name="idm139688234518016"></a><a class="indexterm" name="idm139688234517008"></a><a class="indexterm" name="idm139688234516000"></a><a class="indexterm" name="idm139688234514992"></a><a class="indexterm" name="idm139688234513984"></a><a class="indexterm" name="idm139688234512976"></a><a class="indexterm" name="idm139688234511968"></a><a class="indexterm" name="idm139688234510960"></a><a class="indexterm" name="idm139688234509952"></a><a class="indexterm" name="idm139688234508944"></a><a class="indexterm" name="idm139688234507936"></a><a class="indexterm" name="idm139688234506928"></a><a class="indexterm" name="idm139688234505920"></a><a class="indexterm" name="idm139688234504912"></a><a class="indexterm" name="idm139688234503904"></a><a class="indexterm" name="idm139688234502896"></a><a class="indexterm" name="idm139688234501888"></a><a class="indexterm" name="idm139688234500880"></a><a class="indexterm" name="idm139688234499872"></a><a class="indexterm" name="idm139688234498864"></a><a class="indexterm" name="idm139688234497856"></a><a class="indexterm" name="idm139688234496848"></a><a class="indexterm" name="idm139688234495840"></a><a class="indexterm" name="idm139688234494832"></a><a class="indexterm" name="idm139688234493824"></a><a class="indexterm" name="idm139688234492816"></a><a class="indexterm" name="idm139688234491808"></a><a class="indexterm" name="idm139688234490800"></a><a class="indexterm" name="idm139688234489792"></a><a class="indexterm" name="idm139688234488784"></a><a class="indexterm" name="idm139688234487776"></a><a class="indexterm" name="idm139688234486768"></a><a class="indexterm" name="idm139688234485760"></a><a class="indexterm" name="idm139688234484752"></a><a class="indexterm" name="idm139688234483744"></a><a class="indexterm" name="idm139688234482736"></a><a class="indexterm" name="idm139688234481728"></a><a class="indexterm" name="idm139688234480720"></a><a class="indexterm" name="idm139688234479712"></a><a class="indexterm" name="idm139688234478704"></a><a class="indexterm" name="idm139688234477696"></a><a class="indexterm" name="idm139688234476688"></a><a class="indexterm" name="idm139688234475680"></a><a class="indexterm" name="idm139688234474672"></a><a class="indexterm" name="idm139688234473664"></a><a class="indexterm" name="idm139688234472656"></a><a class="indexterm" name="idm139688234471648"></a><a class="indexterm" name="idm139688234470640"></a><a class="indexterm" name="idm139688234469632"></a><a class="indexterm" name="idm139688234468624"></a><a class="indexterm" name="idm139688234467616"></a><a class="indexterm" name="idm139688234466608"></a><a class="indexterm" name="idm139688234465600"></a><a class="indexterm" name="idm139688234464592"></a><a class="indexterm" name="idm139688234463584"></a><a class="indexterm" name="idm139688234462576"></a><a class="indexterm" name="idm139688234461568"></a><a class="indexterm" name="idm139688234460560"></a><a class="indexterm" name="idm139688234459552"></a><a class="indexterm" name="idm139688234458544"></a><a class="indexterm" name="idm139688234457536"></a><a class="indexterm" name="idm139688234456528"></a><a class="indexterm" name="idm139688234455520"></a><a class="indexterm" name="idm139688234454512"></a><a class="indexterm" name="idm139688234453504"></a><a class="indexterm" name="idm139688234452496"></a><a class="indexterm" name="idm139688234451488"></a><a class="indexterm" name="idm139688234450480"></a><a class="indexterm" name="idm139688234449472"></a><a class="indexterm" name="idm139688234448464"></a><a class="indexterm" name="idm139688234447456"></a><a class="indexterm" name="idm139688234446448"></a><a class="indexterm" name="idm139688234445440"></a><a class="indexterm" name="idm139688234444432"></a><a class="indexterm" name="idm139688234443424"></a><a class="indexterm" name="idm139688234442416"></a><a class="indexterm" name="idm139688234441408"></a><a class="indexterm" name="idm139688234440400"></a><a class="indexterm" name="idm139688234439392"></a><a class="indexterm" name="idm139688234438384"></a><a class="indexterm" name="idm139688234437376"></a><a class="indexterm" name="idm139688234436368"></a><a class="indexterm" name="idm139688234435360"></a><a class="indexterm" name="idm139688234434352"></a><a class="indexterm" name="idm139688234433344"></a><a class="indexterm" name="idm139688234432336"></a><a class="indexterm" name="idm139688234431328"></a><a class="indexterm" name="idm139688234430320"></a><a class="indexterm" name="idm139688234429312"></a><a class="indexterm" name="idm139688234428304"></a><a class="indexterm" name="idm139688234427296"></a><a class="indexterm" name="idm139688234426288"></a><a class="indexterm" name="idm139688234425280"></a><a class="indexterm" name="idm139688234424272"></a><a class="indexterm" name="idm139688234423264"></a><a class="indexterm" name="idm139688234422256"></a><a class="indexterm" name="idm139688234421248"></a><a class="indexterm" name="idm139688234420240"></a><a class="indexterm" name="idm139688234419232"></a><a class="indexterm" name="idm139688234418224"></a><a class="indexterm" name="idm139688234417216"></a><a class="indexterm" name="idm139688234416208"></a><a class="indexterm" name="idm139688234415200"></a><a class="indexterm" name="idm139688234414192"></a><p>
The table below provides a mapping of the MySQL error numbers to
JDBC <code class="literal">SQLState</code> values.
</p><div class="table"><a name="idm139688234412080"></a><p class="title"><b>Table 5.4 Mapping of MySQL Error Numbers to SQLStates</b></p><div class="table-contents"><table summary="Mapping of MySQL Error Numbers to SQLStates" border="1"><colgroup><col><col><col><col></colgroup><thead><tr><th scope="col">MySQL Error Number</th><th scope="col">MySQL Error Name</th><th scope="col">Legacy (X/Open) SQLState</th><th scope="col">SQL Standard SQLState</th></tr></thead><tbody><tr><td scope="row">1022</td><td>ER_DUP_KEY</td><td>23000</td><td>23000</td></tr><tr><td scope="row">1037</td><td>ER_OUTOFMEMORY</td><td>S1001</td><td>HY001</td></tr><tr><td scope="row">1038</td><td>ER_OUT_OF_SORTMEMORY</td><td>S1001</td><td>HY001</td></tr><tr><td scope="row">1040</td><td>ER_CON_COUNT_ERROR</td><td>08004</td><td>08004</td></tr><tr><td scope="row">1042</td><td>ER_BAD_HOST_ERROR</td><td>08004</td><td>08S01</td></tr><tr><td scope="row">1043</td><td>ER_HANDSHAKE_ERROR</td><td>08004</td><td>08S01</td></tr><tr><td scope="row">1044</td><td>ER_DBACCESS_DENIED_ERROR</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1045</td><td>ER_ACCESS_DENIED_ERROR</td><td>28000</td><td>28000</td></tr><tr><td scope="row">1046</td><td>ER_NO_DB_ERROR</td><td>3D000</td><td>3D000</td></tr><tr><td scope="row">1047</td><td>ER_UNKNOWN_COM_ERROR</td><td>08S01</td><td>08S01</td></tr><tr><td scope="row">1048</td><td>ER_BAD_NULL_ERROR</td><td>23000</td><td>23000</td></tr><tr><td scope="row">1049</td><td>ER_BAD_DB_ERROR</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1050</td><td>ER_TABLE_EXISTS_ERROR</td><td>42S01</td><td>42S01</td></tr><tr><td scope="row">1051</td><td>ER_BAD_TABLE_ERROR</td><td>42S02</td><td>42S02</td></tr><tr><td scope="row">1052</td><td>ER_NON_UNIQ_ERROR</td><td>23000</td><td>23000</td></tr><tr><td scope="row">1053</td><td>ER_SERVER_SHUTDOWN</td><td>08S01</td><td>08S01</td></tr><tr><td scope="row">1054</td><td>ER_BAD_FIELD_ERROR</td><td>S0022</td><td>42S22</td></tr><tr><td scope="row">1055</td><td>ER_WRONG_FIELD_WITH_GROUP</td><td>S1009</td><td>42000</td></tr><tr><td scope="row">1056</td><td>ER_WRONG_GROUP_FIELD</td><td>S1009</td><td>42000</td></tr><tr><td scope="row">1057</td><td>ER_WRONG_SUM_SELECT</td><td>S1009</td><td>42000</td></tr><tr><td scope="row">1058</td><td>ER_WRONG_VALUE_COUNT</td><td>21S01</td><td>21S01</td></tr><tr><td scope="row">1059</td><td>ER_TOO_LONG_IDENT</td><td>S1009</td><td>42000</td></tr><tr><td scope="row">1060</td><td>ER_DUP_FIELDNAME</td><td>S1009</td><td>42S21</td></tr><tr><td scope="row">1061</td><td>ER_DUP_KEYNAME</td><td>S1009</td><td>42000</td></tr><tr><td scope="row">1062</td><td>ER_DUP_ENTRY</td><td>S1009</td><td>23000</td></tr><tr><td scope="row">1063</td><td>ER_WRONG_FIELD_SPEC</td><td>S1009</td><td>42000</td></tr><tr><td scope="row">1064</td><td>ER_PARSE_ERROR</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1065</td><td>ER_EMPTY_QUERY</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1066</td><td>ER_NONUNIQ_TABLE</td><td>S1009</td><td>42000</td></tr><tr><td scope="row">1067</td><td>ER_INVALID_DEFAULT</td><td>S1009</td><td>42000</td></tr><tr><td scope="row">1068</td><td>ER_MULTIPLE_PRI_KEY</td><td>S1009</td><td>42000</td></tr><tr><td scope="row">1069</td><td>ER_TOO_MANY_KEYS</td><td>S1009</td><td>42000</td></tr><tr><td scope="row">1070</td><td>ER_TOO_MANY_KEY_PARTS</td><td>S1009</td><td>42000</td></tr><tr><td scope="row">1071</td><td>ER_TOO_LONG_KEY</td><td>S1009</td><td>42000</td></tr><tr><td scope="row">1072</td><td>ER_KEY_COLUMN_DOES_NOT_EXITS</td><td>S1009</td><td>42000</td></tr><tr><td scope="row">1073</td><td>ER_BLOB_USED_AS_KEY</td><td>S1009</td><td>42000</td></tr><tr><td scope="row">1074</td><td>ER_TOO_BIG_FIELDLENGTH</td><td>S1009</td><td>42000</td></tr><tr><td scope="row">1075</td><td>ER_WRONG_AUTO_KEY</td><td>S1009</td><td>42000</td></tr><tr><td scope="row">1080</td><td>ER_FORCING_CLOSE</td><td>08S01</td><td>08S01</td></tr><tr><td scope="row">1081</td><td>ER_IPSOCK_ERROR</td><td>08S01</td><td>08S01</td></tr><tr><td scope="row">1082</td><td>ER_NO_SUCH_INDEX</td><td>S1009</td><td>42S12</td></tr><tr><td scope="row">1083</td><td>ER_WRONG_FIELD_TERMINATORS</td><td>S1009</td><td>42000</td></tr><tr><td scope="row">1084</td><td>ER_BLOBS_AND_NO_TERMINATED</td><td>S1009</td><td>42000</td></tr><tr><td scope="row">1090</td><td>ER_CANT_REMOVE_ALL_FIELDS</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1091</td><td>ER_CANT_DROP_FIELD_OR_KEY</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1101</td><td>ER_BLOB_CANT_HAVE_DEFAULT</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1102</td><td>ER_WRONG_DB_NAME</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1103</td><td>ER_WRONG_TABLE_NAME</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1104</td><td>ER_TOO_BIG_SELECT</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1106</td><td>ER_UNKNOWN_PROCEDURE</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1107</td><td>ER_WRONG_PARAMCOUNT_TO_PROCEDURE</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1109</td><td>ER_UNKNOWN_TABLE</td><td>42S02</td><td>42S02</td></tr><tr><td scope="row">1110</td><td>ER_FIELD_SPECIFIED_TWICE</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1112</td><td>ER_UNSUPPORTED_EXTENSION</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1113</td><td>ER_TABLE_MUST_HAVE_COLUMNS</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1115</td><td>ER_UNKNOWN_CHARACTER_SET</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1118</td><td>ER_TOO_BIG_ROWSIZE</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1120</td><td>ER_WRONG_OUTER_JOIN</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1121</td><td>ER_NULL_COLUMN_IN_INDEX</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1129</td><td>ER_HOST_IS_BLOCKED</td><td>08004</td><td>HY000</td></tr><tr><td scope="row">1130</td><td>ER_HOST_NOT_PRIVILEGED</td><td>08004</td><td>HY000</td></tr><tr><td scope="row">1131</td><td>ER_PASSWORD_ANONYMOUS_USER</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1132</td><td>ER_PASSWORD_NOT_ALLOWED</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1133</td><td>ER_PASSWORD_NO_MATCH</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1136</td><td>ER_WRONG_VALUE_COUNT_ON_ROW</td><td>21S01</td><td>21S01</td></tr><tr><td scope="row">1138</td><td>ER_INVALID_USE_OF_NULL</td><td>S1000</td><td>42000</td></tr><tr><td scope="row">1139</td><td>ER_REGEXP_ERROR</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1140</td><td>ER_MIX_OF_GROUP_FUNC_AND_FIELDS</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1141</td><td>ER_NONEXISTING_GRANT</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1142</td><td>ER_TABLEACCESS_DENIED_ERROR</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1143</td><td>ER_COLUMNACCESS_DENIED_ERROR</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1144</td><td>ER_ILLEGAL_GRANT_FOR_TABLE</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1145</td><td>ER_GRANT_WRONG_HOST_OR_USER</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1146</td><td>ER_NO_SUCH_TABLE</td><td>42S02</td><td>42S02</td></tr><tr><td scope="row">1147</td><td>ER_NONEXISTING_TABLE_GRANT</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1148</td><td>ER_NOT_ALLOWED_COMMAND</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1149</td><td>ER_SYNTAX_ERROR</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1152</td><td>ER_ABORTING_CONNECTION</td><td>08S01</td><td>08S01</td></tr><tr><td scope="row">1153</td><td>ER_NET_PACKET_TOO_LARGE</td><td>08S01</td><td>08S01</td></tr><tr><td scope="row">1154</td><td>ER_NET_READ_ERROR_FROM_PIPE</td><td>08S01</td><td>08S01</td></tr><tr><td scope="row">1155</td><td>ER_NET_FCNTL_ERROR</td><td>08S01</td><td>08S01</td></tr><tr><td scope="row">1156</td><td>ER_NET_PACKETS_OUT_OF_ORDER</td><td>08S01</td><td>08S01</td></tr><tr><td scope="row">1157</td><td>ER_NET_UNCOMPRESS_ERROR</td><td>08S01</td><td>08S01</td></tr><tr><td scope="row">1158</td><td>ER_NET_READ_ERROR</td><td>08S01</td><td>08S01</td></tr><tr><td scope="row">1159</td><td>ER_NET_READ_INTERRUPTED</td><td>08S01</td><td>08S01</td></tr><tr><td scope="row">1160</td><td>ER_NET_ERROR_ON_WRITE</td><td>08S01</td><td>08S01</td></tr><tr><td scope="row">1161</td><td>ER_NET_WRITE_INTERRUPTED</td><td>08S01</td><td>08S01</td></tr><tr><td scope="row">1162</td><td>ER_TOO_LONG_STRING</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1163</td><td>ER_TABLE_CANT_HANDLE_BLOB</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1164</td><td>ER_TABLE_CANT_HANDLE_AUTO_INCREMENT</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1166</td><td>ER_WRONG_COLUMN_NAME</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1167</td><td>ER_WRONG_KEY_COLUMN</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1169</td><td>ER_DUP_UNIQUE</td><td>23000</td><td>23000</td></tr><tr><td scope="row">1170</td><td>ER_BLOB_KEY_WITHOUT_LENGTH</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1171</td><td>ER_PRIMARY_CANT_HAVE_NULL</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1172</td><td>ER_TOO_MANY_ROWS</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1173</td><td>ER_REQUIRES_PRIMARY_KEY</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1176</td><td>ER_KEY_DOES_NOT_EXITS</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1177</td><td>ER_CHECK_NO_SUCH_TABLE</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1178</td><td>ER_CHECK_NOT_IMPLEMENTED</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1179</td><td>ER_CANT_DO_THIS_DURING_AN_TRANSACTION</td><td>25000</td><td>25000</td></tr><tr><td scope="row">1184</td><td>ER_NEW_ABORTING_CONNECTION</td><td>08S01</td><td>08S01</td></tr><tr><td scope="row">1189</td><td>ER_MASTER_NET_READ</td><td>08S01</td><td>08S01</td></tr><tr><td scope="row">1190</td><td>ER_MASTER_NET_WRITE</td><td>08S01</td><td>08S01</td></tr><tr><td scope="row">1203</td><td>ER_TOO_MANY_USER_CONNECTIONS</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1205</td><td>ER_LOCK_WAIT_TIMEOUT</td><td>40001</td><td>40001</td></tr><tr><td scope="row">1207</td><td>ER_READ_ONLY_TRANSACTION</td><td>25000</td><td>25000</td></tr><tr><td scope="row">1211</td><td>ER_NO_PERMISSION_TO_CREATE_USER</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1213</td><td>ER_LOCK_DEADLOCK</td><td>40001</td><td>40001</td></tr><tr><td scope="row">1216</td><td>ER_NO_REFERENCED_ROW</td><td>23000</td><td>23000</td></tr><tr><td scope="row">1217</td><td>ER_ROW_IS_REFERENCED</td><td>23000</td><td>23000</td></tr><tr><td scope="row">1218</td><td>ER_CONNECT_TO_MASTER</td><td>08S01</td><td>08S01</td></tr><tr><td scope="row">1222</td><td>ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT</td><td>21000</td><td>21000</td></tr><tr><td scope="row">1226</td><td>ER_USER_LIMIT_REACHED</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1227</td><td>ER_SPECIFIC_ACCESS_DENIED_ERROR</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1230</td><td>ER_NO_DEFAULT</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1231</td><td>ER_WRONG_VALUE_FOR_VAR</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1232</td><td>ER_WRONG_TYPE_FOR_VAR</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1234</td><td>ER_CANT_USE_OPTION_HERE</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1235</td><td>ER_NOT_SUPPORTED_YET</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1239</td><td>ER_WRONG_FK_DEF</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1241</td><td>ER_OPERAND_COLUMNS</td><td>21000</td><td>21000</td></tr><tr><td scope="row">1242</td><td>ER_SUBQUERY_NO_1_ROW</td><td>21000</td><td>21000</td></tr><tr><td scope="row">1247</td><td>ER_ILLEGAL_REFERENCE</td><td>42S22</td><td>42S22</td></tr><tr><td scope="row">1248</td><td>ER_DERIVED_MUST_HAVE_ALIAS</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1249</td><td>ER_SELECT_REDUCED</td><td>01000</td><td>01000</td></tr><tr><td scope="row">1250</td><td>ER_TABLENAME_NOT_ALLOWED_HERE</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1251</td><td>ER_NOT_SUPPORTED_AUTH_MODE</td><td>08004</td><td>08004</td></tr><tr><td scope="row">1252</td><td>ER_SPATIAL_CANT_HAVE_NULL</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1253</td><td>ER_COLLATION_CHARSET_MISMATCH</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1261</td><td>ER_WARN_TOO_FEW_RECORDS</td><td>01000</td><td>01000</td></tr><tr><td scope="row">1262</td><td>ER_WARN_TOO_MANY_RECORDS</td><td>01000</td><td>01000</td></tr><tr><td scope="row">1263</td><td>ER_WARN_NULL_TO_NOTNULL</td><td>S1000</td><td>01000</td></tr><tr><td scope="row">1264</td><td>ER_WARN_DATA_OUT_OF_RANGE</td><td>01000</td><td>01000</td></tr><tr><td scope="row">1265</td><td>ER_WARN_DATA_TRUNCATED</td><td>01000</td><td>01000</td></tr><tr><td scope="row">1280</td><td>ER_WRONG_NAME_FOR_INDEX</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1281</td><td>ER_WRONG_NAME_FOR_CATALOG</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1286</td><td>ER_UNKNOWN_STORAGE_ENGINE</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1292</td><td>ER_TRUNCATED_WRONG_VALUE</td><td>22007</td><td>22007</td></tr><tr><td scope="row">1303</td><td>ER_SP_NO_RECURSIVE_CREATE</td><td>S1000</td><td>2F003</td></tr><tr><td scope="row">1304</td><td>ER_SP_ALREADY_EXISTS</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1305</td><td>ER_SP_DOES_NOT_EXIST</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1308</td><td>ER_SP_LILABEL_MISMATCH</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1309</td><td>ER_SP_LABEL_REDEFINE</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1310</td><td>ER_SP_LABEL_MISMATCH</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1311</td><td>ER_SP_UNINIT_VAR</td><td>01000</td><td>01000</td></tr><tr><td scope="row">1312</td><td>ER_SP_BADSELECT</td><td>0A000</td><td>0A000</td></tr><tr><td scope="row">1313</td><td>ER_SP_BADRETURN</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1314</td><td>ER_SP_BADSTATEMENT</td><td>0A000</td><td>0A000</td></tr><tr><td scope="row">1315</td><td>ER_UPDATE_LOG_DEPRECATED_IGNORED</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1316</td><td>ER_UPDATE_LOG_DEPRECATED_TRANSLATED</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1317</td><td>ER_QUERY_INTERRUPTED</td><td>S1000</td><td>70100</td></tr><tr><td scope="row">1318</td><td>ER_SP_WRONG_NO_OF_ARGS</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1319</td><td>ER_SP_COND_MISMATCH</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1320</td><td>ER_SP_NORETURN</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1321</td><td>ER_SP_NORETURNEND</td><td>S1000</td><td>2F005</td></tr><tr><td scope="row">1322</td><td>ER_SP_BAD_CURSOR_QUERY</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1323</td><td>ER_SP_BAD_CURSOR_SELECT</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1324</td><td>ER_SP_CURSOR_MISMATCH</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1325</td><td>ER_SP_CURSOR_ALREADY_OPEN</td><td>24000</td><td>24000</td></tr><tr><td scope="row">1326</td><td>ER_SP_CURSOR_NOT_OPEN</td><td>24000</td><td>24000</td></tr><tr><td scope="row">1327</td><td>ER_SP_UNDECLARED_VAR</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1329</td><td>ER_SP_FETCH_NO_DATA</td><td>S1000</td><td>02000</td></tr><tr><td scope="row">1330</td><td>ER_SP_DUP_PARAM</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1331</td><td>ER_SP_DUP_VAR</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1332</td><td>ER_SP_DUP_COND</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1333</td><td>ER_SP_DUP_CURS</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1335</td><td>ER_SP_SUBSELECT_NYI</td><td>0A000</td><td>0A000</td></tr><tr><td scope="row">1336</td><td>ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG</td><td>0A000</td><td>0A000</td></tr><tr><td scope="row">1337</td><td>ER_SP_VARCOND_AFTER_CURSHNDLR</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1338</td><td>ER_SP_CURSOR_AFTER_HANDLER</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1339</td><td>ER_SP_CASE_NOT_FOUND</td><td>S1000</td><td>20000</td></tr><tr><td scope="row">1365</td><td>ER_DIVISION_BY_ZERO</td><td>22012</td><td>22012</td></tr><tr><td scope="row">1367</td><td>ER_ILLEGAL_VALUE_FOR_TYPE</td><td>22007</td><td>22007</td></tr><tr><td scope="row">1370</td><td>ER_PROCACCESS_DENIED_ERROR</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1397</td><td>ER_XAER_NOTA</td><td>S1000</td><td>XAE04</td></tr><tr><td scope="row">1398</td><td>ER_XAER_INVAL</td><td>S1000</td><td>XAE05</td></tr><tr><td scope="row">1399</td><td>ER_XAER_RMFAIL</td><td>S1000</td><td>XAE07</td></tr><tr><td scope="row">1400</td><td>ER_XAER_OUTSIDE</td><td>S1000</td><td>XAE09</td></tr><tr><td scope="row">1401</td><td>ER_XA_RMERR</td><td>S1000</td><td>XAE03</td></tr><tr><td scope="row">1402</td><td>ER_XA_RBROLLBACK</td><td>S1000</td><td>XA100</td></tr><tr><td scope="row">1403</td><td>ER_NONEXISTING_PROC_GRANT</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1406</td><td>ER_DATA_TOO_LONG</td><td>22001</td><td>22001</td></tr><tr><td scope="row">1407</td><td>ER_SP_BAD_SQLSTATE</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1410</td><td>ER_CANT_CREATE_USER_WITH_GRANT</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1413</td><td>ER_SP_DUP_HANDLER</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1414</td><td>ER_SP_NOT_VAR_ARG</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1415</td><td>ER_SP_NO_RETSET</td><td>0A000</td><td>0A000</td></tr><tr><td scope="row">1416</td><td>ER_CANT_CREATE_GEOMETRY_OBJECT</td><td>22003</td><td>22003</td></tr><tr><td scope="row">1425</td><td>ER_TOO_BIG_SCALE</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1426</td><td>ER_TOO_BIG_PRECISION</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1427</td><td>ER_M_BIGGER_THAN_D</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1437</td><td>ER_TOO_LONG_BODY</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1439</td><td>ER_TOO_BIG_DISPLAYWIDTH</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1440</td><td>ER_XAER_DUPID</td><td>S1000</td><td>XAE08</td></tr><tr><td scope="row">1441</td><td>ER_DATETIME_FUNCTION_OVERFLOW</td><td>22008</td><td>22008</td></tr><tr><td scope="row">1451</td><td>ER_ROW_IS_REFERENCED_2</td><td>23000</td><td>23000</td></tr><tr><td scope="row">1452</td><td>ER_NO_REFERENCED_ROW_2</td><td>23000</td><td>23000</td></tr><tr><td scope="row">1453</td><td>ER_SP_BAD_VAR_SHADOW</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1458</td><td>ER_SP_WRONG_NAME</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1460</td><td>ER_SP_NO_AGGREGATE</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1461</td><td>ER_MAX_PREPARED_STMT_COUNT_REACHED</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1463</td><td>ER_NON_GROUPING_FIELD_USED</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1557</td><td>ER_FOREIGN_DUPLICATE_KEY</td><td>23000</td><td>23000</td></tr><tr><td scope="row">1568</td><td>ER_CANT_CHANGE_TX_ISOLATION</td><td>S1000</td><td>25001</td></tr><tr><td scope="row">1582</td><td>ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1583</td><td>ER_WRONG_PARAMETERS_TO_NATIVE_FCT</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1584</td><td>ER_WRONG_PARAMETERS_TO_STORED_FCT</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1586</td><td>ER_DUP_ENTRY_WITH_KEY_NAME</td><td>23000</td><td>23000</td></tr><tr><td scope="row">1613</td><td>ER_XA_RBTIMEOUT</td><td>S1000</td><td>XA106</td></tr><tr><td scope="row">1614</td><td>ER_XA_RBDEADLOCK</td><td>S1000</td><td>XA102</td></tr><tr><td scope="row">1630</td><td>ER_FUNC_INEXISTENT_NAME_COLLISION</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1641</td><td>ER_DUP_SIGNAL_SET</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1642</td><td>ER_SIGNAL_WARN</td><td>01000</td><td>01000</td></tr><tr><td scope="row">1643</td><td>ER_SIGNAL_NOT_FOUND</td><td>S1000</td><td>02000</td></tr><tr><td scope="row">1645</td><td>ER_RESIGNAL_WITHOUT_ACTIVE_HANDLER</td><td>S1000</td><td>0K000</td></tr><tr><td scope="row">1687</td><td>ER_SPATIAL_MUST_HAVE_GEOM_COL</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1690</td><td>ER_DATA_OUT_OF_RANGE</td><td>22003</td><td>22003</td></tr><tr><td scope="row">1698</td><td>ER_ACCESS_DENIED_NO_PASSWORD_ERROR</td><td>28000</td><td>28000</td></tr><tr><td scope="row">1701</td><td>ER_TRUNCATE_ILLEGAL_FK</td><td>42000</td><td>42000</td></tr><tr><td scope="row">1758</td><td>ER_DA_INVALID_CONDITION_NUMBER</td><td>35000</td><td>35000</td></tr><tr><td scope="row">1761</td><td>ER_FOREIGN_DUPLICATE_KEY_WITH_CHILD_INFO</td><td>23000</td><td>23000</td></tr><tr><td scope="row">1762</td><td>ER_FOREIGN_DUPLICATE_KEY_WITHOUT_CHILD_INFO</td><td>23000</td><td>23000</td></tr><tr><td scope="row">1792</td><td>ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION</td><td>S1000</td><td>25006</td></tr><tr><td scope="row">1845</td><td>ER_ALTER_OPERATION_NOT_SUPPORTED</td><td>0A000</td><td>0A000</td></tr><tr><td scope="row">1846</td><td>ER_ALTER_OPERATION_NOT_SUPPORTED_REASON</td><td>0A000</td><td>0A000</td></tr><tr><td scope="row">1859</td><td>ER_DUP_UNKNOWN_IN_INDEX</td><td>23000</td><td>23000</td></tr><tr><td scope="row">1873</td><td>ER_ACCESS_DENIED_CHANGE_USER_ERROR</td><td>28000</td><td>28000</td></tr><tr><td scope="row">1887</td><td>ER_GET_STACKED_DA_WITHOUT_ACTIVE_HANDLER</td><td>S1000</td><td>0Z002</td></tr><tr><td scope="row">1903</td><td>ER_INVALID_ARGUMENT_FOR_LOGARITHM</td><td>S1000</td><td>2201E</td></tr></tbody></table></div></div><br class="table-break"></div></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="connector-j-usagenotes-basic"></a>Chapter 6 JDBC Concepts</h1></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl class="toc"><dt><span class="section"><a href="#connector-j-usagenotes-connect-drivermanager">6.1 Connecting to MySQL Using the JDBC <code class="literal">DriverManager</code>
Interface</a></span></dt><dt><span class="section"><a href="#connector-j-usagenotes-statements">6.2 Using JDBC <code class="literal">Statement</code> Objects to Execute SQL</a></span></dt><dt><span class="section"><a href="#connector-j-usagenotes-statements-callable">6.3 Using JDBC <code class="literal">CallableStatements</code> to Execute Stored
Procedures</a></span></dt><dt><span class="section"><a href="#connector-j-usagenotes-last-insert-id">6.4 Retrieving <code class="literal">AUTO_INCREMENT</code> Column Values through JDBC</a></span></dt></dl></div><a class="indexterm" name="idm139688233963280"></a><p>
This section provides some general JDBC background.
</p><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="connector-j-usagenotes-connect-drivermanager"></a>6.1 Connecting to MySQL Using the JDBC <code class="literal">DriverManager</code>
Interface</h2></div></div></div><p>
When you are using JDBC outside of an application server, the
<code class="literal">DriverManager</code> class manages the establishment
of connections.
</p><p>
Specify to the <code class="literal">DriverManager</code> which JDBC
drivers to try to make Connections with. The easiest way to do
this is to use <code class="literal">Class.forName()</code> on the class
that implements the <code class="literal">java.sql.Driver</code>
interface. With MySQL Connector/J, the name of this class is
<code class="literal">com.mysql.jdbc.Driver</code>. 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.
</p><p>
The following section of Java code shows how you might register
MySQL Connector/J from the <code class="function">main()</code> method of
your application. If testing this code, first read the
installation section at
<a class="xref" href="#connector-j-installing" title="Chapter 3 Connector/J Installation">Chapter 3, <i>Connector/J Installation</i></a>, to make sure you have
connector installed correctly and the
<code class="literal">CLASSPATH</code> set up. Also, ensure that MySQL is
configured to accept external TCP/IP connections.
</p><pre class="programlisting">
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
}
}
}
</pre><p>
After the driver has been registered with the
<code class="literal">DriverManager</code>, you can obtain a
<code class="literal">Connection</code> instance that is connected to a
particular database by calling
<code class="literal">DriverManager.getConnection()</code>:
</p><div class="example"><a name="connector-j-examples-connection-drivermanager"></a><p class="title"><b>Example 6.1 Connector/J: Obtaining a connection from the
<code class="literal">DriverManager</code></b></p><div class="example-contents"><p>
If you have not already done so, please review the portion of
<a class="xref" href="#connector-j-usagenotes-connect-drivermanager" title="6.1 Connecting to MySQL Using the JDBC DriverManager Interface">Section 6.1, “Connecting to MySQL Using the JDBC <code class="literal">DriverManager</code>
Interface”</a>
above before working with the example below.
</p><p>
This example shows how you can obtain a
<code class="literal">Connection</code> instance from the
<code class="literal">DriverManager</code>. There are a few different
signatures for the <code class="function">getConnection()</code>
method. Consult the API documentation that comes with your JDK
for more specific information on how to use them.
</p><pre class="programlisting">
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());
}
</pre><p>
Once a <code class="classname">Connection</code> is established, it
can be used to create <code class="classname">Statement</code> and
<code class="classname">PreparedStatement</code> objects, as well as
retrieve metadata about the database. This is explained in the
following sections.
</p></div></div><br class="example-break"></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="connector-j-usagenotes-statements"></a>6.2 Using JDBC <code class="literal">Statement</code> Objects to Execute SQL</h2></div></div></div><p>
<code class="classname">Statement</code> objects allow you to execute
basic SQL queries and retrieve the results through the
<code class="literal">ResultSet</code> class, which is described later.
</p><p>
To create a <code class="classname">Statement</code> instance, you call
the <code class="function">createStatement()</code> method on the
<code class="literal">Connection</code> object you have retrieved using
one of the <code class="literal">DriverManager.getConnection()</code> or
<code class="literal">DataSource.getConnection()</code> methods described
earlier.
</p><p>
Once you have a <code class="classname">Statement</code> instance, you
can execute a <a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/select.html" target="_top"><code class="literal">SELECT</code></a> query by
calling the <code class="function">executeQuery(String)</code> method
with the SQL you want to use.
</p><p>
To update data in the database, use the
<code class="function">executeUpdate(String SQL)</code> method. This
method returns the number of rows matched by the update
statement, not the number of rows that were modified.
</p><p>
If you do not know ahead of time whether the SQL statement will
be a <a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/select.html" target="_top"><code class="literal">SELECT</code></a> or an
<a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/update.html" target="_top"><code class="literal">UPDATE</code></a>/<a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/insert.html" target="_top"><code class="literal">INSERT</code></a>,
then you can use the <code class="function">execute(String SQL)</code>
method. This method will return true if the SQL query was a
<a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/select.html" target="_top"><code class="literal">SELECT</code></a>, or false if it was an
<a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/update.html" target="_top"><code class="literal">UPDATE</code></a>,
<a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/insert.html" target="_top"><code class="literal">INSERT</code></a>, or
<a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/delete.html" target="_top"><code class="literal">DELETE</code></a> statement. If the
statement was a <a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/select.html" target="_top"><code class="literal">SELECT</code></a> query, you
can retrieve the results by calling the
<code class="function">getResultSet()</code> method. If the statement was
an <a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/update.html" target="_top"><code class="literal">UPDATE</code></a>,
<a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/insert.html" target="_top"><code class="literal">INSERT</code></a>, or
<a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/delete.html" target="_top"><code class="literal">DELETE</code></a> statement, you can
retrieve the affected rows count by calling
<code class="function">getUpdateCount()</code> on the
<code class="classname">Statement</code> instance.
</p><div class="example"><a name="connector-j-examples-execute-select"></a><p class="title"><b>Example 6.2 Connector/J: Using java.sql.Statement to execute a
<code class="literal">SELECT</code> query</b></p><div class="example-contents"><pre class="programlisting">
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;
}
}
</pre></div></div><br class="example-break"></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="connector-j-usagenotes-statements-callable"></a>6.3 Using JDBC <code class="literal">CallableStatements</code> to Execute Stored
Procedures</h2></div></div></div><p>
Starting with MySQL server version 5.0 when used with
Connector/J 3.1.1 or newer, the
<code class="classname">java.sql.CallableStatement</code> interface is
fully implemented with the exception of the
<code class="function">getParameterMetaData()</code> method.
</p><p>
For more information on MySQL stored procedures, please refer to
<a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/stored-routines.html" target="_top">Using Stored Routines (Procedures and Functions)</a>.
</p><p>
Connector/J exposes stored procedure functionality through
JDBC's <code class="classname">CallableStatement</code> interface.
</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><div class="admon-title">Note</div><p>
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
<code class="literal">CallableStatement</code>,
<code class="literal">ResultSetMetaData</code> may return
<code class="literal">NULL</code>.
</p></div><p>
The following example shows a stored procedure that returns the
value of <code class="varname">inOutParam</code> incremented by 1, and the
string passed in using <code class="varname">inputParam</code> as a
<code class="classname">ResultSet</code>:
</p><div class="example"><a name="connector-j-examples-stored-procedure"></a><p class="title"><b>Example 6.3 Connector/J: Calling Stored Procedures</b></p><div class="example-contents"><pre class="programlisting">
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
</pre></div></div><p><br class="example-break">
</p><p>
To use the <code class="literal">demoSp</code> procedure with Connector/J,
follow these steps:
</p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>
Prepare the callable statement by using
<code class="literal">Connection.prepareCall()</code>.
</p><p>
Notice that you have to use JDBC escape syntax, and that the
parentheses surrounding the parameter placeholders are not
optional:
</p><div class="example"><a name="connector-j-examples-preparecall"></a><p class="title"><b>Example 6.4 Connector/J: Using <code class="literal">Connection.prepareCall()</code></b></p><div class="example-contents"><pre class="programlisting">
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");
</pre></div></div><br class="example-break"><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><div class="admon-title">Note</div><p>
<code class="literal">Connection.prepareCall()</code> is an
expensive method, due to the metadata retrieval that the
driver performs to support output parameters. For
performance reasons, minimize unnecessary calls to
<code class="literal">Connection.prepareCall()</code> by reusing
<code class="classname">CallableStatement</code> instances in your
code.
</p></div></li><li class="listitem"><p>
Register the output parameters (if any exist)
</p><p>
To retrieve the values of output parameters (parameters
specified as <code class="literal">OUT</code> or
<code class="literal">INOUT</code> when you created the stored
procedure), JDBC requires that they be specified before
statement execution using the various
<code class="function">registerOutputParameter()</code> methods in
the <code class="classname">CallableStatement</code> interface:
</p><div class="example"><a name="connector-j-examples-output-param"></a><p class="title"><b>Example 6.5 Connector/J: Registering output parameters</b></p><div class="example-contents"><pre class="programlisting">
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);
...
</pre></div></div><p><br class="example-break">
</p></li><li class="listitem"><p>
Set the input parameters (if any exist)
</p><p>
Input and in/out parameters are set as for
<code class="classname">PreparedStatement</code> objects. However,
<code class="classname">CallableStatement</code> also supports
setting parameters by name:
</p><div class="example"><a name="connector-j-examples-callablestatement"></a><p class="title"><b>Example 6.6 Connector/J: Setting <code class="literal">CallableStatement</code> input
parameters</b></p><div class="example-contents"><pre class="programlisting">
...
//
// 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);
...
</pre></div></div><p><br class="example-break">
</p></li><li class="listitem"><p>
Execute the <code class="classname">CallableStatement</code>, and
retrieve any result sets or output parameters.
</p><p>
Although <code class="classname">CallableStatement</code> supports
calling any of the <code class="classname">Statement</code> execute
methods (<code class="function">executeUpdate()</code>,
<code class="function">executeQuery()</code> or
<code class="function">execute()</code>), the most flexible method to
call is <code class="function">execute()</code>, as you do not need
to know ahead of time if the stored procedure returns result
sets:
</p><div class="example"><a name="connector-j-examples-retrieving-results-params"></a><p class="title"><b>Example 6.7 Connector/J: Retrieving results and output parameter values</b></p><div class="example-contents"><pre class="programlisting">
...
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
...
</pre></div></div><p><br class="example-break">
</p></li></ol></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="connector-j-usagenotes-last-insert-id"></a>6.4 Retrieving <code class="literal">AUTO_INCREMENT</code> Column Values through JDBC</h2></div></div></div><p>
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
<code class="classname">Statement</code> interface, or issue the query
<code class="literal">SELECT LAST_INSERT_ID()</code> after issuing an
<a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/insert.html" target="_top"><code class="literal">INSERT</code></a> to a table that had an
<code class="literal">AUTO_INCREMENT</code> key. Using the MySQL-specific
method call isn't portable, and issuing a
<a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/select.html" target="_top"><code class="literal">SELECT</code></a> to get the
<code class="literal">AUTO_INCREMENT</code> 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 <code class="literal">AUTO_INCREMENT</code>
values. First, we demonstrate the use of the new JDBC 3.0 method
<code class="function">getGeneratedKeys()</code> which is now the
preferred method to use if you need to retrieve
<code class="literal">AUTO_INCREMENT</code> keys and have access to JDBC
3.0. The second example shows how you can retrieve the same
value using a standard <code class="literal">SELECT
LAST_INSERT_ID()</code> query. The final example shows how
updatable result sets can retrieve the
<code class="literal">AUTO_INCREMENT</code> value when using the
<code class="function">insertRow()</code> method.
</p><div class="example"><a name="connector-j-examples-autoincrement-getgeneratedkeys"></a><p class="title"><b>Example 6.8 Connector/J: Retrieving <code class="literal">AUTO_INCREMENT</code> column values
using <code class="literal">Statement.getGeneratedKeys()</code></b></p><div class="example-contents"><pre class="programlisting">
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
}
}
}
</pre></div></div><br class="example-break"><div class="example"><a name="connector-j-examples-autoincrement-select"></a><p class="title"><b>Example 6.9 Connector/J: Retrieving <code class="literal">AUTO_INCREMENT</code> column values
using <code class="literal">SELECT LAST_INSERT_ID()</code></b></p><div class="example-contents"><pre class="programlisting">
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
}
}
}
</pre></div></div><br class="example-break"><div class="example"><a name="connector-j-examples-autoincrement-updateable-resultsets"></a><p class="title"><b>Example 6.10 Connector/J: Retrieving <code class="literal">AUTO_INCREMENT</code> column values
in <code class="literal">Updatable ResultSets</code></b></p><div class="example-contents"><pre class="programlisting">
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
}
}
}
</pre></div></div><br class="example-break"><p>
Running the preceding example code should produce the following
output:
</p><pre class="programlisting">
Key returned from getGeneratedKeys(): 1
Key returned from SELECT LAST_INSERT_ID(): 1
Key returned for inserted row: 1
</pre><p>
At times, it can be tricky to use the <code class="literal">SELECT
LAST_INSERT_ID()</code> 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 <code class="function">getGeneratedKeys()</code> method is scoped by
the <code class="classname">Statement</code> instance, so it can be used
even if other queries happen on the same connection, but not on
the same <code class="classname">Statement</code> instance.
</p></div></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="connector-j-usagenotes-j2ee-concepts-connection-pooling"></a>Chapter 7 Connection Pooling with Connector/J</h1></div></div></div><a class="indexterm" name="idm139688233843856"></a><a class="indexterm" name="idm139688233842464"></a><p>
Connection pooling is a technique of creating and managing a pool
of connections that are ready for use by any
<a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/glossary.html#glos_thread" target="_top">thread</a> that needs them.
Connection pooling can greatly increase the performance of your
Java application, while reducing overall resource usage.
</p><h2><a name="idm139688233840128"></a>How Connection Pooling Works</h2><p>
Most applications only need a thread to have access to a JDBC
connection when they are actively processing a
<a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/glossary.html#glos_transaction" target="_top">transaction</a>, 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.
</p><p>
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.
</p><p>
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
<code class="literal">DriverManager.getConnection()</code> 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.
</p><h2><a name="idm139688233835904"></a>Benefits of Connection Pooling</h2><p>
The main benefits to connection pooling are:
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
Reduced connection creation time.
</p><p>
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.
</p></li><li class="listitem"><p>
Simplified programming model.
</p><p>
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.
</p></li><li class="listitem"><p>
Controlled resource usage.
</p><p>
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.
</p></li></ul></div><h2><a name="idm139688233830096"></a>Using Connection Pooling with Connector/J</h2><p>
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.
</p><p>
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:
</p><div class="example"><a name="connector-j-examples-connectionpool-j2ee"></a><p class="title"><b>Example 7.1 Connector/J: Using a connection pool with a J2EE application server</b></p><div class="example-contents"><pre class="programlisting">
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;
}
}
}
}
</pre></div></div><p><br class="example-break">
As shown in the example above, after obtaining the JNDI
<code class="literal">InitialContext</code>, and looking up the
<code class="literal">DataSource</code>, the rest of the code follows
familiar JDBC conventions.
</p><p>
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.
</p><h2><a name="idm139688233821136"></a>Sizing the Connection Pool</h2><p>
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.
</p><p>
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.
</p><p>
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.
</p><p>
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.
</p><h2><a name="idm139688233817264"></a>Validating Connections</h2><p>
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:
</p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>
Before the pool returns a connection to the application.
</p></li><li class="listitem"><p>
When the application returns a connection to the pool.
</p></li><li class="listitem"><p>
During periodic checks of idle connections.
</p></li></ol></div><p>
To use this feature, specify a validation query in your connection
pool that starts with <code class="literal">/* ping */</code>. 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 <code class="literal">ReplicationConnection</code> or
<code class="literal">LoadBalancedConnection</code>, the ping will be sent
across all active connections.
</p><p>
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:
</p><pre class="programlisting">
protected static final String PING_MARKER = "/* ping */";
...
if (sql.charAt(0) == '/') {
if (sql.startsWith(PING_MARKER)) {
doPingInstead();
...
</pre><p>
None of the following snippets will work, because the ping syntax
is sensitive to whitespace, capitalization, and placement:
</p><pre class="programlisting">
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";
</pre><p>
All of the previous statements will issue a normal
<code class="literal">SELECT</code> statement and will
<span class="bold"><strong>not</strong></span> 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
<code class="literal">loadBalanceValidateConnectionOnSwapServer</code> to
validate the connection before use.
</p><p>
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 <span class="emphasis"><em>exactly</em></span> with
<code class="literal">/* ping */</code>. 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.
</p></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="connector-j-multi-host-connections"></a>Chapter 8 Multi-Host Connections</h1></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl class="toc"><dt><span class="section"><a href="#connector-j-config-failover">8.1 Configuring Server Failover</a></span></dt><dt><span class="section"><a href="#connector-j-usagenotes-j2ee-concepts-managing-load-balanced-connections">8.2 Configuring Load Balancing with Connector/J</a></span></dt><dt><span class="section"><a href="#connector-j-master-slave-replication-connection">8.3 Configuring Master/Slave Replication with Connector/J</a></span></dt><dt><span class="section"><a href="#connector-j-usagenotes-j2ee-concepts-load-balancing-failover">8.4 Advanced Load-balancing and Failover Configuration</a></span></dt></dl></div><a class="indexterm" name="idm139688233801200"></a><p>
The following sections discuss a number of topics that involve
multi-host connections, namely, server load-balancing, failover,
and replication.
</p><p>
Developers should know the following things about multi-host
connections that are managed through Connector/J:
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
Each multi-host connection is a wrapper of the underlying
physical connections.
</p></li><li class="listitem"><p>
Each of the underlying physical connections has its own
session. Sessions cannot be tracked, shared, or copied,
given the MySQL architecture.
</p></li><li class="listitem"><p>
Every switch between physical connections means a switch
between sessions.
</p></li><li class="listitem"><p>
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.
</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><div class="admon-title">Note</div><p>
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.
</p></div></li></ul></div><p>
</p><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="connector-j-config-failover"></a>8.1 Configuring Server Failover</h2></div></div></div><a class="indexterm" name="idm139688233791680"></a><p>
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 (<code class="literal">Statement</code>,
<code class="literal">ResultSet</code>, 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.
</p><p>
</p><p>
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.
</p><p>
The failover is configured at the initial setup stage of the
server connection by the connection URL (see explanations for
its format
<a class="link" href="#connector-j-reference-url-format" title="JDBC URL Format">here</a>):
</p><pre class="programlisting">
jdbc:mysql://[<em class="replaceable"><code>primary host</code></em>][:<em class="replaceable"><code>port</code></em>],[<em class="replaceable"><code>secondary host 1</code></em>][:<em class="replaceable"><code>port</code></em>][,[<em class="replaceable"><code>secondary host 2</code></em>][:<em class="replaceable"><code>port</code></em>]]...[/[<em class="replaceable"><code>database</code></em>]]»
[?<em class="replaceable"><code>propertyName1</code></em>=<em class="replaceable"><code>propertyValue1</code></em>[&<em class="replaceable"><code>propertyName2</code></em>=<em class="replaceable"><code>propertyValue2</code></em>]...]
</pre><p>
</p><p>
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.
</p><p>
The failover support is configured by the following connection
properties (their functions are explained in the paragraphs
below):
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
<code class="literal">failOverReadOnly</code>
</p></li><li class="listitem"><p>
<code class="literal">secondsBeforeRetryMaster</code>
</p></li><li class="listitem"><p>
<code class="literal">queriesBeforeRetryMaster</code>
</p></li><li class="listitem"><p>
<code class="literal">retriesAllDown</code>
</p></li><li class="listitem"><p>
<code class="literal">autoReconnect</code>
</p></li><li class="listitem"><p>
<code class="literal">autoReconnectForPools</code>
</p></li></ul></div><p>
</p><h3><a name="idm139688233770256"></a>Configuring Connection Access Mode</h3><p>
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
<code class="literal">failOverReadOnly</code>, which is
<span class="quote">“<span class="quote">true</span>”</span> 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<code class="literal"> Connection.setReadOnly(boolean)</code>, which
partially overrides the property
<code class="literal">failOverReadOnly</code>. When
<code class="literal">failOverReadOnly=false</code> 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
<code class="literal">failOverReadOnly=true</code>, 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.
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
Sequence A, with <code class="literal">failOverReadOnly=true</code>:
</p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>
Connects to primary host in read/write mode
</p></li><li class="listitem"><p>
Sets
<code class="literal">Connection.setReadOnly(true)</code>;
primary host now in read-only mode
</p></li><li class="listitem"><p>
Failover event; connects to secondary host in
read-only mode
</p></li><li class="listitem"><p>
Sets
<code class="literal">Connection.setReadOnly(false)</code>;
secondary host remains in read-only mode
</p></li><li class="listitem"><p>
Falls back to primary host; connection now in
read/write mode
</p></li></ol></div><p>
</p></li><li class="listitem"><p>
Sequence B, with <code class="literal">failOverReadOnly=false</code>
</p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>
Connects to primary host in read/write mode
</p></li><li class="listitem"><p>
Sets <code class="literal">Connection.setReadOnly(true)</code>;
primary host now in read-only mode
</p></li><li class="listitem"><p>
Failover event; connects to secondary host in
read-only mode
</p></li><li class="listitem"><p>
Set <code class="literal">Connection.setReadOnly(false)</code>;
connection to secondary host switches to read/write
mode
</p></li><li class="listitem"><p>
Falls back to primary host; connection now in
read/write mode
</p></li></ol></div></li></ul></div><p>
</p><p>
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.
</p><h3><a name="idm139688233747088"></a>Configuring Fallback to Primary Host</h3><p>
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,
<code class="literal">secondsBeforeRetryMaster</code> and
<code class="literal">queriesBeforeRetryMaster</code>, determine when the
driver is ready to retry a reconnection to the primary host (the
<code class="literal">Master</code> 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):
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
<code class="literal">secondsBeforeRetryMaster</code> determines how
much time the driver waits before trying to fall back to
the primary host
</p></li><li class="listitem"><p>
<code class="literal">queriesBeforeRetryMaster</code> 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
<code class="literal">Statement.execute*()</code> method increments
the query execution counter; therefore, when calls are
made to <code class="literal">Statement.executeBatch()</code> or if
<code class="literal">allowMultiQueries</code> or
<code class="literal">rewriteBatchStatements</code> 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 <code class="literal">Statement.execute*()</code> methods
internally in several occasions. All these mean you can
only use <code class="literal">queriesBeforeRetryMaster</code> only
as a coarse specification for when to fall back to the
primary host.
</p></li></ul></div><p>
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
<code class="literal">Connection.commit()</code> or
<code class="literal">Connection.rollback()</code> is called. The
automatic fallback to the primary host can be turned off by
setting simultaneously
<code class="literal">secondsBeforeRetryMaster</code> and
<code class="literal">queriesBeforeRetryMaster</code> to <span class="quote">“<span class="quote">0</span>”</span>.
Setting only one of the properties to <span class="quote">“<span class="quote">0</span>”</span> only
disables one part of the check.
</p><h3><a name="connector-j-config-reconnect"></a>Configuring Reconnection Attempts</h3><p>
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
<code class="literal">secondsBeforeRetryMaster</code> and
<code class="literal">queriesBeforeRetryMaster</code> 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
<code class="literal">retriesAllDown</code>.
</p><h3><a name="idm139688233727936"></a>Seamless Reconnection</h3><p>
Although not recommended, you can make the driver perform
failovers without invalidating the active
<code class="literal">Statement</code> or <code class="literal">ResultSet</code>
instances by setting either the parameter
<code class="literal">autoReconnect</code> or
<code class="literal">autoReconnectForPools</code> to
<code class="literal">true</code>. 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
<code class="literal">ResultSet</code> looks to be alright, but the
underlying connection may have changed already, and no backing
cursor is available anymore.
</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="connector-j-usagenotes-j2ee-concepts-managing-load-balanced-connections"></a>8.2 Configuring Load Balancing with Connector/J</h2></div></div></div><a class="indexterm" name="idm139688233720928"></a><a class="indexterm" name="idm139688233719536"></a><p>
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.
</p><p>
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
<a class="link" href="#connector-j-reference-url-format" title="JDBC URL Format">the general URL
for MySQL connection</a>, but a specialized scheme:
</p><pre class="programlisting">
jdbc:mysql:loadbalance://[<em class="replaceable"><code>host</code></em>1][:<em class="replaceable"><code>port</code></em>],[<em class="replaceable"><code>host</code></em>2][:<em class="replaceable"><code>port</code></em>][,[<em class="replaceable"><code>host</code></em>3][:<em class="replaceable"><code>port</code></em>]]...[/[<em class="replaceable"><code>database</code></em>]] »
[?<em class="replaceable"><code>propertyName1</code></em>=<em class="replaceable"><code>propertyValue1</code></em>[&<em class="replaceable"><code>propertyName2</code></em>=<em class="replaceable"><code>propertyValue2</code></em>]...]
</pre><p>
</p><p>
There are two configuration properties associated with this
functionality:
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
<code class="literal">loadBalanceConnectionGroup</code> – 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 <code class="literal">loadBalanceConnectionGroup</code>,
you cannot manage the connections. All load-balanced
connections sharing the same
<code class="literal">loadBalanceConnectionGroup</code> value,
regardless of how the application creates them, will be
managed together.
</p></li><li class="listitem"><p>
<code class="literal">loadBalanceEnableJMX</code> – The ability to
manage the connections is exposed when you define a
<code class="literal">loadBalanceConnectionGroup</code>; but if you
want to manage this externally, enable JMX by setting this
property to <code class="literal">true</code>. This enables a JMX
implementation, which exposes the management and monitoring
operations of a connection group. Further, start your
application with the
<code class="literal">-Dcom.sun.management.jmxremote</code> JVM flag.
You can then perform connect and perform operations using a
JMX client such as <code class="literal">jconsole</code>.
</p></li></ul></div><p>
Once a connection has been made using the correct connection
properties, a number of monitoring properties are available:
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
Current active host count.
</p></li><li class="listitem"><p>
Current active physical connection count.
</p></li><li class="listitem"><p>
Current active logical connection count.
</p></li><li class="listitem"><p>
Total logical connections created.
</p></li><li class="listitem"><p>
Total transaction count.
</p></li></ul></div><p>
The following management operations can also be performed:
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
Add host.
</p></li><li class="listitem"><p>
Remove host.
</p></li></ul></div><p>
The JMX interface,
<code class="literal">com.mysql.jdbc.jmx.LoadBalanceConnectionGroupManagerMBean</code>,
has the following methods:
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
<code class="literal">int getActiveHostCount(String group);</code>
</p></li><li class="listitem"><p>
<code class="literal">int getTotalHostCount(String group);</code>
</p></li><li class="listitem"><p>
<code class="literal">long getTotalLogicalConnectionCount(String
group);</code>
</p></li><li class="listitem"><p>
<code class="literal">long getActiveLogicalConnectionCount(String
group);</code>
</p></li><li class="listitem"><p>
<code class="literal">long getActivePhysicalConnectionCount(String
group);</code>
</p></li><li class="listitem"><p>
<code class="literal">long getTotalPhysicalConnectionCount(String
group);</code>
</p></li><li class="listitem"><p>
<code class="literal">long getTotalTransactionCount(String
group);</code>
</p></li><li class="listitem"><p>
<code class="literal">void removeHost(String group, String host) throws
SQLException;</code>
</p></li><li class="listitem"><p>
<code class="literal">void stopNewConnectionsToHost(String group, String
host) throws SQLException;</code>
</p></li><li class="listitem"><p>
<code class="literal">void addHost(String group, String host, boolean
forExisting);</code>
</p></li><li class="listitem"><p>
<code class="literal">String getActiveHostsList(String group);</code>
</p></li><li class="listitem"><p>
<code class="literal">String getRegisteredConnectionGroups();</code>
</p></li></ul></div><p>
The <code class="literal">getRegisteredConnectionGroups()</code> method
returns the names of all connection groups defined in that class
loader.
</p><p>
You can test this setup with the following code:
</p><pre class="programlisting">
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();
}
}
}
}
}
</pre><p>
After compiling, the application can be started with the
<code class="literal">-Dcom.sun.management.jmxremote</code> flag, to
enable remote management. <code class="literal">jconsole</code> can then
be started. The <code class="literal">Test</code> main class will be
listed by <code class="literal">jconsole</code>. Select this and click
<span class="guibutton">Connect</span>. You can then navigate to the
<code class="literal">com.mysql.jdbc.jmx.LoadBalanceConnectionGroupManager</code>
bean. At this point, you can click on various operations and
examine the returned result.
</p><p>
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 <code class="literal">addHost()</code>, which is exposed in
<code class="literal">jconsole</code>. Note that these operations can be
performed dynamically without having to stop the application
running.
</p><p>
For further information on the combination of load balancing and
failover, see
<a class="xref" href="#connector-j-usagenotes-j2ee-concepts-load-balancing-failover" title="8.4 Advanced Load-balancing and Failover Configuration">Section 8.4, “Advanced Load-balancing and Failover Configuration”</a>.
</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="connector-j-master-slave-replication-connection"></a>8.3 Configuring Master/Slave Replication with Connector/J</h2></div></div></div><a class="indexterm" name="idm139688233661616"></a><a class="indexterm" name="idm139688233660224"></a><p>
This section describe a number of features of Connector/J's
support for replication-aware deployments.
</p><p>
The replication is configured at the initial setup stage of the
server connection by the connection URL, which has a similar
format as <a class="link" href="#connector-j-reference-url-format" title="JDBC URL Format">the
general URL for MySQL connection</a>, but a specialized
scheme:
</p><pre class="programlisting">
jdbc:mysql:replication://[<em class="replaceable"><code>master host</code></em>][:<em class="replaceable"><code>port</code></em>],[<em class="replaceable"><code>slave host 1</code></em>][:<em class="replaceable"><code>port</code></em>][,[<em class="replaceable"><code>slave host 2</code></em>][:<em class="replaceable"><code>port</code></em>]]...[/[<em class="replaceable"><code>database</code></em>]] »
[?<em class="replaceable"><code>propertyName1</code></em>=<em class="replaceable"><code>propertyValue1</code></em>[&<em class="replaceable"><code>propertyName2</code></em>=<em class="replaceable"><code>propertyValue2</code></em>]...]
</pre><p>
</p><p>
Users may specify the property<code class="literal">
allowMasterDownConnections=true</code> to allow
<code class="literal">Connection</code> objects to be created even though
no master hosts are reachable. Such
<code class="literal">Connection</code> objects report they are read-only,
and <code class="literal">isMasterConnection()</code> returns false for
them. The <code class="literal">Connection</code> tests for available
master hosts when
<code class="literal">Connection.setReadOnly(false)</code> 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.
</p><p>
For Connector/J 5.1.38 and later, users may specify the
property<code class="literal"> allowSlavesDownConnections=true</code> to
allow <code class="literal">Connection</code> objects to be created even
though no slave hosts are reachable. A
<code class="literal">Connection</code> then, at runtime, tests for
available slave hosts when
<code class="literal">Connection.setReadOnly(true)</code> is called (see
explanation for the method below), throwing an SQLException if
it cannot establish a connection to a slave, unless the property
<code class="literal">readFromMasterWhenNoSlaves</code>
is set to be <span class="quote">“<span class="quote">true</span>”</span> (see below for a description of
the property).
</p><h3><a name="idm139688233642768"></a>Scaling out Read Load by Distributing Read Traffic to Slaves</h3><p>
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 <code class="literal">Connection.getReadOnly()</code>.
</p><p>
An application signals that it wants a transaction to be
read-only by calling
<code class="literal">Connection.setReadOnly(true)</code>. The
replication-aware connection will use one of the slave
connections, which are load-balanced per-virtual-machine using a
round-robin scheme (a given connection is sticky to a slave
unless that slave is removed from service). For Connector/J
5.1.38 and later, after calling
<code class="literal">Connection.setReadOnly(true)</code>, if you want to
allow connection to a master when no slaves are available, set
the property
<code class="literal">readFromMasterWhenNoSlaves</code> to
<span class="quote">“<span class="quote">true.</span>”</span> 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
<code class="literal">readFromMasterWhenNoSlaves=true</code>
might result in an extra load for the master host in a
transparent manner.
</p><p>
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
<code class="literal">Connection.setReadOnly(false)</code> 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.
</p><p>
To enable this functionality, use the
<code class="literal">com.mysql.jdbc.ReplicationDriver</code> 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, <code class="literal">ReplicationDriver</code>
does not currently work with
<code class="literal">java.sql.DriverManager</code>-based connection
creation unless it is the only MySQL JDBC driver registered with
the <code class="literal">DriverManager</code> .
</p><p>
Here is a short example of how
<code class="literal">ReplicationDriver</code> might be used in a
standalone application:
</p><a name="connector-j-using-replication-driver-example"></a><pre class="programlisting">
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");
.......
}
}
</pre><p>
Consider using the Load Balancing JDBC Pool
(<span class="command"><strong>lbpool</strong></span>) 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
<a class="ulink" href="http://code.google.com/p/mysql-lbpool/" target="_top">Load
Balancing JDBC Driver for MySQL (mysql-lbpool)</a>.
</p><h3><a name="connector-j-multiple-master-replication"></a>Support for Multiple-Master Replication Topographies</h3><p>
Since Connector/J 5.1.27, multi-master replication topographies
are supported.
</p><p>
The connection URL for replication discussed earlier (i.e., in
the format of
<code class="literal">jdbc:mysql:replication://master,slave1,slave2,slave3/test</code>)
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
<a class="xref" href="#connector-j-reference-ipv6-url" title="IPv6 Connections">IPv6 Connections</a> with the
property <code class="literal">type=[master|slave]</code>; for example:
</p><pre class="programlisting">jdbc:mysql://address=(type=master)(host=master1host),address=(type=master)(host=master2host),address=(type=slave)(host=slave1host)/database</pre><p>
</p><p>
Connector/J uses a load-balanced connection internally for
management of the master connections, which means that
<code class="literal">ReplicationConnection</code>, when configured to use
multiple masters, exposes the same options to balance load
across master hosts as described in
<a class="xref" href="#connector-j-usagenotes-j2ee-concepts-managing-load-balanced-connections" title="8.2 Configuring Load Balancing with Connector/J">Section 8.2, “Configuring Load Balancing with Connector/J”</a>.
</p><h3><a name="idm139688233618944"></a>Live Reconfiguration of Replication Topography</h3><p><a name="connector-j-live-reconfiguration-replication"></a>
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.
</p><p>
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
<code class="literal">ReplicationConnection</code> objects register
themselves with the appropriate
<code class="literal">ReplicationConnectionGroup</code> if a value for the
new <code class="literal">replicationConnectionGroup</code> property is
specified. The <code class="literal">ReplicationConnectionGroup</code>
object tracks these connections until they are closed, and it is
used to manipulate the hosts associated with these connections.
</p><p>
Some important methods related to host management include:
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
<code class="literal">getMasterHosts()</code>: Returns a collection
of strings representing the hosts configured as masters
</p></li><li class="listitem"><p>
<code class="literal">getSlaveHosts()</code>: Returns a collection
of strings representing the hosts configured as slaves
</p></li><li class="listitem"><p>
<code class="literal">addSlaveHost(String host)</code>: Adds new
host to pool of possible slave hosts for selection at
start of new read-only workload
</p></li><li class="listitem"><p>
<code class="literal">promoteSlaveToMaster(String host)</code>:
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
</p></li><li class="listitem"><p>
<code class="literal">removeSlaveHost(String host, boolean
closeGently)</code>: Removes the host (host name match
must be exact) from the list of configured slaves; if
<code class="literal">closeGently</code> is false, existing
connections which have this host as currently active will
be closed hardly (application should expect exceptions)
</p></li><li class="listitem"><p>
<code class="literal">removeMasterHost(String host, boolean
closeGently)</code>: Same as
<code class="literal">removeSlaveHost()</code>, but removes the host
from the list of configured masters
</p></li></ul></div><p>
</p><p>
Some useful management metrics include:
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
<code class="literal">getConnectionCountWithHostAsSlave(String
host)</code>: Returns the number of
ReplicationConnection objects that have the given host
configured as a possible slave
</p></li><li class="listitem"><p>
<code class="literal"> getConnectionCountWithHostAsMaster(String
host)</code>: Returns the number of
ReplicationConnection objects that have the given host
configured as a possible master
</p></li><li class="listitem"><p>
<code class="literal">getNumberOfSlavesAdded()</code>: Returns the
number of times a slave host has been dynamically added to
the group pool
</p></li><li class="listitem"><p>
<code class="literal">getNumberOfSlavesRemoved()</code>: Returns the
number of times a slave host has been dynamically removed
from the group pool
</p></li><li class="listitem"><p>
<code class="literal">getNumberOfSlavePromotions()</code>: Returns
the number of times a slave host has been promoted to a
master
</p></li><li class="listitem"><p>
<code class="literal">getTotalConnectionCount()</code>: Returns the
number of ReplicationConnection objects which have been
registered with this group
</p></li><li class="listitem"><p>
<code class="literal">getActiveConnectionCount()</code>: Returns the
number of ReplicationConnection objects currently being
managed by this group
</p></li></ul></div><p>
</p><h3><a name="idm139688233590016"></a>ReplicationConnectionGroupManager</h3><p>
<code class="literal">com.mysql.jdbc.ReplicationConnectionGroupManager</code>
provides access to the replication connection groups, together
with some utility methods.
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
<code class="literal">getConnectionGroup(String groupName)</code>:
Returns the <code class="literal">ReplicationConnectionGroup</code>
object matching the groupName provided
</p></li></ul></div><p>
</p><p>
The other methods in
<code class="literal">ReplicationConnectionGroupManager</code> mirror
those of <code class="literal">ReplicationConnectionGroup</code>, 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
<code class="literal">ReplicationConnectionGroups</code>.
</p><p>
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.
</p><h3><a name="idm139688233582608"></a>Using JMX for Managing Replication Hosts</h3><p>
When Connector/J is started with
<code class="literal">replicationEnableJMX=true</code> and a value set for
the property <code class="literal">replicationConnectionGroup</code>, a
JMX MBean will be registered, allowing manipulation of
replication hosts by a JMX client. The MBean interface is
defined in
<code class="literal">com.mysql.jdbc.jmx.ReplicationGroupManagerMBean</code>,
and leverages the
<code class="literal">ReplicationConnectionGroupManager</code> static
methods:
</p><pre class="programlisting">
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);
</pre></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="connector-j-usagenotes-j2ee-concepts-load-balancing-failover"></a>8.4 Advanced Load-balancing and Failover Configuration</h2></div></div></div><p>
Connector/J provides a useful load-balancing implementation for
MySQL Cluster or multi-master deployments, as explained in
<a class="xref" href="#connector-j-usagenotes-j2ee-concepts-managing-load-balanced-connections" title="8.2 Configuring Load Balancing with Connector/J">Section 8.2, “Configuring Load Balancing with Connector/J”</a>
and
<a class="xref" href="#connector-j-multiple-master-replication" title="Support for Multiple-Master Replication Topographies">Support for Multiple-Master Replication Topographies</a>.
As of Connector/J 5.1.12, this same implementation is used for
balancing load between read-only slaves with
<code class="literal">ReplicationDriver</code>.
</p><p>
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:
</p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>
At transaction boundaries (transactions are explicitly
committed or rolled back).
</p></li><li class="listitem"><p>
A communication exception (SQL State starting with "08") is
encountered.
</p></li><li class="listitem"><p>
When a <code class="literal">SQLException</code> matches conditions
defined by user, using the extension points defined by the
<code class="literal">loadBalanceSQLStateFailover</code>,
<code class="literal">loadBalanceSQLExceptionSubclassFailover</code>
or <code class="literal">loadBalanceExceptionChecker</code>
properties.
</p></li></ol></div><p>
The third condition revolves around three new properties
introduced with Connector/J 5.1.13. It allows you to control
which <code class="literal">SQLException</code>s trigger failover.
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
<code class="literal">loadBalanceExceptionChecker</code> - The
<code class="literal">loadBalanceExceptionChecker</code> property is
really the key. This takes a fully-qualified class name
which implements the new
<code class="literal">com.mysql.jdbc.LoadBalanceExceptionChecker</code>
interface. This interface is very simple, and you only need
to implement the following method:
</p><pre class="programlisting">
public boolean shouldExceptionTriggerFailover(SQLException ex)
</pre><p>
A <code class="literal">SQLException</code> is passed in, and a
boolean returned. A value of <code class="literal">true</code>
triggers a failover, <code class="literal">false</code> does not.
</p><p>
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:
</p><pre class="programlisting">
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")));
}
}
</pre><p>
The code above extends
<code class="literal">com.mysql.jdbc.StandardLoadBalanceExceptionChecker</code>,
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:
<code class="literal">loadBalanceSQLStateFailover</code> and
<code class="literal">loadBalanceSQLExceptionSubclassFailover</code>.
</p></li><li class="listitem"><p>
<code class="literal">loadBalanceSQLStateFailover</code> - allows you
to define a comma-delimited list of
<code class="literal">SQLState</code> code prefixes, against which a
<code class="literal">SQLException</code> is compared. If the prefix
matches, failover is triggered. So, for example, the
following would trigger a failover if a given
<code class="literal">SQLException</code> starts with "00", or is
"12345":
</p><pre class="programlisting">
loadBalanceSQLStateFailover=00,12345
</pre></li><li class="listitem"><p>
<code class="literal">loadBalanceSQLExceptionSubclassFailover</code> -
can be used in conjunction with
<code class="literal">loadBalanceSQLStateFailover</code> or on its
own. If you want certain subclasses of
<code class="literal">SQLException</code> 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 <code class="literal">SQLTransientConnectionExceptions</code> to
trigger failover, you would specify:
</p><pre class="programlisting">
loadBalanceSQLExceptionSubclassFailover=java.sql.SQLTransientConnectionException
</pre></li></ul></div><p>
While the three failover conditions enumerated earlier suit most
situations, if <code class="literal">autocommit</code> 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 <code class="literal">autocommit</code> is enabled. This
functionality is dependent upon the following properties:
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
<code class="literal">loadBalanceAutoCommitStatementThreshold</code>
– 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 <code class="literal">autocommit</code> enabled are
never balanced.
</p></li><li class="listitem"><p>
<code class="literal">loadBalanceAutoCommitStatementRegex</code> –
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 <span class="quote">“<span class="quote">test</span>”</span>:
</p><pre class="programlisting">
loadBalanceAutoCommitStatementThreshold=3
loadBalanceAutoCommitStatementRegex=.*test.*
</pre><p>
<code class="literal">loadBalanceAutoCommitStatementRegex</code> 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.
</p></li></ul></div></div></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="connector-j-interceptors"></a>Chapter 9 Using the Connector/J Interceptor Classes</h1></div></div></div><p>
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.
</p><p>
The connection properties that control the interceptors are
explained in
<a class="xref" href="#connector-j-reference-configuration-properties" title="5.1 Driver/Datasource Class Names, URL Syntax and Configuration Properties for Connector/J">Section 5.1, “Driver/Datasource Class Names, URL Syntax and Configuration Properties
for Connector/J”</a>:
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
<code class="literal">connectionLifecycleInterceptors</code>, where you
specify the fully qualified names of classes that implement
the
<code class="literal">com.mysql.jdbc.ConnectionLifecycleInterceptor</code>
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
<code class="literal">setAutoCommit()</code>.
</p></li><li class="listitem"><p>
<code class="literal">exceptionInterceptors</code>, where you specify
the fully qualified names of classes that implement the
<code class="literal">com.mysql.jdbc.ExceptionInterceptor</code>
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 <code class="literal">exceptionInterceptors</code> classes are
only called when handling a <code class="literal">SQLException</code>
thrown from Connector/J code, they can be used even in
production deployments without substantial performance
overhead.
</p></li><li class="listitem"><p>
<code class="literal">statementInterceptors</code>, where you specify
the fully qualified names of classes that implement the
<code class="literal">com.mysql.jdbc.StatementInterceptorV2</code>
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 <span class="command"><strong>memcached</strong></span> server, rewriting slow queries,
logging information about statement execution, or route
requests to remote servers.
</p></li></ul></div></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="connector-j-usagenotes-tomcat"></a>Chapter 10 Using Connector/J with Tomcat</h1></div></div></div><a class="indexterm" name="idm139688233521472"></a><p>
The following instructions are based on the instructions for
Tomcat-5.x, available at
<a class="ulink" href="http://tomcat.apache.org/tomcat-5.5-doc/jndi-datasource-examples-howto.html" target="_top">http://tomcat.apache.org/tomcat-5.5-doc/jndi-datasource-examples-howto.html</a>
which is current at the time this document was written.
</p><p>
First, install the <code class="filename">.jar</code> file that comes with
Connector/J in <code class="filename">$CATALINA_HOME/common/lib</code> so
that it is available to all applications installed in the
container.
</p><p>
Next, configure the JNDI DataSource by adding a declaration
resource to <code class="filename">$CATALINA_HOME/conf/server.xml</code> in
the context that defines your web application:
</p><pre class="programlisting">
<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>
</pre><p>
Note that Connector/J 5.1.3 introduced a facility whereby, rather
than use a <code class="literal">validationQuery</code> value of
<code class="literal">SELECT 1</code>, it is possible to use
<code class="literal">validationQuery</code> with a value set to <code class="literal">/*
ping */</code>. 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
<code class="literal">ReplicationConnection</code> or
<code class="literal">LoadBalancedConnection</code> type connections, the
ping will be sent across all active connections. The following XML
snippet illustrates how to select this option:
</p><pre class="programlisting">
<parameter>
<name>validationQuery</name>
<value>/* ping */</value>
</parameter>
</pre><p>
Note that <code class="literal">/* ping */</code> has to be specified
exactly.
</p><p>
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:
</p><pre class="programlisting">
Error: java.sql.SQLException: Cannot load JDBC driver class 'null ' SQL
state: null
</pre><p>
Note that the auto-loading of drivers having the
<code class="filename">META-INF/service/java.sql.Driver</code> 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 "<code class="literal">antiResourceLocking=true</code>" as a
Tomcat Context attribute, or remove the
<code class="filename">META-INF/</code> directory.
</p></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="connector-j-usagenotes-jboss"></a>Chapter 11 Using Connector/J with JBoss</h1></div></div></div><a class="indexterm" name="idm139688233501568"></a><p>
These instructions cover JBoss-4.x. To make the JDBC driver
classes available to the application server, copy the
<code class="filename">.jar</code> file that comes with Connector/J to the
<code class="filename">lib</code> directory for your server configuration
(which is usually called <code class="filename">default</code>). Then, in
the same configuration directory, in the subdirectory named
deploy, create a datasource configuration file that ends with
<code class="literal">-ds.xml</code>, which tells JBoss to deploy this file
as a JDBC Datasource. The file should have the following contents:
</p><pre class="programlisting">
<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>
</pre></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="connector-j-usagenotes-spring-config"></a>Chapter 12 Using Connector/J with Spring</h1></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl class="toc"><dt><span class="section"><a href="#connector-j-usagenotes-spring-config-jdbctemplate">12.1 Using <code class="classname">JdbcTemplate</code></a></span></dt><dt><span class="section"><a href="#connector-j-usagenotes-spring-config-transactional">12.2 Transactional JDBC Access</a></span></dt><dt><span class="section"><a href="#connector-j-usagenotes-spring-config-connpooling">12.3 Connection Pooling with Spring</a></span></dt></dl></div><a class="indexterm" name="idm139688233493792"></a><p>
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
<a class="ulink" href="http://www.martinfowler.com/articles/injection.html" target="_top">Inversion
of Control Containers and the Dependency Injection
pattern</a>). 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.
</p><p>
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.
</p><p>
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
<span class="quote">“<span class="quote">bean</span>”</span> terminology. For example, to configure a
connection to a MySQL server supporting the world sample database,
you might use:
</p><pre class="programlisting">
<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>
</pre><p>
In the above example, we are assigning values to properties that
will be used in the configuration. For the datasource
configuration:
</p><pre class="programlisting">
<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>
</pre><p>
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.
</p><pre class="programlisting">
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="properties" ref="dbProps"/>
</bean>
</pre><p>
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.
</p><pre class="programlisting">
// 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);
}
</pre><p>
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.
</p><p>
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.
</p><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="connector-j-usagenotes-spring-config-jdbctemplate"></a>12.1 Using <code class="classname">JdbcTemplate</code></h2></div></div></div><p>
Spring makes extensive use of the Template method design pattern
(see
<a class="ulink" href="http://en.wikipedia.org/wiki/Template_method_pattern" target="_top">Template
Method Pattern</a>). Our immediate focus will be on the
<code class="literal">JdbcTemplate</code> and related classes,
specifically <code class="literal">NamedParameterJdbcTemplate</code>. The
template classes handle obtaining and releasing a connection for
data access when one is needed.
</p><p>
The next example shows how to use
<code class="literal">NamedParameterJdbcTemplate</code> inside of a DAO
(Data Access Object) class to retrieve a random city given a
country code.
</p><pre class="programlisting">
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;
}
}
</pre><p>
The focus in the above code is on the
<code class="function">getRandomCityByCountryCode()</code> method. We
pass a country code and use the
<code class="literal">NamedParameterJdbcTemplate</code> 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.
</p><p>
To access this code, you need to configure it with Spring by
providing a reference to the data source.
</p><pre class="programlisting">
<bean id="dao" class="code.Ex2JdbcDao">
<property name="dataSource" ref="dataSource"/>
</bean>
</pre><p>
At this point, we can just grab a reference to the DAO from
Spring and call
<code class="function">getRandomCityByCountryCode()</code>.
</p><pre class="programlisting">
// 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));
</pre><p>
This example shows how to use Spring's JDBC classes to
completely abstract away the use of traditional JDBC classes
including <code class="literal">Connection</code> and
<code class="literal">PreparedStatement</code>.
</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="connector-j-usagenotes-spring-config-transactional"></a>12.2 Transactional JDBC Access</h2></div></div></div><p>
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).
</p><p>
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.
</p><pre class="programlisting">
ALTER TABLE City ENGINE=InnoDB;
ALTER TABLE Country ENGINE=InnoDB;
ALTER TABLE CountryLanguage ENGINE=InnoDB;
</pre><p>
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.
</p><p>
First you create a simple interface:
</p><pre class="programlisting">
public interface Ex3Dao {
Integer createCity(String name, String countryCode,
String district, Integer population);
}
</pre><p>
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.
</p><pre class="programlisting">
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();
}
}
</pre><p>
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.
</p><pre class="programlisting">
<bean id="dao" class="code.Ex3DaoImpl">
<property name="dataSource" ref="dataSource"/>
<property name="updateQuery">...</property>
<property name="idQuery">...</property>
</bean>
</pre><p>
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 <code class="literal">dao</code> methods.
</p><pre class="programlisting">
<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>
</pre><p>
The preceding code creates a transaction manager that handles
transactions for the data source provided to it. The
<code class="literal">txAdvice</code> 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.
</p><pre class="programlisting">
<aop:config>
<aop:pointcut id="daoMethods"
expression="execution(* code.Ex3Dao.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="daoMethods"/>
</aop:config>
</pre><p>
This basically says that all methods called on the
<code class="literal">Ex3Dao</code> interface will be wrapped in a
transaction. To make use of this, you only have to retrieve the
<code class="literal">dao</code> from the application context and call a
method on the <code class="literal">dao</code> instance.
</p><pre class="programlisting">
Ex3Dao dao = (Ex3Dao) ctx.getBean("dao");
Integer id = dao.createCity(name, countryCode, district, pop);
</pre><p>
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.
</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="connector-j-usagenotes-spring-config-connpooling"></a>12.3 Connection Pooling with Spring</h2></div></div></div><a class="indexterm" name="idm139688233443840"></a><p>
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
<code class="literal">TIME_WAIT</code> state.
</p><p>
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
<a class="ulink" href="http://jakarta.apache.org/commons/dbcp/" target="_top">Jakarta
Commons DBCP library</a>. The example below replaces the
source configuration that was based on
<code class="literal">DriverManagerDataSource</code> with DBCP's
BasicDataSource.
</p><pre class="programlisting">
<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>
</pre><p>
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
<code class="literal">initialSize</code>. This tells DBCP that we want
three connections in the pool when it is created.
</p><p>
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 <code class="filename">mysql-local-ds.xml</code> 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.
</p><pre class="programlisting">
<jee:jndi-lookup id="dataSource" jndi-name="java:MySQL_DS"/>
</pre></div></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="connector-j-usagenotes-glassfish-config"></a>Chapter 13 Using Connector/J with GlassFish</h1></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl class="toc"><dt><span class="section"><a href="#connector-j-usagenotes-glassfish-config-jsp">13.1 A Simple JSP Application with GlassFish, Connector/J and MySQL</a></span></dt><dt><span class="section"><a href="#connector-j-usagenotes-glassfish-config-servlet">13.2 A Simple Servlet with GlassFish, Connector/J and MySQL</a></span></dt></dl></div><a class="indexterm" name="idm139688233432432"></a><a class="indexterm" name="idm139688233431344"></a><p>
This section explains how to use MySQL Connector/J with GlassFish ™
Server Open Source Edition 3.0.1. GlassFish can be downloaded from
the
<a class="ulink" href="https://glassfish.dev.java.net/public/downloadsindex.html#top" target="_top">GlassFish
website</a>.
</p><p>
Once GlassFish is installed, make sure it can access MySQL Connector/J. To do
this, copy the MySQL Connector/J <code class="filename">jar</code> file to the
<code class="filename"><em class="replaceable"><code>domain-dir</code></em>/lib</code>
directory. For example, copy
<code class="filename">mysql-connector-java-5.1.30-bin.jar</code> to
<code class="filename">C:\<em class="replaceable"><code>glassfish-install-path</code></em>\domains\<em class="replaceable"><code>domain-name</code></em>\lib</code>.
Restart the GlassFish Application Server. For more information,
see <span class="quote">“<span class="quote">Integrating the JDBC Driver</span>”</span> in
<em class="citetitle">GlassFish Server Open Source Edition Administration
Guide</em>, available at
<a class="ulink" href="https://glassfish.java.net/documentation.html" target="_top">GlassFish
Server Documentation</a>.
</p><p>
You are now ready to create JDBC Connection Pools and JDBC
Resources.
</p><p>
<span class="bold"><strong>Creating a Connection Pool</strong></span>
</p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>
In the GlassFish Administration Console, using the navigation
tree navigate to <span class="guilabel">Resources</span>,
<span class="guilabel">JDBC</span>, <span class="guilabel">Connection
Pools</span>.
</p></li><li class="listitem"><p>
In the <span class="guilabel">JDBC Connection Pools</span> frame click
<span class="guibutton">New</span>. You will enter a two step wizard.
</p></li><li class="listitem"><p>
In the <span class="guilabel">Name</span> field under <span class="guilabel">General
Settings</span> enter the name for the connection pool,
for example enter <strong class="userinput"><code>MySQLConnPool</code></strong>.
</p></li><li class="listitem"><p>
In the <span class="guilabel">Resource Type</span> field, select
<code class="literal">javax.sql.DataSource</code> from the drop-down
listbox.
</p></li><li class="listitem"><p>
In the <span class="guilabel">Database Vendor</span> field, select
<code class="literal">MySQL</code> from the drop-down listbox. Click
<span class="guibutton">Next</span> to go to the next page of the
wizard.
</p></li><li class="listitem"><p>
You can accept the default settings for General Settings, Pool
Settings and Transactions for this example. Scroll down to
Additional Properties.
</p></li><li class="listitem"><p>
In Additional Properties you will need to ensure the following
properties are set:
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
<span class="bold"><strong>ServerName</strong></span> - The server
to connect to. For local testing this will be
<code class="literal">localhost</code>.
</p></li><li class="listitem"><p>
<span class="bold"><strong>User</strong></span> - The user name with
which to connect to MySQL.
</p></li><li class="listitem"><p>
<span class="bold"><strong>Password</strong></span> - The
corresponding password for the user.
</p></li><li class="listitem"><p>
<span class="bold"><strong>DatabaseName</strong></span> - The
database to connect to, for example the sample MySQL
database <code class="literal">World</code>.
</p></li></ul></div></li><li class="listitem"><p>
Click <span class="guibutton">Finish</span> to exit the wizard. You
will be taken to the <span class="guilabel">JDBC Connection
Pools</span> page where all current connection pools,
including the one you just created, will be displayed.
</p></li><li class="listitem"><p>
In the <span class="guilabel">JDBC Connection Pools</span> 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 <span class="guilabel">Advanced</span> tab, and under Connection
Validation, configure the following settings:
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
<span class="bold"><strong>Connection Validation</strong></span> -
select <span class="guilabel">Required</span>.
</p></li><li class="listitem"><p>
<span class="bold"><strong>Validation Method</strong></span> -
select <span class="guilabel">table</span> from the drop-down
menu.
</p></li><li class="listitem"><p>
<span class="bold"><strong>Table Name</strong></span> - enter
<code class="literal">DUAL</code>.
</p></li></ul></div><p>
</p></li><li class="listitem"><p>
To test your connection pool click the
<span class="guibutton">Ping</span> 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.
</p></li></ol></div><p>
Now that you have created a connection pool you will also need to
create a JDBC Resource (data source) for use by your application.
</p><p>
<span class="bold"><strong>Creating a JDBC Resource</strong></span>
</p><p>
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.
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
Using the navigation tree in the GlassFish Administration
Console, navigate to <span class="guilabel">Resources</span>,
<span class="guilabel">JDBC</span>, <span class="guilabel">JDBC
Resources</span>. A list of resources will be displayed in
the <span class="guilabel">JDBC Resources</span> frame.
</p></li><li class="listitem"><p>
Click <span class="guibutton">New</span>. The <span class="guilabel">New JDBC
Resource</span> frame will be displayed.
</p></li><li class="listitem"><p>
In the <span class="guilabel">JNDI Name</span> field, enter the JNDI
name that will be used to access this resource, for example
enter <strong class="userinput"><code>jdbc/MySQLDataSource</code></strong>.
</p></li><li class="listitem"><p>
In the <span class="guilabel">Pool Name</span> field, select a
connection pool you want this resource to use from the
drop-down listbox.
</p></li><li class="listitem"><p>
Optionally, you can enter a description into the
<span class="guilabel">Description</span> field.
</p></li><li class="listitem"><p>
Additional properties can be added if required.
</p></li><li class="listitem"><p>
Click <span class="guibutton">OK</span> to create the new JDBC
resource. The <span class="guilabel">JDBC Resources</span> frame will
list all available JDBC Resources.
</p></li></ul></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="connector-j-usagenotes-glassfish-config-jsp"></a>13.1 A Simple JSP Application with GlassFish, Connector/J and MySQL</h2></div></div></div><p>
This section shows how to deploy a simple JSP application on
GlassFish, that connects to a MySQL database.
</p><p>
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 <code class="literal">world</code>.
</p><p>
The main application code, <code class="filename">index.jsp</code> is
presented here:
</p><pre class="programlisting">
<%@ 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>
</pre><p>
In addition two XML files are required:
<code class="filename">web.xml</code>, and
<code class="filename">sun-web.xml</code>. There may be other files
present, such as classes and images. These files are organized
into the directory structure as follows:
</p><pre class="programlisting">
index.jsp
WEB-INF
|
- web.xml
- sun-web.xml
</pre><p>
The code for <code class="filename">web.xml</code> is:
</p><pre class="programlisting">
<?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>
</pre><p>
The code for <code class="filename">sun-web.xml</code> is:
</p><pre class="programlisting">
<?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>
</pre><p>
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 <code class="literal">jdbc/MySQLDataSource</code>. This must
be mapped to the name given in the application. In this example
the name specified in the application,
<code class="literal">jdbc/MySQLDataSource</code>, 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
<code class="filename">sun-web.xml</code>. The resource also has to be
created in the <code class="filename">web.xml</code> file, although the
mapping of the resource to a JNDI name takes place in the
<code class="filename">sun-web.xml</code> file.
</p><p>
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:
</p><pre class="programlisting">
ds = (DataSource) ctx.lookup("java:comp/env/jdbc/MySQLDataSource");
</pre><p>
You will still be able to access the data source directly using:
</p><pre class="programlisting">
ds = (DataSource) ctx.lookup("jdbc/MySQLDataSource");
</pre><p>
With the source files in place, in the correct directory
structure, you are ready to deploy the application:
</p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>
In the navigation tree, navigate to
<span class="guilabel">Applications</span> - the
<span class="guilabel">Applications</span> frame will be displayed.
Click <span class="guibutton">Deploy</span>.
</p></li><li class="listitem"><p>
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.
</p></li><li class="listitem"><p>
Now select the application type from the
<span class="guilabel">Type</span> drop-down listbox, which in this
example is <code class="literal">Web application</code>.
</p></li><li class="listitem"><p>
Click OK.
</p></li></ol></div><p>
Now, when you navigate to the <span class="guilabel">Applications</span>
frame, you will have the option to <span class="guilabel">Launch</span>,
<span class="guilabel">Redeploy</span>, or <span class="guilabel">Restart</span>
your application. You can test your application by clicking
<span class="guilabel">Launch</span>. The application will connection to
the MySQL database and display the Name and Population of
countries in the <code class="literal">Country</code> table.
</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="connector-j-usagenotes-glassfish-config-servlet"></a>13.2 A Simple Servlet with GlassFish, Connector/J and MySQL</h2></div></div></div><a class="indexterm" name="idm139688233327024"></a><p>
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
<code class="literal">world</code> is installed.
</p><p>
The project is set up with the following directory structure:
</p><pre class="programlisting">
index.html
WEB-INF
|
- web.xml
- sun-web.xml
- classes
|
- HelloWebServlet.java
- HelloWebServlet.class
</pre><p>
The code for the servlet, located in
<code class="filename">HelloWebServlet.java</code>, is as follows:
</p><pre class="programlisting">
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();
}
}
}
</pre><p>
In the preceding code a basic <code class="literal">doGet()</code> 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,
<a class="xref" href="#connector-j-usagenotes-glassfish-config-jsp" title="13.1 A Simple JSP Application with GlassFish, Connector/J and MySQL">Section 13.1, “A Simple JSP Application with GlassFish, Connector/J and MySQL”</a>,
and is most conveniently located in the servlet
<code class="literal">init()</code> method. The corresponding freeing of
resources is located in the destroy method. The main
functionality of the servlet is located in the
<code class="literal">doPost()</code> 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 <code class="filename">index.html</code>:
</p><pre class="programlisting">
<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>
</pre><p>
The XML files <code class="filename">web.xml</code> and
<code class="filename">sun-web.xml</code> are as for the example in the
preceding section,
<a class="xref" href="#connector-j-usagenotes-glassfish-config-jsp" title="13.1 A Simple JSP Application with GlassFish, Connector/J and MySQL">Section 13.1, “A Simple JSP Application with GlassFish, Connector/J and MySQL”</a>,
no additional changes are required.
</p><p>
When compiling the Java source code, you will need to specify
the path to the file <code class="filename">javaee.jar</code>. On
Windows, this can be done as follows:
</p><pre class="programlisting">
shell> javac -classpath c:\glassfishv3\glassfish\lib\javaee.jar HelloWebServlet.java
</pre><p>
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,
<a class="xref" href="#connector-j-usagenotes-glassfish-config-jsp" title="13.1 A Simple JSP Application with GlassFish, Connector/J and MySQL">Section 13.1, “A Simple JSP Application with GlassFish, Connector/J and MySQL”</a>.
</p><p>
Once deployed the application can be launched from within the
GlassFish Administration Console. Enter a country name such as
<span class="quote">“<span class="quote">England</span>”</span>, and the application will return
<span class="quote">“<span class="quote">Country does not exist!</span>”</span>. Enter
<span class="quote">“<span class="quote">France</span>”</span>, and the application will return a
population of 59225700.
</p></div></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="connector-j-usagenotes-fabric"></a>Chapter 14 Using Connector/J with MySQL Fabric</h1></div></div></div><a class="indexterm" name="idm139688233302672"></a><p>
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.
</p><p>
For more information on MySQL Fabric, see
<a class="ulink" href="http://dev.mysql.com/doc/mysql-utilities/1.5/en/fabric.html" target="_top">MySQL Fabric</a>. For instructions on how to use
Connector/J with MySQL Fabric, see
<a class="ulink" href="http://dev.mysql.com/doc/mysql-utilities/1.5/en/connector-j-fabric.html" target="_top">Using Connector/J with MySQL Fabric</a>.
</p></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="connector-j-usagenotes-troubleshooting"></a>Chapter 15 Troubleshooting Connector/J Applications</h1></div></div></div><a class="indexterm" name="idm139688233297504"></a><a class="indexterm" name="idm139688233296016"></a><a class="indexterm" name="idm139688233294528"></a><p>
This section explains the symptoms and resolutions for the most
commonly encountered issues with applications using MySQL
Connector/J.
</p><p><span class="bold"><strong>Questions</strong></span></p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p><a class="link" href="#qandaitem-15-1-1">15.1: </a>
When I try to connect to the database with MySQL
Connector/J, I get the following exception:
</p><pre class="programlisting">
SQLException: Server configuration denies access to data source
SQLState: 08001
VendorError: 0
</pre><p>
What is going on? I can connect just fine with the MySQL
command-line client.
</p></li><li class="listitem"><p><a class="link" href="#qandaitem-15-1-2">15.2: </a>
My application throws an SQLException 'No Suitable Driver'.
Why is this happening?
</p></li><li class="listitem"><p><a class="link" href="#qandaitem-15-1-3">15.3: </a>
I'm trying to use MySQL Connector/J in an applet or
application and I get an exception similar to:
</p><pre class="programlisting">
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
</pre></li><li class="listitem"><p><a class="link" href="#qandaitem-15-1-4">15.4: </a>
I have a servlet/application that works fine for a day, and
then stops working overnight
</p></li><li class="listitem"><p><a class="link" href="#qandaitem-15-1-5">15.5: </a>
I'm trying to use JDBC 2.0 updatable result sets, and I get
an exception saying my result set is not updatable.
</p></li><li class="listitem"><p><a class="link" href="#qandaitem-15-1-6">15.6: </a>
I cannot connect to the MySQL server using Connector/J, and
I'm sure the connection parameters are correct.
</p></li><li class="listitem"><p><a class="link" href="#qandaitem-15-1-7">15.7: </a>
I am trying to connect to my MySQL server within my
application, but I get the following error and stack trace:
</p><pre class="programlisting">
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)
</pre></li><li class="listitem"><p><a class="link" href="#qandaitem-15-1-8">15.8: </a>
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.
</p></li><li class="listitem"><p><a class="link" href="#qandaitem-15-1-9">15.9: </a>
When using <span class="command"><strong>gcj</strong></span>, a
<code class="literal">java.io.CharConversionException</code> exception
is raised when working with certain character sequences.
</p></li><li class="listitem"><p><a class="link" href="#qandaitem-15-1-10">15.10: </a>
Updating a table that contains a
<a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/glossary.html#glos_primary_key" target="_top">primary key</a> that is
either <a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/floating-point-types.html" target="_top"><code class="literal">FLOAT</code></a> or compound
primary key that uses <a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/floating-point-types.html" target="_top"><code class="literal">FLOAT</code></a>
fails to update the table and raises an exception.
</p></li><li class="listitem"><p><a class="link" href="#qandaitem-15-1-11">15.11: </a>
You get an
<a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/error-messages-server.html#error_er_net_packet_too_large" target="_top"><code class="literal">ER_NET_PACKET_TOO_LARGE</code></a>
exception, even though the binary blob size you want to
insert using JDBC is safely below the
<a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_max_allowed_packet" target="_top"><code class="literal">max_allowed_packet</code></a> size.
</p></li><li class="listitem"><p><a class="link" href="#qandaitem-15-1-12">15.12: </a>
What should you do if you receive error messages similar to
the following: <span class="quote">“<span class="quote">Communications link failure – Last
packet sent to the server was X ms ago</span>”</span>?
</p></li><li class="listitem"><p><a class="link" href="#qandaitem-15-1-13">15.13: </a>
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
<code class="literal">autoReconnect</code> connection string option?
</p></li><li class="listitem"><p><a class="link" href="#qandaitem-15-1-14">15.14: </a>
How can I use 3-byte UTF8 with Connector/J?
</p></li><li class="listitem"><p><a class="link" href="#qandaitem-15-1-15">15.15: </a>
How can I use 4-byte UTF8, <code class="literal">utf8mb4</code> with
Connector/J?
</p></li><li class="listitem"><p><a class="link" href="#qandaitem-15-1-16">15.16: </a>
Using <code class="literal">useServerPrepStmts=false</code> and
certain character encodings can lead to corruption when
inserting BLOBs. How can this be avoided?
</p></li></ul></div><p><span class="bold"><strong>Questions and Answers</strong></span></p><p><a name="qandaitem-15-1-1"></a><span class="bold"><strong>15.1: </strong></span><span class="bold"><strong>
When I try to connect to the database with MySQL
Connector/J, I get the following exception:
</strong></span></p><pre class="programlisting">
SQLException: Server configuration denies access to data source
SQLState: 08001
VendorError: 0
</pre><p><span class="bold"><strong>
What is going on? I can connect just fine with the MySQL
command-line client.
</strong></span></p><p>
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.
</p><p>
You must add the necessary security credentials to the MySQL
server for this to happen, using the
<a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/grant.html" target="_top"><code class="literal">GRANT</code></a> statement to your MySQL
Server. See <a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/grant.html" target="_top">GRANT Syntax</a>, for more information.
</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><div class="admon-title">Note</div><p>
Testing your connectivity with the
<span class="command"><strong>mysql</strong></span> command-line client will not work
unless you add the "host" flag, and use something other
than <code class="literal">localhost</code> for the host. The
<span class="command"><strong>mysql</strong></span> command-line client will use Unix
domain sockets if you use the special host name
<code class="literal">localhost</code>. If you are testing
connectivity to <code class="literal">localhost</code>, use
<code class="literal">127.0.0.1</code> as the host name instead.
</p></div><div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;"><div class="admon-title">Warning</div><p>
Changing privileges and permissions improperly in MySQL
can potentially cause your server installation to not have
optimal security properties.
</p></div><p><a name="qandaitem-15-1-2"></a><span class="bold"><strong>15.2: </strong></span><span class="bold"><strong>
My application throws an SQLException 'No Suitable Driver'.
Why is this happening?
</strong></span></p><p>
There are three possible causes for this error:
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
The Connector/J driver is not in your
<code class="literal">CLASSPATH</code>, see
<a class="xref" href="#connector-j-installing" title="Chapter 3 Connector/J Installation">Chapter 3, <i>Connector/J Installation</i></a>.
</p></li><li class="listitem"><p>
The format of your connection URL is incorrect, or you
are referencing the wrong JDBC driver.
</p></li><li class="listitem"><p>
When using DriverManager, the
<code class="literal">jdbc.drivers</code> system property has not
been populated with the location of the Connector/J
driver.
</p></li></ul></div><p><a name="qandaitem-15-1-3"></a><span class="bold"><strong>15.3: </strong></span><span class="bold"><strong>
I'm trying to use MySQL Connector/J in an applet or
application and I get an exception similar to:
</strong></span></p><pre class="programlisting">
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
</pre><p>
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.
</p><p>
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.
</p><p>
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.
</p><p>
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
<code class="filename">/etc/mysql/my.cnf</code> or
<code class="filename">/etc/my.cnf</code>. Of course your
<code class="filename">my.cnf</code> file might also exist in the
<code class="filename">data</code> directory of your MySQL server, or
anywhere else (depending on how MySQL was compiled for your
system). Binaries created by us always look in
<code class="filename">/etc/my.cnf</code> and
<code class="filename"><em class="replaceable"><code>datadir</code></em>/my.cnf</code>.
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).
</p><p><a name="qandaitem-15-1-4"></a><span class="bold"><strong>15.4: </strong></span><span class="bold"><strong>
I have a servlet/application that works fine for a day, and
then stops working overnight
</strong></span></p><p>
MySQL closes connections after 8 hours of inactivity. You
either need to use a connection pool that handles stale
connections or use the <code class="option">autoReconnect</code>
parameter (see
<a class="xref" href="#connector-j-reference-configuration-properties" title="5.1 Driver/Datasource Class Names, URL Syntax and Configuration Properties for Connector/J">Section 5.1, “Driver/Datasource Class Names, URL Syntax and Configuration Properties
for Connector/J”</a>).
</p><p>
Also, catch <code class="literal">SQLExceptions</code> 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
<code class="literal">SQLState</code> (see
<code class="literal">java.sql.SQLException.getSQLState()</code> in
your API docs) to <code class="literal">08S01</code> when it
encounters network-connectivity issues during the processing
of a query. Attempt to reconnect to MySQL at this point.
</p><p>
The following (simplistic) example shows what code that can
handle these exceptions might look like:
</p><p>
</p><div class="example"><a name="connector-j-examples-transaction-retry"></a><p class="title"><b>Example 15.1 Connector/J: Example of transaction with retry logic</b></p><div class="example-contents"><pre class="programlisting">
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));
}
</pre></div></div><p><br class="example-break">
</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><div class="admon-title">Note</div><p>
Use of the <code class="option">autoReconnect</code> 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
<code class="option">autoReconnect</code> facility is deprecated, and
may be removed in a future release.
</p></div><p><a name="qandaitem-15-1-5"></a><span class="bold"><strong>15.5: </strong></span><span class="bold"><strong>
I'm trying to use JDBC 2.0 updatable result sets, and I get
an exception saying my result set is not updatable.
</strong></span></p><p>
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
<a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/glossary.html#glos_primary_key" target="_top">primary key</a>, 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.
</p><p>
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
<a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/update.html" target="_top"><code class="literal">UPDATE</code></a> or
<a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/delete.html" target="_top"><code class="literal">DELETE</code></a> statements on a table
where you can individually specify the criteria to be
matched using a <code class="literal">WHERE</code> clause.
</p><p><a name="qandaitem-15-1-6"></a><span class="bold"><strong>15.6: </strong></span><span class="bold"><strong>
I cannot connect to the MySQL server using Connector/J, and
I'm sure the connection parameters are correct.
</strong></span></p><p>
Make sure that the
<a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/server-options.html#option_mysqld_skip-networking" target="_top"><code class="option">skip-networking</code></a> 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
<a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/can-not-connect-to-server.html" target="_top">Can't connect to [local] MySQL server</a>.
</p><p><a name="qandaitem-15-1-7"></a><span class="bold"><strong>15.7: </strong></span><span class="bold"><strong>
I am trying to connect to my MySQL server within my
application, but I get the following error and stack trace:
</strong></span></p><pre class="programlisting">
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)
</pre><p>
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.
</p><p>
It is likely that the older version of the Connector/J
driver exists within your application directory or your
<code class="literal">CLASSPATH</code> includes the older Connector/J
package.
</p><p><a name="qandaitem-15-1-8"></a><span class="bold"><strong>15.8: </strong></span><span class="bold"><strong>
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.
</strong></span></p><p>
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.
</p><p>
You can increase the timeout value by setting the
<code class="literal">TransactionTimeout</code> attribute to the
<code class="literal">TransactionManagerService</code> within the
<code class="filename">/conf/jboss-service.xml</code> file
(pre-4.0.3) or <code class="filename">/deploy/jta-service.xml</code>
for JBoss 4.0.3 or later. See
<a class="ulink" href="http://wiki.jboss.org/wiki/Wiki.jsp?page=TransactionTimeout" target="_top">TransactionTimeout</a>
within the JBoss wiki for more information.
</p><p><a name="qandaitem-15-1-9"></a><span class="bold"><strong>15.9: </strong></span><span class="bold"><strong>
When using <span class="command"><strong>gcj</strong></span>, a
<code class="literal">java.io.CharConversionException</code> exception
is raised when working with certain character sequences.
</strong></span></p><p>
This is a known issue with <span class="command"><strong>gcj</strong></span> which
raises an exception when it reaches an unknown character or
one it cannot convert. Add
<code class="literal">useJvmCharsetConverters=true</code> to your
connection string to force character conversion outside of
the <span class="command"><strong>gcj</strong></span> libraries, or try a different
JDK.
</p><p><a name="qandaitem-15-1-10"></a><span class="bold"><strong>15.10: </strong></span><span class="bold"><strong>
Updating a table that contains a
<a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/glossary.html#glos_primary_key" target="_top">primary key</a> that is
either <a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/floating-point-types.html" target="_top"><code class="literal">FLOAT</code></a> or compound
primary key that uses <a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/floating-point-types.html" target="_top"><code class="literal">FLOAT</code></a>
fails to update the table and raises an exception.
</strong></span></p><p>
Connector/J adds conditions to the <code class="literal">WHERE</code>
clause during an <a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/update.html" target="_top"><code class="literal">UPDATE</code></a> 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.
</p><p>
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.
</p><p>
To prevent this issue, use a primary key that does not use
<a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/floating-point-types.html" target="_top"><code class="literal">FLOAT</code></a>. If you have to use a
floating point column in your primary key, use
<a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/floating-point-types.html" target="_top"><code class="literal">DOUBLE</code></a> or
<a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/fixed-point-types.html" target="_top"><code class="literal">DECIMAL</code></a> types in place of
<a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/floating-point-types.html" target="_top"><code class="literal">FLOAT</code></a>.
</p><p><a name="qandaitem-15-1-11"></a><span class="bold"><strong>15.11: </strong></span><span class="bold"><strong>
You get an
<a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/error-messages-server.html#error_er_net_packet_too_large" target="_top"><code class="literal">ER_NET_PACKET_TOO_LARGE</code></a>
exception, even though the binary blob size you want to
insert using JDBC is safely below the
<a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_max_allowed_packet" target="_top"><code class="literal">max_allowed_packet</code></a> size.
</strong></span></p><p>
This is because the <code class="literal">hexEscapeBlock()</code>
method in
<code class="literal">com.mysql.jdbc.PreparedStatement.streamToBytes()</code>
may almost double the size of your data.
</p><p><a name="qandaitem-15-1-12"></a><span class="bold"><strong>15.12: </strong></span><span class="bold"><strong>
What should you do if you receive error messages similar to
the following: <span class="quote">“<span class="quote">Communications link failure – Last
packet sent to the server was X ms ago</span>”</span>?
</strong></span></p><p>
Generally speaking, this error suggests that the network
connection has been closed. There can be several root
causes:
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
Firewalls or routers may clamp down on idle connections
(the MySQL client/server protocol does not ping).
</p></li><li class="listitem"><p>
The MySQL Server may be closing idle connections that
exceed the <code class="literal">wait_timeout</code> or
<code class="literal">interactive_timeout</code> threshold.
</p></li></ul></div><p>
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.
</p><p>
Further, if the time a packet was last sent/received exceeds
the <code class="literal">wait_timeout</code> or
<code class="literal">interactive_timeout</code> threshold, this is
noted in the exception message.
</p><p>
Although network connections can be volatile, the following
can be helpful in avoiding problems:
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
Ensure connections are valid when used from the
connection pool. Use a query that starts with
<code class="literal">/* ping */</code> to execute a lightweight
ping instead of full query. Note, the syntax of the ping
needs to be exactly as specified here.
</p></li><li class="listitem"><p>
Minimize the duration a connection object is left idle
while other application logic is executed.
</p></li><li class="listitem"><p>
Explicitly validate the connection before using it if
the connection has been left idle for an extended period
of time.
</p></li><li class="listitem"><p>
Ensure that <code class="literal">wait_timeout</code> and
<code class="literal">interactive_timeout</code> are set
sufficiently high.
</p></li><li class="listitem"><p>
Ensure that <code class="literal">tcpKeepalive</code> is enabled.
</p></li><li class="listitem"><p>
Ensure that any configurable firewall or router timeout
settings allow for the maximum expected connection idle
time.
</p></li></ul></div><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><div class="admon-title">Note</div><p>
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.
</p></div><p><a name="qandaitem-15-1-13"></a><span class="bold"><strong>15.13: </strong></span><span class="bold"><strong>
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
<code class="literal">autoReconnect</code> connection string option?
</strong></span></p><p>
There are several reasons for this. The first is
transactional integrity. The MySQL Reference Manual states
that <span class="quote">“<span class="quote">there is no safe method of reconnecting to the
MySQL server without risking some corruption of the
connection state or database state information</span>”</span>.
Consider the following series of statements for example:
</p><pre class="programlisting">
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();
</pre><p>
Consider the case where the connection to the server fails
after the <code class="literal">UPDATE</code> to
<code class="literal">checking_account</code>. 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
<code class="literal">savings_account</code> 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.
</p><p>
Note that running with <code class="literal">autocommit</code> 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:
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
The server never received the statement, and therefore
no related processing occurred on the server.
</p></li><li class="listitem"><p>
The server received the statement, executed it in full,
but the response was not received by the client.
</p></li></ul></div><p>
If you are running with <code class="literal">autocommit</code>
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
<code class="literal">autocommit</code> statements though. If the
communication problem occurred during
<code class="literal">Connection.commit()</code>, 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.
</p><p>
The second reason for the generation of exceptions is that
transaction-scoped contextual data may be vulnerable, for
example:
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
Temporary tables.
</p></li><li class="listitem"><p>
User-defined variables.
</p></li><li class="listitem"><p>
Server-side prepared statements.
</p></li></ul></div><p>
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.
</p><p>
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.
</p><p><a name="qandaitem-15-1-14"></a><span class="bold"><strong>15.14: </strong></span><span class="bold"><strong>
How can I use 3-byte UTF8 with Connector/J?
</strong></span></p><p>
To use 3-byte UTF8 with Connector/J set
<code class="literal">characterEncoding=utf8</code> and set
<code class="literal">useUnicode=true</code> in the connection string.
</p><p><a name="qandaitem-15-1-15"></a><span class="bold"><strong>15.15: </strong></span><span class="bold"><strong>
How can I use 4-byte UTF8, <code class="literal">utf8mb4</code> with
Connector/J?
</strong></span></p><p>
To use 4-byte UTF8 with Connector/J configure the MySQL
server with <code class="literal">character_set_server=utf8mb4</code>.
Connector/J will then use that setting as long as
<code class="literal">characterEncoding</code> has not been set in the
connection string. This is equivalent to autodetection of
the character set.
</p><p><a name="qandaitem-15-1-16"></a><span class="bold"><strong>15.16: </strong></span><span class="bold"><strong>
Using <code class="literal">useServerPrepStmts=false</code> and
certain character encodings can lead to corruption when
inserting BLOBs. How can this be avoided?
</strong></span></p><p>
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:
</p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>
Set the connection string option
<code class="literal">useServerPrepStmts</code> to
<code class="literal">true</code>.
</p></li><li class="listitem"><p>
Set <code class="literal">SQL_MODE</code> to
<code class="literal">NO_BACKSLASH_ESCAPES</code>.
</p></li></ol></div></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="connector-j-usagenotes-known-issues-limitations"></a>Chapter 16 Known Issues and Limitations</h1></div></div></div><a class="indexterm" name="idm139688233096400"></a><a class="indexterm" name="idm139688233094912"></a><a class="indexterm" name="idm139688233093424"></a><a class="indexterm" name="idm139688233091936"></a><a class="indexterm" name="idm139688233090448"></a><p>
The following are some known issues and limitations for MySQL
Connector/J:
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
When Connector/J retrieves timestamps for a daylight saving
time (DST) switch day using the
<code class="function">getTimeStamp()</code> 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:
</p><pre class="programlisting">
useTimezone=true
useLegacyDatetimeCode=false
serverTimezone=UTC
</pre><p>
</p></li></ul></div></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="connector-j-support"></a>Chapter 17 Connector/J Support</h1></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl class="toc"><dt><span class="section"><a href="#connector-j-support-community">17.1 Connector/J Community Support</a></span></dt><dt><span class="section"><a href="#connector-j-support-bug-report">17.2 How to Report Connector/J Bugs or Problems</a></span></dt></dl></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="connector-j-support-community"></a>17.1 Connector/J Community Support</h2></div></div></div><p>
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
<a class="ulink" href="http://lists.mysql.com/java" target="_top">http://lists.mysql.com/java</a>.
</p><p>
For information about subscribing to MySQL mailing lists or to
browse list archives, visit
<a class="ulink" href="http://lists.mysql.com/" target="_top">http://lists.mysql.com/</a>. See
<a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/mailing-lists.html" target="_top">MySQL Mailing Lists</a>.
</p><p>
Community support from experienced users is also available
through the <a class="ulink" href="http://forums.mysql.com/list.php?39" target="_top">JDBC
Forum</a>. You may also find help from other users in the
other MySQL Forums, located at
<a class="ulink" href="http://forums.mysql.com" target="_top">http://forums.mysql.com</a>. See
<a class="ulink" href="http://dev.mysql.com/doc/refman/5.7/en/forums.html" target="_top">MySQL Community Support at the MySQL Forums</a>.
</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="connector-j-support-bug-report"></a>17.2 How to Report Connector/J Bugs or Problems</h2></div></div></div><a class="indexterm" name="idm139688233076032"></a><p>
The normal place to report bugs is
<a class="ulink" href="http://bugs.mysql.com/" target="_top">http://bugs.mysql.com/</a>, 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.
</p><p>
If you find a sensitive security bug in MySQL Server, please let
us know immediately by sending an email message to
<code class="email"><<a class="email" href="mailto:secalert_us@oracle.com">secalert_us@oracle.com</a>></code>. Exception: Support
customers should report all problems, including security bugs,
to Oracle Support at <a class="ulink" href="http://support.oracle.com/" target="_top">http://support.oracle.com/</a>.
</p><p>
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.
</p><p>
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.
</p><p>
If you have a repeatable bug report, please report it to the
bugs database at <a class="ulink" href="http://bugs.mysql.com/" target="_top">http://bugs.mysql.com/</a>. Any bug
that we are able to repeat has a high chance of being fixed in
the next MySQL release.
</p><p>
To report other problems, you can use one of the MySQL mailing
lists.
</p><p>
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.
</p><p>
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.
</p><p>
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).
</p><p>
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, <span class="quote">“<span class="quote">Why doesn't this work for me?</span>”</span>
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.
</p><p>
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.
</p><p>
If at all possible, create a repeatable, standalone testcase
that doesn't involve any third-party classes.
</p><p>
To streamline this process, we ship a base class for testcases
with Connector/J, named
'<code class="classname">com.mysql.jdbc.util.BaseBugReport</code>'. To
create a testcase for Connector/J using this class, create your
own class that inherits from
<code class="classname">com.mysql.jdbc.util.BaseBugReport</code> and
override the methods <code class="function">setUp()</code>,
<code class="function">tearDown()</code> and
<code class="function">runTest()</code>.
</p><p>
In the <code class="function">setUp()</code> method, create code that
creates your tables, and populates them with any data needed to
demonstrate the bug.
</p><p>
In the <code class="function">runTest()</code> method, create code that
demonstrates the bug using the tables and data you created in
the <code class="literal">setUp</code> method.
</p><p>
In the <code class="function">tearDown()</code> method, drop any tables
you created in the <code class="function">setUp()</code> method.
</p><p>
In any of the above three methods, use one of the variants of
the <code class="function">getConnection()</code> method to create a JDBC
connection to MySQL:
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
<code class="function">getConnection()</code> - Provides a connection
to the JDBC URL specified in <code class="function">getUrl()</code>.
If a connection already exists, that connection is returned,
otherwise a new connection is created.
</p></li><li class="listitem"><p>
<code class="function">getNewConnection()</code> - Use this if you
need to get a new connection for your bug report (that is,
there is more than one connection involved).
</p></li><li class="listitem"><p>
<code class="function">getConnection(String url)</code> - Returns a
connection using the given URL.
</p></li><li class="listitem"><p>
<code class="function">getConnection(String url, Properties
props)</code> - Returns a connection using the given URL
and properties.
</p></li></ul></div><p>
If you need to use a JDBC URL that is different from
'jdbc:mysql:///test', override the method
<code class="function">getUrl()</code> as well.
</p><p>
Use the <code class="function">assertTrue(boolean expression)</code> and
<code class="function">assertTrue(String failureMessage, boolean
expression)</code> 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).
</p><p>
Finally, create a <code class="function">main()</code> method that
creates a new instance of your testcase, and calls the
<code class="literal">run</code> method:
</p><pre class="programlisting">
public static void main(String[] args) throws Exception {
new MyBugReport().run();
}
</pre><p>
Once you have finished your testcase, and have verified that it
demonstrates the bug you are reporting, upload it with your bug
report to <a class="ulink" href="http://bugs.mysql.com/" target="_top">http://bugs.mysql.com/</a>.
</p></div></div><div class="appendix"><div class="titlepage"><div><div><h1 class="title"><a name="connector-j-third-party-licenses"></a>Appendix A Licenses for Third-Party Components</h1></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl class="toc"><dt><span class="section"><a href="#license-ant-contrib">A.1 Ant-Contrib License</a></span></dt><dt><span class="section"><a href="#license-c3p0-0-91">A.2 c3p0 JDBC Library License</a></span></dt><dt><span class="section"><a href="#license-gnu-lgpl-2-1">A.3 GNU Lesser General Public License Version 2.1, February 1999</a></span></dt><dt><span class="section"><a href="#license-jboss-common-jdbc-wrapper">A.4 jboss-common-jdbc-wrapper.jar License</a></span></dt><dt><span class="section"><a href="#license-nanoxml">A.5 NanoXML License</a></span></dt><dt><span class="section"><a href="#license-rox-jar">A.6 rox.jar License</a></span></dt><dt><span class="section"><a href="#license-slf4j">A.7 Simple Logging Facade for Java (SLF4J) License</a></span></dt><dt><span class="section"><a href="#license-unicode-data-files">A.8 Unicode Data Files</a></span></dt></dl></div><h2><a name="idm139688233038048"></a>MySQL Connector/J 5.1</h2><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p><a class="xref" href="#license-ant-contrib" title="A.1 Ant-Contrib License">Section A.1, “Ant-Contrib License”</a></p></li><li class="listitem"><p><a class="xref" href="#license-c3p0-0-91" title="A.2 c3p0 JDBC Library License">Section A.2, “c3p0 JDBC Library License”</a></p></li><li class="listitem"><p><a class="xref" href="#license-gnu-lgpl-2-1" title="A.3 GNU Lesser General Public License Version 2.1, February 1999">Section A.3, “GNU Lesser General Public License Version 2.1, February 1999”</a></p></li><li class="listitem"><p><a class="xref" href="#license-jboss-common-jdbc-wrapper" title="A.4 jboss-common-jdbc-wrapper.jar License">Section A.4, “jboss-common-jdbc-wrapper.jar License”</a></p></li><li class="listitem"><p><a class="xref" href="#license-nanoxml" title="A.5 NanoXML License">Section A.5, “NanoXML License”</a></p></li><li class="listitem"><p><a class="xref" href="#license-rox-jar" title="A.6 rox.jar License">Section A.6, “rox.jar License”</a></p></li><li class="listitem"><p><a class="xref" href="#license-slf4j" title="A.7 Simple Logging Facade for Java (SLF4J) License">Section A.7, “Simple Logging Facade for Java (SLF4J) License”</a></p></li><li class="listitem"><p><a class="xref" href="#license-unicode-data-files" title="A.8 Unicode Data Files">Section A.8, “Unicode Data Files”</a></p></li></ul></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="license-ant-contrib"></a>A.1 Ant-Contrib License</h2></div></div></div><p>
The following software may be included in this product up to version
5.1.26: Ant-Contrib
</p><pre class="programlisting">
Ant-Contrib
Copyright (c) 2001-2003 Ant-Contrib project. All rights reserved.
Licensed under the Apache 1.1 License Agreement, a copy of which is reproduced below.
The Apache Software License, Version 1.1
Copyright (c) 2001-2003 Ant-Contrib project. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The end-user documentation included with the redistribution, if
any, must include the following acknowlegement:
"This product includes software developed by the
Ant-Contrib project (http://sourceforge.net/projects/ant-contrib)."
Alternately, this acknowlegement may appear in the software itself,
if and wherever such third-party acknowlegements normally appear.
4. The name Ant-Contrib must not be used to endorse or promote
products derived from this software without prior written
permission. For written permission, please contact
ant-contrib-developers@lists.sourceforge.net.
5. Products derived from this software may not be called "Ant-Contrib"
nor may "Ant-Contrib" appear in their names without prior written
permission of the Ant-Contrib project.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE ANT-CONTRIB PROJECT OR ITS
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
</pre></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="license-c3p0-0-91"></a>A.2 c3p0 JDBC Library License</h2></div></div></div><p>
You are receiving a copy of <code class="filename">c3p0-0.9.1-pre6.jar</code>
in both source and object code in the following
<code class="filename">/src/lib/c3p0-0.9.1-pre6.jar</code>. The terms of the
Oracle license do NOT apply to
<code class="filename">c3p0-0.9.1-pre6.jar</code>; it is licensed under the
following license, separately from the Oracle programs you receive.
If you do not wish to install this library, you may remove the file
<code class="filename">/src/lib/c3p0-0.9.1-pre6.jar</code>, but the Oracle
program might not operate properly or at all without the library.
</p><p>
This component is licensed under
<a class="xref" href="#license-gnu-lgpl-2-1" title="A.3 GNU Lesser General Public License Version 2.1, February 1999">Section A.3, “GNU Lesser General Public License Version 2.1, February 1999”</a>.
</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="license-gnu-lgpl-2-1"></a>A.3 GNU Lesser General Public License Version 2.1, February 1999</h2></div></div></div><pre class="programlisting">
The following applies to all products licensed under the
GNU Lesser General Public License, Version 2.1: You may
not use the identified files except in compliance with
the GNU Lesser General Public License, Version 2.1 (the
"License"). You may obtain a copy of the License at
http://www.gnu.org/licenses/lgpl-2.1.html. A copy of the
license is also reproduced below. Unless required by
applicable law or agreed to in writing, software distributed
under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
or implied. See the License for the specific language governing
permissions and limitations under the License.
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it
becomes a de-facto standard. To achieve this, non-free programs
must be allowed to use the library. A more frequent case is that
a free library does the same job as widely used non-free libraries.
In this case, there is little to gain by limiting the free library
to free software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control
compilation and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended
to apply, and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms
of the ordinary General Public License).
To apply these terms, attach the following notices to the library.
It is safest to attach them to the start of each source file to most
effectively convey the exclusion of warranty; and each file should
have at least the "copyright" line and a pointer to where the full
notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James
Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!
</pre></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="license-jboss-common-jdbc-wrapper"></a>A.4 jboss-common-jdbc-wrapper.jar License</h2></div></div></div><p>
You are receiving a copy of
<code class="filename">jboss-common-jdbc-wrapper.jar</code> in both source
and object code in the following
<code class="filename">/src/lib/jboss-common-jdbc-wrapper.jar</code>. The
terms of the Oracle license do NOT apply to
<code class="filename">jboss-common-jdbc-wrapper.jar</code>; it is licensed
under the following license, separately from the Oracle programs you
receive. If you do not wish to install this library, you may remove
the file
<code class="filename">/src/lib/jboss-common-jdbc-wrapper.jar</code>, but the
Oracle program might not operate properly or at all without the
library.
</p><p>
This component is licensed under
<a class="xref" href="#license-gnu-lgpl-2-1" title="A.3 GNU Lesser General Public License Version 2.1, February 1999">Section A.3, “GNU Lesser General Public License Version 2.1, February 1999”</a>.
</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="license-nanoxml"></a>A.5 NanoXML License</h2></div></div></div><p>
The following software may be included in this product:
</p><p>
NanoXML
</p><pre class="programlisting">
* Copyright (C) 2000-2002 Marc De Scheemaecker, All Rights Reserved.
*
* This software is provided 'as-is', without any express or implied warranty.
* In no event will the authors be held liable for any damages arising from the
* use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software in
* a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source distribution.
*
</pre></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="license-rox-jar"></a>A.6 rox.jar License</h2></div></div></div><p>
The following software may be included in this product:
</p><p>
rox.jar
</p><pre class="programlisting">
Copyright (c) 2006, James Greenfield
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the <ORGANIZATION> nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
</pre></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="license-slf4j"></a>A.7 Simple Logging Facade for Java (SLF4J) License</h2></div></div></div><p>
The following software may be included in this product:
</p><pre class="programlisting">
Simple Logging Facade for Java (SLF4J)
Copyright (c) 2004-2008 QOS.ch
All rights reserved.
Permission is hereby granted, free of charge,
to any person obtaining a copy of this software
and associated documentation files (the "Software"),
to deal in the Software without restriction, including
without limitation the rights to use, copy, modify,
merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom
the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY
OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
OR OTHER DEALINGS IN THE SOFTWARE.
</pre></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="license-unicode-data-files"></a>A.8 Unicode Data Files</h2></div></div></div><p>
The following software may be included in this product:
</p><p>
Unicode Data Files
</p><pre class="programlisting">
COPYRIGHT AND PERMISSION NOTICE
Copyright © 1991-2014 Unicode, Inc. All rights reserved. Distributed under
the Terms of Use in http://www.unicode.org/copyright.html.
Permission is hereby granted, free of charge, to any person obtaining a copy
of the Unicode data files and any associated documentation (the "Data Files")
or Unicode software and any associated documentation (the "Software") to deal
in the Data Files or Software without restriction, including without
limitation the rights to use, copy, modify, merge, publish, distribute,
and/or sell copies of the Data Files or Software, and to permit persons to
whom the Data Files or Software are furnished to do so, provided that (a) the
above copyright notice(s) and this permission notice appear with all copies
of the Data Files or Software, (b) both the above copyright notice(s) and
this permission notice appear in associated documentation, and (c) there is
clear notice in each modified Data File or in the Software as well as in the
documentation associated with the Data File(s) or Software that the data or
software has been modified.
THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR
CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE
DATA FILES OR SOFTWARE.
Except as contained in this notice, the name of a copyright holder shall not
be used in advertising or otherwise to promote the sale, use or other
dealings in these Data Files or Software without prior written authorization
of the copyright holder.
</pre></div></div></div><div class="copyright-footer"></div></body></html>