mysql-connector-cpp,MySQL Connector/C++ 操作MySQL数据库(例程)

转载出处: http://blog.csdn.net/callmequeen110/article/details/50236155

如果我翻译错了或者翻译的不好,欢迎指正~

Developing Database Applications Using MySQL Connector/C++

这个教程会教你搭建安装MySQL Connector/C++ driver的要点和步骤,以一个简单的连接MySQL的例子,从MySQL中获取数据并对其进行插入(数据)操作。因为重点在于从C++程序连接数据库,所以本文档假设MySQL已经运行并且能从客户端访问。

本文是面向那些初次接触MySQL Connector/C++的程序开发者的教程,并不是讲述C++编程和MySQL数据库的。

构建和运行本教程的例子需要下列工具和技术来编译: DatabaseMySQL Server 5.1.24-rc

C++ DriverMySQL Connector/C++ 1.0.5

MySQL Client LibraryMySQL Connector/C 6.0

CompilerSun Studio 12 C++ compiler

MakeCMake 2.6.3

Operating SystemOpenSolaris 2008.11 32-bit

CPU / ISAIntel Centrino / x86

HardwareToshiba Tecra M2 Laptop

CONTENTS

MySQL C++ Driver 基于JDBC 4.0标准实现

MySQL Connector/C++是最新发布的MySQL连接器,由Sun Microsystems开发。MySQL connector为C++提供面向对象的编程接口(API)和连接MySQL Server的数据库驱动器

与现存的driver不同,Connector/C++是JDBC API在C++中的实现。换句话说,Connector/C++ driver的接口主要是基于Java语言的JDBC API。Java数据库连接(JDBC)是Java连接各种数据库的业界标准。Connector/C++实现了JDBC 4.0的大部分规范。熟悉JDBC编程的C++程序开发者可以提高程序开发的效率。

MySQL Connecotr/C++实现了以下类: Driver

Connection

Statement

PreparedStatement

ResultSet

Savepoint

DatabaseMetaData

ResultSetMetaData

ParameterMetaData

Connecotr/C++ driver可用于连接MySQL5.1以及后续版本。

在MySQL Connector/C++出现之前,C++程序员需要使用非标准的、过程化的MySQL C API或MySQL++ API连接MySQL,MySQL Connector/C++是MySQL C API的C++封装

安装MySQL Connector/C++

从二进制程序安装

从1.0.4版本开始,Connector/C++可用于Solaris, Linux, Windows, FreeBSD, Mac OS X, HP-UX and AIX平台。MSI安装程序和二进制ZIP文件并不需要安装程序可用于Windows,GNU TAR的压缩文档(tar.gz)可用于其他的平台。你可以从“Connector/C++ download“下载预编译的二进制文件。

在Windows和其他平台下二进制包的安装是非常简单的-简单的解压缩文档到指定位置安装Connector/C++ driver。静态链接和动态链接的Connector/C++ driver可以在安装目录下找到lib目录。如果您打算使用动态链接版本的MySQL连接器/ C + +,要确保运行时链接程序可以找到MySQL客户端库。请查阅你操作系统文档,修改和扩展库的搜索路径。如果你无法修改库的搜索路径,那么复制你的程序、MySQL Connector/C++ driver和MySQL客户端库到相同的目录。这种方法在大多数平台都可行,编译器到其他地方都所必须动态库之前会先搜索原始目录(当前目录)。

从源码安装

运行时依赖

略(英语水平有限,这一段翻译的不通畅,就不写了,于阅读本教程没什么影响)

使用IDE开发C++程序

如果你正在寻找一个集成开发环境(IDE)来开发C/C++程序,可以考虑使用开源免费的NetBeans平台。NetBeans C/C++开发包让程序员可以使用他们指定的编译器和工具来搭配NetBeans IDE,构建Solaris,Linux,Windows和Mac OS X的原生应用。C/C++开发包使编辑器具有语言识别功能,可以识别C/C++语言,并且提供项目模板,一个动态类浏览器,支持Makefile和m(不知道是什么)调试器功能。可以通过模块和插件来扩展C/C++开发包的基础功能。

为实例代码创建City表和test数据库

