- 浏览: 114699 次
- 性别:
- 来自: 成都
最新评论
-
sp42:
Oracle 不是很吊的么,怎么连个分页都这么麻烦?
数据库分页大全(oracle利用解析函数row_number高效分页) -
metarnetyflu:
不知道哪里快了!!!over()是最慢的,rownum其次,r ...
数据库分页大全(oracle利用解析函数row_number高效分页) -
wfd0807:
09年发的博文,五年了,一定影响到了不少人。首先,你描述的三层 ...
数据库分页大全(oracle利用解析函数row_number高效分页) -
diyunpeng:
学习了,写的不错。
python urlOpen使用代理 -
qepwqnp:
帖子沉的好深,涝起来
js_自己封装一个可查询frame中对象的一个方法
原文地址:http://dev.mysql.com/tech-resources/articles/mysql-connector-cpp.html#trx
翻译: DarkBull(www.darkbull.net)
示例代码:MySqlDemo.7z
译者注:该教程是一篇介绍如何使用C++操作MySQL的入门教程,内容简单易用。我对原文中的一些例子进行了修改,并新添加了部分例子,主要目标是更简单明了的向读者介绍如何操作MySQL数据库。本人也是MySQL的初学者,错误也在所难免,欢迎拍砖!
这篇教程将一步一步引导您如何去构建和安装MySql Connection/C++ Driver,同时提供几个简单的例子来演示如何连接MySQL数据库,如何向MySQL添加、获取数据。本教程关注如何在C++应用程序中操作MySQL,所以首先应该确定MySQL数据库服务已经开启并且在当前机器能够访问到。
下面的的代码段通过调用Connection对象的createStatemenet来获取一个Statement对象:
本教程面向的读者是MySQL Connector/C++的初学者,如果您对C++语言或者MySQL数据库不是很了解,请参考其他的教程。
教程使用了下面所列的一些工具和技术,来构建、编译、运行例子程序(译者注:这是原文作者使用的环境。笔者使用的环境是:WinXP,MySQL5.1,VS2008, ):
- Database MySQL Server 5.1.24-rc
- C++ Driver MySQL Connector/C++ 1.0.5
- MySQL Client Library MySQL Connector/C 6.0
- Compiler Sun Studio 12 C++ compiler
- Make CMake 2.6.3
- Operating System OpenSolaris 2008.11 32-bit
- CPU / ISA Intel Centrino / x86
- Hardware Toshiba Tecra M2 Laptop
目录
MySQL C++ Driver的实现基于JDBC4.0规范
安装MySQL Connector/C++
运行时依赖
C++ IDE
为示例程序创建数据库与数据表
使用Connector/C++测试数据库连接
使用prepared Statements
使用事务
访问Result Set Metadata
访问Database Metadata
通过PreparedStatment对象访问参数元数据
捕获异常
调试/跟踪 MySQL Connector/C++
更多信息
MySQL C++ Driver的实现基于JDBC4.0规范
MySQL Connector/C++是由Sun Microsystems开发的MySQL连接器。它提供了基于OO的编程接口与数据库驱动来操作MySQL服务器。
与许多其他现存的C++接口实现不同,Connector/C++遵循了JDBC规范。也就是说,Connector/C++ Driver的API主要是基于Java语言的JDBC接口。JDBC是java语言与各种数据库连接的标准工业接口。Connector/C++实现了大部分JDBC4.0规范。如果C++程序的开发者很熟悉JDBC编程,将很快的入门。
MySQL Connector/C++实现了下面这些类:
- Driver
- Connection
- Statement
- PreparedStatement
- ResultSet
- Savepoint
- DatabaseMetaData
- ResultSetMetaData
- ParameterMetaData
在MySQL Connector/C++发布之前,C++程序员可以使用MySQL C API或者MySQL++访问MySQL。前者是非标准、过程化的C API,后者是对MySQL C API的C++封装。
安装MySQL Connector/C++
此处略。(译者注:用户可以到MySQL的官网[http://dev.mysql.com/downloads/connector/cpp/1.0.html]去下载MySQL Connector/C++的安装程序,或者只下载dll,或者下载源代码自己编译。笔者在Window平台上使用MySQL,下载了mysql-connector-c++-noinstall-1.0.5-win32这个版本用于调试。)
运行时依赖
MySQL Connector/C++ Driver依赖MySQL的客户端库,在MySQL安装目录下的lib\opt\libmysql.dll。如果是通过安装程序来安装MySQL Connector/C++,libmysql会一并安装,如果从官网只下载了dll或源码,在使用时,程序必须链接到libmysql.dll。
C++ IDE
此处略。(译者注:原文作者使用NetBean作为C++的IED。笔者使用VS2008)
为示例程序创建数据库与数据表
(译者注:此节略掉许多不太重要的内容。)在MySQL中创建test数据库,使用下面语句创建数据表:City:
然后向City表中添加一些数据。最后表的内容为:
Create Table: CREATE TABLE `City` ( `CityName` varchar(30) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=ascii
mysql>SELECT * FROM City;
+--------------------+
| CityName |
+--------------------+
| Hyderabad, India |
| San Francisco, USA
|
| Sydney, Australia |
+--------------------+
3 rows in set (0.17 sec)
使用Connector/C++测试数据库连接
下面的代码演示如何使用Connector/C++连接到MySQL服务器:
- 连接到test数据库;
- 执行一个查询获取City表中的数据,显示在控制台上;
- 使用Prepared Statements向City表插入数据;
- 使用savepoints演示事务;
- 获取结果集和数据库的元信息;
例子代码仅仅用于演示,不建议读者在实际开发中使用这种样式的代码。(译者注:例子代码很长,如果看不太明白,没关系,等阅读完全文之后再回过头来看)
#include <iostream> #include <map> #include <string> #include <memory> #include "mysql_driver.h" #include "mysql_connection.h" #include "cppconn/driver.h" #include "cppconn/statement.h" #include "cppconn/prepared_statement.h" #include "cppconn/metadata.h" #include "cppconn/exception.h" #define DBHOST "tcp://127.0.0.1:3306" #define USER "root" #define PASSWORD "000000" #define DATABASE "test" #define NUMOFFSET 100 #define COLNAME 200 using namespace std; using namespace sql; #pragma comment(lib, "mysqlcppconn.lib") void Demo(); int main(int argc, char *argv[]) { Demo(); return 0; } /* 获取数据库信息 */ static void GetDBMetaData(Connection *dbcon) { if (dbcon->isClosed()) { throw runtime_error("DatabaseMetaData FAILURE - database connection closed"); } cout << "\nDatabase Metadata" << endl; cout << "-----------------" << endl; cout << boolalpha; /* The following commented statement won't work with Connector/C++ 1.0.5 and later */ //auto_ptr < DatabaseMetaData > dbcon_meta (dbcon->getMetaData()); DatabaseMetaData *dbcon_meta = dbcon->getMetaData(); cout << "Database Product Name: " << dbcon_meta->getDatabaseProductName() << endl; cout << "Database Product Version: " << dbcon_meta->getDatabaseProductVersion() << endl; cout << "Database User Name: " << dbcon_meta->getUserName() << endl << endl; cout << "Driver name: " << dbcon_meta->getDriverName() << endl; cout << "Driver version: " << dbcon_meta->getDriverVersion() << endl << endl; cout << "Database in Read-Only Mode?: " << dbcon_meta->isReadOnly() << endl; cout << "Supports Transactions?: " << dbcon_meta->supportsTransactions() << endl; cout << "Supports DML Transactions only?: " << dbcon_meta->supportsDataManipulationTransactionsOnly() << endl; cout << "Supports Batch Updates?: " << dbcon_meta->supportsBatchUpdates() << endl; cout << "Supports Outer Joins?: " << dbcon_meta->supportsOuterJoins() << endl; cout << "Supports Multiple Transactions?: " << dbcon_meta->supportsMultipleTransactions() << endl; cout << "Supports Named Parameters?: " << dbcon_meta->supportsNamedParameters() << endl; cout << "Supports Statement Pooling?: " << dbcon_meta->supportsStatementPooling() << endl; cout << "Supports Stored Procedures?: " << dbcon_meta->supportsStoredProcedures() << endl; cout << "Supports Union?: " << dbcon_meta->supportsUnion() << endl << endl; cout << "Maximum Connections: " << dbcon_meta->getMaxConnections() << endl; cout << "Maximum Columns per Table: " << dbcon_meta->getMaxColumnsInTable() << endl; cout << "Maximum Columns per Index: " << dbcon_meta->getMaxColumnsInIndex() << endl; cout << "Maximum Row Size per Table: " << dbcon_meta->getMaxRowSize() << " bytes" << endl; cout << "\nDatabase schemas: " << endl; auto_ptr < ResultSet > rs ( dbcon_meta->getSchemas()); cout << "\nTotal number of schemas = " << rs->rowsCount() << endl; cout << endl; int row = 1; while (rs->next()) { cout << "\t" << row << ". " << rs->getString("TABLE_SCHEM") << endl; ++row; } // while cout << endl << endl; } /* 获取结果集信息 */ static void GetResultDataMetaBata(ResultSet *rs) { if (rs -> rowsCount() == 0) { throw runtime_error("ResultSetMetaData FAILURE - no records in the result set"); } cout << "ResultSet Metadata" << endl; cout << "------------------" << endl; /* The following commented statement won't work with Connector/C++ 1.0.5 and later */ //auto_ptr < ResultSetMetaData > res_meta ( rs -> getMetaData() ); ResultSetMetaData *res_meta = rs -> getMetaData(); int numcols = res_meta -> getColumnCount(); cout << "\nNumber of columns in the result set = " << numcols << endl << endl; cout.width(20); cout << "Column Name/Label"; cout.width(20); cout << "Column Type"; cout.width(20); cout << "Column Size" << endl; for (int i = 0; i < numcols; ++i) { cout.width(20); cout << res_meta -> getColumnLabel (i+1); cout.width(20); cout << res_meta -> getColumnTypeName (i+1); cout.width(20); cout << res_meta -> getColumnDisplaySize (i+1) << endl << endl; } cout << "\nColumn \"" << res_meta -> getColumnLabel(1); cout << "\" belongs to the Table: \"" << res_meta -> getTableName(1); cout << "\" which belongs to the Schema: \"" << res_meta -> getSchemaName(1) << "\"" << endl << endl; } /* 打印结果集中的数据 */ static void RetrieveDataAndPrint(ResultSet *rs, int type, int colidx, string colname) { /* retrieve the row count in the result set */ cout << "\nRetrieved " << rs->rowsCount() << " row(s)." << endl; cout << "\nCityName" << endl; cout << "--------" << endl; /* fetch the data : retrieve all the rows in the result set */ while (rs->next()) { if (type == NUMOFFSET) { cout << rs -> getString(colidx) << endl; } else if (type == COLNAME) { cout << rs -> getString(colname) << endl; } // if-else } // while cout << endl; } void Demo() { Driver *driver; Connection *con; Statement *stmt; ResultSet *res; PreparedStatement *prep_stmt; Savepoint *savept; int updatecount = 0; /* initiate url, user, password and database variables */ string url(DBHOST); const string user(USER); const string password(PASSWORD); const string database(DATABASE); try { driver = get_driver_instance(); /* create a database connection using the Driver */ con = driver -> connect(url, user, password); /* alternate syntax using auto_ptr to create the db connection */ //auto_ptr con (driver -> connect(url, user, password)); /* turn off the autocommit */ con -> setAutoCommit(0); cout << "\nDatabase connection\'s autocommit mode = " << con -> getAutoCommit() << endl; /* select appropriate database schema */ con -> setSchema(database); /* retrieve and display the database metadata */ GetDBMetaData(con); /* create a statement object */ stmt = con -> createStatement(); cout << "Executing the Query: \"SELECT * FROM City\" .." << endl; /* run a query which returns exactly one result set */ res = stmt -> executeQuery ("SELECT * FROM City"); cout << "Retrieving the result set .." << endl; /* retrieve the data from the result set and display on stdout */ RetrieveDataAndPrint (res, NUMOFFSET, 1, string("CityName")); /* retrieve and display the result set metadata */ GetResultDataMetaBata (res); cout << "Demonstrating Prepared Statements .. " << endl << endl; /* insert couple of rows of data into City table using Prepared Statements */ prep_stmt = con -> prepareStatement ("INSERT INTO City (CityName) VALUES (?)"); cout << "\tInserting \"London, UK\" into the table, City .." << endl; prep_stmt -> setString (1, "London, UK"); updatecount = prep_stmt -> executeUpdate(); cout << "\tCreating a save point \"SAVEPT1\" .." << endl; savept = con -> setSavepoint ("SAVEPT1"); cout << "\tInserting \"Paris, France\" into the table, City .." << endl; prep_stmt -> setString (1, "Paris, France"); updatecount = prep_stmt -> executeUpdate(); cout << "\tRolling back until the last save point \"SAVEPT1\" .." << endl; con -> rollback (savept); con -> releaseSavepoint (savept); cout << "\tCommitting outstanding updates to the database .." << endl; con -> commit(); cout << "\nQuerying the City table again .." << endl; /* re-use result set object */ res = NULL; res = stmt -> executeQuery ("SELECT * FROM City"); /* retrieve the data from the result set and display on stdout */ RetrieveDataAndPrint(res, COLNAME, 1, string ("CityName")); cout << "Cleaning up the resources .." << endl; /* Clean up */ delete res; delete stmt; delete prep_stmt; con -> close(); delete con; } catch (SQLException &e) { cout << "ERROR: " << e.what(); cout << " (MySQL error code: " << e.getErrorCode(); cout << ", SQLState: " << e.getSQLState() << ")" << endl; if (e.getErrorCode() == 1047) { /* Error: 1047 SQLSTATE: 08S01 (ER_UNKNOWN_COM_ERROR) Message: Unknown command */ cout << "\nYour server does not seem to support Prepared Statements at all. "; cout << "Perhaps MYSQL < 4.1?" << endl; } return; } catch (std::runtime_error &e) { cout << "ERROR: " << e.what() << endl; return; } return; }
建立数据库连接
sql::Connection代表到数据库的连接,可以通过sql::Driver来创建。sql::mysql::get_mysql_driver_instance()方法用于获取sql::Driver,通过调用sql::Driver::connect方法来创建sql::Connection对象。(译者注:笔者使用的Connector/C++版本与作者使用的版本不一样,接口方面也有点细微的差别。这里根据笔者使用的最新版本mysql-connector-c++-noinstall-1.0.5-win32来说明。)
下面是get_mysql_driver_instance与connect这两个方法的签名:
/* mysql_driver.h */ MySQL_Driver *sql::mysql::get_mysql_driver_instance() /* mysql_driver.h */ sql::Connection * connect(const std::string& hostName, const std::string& userName, const std::string& password); sql::Connection * connect(std::map<std::string, sql::ConnectPropertyVal> & options);
Driver类重载了connect方法,一个接收数据库地址的url、用户名和密码的字符串,后一个接收一个map,map中以key/value的形式包含数据库地址、用户名与密码。使用TCP/IP连接到MySql服务器的url字符串的格式如下:"tcp://[hostname[:port]][/schemaname]"。例如:tcp://127.0.0.1:5555/some_scehma。hostname和端口号是可选的,如果省略,默认是127.0.0.1与3306。如果hostname为"localhost",会被自动转换为"127.0.0.1"。schemaname也是可选的,如果连接字符串中没有设置schema,需要在程序中通过Connection::setSchema方法手动设置。
在unix系统上,可以通过UNIX domain socket连接运行在本地的MySQL服务,连接字符串格式为:"unix://path/to/unix_socket_file",例如:unix:///tmp/mysql.sock.
在windows系统上,可以以命名管道的方式连接到运行在本地的MySQL数据库,连接字符串格式为:"pipe://path/to/the/pipe"。MySQL服务必须启动允许命名管道连接,可以在启动MySQL服务器的时候,通过--enable-named-pipe命令行选项来启动该功能。如果没有通过--socket=name选项设置命名管道的名称,系统默认使用MySQL。在windows上,管道的名称是区别大小写的。
下面的代码片断尝试连接到本地的MySQL服务器,通过3306端口,用户名为root,密码是000000,schema为test.
下面的代码片断尝试连接到本地的MySQL服务器,通过3306端口,用户名为root,密码是000000,schema为test.
sql::mysql::MySQL_Driver *driver = 0; sql::Connection *conn = 0; try { driver = sql::mysql::get_mysql_driver_instance(); conn = driver->connect("tcp://localhost:3306/test", "root", "000000"); cout << "连接成功" << endl; } catch (...) { cout << "连接失败" << endl; } if (conn != 0) { delete conn; }
也可以通过connection的第二个重载方法连接MySQL。ConnectPropertyVal是union类型,在connection.h中定义。
sql::mysql::MySQL_Driver *driver = 0; sql::Connection *conn = 0; std::map<std::string, ConnectPropertyVal> connProperties; ConnectPropertyVal tmp; tmp.str.val = "tcp://127.0.0.1:3306/test"; connProperties[std::string("hostName")] = tmp; tmp.str.val = "root"; connProperties[std::string("userName")] = tmp; tmp.str.val = "000000"; connProperties[std::string("password")] = tmp; try { driver = sql::mysql::get_mysql_driver_instance(); conn = driver -> connect(connProperties); cout << "连接成功" << endl; } catch(...) { cout << "连接失败" << endl; } if (conn != 0) { delete conn; }
上面的连接字符串可以将协议与路径分开写(译者注:C++会把两个连在一起的字符串合并成一个字符串),如:mp.str.val = "unix://" "/tmp/mysql.sock"
当建立与服务器之间的连接后,通过Connection::setSessionVariable方法可以设置像sql_mode这样的选项。
C++细节注意点
像Connection这样的对象,必须在用完之后,显式的delete,例如:sql::Connection *conn = driver -> connect("tcp://127.0.0.1:3306", "root", "000000"); // do something delete conn
使用使用auto_ptr来维护连接对象的清理, 如:
use namespace std; use namespace sql; auto_ptr < Connection > con ( driver -> connect("tcp://127.0.0.1:3306", "root", "000000") );
获取Statement对象
Statement对象用于向MySQL服务器发送SQL语句。该对象可以通过调用Connection::createStatement方法获得。Statement向MySQL发送一个静态的SQL语句,然后从MySQL获取操作的结果,我们无法向它提供sql参数。如果要向它传递参数,可以使用PreparedStatemenet类。如果相同的SQL语句(只SQL参数不同)要被执行多次,建议使用PreparedStatement类。
Connection::createStatement的签名如下(关于Connection类所提供的方法列表,可以查看connection.h头文件):
Connection::createStatement的签名如下(关于Connection类所提供的方法列表,可以查看connection.h头文件):
/* connection.h */ Statement* Connection::createStatement();
Connection *conn; // Connection对象的引用 Statement *stat; Statement stat = conn -> createStatement();
执行SQL语句
在执行SQL语句之前应该通过Connection对象的setSchema方法设置相应的Schema(如果没有在数据库地址URL中指定schema)。
Statement::executeQuery用于执行一个Select语句,它返回ResultSet对象。Statement::executeUpdate方法主要用于执行INSERT, UPDATE, DELETE语句(executeUpdate可以执行所有的SQL语句,如DDL语句,像创建数据表。),该方法返回受影响记录的条数。
如果你不清楚要执行的是像select这样的查询语句还是像update/insert/delete这样的操作语句,可以使用execute方法。对于查询语句,execute()返回True,然后通过getResultSet方法获取查询的结果;对于操作语句,它返回False,通过getUpdateCount方法获取受影响记录的数量。
在一些特殊的情况下,单条SQL语句(如执行存储过程),可能会返回多个结果集 和/或 受影响的记录数量。如果你不想忽略这些结果,通过getResultSet或getUpdateCount方法第一个结果后,再通过getMoreResults()来获取其他的结果集。
下面是这些方法的签名,可以在statement.h头文件中查阅Statement的完整方法列表。
/* connection.h */ void Connection::setSchema(const std::string& catalog); /* statement.h */ ResultSet* Statement::executeQuery (const std::string& sql); int Statement::executeUpdate (const std::string& sql); bool Statement::execute (const std::string& sql); ResultSet* Statement::getResultSet(); uint64_t Statement::getUpdateCount();
这些方法出错时都会抛出SQLException异常,所以在你的代码中应该使用try...catch语句块来捕获这些异常。
现在回顾上面那个完全的例子,你会发现获取City表的所有记录是如此的简单:Statement *stmt; ResultSet *res; res = stmt -> executeQuery ("SELECT * FROM City");
executeQuery方法返回ResultSet对象,它包含了查询的结果。在以下情况下,executeQuery会抛出SQLException异常:数据库在执行查询时出错;在一个关闭的Statement对象上调用executeQuery;给出的SQL语句返回的不是一个简单的结果集;
上面的代码可以用Statement::execute()重写:
bool retvalue = stmt -> execute ("SELECT * FROM City"); if (retvalue) { res = stmt -> getResultSet(); } else { ... }execute()返回True表示操作的结果是一个ResultSet对象,否则结果是受影响记录的数量或没有结果。当返回True时,通过getResultSet方法获取结果集,在返回False的情况下调用getResultSet方法,将返回NULL。
当数据库在执行时发生错误或者在一个已关闭的Statement对象上执行execute与getResultSet方法,都会抛出SQLException异常。
如果要往数据库里添加一条新的记录,可以像下面的例子一样简单的调用executeUpdate方法:
int updateCount = stmt -> executeUpdate ("INSERT INTO City (CityName) VALUES ('Napier, New Zealand')");
如果executeUpdate执行的是像INSERT, UPDATE或DELETE这样的数据操作语句(DML),它返回受影响的记录的数量;如果执行的是数据定义语句(DDL),它返回0。在数据库操作失败,或者在一个已经关闭的Statement上调用该方法,或者给出的SQL语句是一个查询语句(会返回结果集),该方法会抛出SQLException异常。
下面的代码使用execute和getUpdateCount方法来生写上面的例子:
int updateCount = 0; bool retstatus = stat->execute("INSERT INTO City (CityName) VALUES ('Napier, New Zealand')"); if (!retstatus) { updateCount = stat->getUpdateCount(); } else { ... }
从ResultData中获取数据
上面的段落介绍了执行SQL查询的方法:executeQuery和execute,用于获取ResultSet对象。我们可以通过ResultSet访问查询的结果。每一个ResultSet都包含一个游标(cursor),它指向数据集中的当前记录行。ResultSet中排列的记录是有序的(译者注:只能按顺序一条一条获取,不能跳跃式获取)。(但)在同一行中,列值的访问却是随意的:可以通过列的位置或者名称。通过列的名称访问列值让代码更清晰,而通过位置访问列值则更高效。
列的名称通过SQL语句的AS子名设定,如果SQL语句中没有使用AS子名,列的名称默认为数据表中对应的列名。例如对于"SELECT CityName AS CN FROM City",CN就是结果集中列的名称。
在ResultSet中的数据,可以通过getXX系列方法来获取,例如:getString(), getInt(),"XX"取决于数据的类型。next()与previous()使游标移到结果集中的下一条或上一条记录。
在ResultSet中的数据,可以通过getXX系列方法来获取,例如:getString(), getInt(),"XX"取决于数据的类型。next()与previous()使游标移到结果集中的下一条或上一条记录。
Statement执行SQL语句返回ResultSet对象后,ResultSet就变成一个独立的对象,与原先的Statement再也没有联系,即使Statement对象关闭,重新执行其他sql语句,或者获取多个结果集中的下一个。ResultSet将一直有效,除非显式或隐式地将其关闭。
在撰写本文时,对于Statement对象,MySQL Connector/C++总是返回缓存结果,这些结果在客户端缓存。不管结果集数据量大小,MySQLConnector/C++ Driver总是获取所有的数据。希望以后的版本中,Statement对象能够返回缓存和非缓存的结果集。
在撰写本文时,对于Statement对象,MySQL Connector/C++总是返回缓存结果,这些结果在客户端缓存。不管结果集数据量大小,MySQLConnector/C++ Driver总是获取所有的数据。希望以后的版本中,Statement对象能够返回缓存和非缓存的结果集。
下面是数据获取方法的签名,可以在resultset.h头文件中查看所有ResultSet类支持的方法。
/* resultset.h */ size_t ResultSet::rowsCount() const; void ResultSet::close(); bool ResultSet::next(); bool ResultSet::previous(); bool ResultSet::last(); bool ResultSet::first(); void ResultSet::afterLast(); void ResultSet::beforeFirst(); bool ResultSet::isAfterLast() const; bool ResultSet::isBeforeFirst()const; bool ResultSet::isClosed() const; bool ResultSet::isNull(uint32_t columnIndex) const; bool ResultSet::isNull(const std::string& columnLabel) const; bool ResultSet::wasNull() const; std::string ResultSet::getString(uint32_t columnIndex) const; std::string ResultSet::getString(const std::string& columnLabel) const; int32_t ResultSet::getInt(uint32_t columnIndex) const; int32_t ResultSet::getInt(const std::string& columnLabel) const;在下面的简单示例中,查询语句"SELECT * FROM City"返回的ResultSet中只包含一列:CityName,数据类型为String,对应MySQL中的VARCHAR类型。这个例子通过next方法循环从结果集中获取CityName值,并显示在控制台上:
while (res -> next()) { cout << rs -> getString("CityName") << endl; }
也可以通过位置来获取列值(位置从1开始而非从0开始),下面的代码产生相同的结果:
while (res -> next()) { cout << rs -> getString(1) << endl; }
如果数据库中该字段的值为NULL,getString将返回一个空的字符串。Result::isNull用于判断指定列在数据库中的值是否为NULL。Result::wasNULL()用于判断最近读取的列的值是否为空。
下面的例子演示了通过cursor(游标)倒序读取结果集中的数据:
/* Move the cursor to the end of the ResultSet object, just after the last row */ res -> afterLast(); if (!res -> isAfterLast()) { throw runtime_error("Error: Cursor position should be at the end of the result set after the last row."); } /* fetch the data : retrieve all the rows in the result set */ while (res -> previous()) { cout << rs->getString("CityName") << endl; }
getString方法在以下情况下会抛出SQLException异常:指定列名或位置不存在;数据库在执行操作时失败;在一个关闭的cursor上执行调用该方法。
未完待续!
发表评论
-
INSERT INTO ON DUPLICATE KEY UPDATE
2017-04-20 17:28 633mysql当插入重复时更新的方法: 第一种方法: ... -
SpringMVC加载WebApplicationContext源码分析
2015-09-06 19:04 932Spring框架提供了构建Web应用程序的全功能MVC模块, ... -
CSS让你的IE浏览器崩溃
2010-06-06 12:58 1038原文链接:http://blog.gulu77.com/?p= ... -
Android用户界面详解
2011-03-21 21:56 836这个章节描述怎么实现 ... -
【转】Launcher研究之AndroidManifest.xml分析
2011-03-22 11:50 1010Launcher的AndroidManifest.xml文件有 ... -
【转】AndroidManifest.xml文件综合详解
2011-03-22 19:56 866转自:http://yangguangfu.j ... -
Javascript的回调机制讲解
2011-04-06 23:05 1174本文出自http://blog.csdn.ne ... -
再次封装IOCP的收获
2010-01-17 23:19 2744以前写过一篇用python封 ... -
译: Code::Blocks手册 使用篇
2010-01-25 00:05 1594原手册下载:http://www.codeblocks.or ... -
python模块学习 ---- Cookie
2010-04-02 23:18 1337最近在用GAE开发自己的 ... -
Python模块学习 ---- datetime
2010-04-07 11:02 1009Python提供了多个内置模块用于操作日期时间,像ca ... -
Python模块学习 ---- filecmp 文件比较
2010-04-08 10:53 1180filecmp模块用于比较文件及文件夹的内容,它是一个 ... -
用Python写的图片蜘蛛人
2010-04-10 23:32 833写了个图片蜘蛛人玩玩,抓了几个网页试试,感觉不不错。核 ... -
Python模块学习 --- urllib
2010-04-16 15:13 934urllib模块提供的上层接口,使我们可以像读取本地文 ... -
Python模块学习 ---- atexit
2010-04-19 21:47 942atexit模块很简单,只定义了一个register函 ... -
C语言复杂声明
2010-05-23 21:31 718《C专家编程》第三章介绍了如何分析复杂的声明,讲的非常 ... -
像定义“函数”一样定义宏
2010-06-06 23:40 960可以使用宏定义没有返回值的“函数”。例如: #def ... -
python版本问题导致Boost.Python无法正常使用
2010-08-08 22:29 1454(www.darkbull.net) 今天打算将Pyth ... -
boost::shared_ptr的性能
2010-08-16 00:10 1938原文出版:http://www.darkbull.net/ ... -
跨语言使用对称加密
2010-09-16 17:27 1501这两天在写GM工具,使用wxPython开发,GM工具 ...
相关推荐
【C++入门教程:适合新人】的教程旨在为初学者提供一条清晰的学习路径,帮助他们逐步掌握C++编程语言的基础知识。C++是一种强大的、通用的编程语言,它结合了低级内存操作的能力和高级面向对象编程的概念。作为一门...
这个"一个C++做MYSQL开发的精简开发包"正是为了解决这个问题,它包含了一些必要的头文件和可能的示例代码,帮助开发者快速入门C++与MySQL的集成。 标题中的"C++做MYSQL开发"意味着这个包是为C++程序员提供的一种...
**MySQL入门教程——cpp-MySQL实战** MySQL是一种广泛使用的开源关系型数据库管理系统(RDBMS),以其高效、稳定和易用性而闻名。本教程专为C++开发者设计,旨在帮助初学者掌握如何使用C++与MySQL进行数据交互。...
- **教程**: 针对初学者的入门教程。 - **示例**: 实际应用场景的案例研究。 ##### 9.2 FAQs - **常见问题解答**: 解答用户在使用过程中遇到的问题。 ##### 9.3 Restrictions and Limitations - **限制**: MySQL...
- **Tutorial(教程)**:提供了入门级教程,帮助新手快速上手MySQL的安装、配置和基本操作。 - **Change History(变更历史)**:记录了MySQL 5.5版本的所有变更细节,对于追踪问题解决和功能更新至关重要。 #### ...
- **Connector/C++**:C++ 开发者的官方驱动。 - **Connector/Net**:.NET 开发者的官方驱动。 - **Connector/MXJ**:用于 Java 的官方驱动。 - **Connector/Python**:虽然文档中未明确提及,但 MySQL 5.6 也...
这是一个关于在 Windows 平台上安装 MySQL 数据库的详细图文教程。MySQL 是一个关系型数据库管理系统,广泛应用于中小型网站。它的体积小、速度快、总体拥有成本低,而且开放源码,分为商业版和社区版。这里我们将...
C++可以通过ODBC(Open Database Connectivity)或更具体的数据库API(如MySQL Connector/C++)来实现与数据库的连接。在SQL语句的帮助下,可以进行数据的增删改查操作,确保数据的一致性和完整性。 在系统实现过程...
- **数据库API(Application Programming Interface)**:如ODBC(Open Database Connectivity)或MySQL Connector/C++,用于C++连接数据库。 7. **编译与链接**: - **编译器(Compiler)**:将源代码转换成可...
本文将详细介绍如何在Windows上安装MySQL,帮助你快速入门。 首先,你需要从MySQL官方网站下载最新版本的安装包。通常,这个文件会是一个名为`MySQL-installer-community-<version>.msi`的可执行文件,其中`...
为了在C++中使用SQL,我们需要一个数据库API,如ODBC(Open Database Connectivity)或MySQL Connector/C++。ODBC提供了一个标准的接口,可以让C++程序连接到各种不同类型的数据库系统。安装相应的ODBC驱动后,你...
在Windows环境下搭建MySQL的实践可以帮助开发者快速入门,理解数据库的基本操作,以及如何在Windows平台上使用MySQL。这是任何希望从事数据库开发和管理工作的IT专业人士必须掌握的基本技能之一。
- **数据库连接**:C++通过ODBC或特定数据库API(如MySQL Connector/C++)与数据库建立连接,实现数据的交互。 3. **用户界面设计**: - **命令行界面**:最基础的实现方式,通过标准输入/输出进行交互,适合初学...
虽然JDBC是Java特有的,但C++也有多种数据库连接库,如ODBC、MySQL Connector/C++等。C++通常更注重性能,而Java的JDBC则提供了更高的平台独立性和易用性。 ### 七、其他相关技术 - **JPA (Java Persistence API)*...
在C++中,可以使用ODBC或MySQL Connector/C++等库来连接和操作数据库。 四、文件操作与持久化存储 在没有使用外部数据库的情况下,系统可能会使用文件来保存和读取数据。C++提供了fstream库进行文件操作,如打开、...