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:
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;
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();
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)
{
cout << "# ERR: SQLException in " << __FILE__;
cout << "(" << "EXAMPLE_FUNCTION" << ") on line " << __LINE__ << endl;
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:
#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;
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();
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)
{
cout << "# ERR: SQLException in " << __FILE__;
cout << "(" << "EXAMPLE_FUNCTION" << ") on line " << __LINE__ << endl;
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;
}