本教程中的简单示例代码尝试获取MySQL中的test数据库中的City表的数据。此表的结构和数据已经使用mysql客户端显示在下面。MySQL服务运行在3306默认端口。 # mysql -u root -pEnter password: adminWelcome to the MySQL monitor. Commands end with ; or \g.Your MySQL connection id is 5Server version: 5.1.24-rc-standard Source distributionType 'help;' or '\h' for help. Type '\c' to clear the buffer.mysql> USE test;Database changedmysql> DESCRIBE City;+----------+-------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+----------+-------------+------+-----+---------+-------+| CityName | varchar(30) | YES | | NULL | |+----------+-------------+------+-----+---------+-------+1 row in set (0.07 sec)mysql> SHOW CREATE TABLE City\G*************************** 1. row *************************** Table: CityCreate Table: CREATE TABLE `City` ( `CityName` varchar(30) DEFAULT NULL) ENGINE=InnoDB DEFAULT CHARSET=ascii1 row in set (0.00 sec)mysql> SELECT * FROM City;+--------------------+| CityName |+--------------------+| Hyderabad, India || San Francisco, USA || Sydney, Australia |+--------------------+3 rows in set (0.17 sec)

本教程的所有例子的运行结果都是使用bash shell显示

使用Connector/C++测试与数据库连接

下面的C++示例代码简单演示如何使用MySQL Connector/C++连接本机的MySQL服务。实例代码使用Connector/C++提供的类似于JDBC的API连接到MySQL中的test数据库,实行一条查询语句,从City表中获取所有行数据,从结果集中提取数据并显示在标准输出上,使用"Prepared Statements"插入几行数据到City表中。

示例代码仅仅供参考。不建议读者使用特定的编码风格。为了简单起见,实例代码假设用户提供了合法的输入,所以下面例子中并没有明确的错误检测代码。

203284379_1_20200927055000399.gif # cat MySQLConnectorC++Client.cpp/*Standard C++ headers*/#include#include#include#include#include/*MySQL Connector/C++ specific headers (注意:所有头文件都放在/usr/include/cppconn/下面)*/#include#include#include#include#include#include#include#include#include #define DBHOST "tcp://127.0.0.1:3306"#define USER "root"#define PASSWORD "admin"#define DATABASE "test"#define NUMOFFSET 100#define COLNAME 200using namespacestd;using namespacesql;static void retrieve_data_and_print (ResultSet *rs, int type, int colidx, stringcolname) {/*retrieve the row count in the result set*/cout<< "\nRetrieved" << rs -> rowsCount() << "row(s)." <next()) {if (type ==NUMOFFSET) { cout<< rs -> getString(colidx) < getString(colname) <isClosed()) {throw runtime_error("DatabaseMetaData FAILURE - database connection closed"); } cout<< "\nDatabase Metadata" < dbcon_meta (dbcon -> getMetaData());DatabaseMetaData*dbcon_meta = dbcon ->getMetaData(); cout<< "Database Product Name:" << dbcon_meta -> getDatabaseProductName() < getDatabaseProductVersion() < getUserName() << endl < getDriverName() < getDriverVersion() << endl < isReadOnly() < supportsTransactions() < supportsDataManipulationTransactionsOnly() < supportsBatchUpdates() < supportsOuterJoins() < supportsMultipleTransactions() < supportsNamedParameters() < supportsStatementPooling() < supportsStoredProcedures() < supportsUnion() << endl < getMaxConnections() < getMaxColumnsInTable() < getMaxColumnsInIndex() < getMaxRowSize() << "bytes" < rs ( dbcon_meta ->getSchemas()); cout<< "\nTotal number of schemas =" << rs -> rowsCount() <next()) { cout<< "\t" << row << "." << rs -> getString("TABLE_SCHEM") < rowsCount() == 0) {throw runtime_error("ResultSetMetaData FAILURE - no records in the result set"); } cout<< "ResultSet Metadata" < res_meta ( rs -> getMetaData() );ResultSetMetaData*res_meta = rs ->getMetaData();int numcols = res_meta ->getColumnCount(); cout<< "\nNumber of columns in the result set =" << numcols << endl < getColumnLabel (i+1); cout.width(20); cout<< res_meta -> getColumnTypeName (i+1); cout.width(20); cout<< res_meta -> getColumnDisplaySize (i+1) << endl < getColumnLabel(1); cout<< "\" belongs to the Table: \"" << res_meta -> getTableName(1); cout<< "\" which belongs to the Schema: \"" << res_meta -> getSchemaName(1) << "\"" << endl <= 2 ? argv[1] : DBHOST);const string user(argc >= 3 ? argv[2] : USER);const string password(argc >= 4 ? argv[3] : PASSWORD);const string database(argc >= 5 ? argv[4] : 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() <setSchema(database);/*retrieve and display the database metadata*/retrieve_dbmetadata_and_print (con);/*create a statement object*/stmt= con ->createStatement(); cout<< "Executing the Query: \"SELECT * FROM City\" .." < executeQuery ("SELECT * FROM City"); cout<< "Retrieving the result set .." < prepareStatement ("INSERT INTO City (CityName) VALUES (?)"); cout<< "\tInserting \"London, UK\" into the table, City .." < setString (1, "London, UK"); updatecount= prep_stmt ->executeUpdate(); cout<< "\tCreating a save point \"SAVEPT1\" .." < setSavepoint ("SAVEPT1"); cout<< "\tInserting \"Paris, France\" into the table, City .." < setString (1, "Paris, France"); updatecount= prep_stmt ->executeUpdate(); cout<< "\tRolling back until the last save point \"SAVEPT1\" .." <rollback (savept); con->releaseSavepoint (savept); cout<< "\tCommitting outstanding updates to the database .." <commit(); cout<< "\nQuerying the City table again .." < executeQuery ("SELECT * FROM City");/*retrieve the data from the result set and display on stdout*/retrieve_data_and_print (res, COLNAME,1, string ("CityName")); cout<< "Cleaning up the resources .." <close(); delete con; }catch (SQLException &e) { cout<< "ERROR: SQLException in" <<__file__ cout __func__ on line __line__ error code: sqlstate: e.getsqlstate message: unknown command server does not seem to support prepared statements at all. mysql runtime_error in e.what>

