MySQL Connector/C++
MySQL connector library for C and C++ applications
Connector/C++ 8 legacy C++ API based on JDBC4

Connector/C++ 8 supports the legacy C++ API based on the JDBC4 specification.

This allows an easy migration to Connector/C++ version 8.x for applications that use Connector/C++ version 1.1.

More detailed information about the legacy C++ API can be found in the MySQL Connector/C++ 1.1 Developer Guide of MySQL online manual.

Sample code which uses Connector/C++ with legacy C++ API

The following code demonstrates how to connect to MySQL Server using the legacy C++ API.

Note
The connection is established over the legacy protocol and therefore X Plugin is not needed and the server does not need to support X Protocol.

After the connection is established the code executes a simple SQL statement and reads the result from the server. The source file can be found in testapp/jdbc_test.cc in the source distribution of Connector/C++ 8. See Using Connector/C++ 8 for instructions on how to build the sample code.

Each program which uses the legacy C++ API has to include this header:

#include <mysql/jdbc.h>

Define the credentials for connecting, process command line parameters and other housekeeping:

#define DEFAULT_URI "tcp://127.0.0.1"
#define EXAMPLE_USER "root"
#define EXAMPLE_PASS ""
#define EXAMPLE_DB "test"
using namespace std;
/*
Usage example for Driver, Connection, (simple) Statement, ResultSet
*/
int main(int argc, const char **argv)
{
const char *url = (argc > 1 ? argv[1] : DEFAULT_URI);
const string user(argc >= 3 ? argv[2] : EXAMPLE_USER);
const string pass(argc >= 4 ? argv[3] : EXAMPLE_PASS);
const string database(argc >= 5 ? argv[4] : EXAMPLE_DB);
cout << endl;
cout << "Connector/C++ standalone program example..." << endl;
cout << endl;
try {

To establish a connection to MySQL Server, retrieve an instance of sql::Connection from a sql::mysql::MySQL_Driver object. A sql::mysql::MySQL_Driver object is returned by sql::mysql::get_mysql_driver_instance():

sql::Driver * driver = sql::mysql::get_driver_instance();
/* Using the Driver to create a connection */
cout << "Creating session on " << url << " ..."
<< endl << endl;
std::unique_ptr< sql::Connection >
con(driver->connect(url, user, pass));

Make sure that you free con, the sql::Connection object, as soon as you do not need it any more. But do not explicitly free driver, the connector object. Connector/C++ takes care of freeing that.

Note
get_mysql_driver_instance() calls get_driver_instance(), which is not thread-safe. Either avoid invoking these methods from within multiple threads at once, or surround the calls with a mutex to prevent simultaneous execution in multiple threads.

These methods can be used to check the connection state or reconnect:

  • sql::Connection::isValid() checks whether the connection is alive
  • sql::Connection::reconnect() reconnects if the connection has gone down

The sql::Connection is used to set the schema and create a statement:

con->setSchema(database);
std::unique_ptr< sql::Statement > stmt(con->createStatement());

To run simple queries, you can use the sql::Statement::execute(), sql::Statement::executeQuery(), and sql::Statement::executeUpdate() methods. Use the method sql::Statement::execute() if your query does not return a result set or if your query returns more than one result set:

std::unique_ptr< sql::ResultSet >
res(stmt->executeQuery("SELECT 'Welcome to Connector/C++' AS _message"));
Note
The Statement and ResultSet objects are temporary, but they are dynamically allocated. Therefore we use std::unique_ptr<> to free memory when they are not needed anymore.

The API for fetching result sets is identical for (simple) statements and prepared statements. If your query returns one result set, use sql::Statement::executeQuery() or sql::PreparedStatement::executeQuery() to run your query. Both methods return sql::ResultSet objects. By default, Connector/C++ buffers all result sets on the client to support cursors.

The code below walks through the entire result set row by row using sql::ResultSet::next() method, which returns true if the row was successfully read. Otherwise it returns false, which means we reached the end of the result set and there are no more rows to read.

The actual data is obtained through the getXxxx() functions such as getInt(), getString(), etc. The columns can be indexed by numbers in the order they are given inside the result set starting from 1. Alternatively the column name can be used as a string index.

while (res->next())
{
cout << "\t... MySQL replies: " << res->getString("_message") << endl;
cout << "\t... say it again, MySQL" << endl;
cout << "\t....MySQL replies: " << res->getString(1) << endl;
}

Error handling is done through the standard try/catch blocks:

catch (sql::SQLException &e)
{
/*
The JDBC API throws three different exceptions:
- sql::MethodNotImplementedException (derived from sql::SQLException)
- sql::InvalidArgumentException (derived from sql::SQLException)
- sql::SQLException (derived from std::runtime_error)
*/
cout << "# ERR: SQLException in " << __FILE__;
cout << "(" << "EXAMPLE_FUNCTION" << ") on line " << __LINE__ << endl;
/* Use what() (derived from std::runtime_error) to fetch the error message */
cout << "# ERR: " << e.what();
cout << " (MySQL error code: " << e.getErrorCode();
cout << ", SQLState: " << e.getSQLState() << " )" << endl;
return EXIT_FAILURE;
}

Here is the complete C++ code of the test sample for the legacy C++ API:

/*
* Copyright (c) 2008, 2020, Oracle and/or its affiliates.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2.0, as
* published by the Free Software Foundation.
*
* This program is also distributed with certain software (including
* but not limited to OpenSSL) that is licensed under separate terms,
* as designated in a particular file or component or in included license
* documentation. The authors of MySQL hereby grant you an
* additional permission to link the program and your derivative works
* with the separately licensed software that they have included with
* MySQL.
*
* Without limiting anything contained in the foregoing, this file,
* which is part of MySQL Connector/C++, is also subject to the
* Universal FOSS Exception, version 1.0, a copy of which can be found at
* http://oss.oracle.com/licenses/universal-foss-exception.
*
* This program 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 General Public License, version 2.0, for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
Basic example of an application using JDBC API of Connector/C++
*/
/* Standard C++ includes */
#include <stdlib.h>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <memory>
#include <mysql/jdbc.h>
#define DEFAULT_URI "tcp://127.0.0.1"
#define EXAMPLE_USER "root"
#define EXAMPLE_PASS ""
#define EXAMPLE_DB "test"
using namespace std;
/*
Usage example for Driver, Connection, (simple) Statement, ResultSet
*/
int main(int argc, const char **argv)
{
const char *url = (argc > 1 ? argv[1] : DEFAULT_URI);
const string user(argc >= 3 ? argv[2] : EXAMPLE_USER);
const string pass(argc >= 4 ? argv[3] : EXAMPLE_PASS);
const string database(argc >= 5 ? argv[4] : EXAMPLE_DB);
cout << endl;
cout << "Connector/C++ standalone program example..." << endl;
cout << endl;
try {
sql::Driver * driver = sql::mysql::get_driver_instance();
/* Using the Driver to create a connection */
cout << "Creating session on " << url << " ..."
<< endl << endl;
std::unique_ptr< sql::Connection >
con(driver->connect(url, user, pass));
con->setSchema(database);
std::unique_ptr< sql::Statement > stmt(con->createStatement());
std::unique_ptr< sql::ResultSet >
res(stmt->executeQuery("SELECT 'Welcome to Connector/C++' AS _message"));
cout << "\t... running 'SELECT 'Welcome to Connector/C++' AS _message'"
<< endl;
while (res->next())
{
cout << "\t... MySQL replies: " << res->getString("_message") << endl;
cout << "\t... say it again, MySQL" << endl;
cout << "\t....MySQL replies: " << res->getString(1) << endl;
}
}
catch (sql::SQLException &e)
{
/*
The JDBC API throws three different exceptions:
- sql::MethodNotImplementedException (derived from sql::SQLException)
- sql::InvalidArgumentException (derived from sql::SQLException)
- sql::SQLException (derived from std::runtime_error)
*/
cout << "# ERR: SQLException in " << __FILE__;
cout << "(" << "EXAMPLE_FUNCTION" << ") on line " << __LINE__ << endl;
/* Use what() (derived from std::runtime_error) to fetch the error message */
cout << "# ERR: " << e.what();
cout << " (MySQL error code: " << e.getErrorCode();
cout << ", SQLState: " << e.getSQLState() << " )" << endl;
return EXIT_FAILURE;
}
cout << endl;
cout << "... find more at http://www.mysql.com" << endl;
cout << endl;
return EXIT_SUCCESS;
}