203284379_1_20200927055000399.gif

203284379_1_20200927055000399.gif # CC -VCC: Sun C++ 5.9 SunOS_i386 Patch 124864-09 2008/12/16# CC-o mysqlconnectorc++client -g0 -xO4 -features=extensions -I/opt/coolstack/mysql_32bit/include/mysql-I/export/expts/MySQLConnectorC++/include/cppconn -L/opt/coolstack/mysql_32bit/lib/mysql-L/export/expts/MySQLConnectorC++/lib -lmysqlclient_r -lmysqlcppconn MySQLConnectorC++Client.cpp# export LD_LIBRARY_PATH=/opt/coolstack/mysql_32bit/lib/mysql:/export/expts/ConnectorC++/lib/:$LD_LIBRARY_PATH# ./mysqlconnectorc++client localhost root admin testDatabase connection's autocommit mode = 0Database Metadata-----------------Database Product Name: MySQLDatabase Product Version:5.1.24-rc-standardDatabase User Name: root@localhostDriver name: MySQL Connector/C++Driver version:1.0.5Databasein Read-Only Mode?: falseSupports Transactions?: trueSupports DML Transactions only?: falseSupports Batch Updates?: trueSupports Outer Joins?: trueSupports Multiple Transactions?: trueSupports Named Parameters?: falseSupports Statement Pooling?: falseSupports Stored Procedures?: trueSupports Union?: trueMaximum Connections:151Maximum Columns per Table:512Maximum Columns per Index:16Maximum Row Size per Table:2147483639bytesDatabase schemas: Total number of schemas= 4 1. information_schema2. ISVe3. mysql4. testExecuting the Query:"SELECT * FROM City"..Retrieving the result set ..Retrieved3row(s).CityName--------Hyderabad, IndiaSan Francisco, USASydney, AustraliaResultSet Metadata------------------Number of columnsin the result set = 1Column Name/Label Column Type Column Size CityName VARCHAR30Column"CityName" belongs to the Table: "City" which belongs to the Schema: "test"Demonstrating Prepared Statements .. Inserting"London, UK"into the table, City .. Creating a save point"SAVEPT1".. Inserting"Paris, France"into the table, City .. Rolling backuntil the last save point "SAVEPT1".. Committing outstanding updates to the database ..Querying the City table again ..Retrieved4row(s).CityName--------Hyderabad, IndiaSan Francisco, USASydney, AustraliaLondon, UKCleaning up the resources ..

203284379_1_20200927055000399.gif

上述示例代码的一些重要步骤说明如下:

建立一个连接到MySQL Server

通过sql::Driver对象实例的sql::Connection成员与MySQL建立连接,sql::Driver对象通过sql::Driver::get_driver_instance函数的返回值设定,而sql::Driver::connect函数返回一个sql::Connection对象。

注:

上一段使用的::::符号为完全限定的函数名。例如,在sql::Driver::get_driver_instance()中,sql是名称空间,Driver是类名以及get_driver_instance()是函数名。在C++程序中如此使用Connector/C++,你可以在代码头中使用"using namespace sql;"指令,这样每次使用相应声明的时候就不需要用“sql::”前缀。所以本教程其余部分使用“sql”名称空间中的函数或其他成员时,都省略了“sql”名称空间的前缀,这样会更简单清晰。

下面是Driver::get_driver_instance和Driver::connect函数的签名。你可以通过查看安装程序中的driver.h头文件获取完整的函数列表。

203284379_1_20200927055000399.gif /*driver.h*/Driver*Driver::get_driver_instance()Connection* Driver::connect(const std::string& URL, const std::string& userName, const std::string&password)Connection* Driver::connect(std::map<:string connectpropertyval> properties)

203284379_1_20200927055000399.gif

connect在Driver类中是一个重载函数。这里有两个重载版本。在第一个版本中,connect接受一个数据库连接URL以及数据库的用户名和密码。第二个版本中,connector接受一个std::map对象,此对象是包含了数据库连接的URL,用户名和密码的键值对。

你可以在连接URL中指定TCP/IP,“tcp://[hostname[:port]][/schemaname]"的形式连接到MySQL。例如:tcp://127.0.0.1:5555/some_schema. hostname和port是可选的,默认使用127.0.0.1和3306.运行时,"localhost"会自动转换成127.0.0.1。是否指定schema name 也是可选的,如果没设置,则必须使用Connector::setSchema函数来设置schema。

如果你要使用UNIX域的套接口来连接本机的MySQL Server,需在数据库连接URL中指定"unix://path/to/unix_socket_file"。例如:unix://tmp/mysql.sock. 在Windwos中,你可以使用命名管道来连接MySQL Server,需要在数据库连接URL中指定字符串"pipe://path/to/the/pipe"。要启用管道支持,必须在启动MySQL时加上--enable-named-pipe选项。如果你没有使用--socket=name选项指定管道名称,那么会默认创建名为MySQL的命名管道。在Microsoft Windows中,name不区分大小写。

下列代码尝试连接到本地的MySQL Server默认端口:3306,使用root用户名,密码为admin,schema名称为test.

203284379_1_20200927055000399.gif using namespacesql;Driver*driver;Connection*con;try{ driver=get_driver_instance(); con= driver -> connect("tcp://127.0.0.1:3306/test", "root", "admin");}catch(..) { ..}

203284379_1_20200927055000399.gif

connect也可以像下面这样使用,调用第二个重载版本。ConnectPropertyVal是一个枚举类型,定义在connection.h头文件中。编译此段代码需要包含map头文件。

203284379_1_20200927055000399.gif ..std::map conn_properties;ConnectPropertyVal tmp;tmp.str.val= "unix:///tmp/mysql.sock";conn_properties [std::string("hostName")] =tmp;tmp.str.val= "root";conn_properties [std::string("userName")] =tmp;tmp.str.val= "admin";conn_properties [std::string("password")] =tmp;try{ driver=get_driver_instance(); con= driver ->connect(conn_properties);}catch(..) { ..}

203284379_1_20200927055000399.gif

如果你更喜欢使用指定UNIX套接口协议,可以重写上述代码的数据库连接URL,如下所示:

tmp.str.val = "unix://" "/tmp/mysql.sock";

一旦建立了连接,你就可以使用Connection::setSessionVariable函数来设置变量,如sql_mode。

C++ Specific Note

"sql::Connection *con = driver -> connect("tcp://127.0.0.1:3306", "root", "admin");”语句可以使用auto_ptr来重写: std::auto_ptr < sql::Connection > con ( driver -> connect("tcp://127.0.0.1:3306", "root", "admin") );= OR =use namespace std;use namespace sql;auto_ptr < Connection > con ( driver -> connect("tcp://127.0.0.1:3306", "root", "admin") );

C++标准模板类auto_ptr帮助开发者管理动态内存分配,防止在意想不到的情况下发生内存泄漏,比如在某些情况下,正常的清理(内存)代码被跳过了。auto_ptr对象与指针具有相同的语义,但是auto_ptr对象超出作用域时将会自动释放掉动态分配的内存。也就是说,使用auto_ptr时,你不必显式使用delete操作符来释放内存,delete con;

要使用auto_ptr类,你需要包含这个头文件,并且auto_ptr是定义在std名称空间内的,所以也要通过std名称空间来访问。type可以是指向任意类型/对象的指针。

至于采用auto_ptr智能指针机制,还是传统机制来动态管理内存,由读者自己决定。

获取一个Statement对象

当调用Connection::createStatement函数时,返回一个Statement对象,它可以用来向数据库服务器发送SQL语句。一般情况下,Statement对象执行的是不带参数的SQL语句。换句话说,一个Statement对象用于执行静态SQL语句,并返回其执行结果。如果需要执行多次不同输入的SQL语句,可以考虑使用Prepared Statements对象。

Connection::createStatement的函数签名(原型)如下所示,完整的Connection的接口函数列表,请阅看你的Connector/C++安装文件中的connection.h头文件

/*connection.h*/Statement* Connection::createStatement();

下面代码片段调用Connection对象中的createStatement函数,获得一个Statement类型的对象。

Connection *con;Statement*stmt;Statement stmt= con -> createStatement();

这个例子中,con是Connection类型的引用(指针)

执行SQL语句

在执行SQL语句前,你需要先连接数据库,并且选择相应的数据库架构。通过调用Connection对象中的setSchema函数来选择需要连接的架构,setSchema函数的参数是架构的名称。

以SQL语句作为(executeQuery的)参数,调用Statement::executeQuery函数执行查询语句。executeQuery()返回一个ResultSet对象。Statement::executeUpdate函数可用于执行特定的SQL语句,如INSERT,UPDATE,DELETE。或者是不返回任何结果的SQL语句,如SQL DDL语句。与excuteQuery()不同,excuteUpdate函数不返回ResultSet对象。相反,它返回INSERT,UPDATE,DELETE操作后受影响的行数。

如果你事先并不知道SQL语句是SELECT还是INSERT,UPDATE或DELETE,你可以使用execute函数。当SQL语句是SELECT操作时,execute()返回true,当SQL语句是INSERT,UPDATE,DELETE操作时,execute()返回false。如果语句是SELECT查询操作,你可以调用Statement实例中的getResultSet函数获取查询结果集。如果语句是INSERT,UPDATE,DELETE操作,你可以调用getUpdateCount()获取受影响的行数。

在少数情况下,一条SQL语句可能返回多个结果和/或更新行数。一般情况下,你可以忽略这一点。除非你执行一个存储过程,你知道可能会返回多个结果;或者动态执行未知的SQL语句。使用getResultSet或getUpdateCount函数可以获取结果,getMoreResults()可以检查是否还有其他结果集合。

相应的函数签名如下所示。完整的Connection和Statement的接口函数列表,请查看connection.h头文件。

203284379_1_20200927055000399.gif /*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();

203284379_1_20200927055000399.gif

上述所有函数都可能抛出SQLException(SQL异常),所以在代码中必须确保catch(捕捉)到这些异常。为了简单起见,在实例代码中并没有使用try...catch块(指retrieve_data_and_print函数中)。如果你重新查看完整的实例代码,你会发现其目的只是获取test数据库中City表的所有行数据。于是,使用executeQuery()的示例代码如下所示:

Statement *stmt;ResultSet*res;res= stmt -> executeQuery ("SELECT * FROM City");

executeQuery函数返回一个ResultSet对象,它包含了给定查询语句所生成的结果数据。当发生数据库访问错误,或调用已关闭的Statement对象,或给定的SQL语句产生的数据超过单一ResultSet对象,executeQuery将抛出SQLException。

另外,上述代码段可以用Statement::execute()重写,如下所示:

203284379_1_20200927055000399.gif bool retvalue = stmt -> execute ("SELECT * FROM City");if(retvalue) { res= stmt ->getResultSet();}else{ ...}

203284379_1_20200927055000399.gif

如果查询结果是一个ResultSet对象(SELECT操作),execute函数返回true,如果查询结果是更新的行数(UPDATE,INSERT,DELETE)或者无结果,execute函数返回false。如果execute()返回true,使用getResultSet函数可以获取结果集。如果查询结果是更新的行数或者没有结果,getResultSet返回NULL。

execute和getResultSet这两个函数在发生数据库访问错误或在已经关闭的Statement上调用时,都会抛出SQLException.如果你需要插入新记录到数据库,你可以使用executeUpdate函数,如下所示:

int updateCount = stmt -> executeUpdate ("INSERT INTO City (CityName) VALUES ('Napier, New Zealand')");

executeUpdate执行给定的SQL数据操作语言(DML)语句,例如INSERT,UPDATE,DELETE;或不返回任何数据的SQL语句,例如DDL语句。执行INSERT,UPDATE,DELETE操作,executeUpdate()返回受影响的行数,如果SQL语句不返回任何数据,executeUpdate()返回0值。

当发生数据库访问错误或在已关闭的Statement对象上调用executeUpdate(),或者是SQL语句产生一个结果集对象,executeUpdate都会抛出SQLException.

另一方面,使用execute和getUpdateCount函数可以重写上述代码段,如下所示:

203284379_1_20200927055000399.gif int updateCount = 0;bool retstatus = stmt -> execute ("INSERT INTO City (CityName) VALUES ('Napier, New Zealand')");if (!retstatus) { updateCount= stmt ->getUpdateCount();}else{ ...}

203284379_1_20200927055000399.gif

如果SQL语句的执行的返回结果是受(更新)影响的行数,execute函数返回false,此时可以使用getUpdateCount函数获得受影响行数值。如果SQL语句执行结果返回一个ResultSet对象或者更多结果,getUpdateCount()返回-1.

在已关闭的Statement对象上调用execute和getUpdateCount或出现数据库访问错误的情况下都会抛出SQLException.

从结果集中获取数据

前面的段落解析到,executeQuery和execute两个函数执行SQL查询语句,前者返回一个ResultSet实例。你可以使用ResultSet对象访问SQL查询语句从数据库返回的数据。没一个ResultSet维护一个游标(指针),它指向其当前数据行。利用游标可以顺序读取数据集中的行。在一行中,列的值可以以任意顺序访问。你可以根据列的位置(offset)或它们的列名/标签来访问,后者具有一定的容错性,尤其是在表的架构发生改变后。使用列标签或列名会使代码更加清晰。另一方面,通过列的索引或位置访问,可以提高性能。

列标签就是SQL“AS”子句中指定的标签名。如果SQL“AS”子句没有指定标签,那么标签名就是列名。例如在“SELECT CityName AS CN FROM City”中,CN就是列标签名。

存储在ResultSet中的数据可以通过getXXX函数来获取,例如getString() 或 getInt(),根据数据类型的不同使用相应的函数获取数据。使用使用ResulSet的next和previous函数移动游标指向下一行数据。

ResultSet会一直保持打开,即使生成他的Statement对象关闭了,重新执行可以获取多个结果集队列中的下一个结果。一旦Statement生成了结果集,该ResultSet会一直有效,直到显示或隐式的关闭它(才会失效),不论产生它的Statement对象状态如何,都不会影响到已经产生的ResultSet。

截至撰写这篇文章时,MySQL Connector/C++的Statement对象返回一个结果缓冲区。缓冲区缓存在客户端上。不论结果集多大,driver都会获取所有的数据。connector未来的版本Statement对象有望返回缓冲和非缓冲结果集。

相关的函数签名如下所示。ResultSet支持的接口完整列表请查看resultset.h头文件。 /* 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”返回的结果集只有一列CityName数据,数据类型为String,在MySQL中为VARCHAR类型

下列代码片段遍历ResultSet对象res,通过准确的列名获取每一行数据,并显示在标准输出上。

while (res ->next()) { cout<< rs -> getString("CityName") <

因为也可以通过列的索引访问,所以下列代码片段也能得到相同的效果:

while (res ->next()) { cout<< rs -> getString(1) <

getString()的整形参数引用查询语句中指定的列,列号从1开始。(译者注:比如“SELECT COLUMN1 COLUMN2 COLUMN3 FROM TABLE”返回的结果中,第一列就是COLUMN1,第二列为COLUMN2,第三列为COLUMN3,通过getString(1)、getString(2)、getString(3)获取对应数据)

这两个版本的getString()都返回列值。如果列值为空(NULL),则返回值为空字符串(string对象)。你可以通过ResultSet::isNull函数,以列索引或列名/列标签作为参数,检查相应的列值是否为SQL NULL。通过ResultSet::wasNull()函数可以确定读取的最后一列的值是否为SQL NULL,此函数没有参数。

下列实例演示如何反向遍历结果集中的数据:

203284379_1_20200927055000399.gif /*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") <

203284379_1_20200927055000399.gif

如果列名/列标签无效,或出现数据库访问错误,或在已关闭的ResultSet对象上调用getString(),getString()都会抛出SQLException.

(未完待续)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值