博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

MySQL connector c++使用笔记

Posted on 2016-10-14 14:04  bw_0927  阅读(2374)  评论(0)    收藏  举报

https://dev.mysql.com/doc/connector-cpp/en/connector-cpp-examples-complete-example-1.html

http://www.cnblogs.com/icejoywoo/p/3451991.html

 

MySQL的connector官方地址: http://dev.mysql.com/downloads/connector/

针对c++来说, 可以选择c或者c++的库.

c++的实现是参考了java的JDBC, 所以熟悉JDBC的人可以很快上手.

定义这样几个类

  • Connection

  • Driver

  • PreparedStatement

  • ResultSet

  • ResultSetMetaData

  • Statement

 下载安装mysql connector c++, 启动mysql, 使用test database.

准备数据(使用官方提供的示例数据, 参考 MySQL手册 3.3.3 http://dev.mysql.com/doc/refman/5.1/zh/tutorial.html)

1
2
3
4
5
6
7
8
CREATE TABLE pet (
name VARCHAR(20),
owner VARCHAR(20),
species VARCHAR(20),
sex CHAR(1),
birth DATE,
death DATE
);

 导入数据(路径可以为相对路径或绝对路径)

1
LOAD DATA LOCAL INFILE 'pet.txt' INTO TABLE pet;

 pet.txt(修改中间的间隔为\t)

1
2
3
4
5
6
7
8
Fluffy  Harold  cat f   1993-02-04  \N
Claws   Gwen    cat m   1994-03-17  \N
Buffy   Harold  dog f   1989-05-13  \N
Fang    Benny   dog m   1990-08-27  \N
Bowser  Diane   dog m   1979-08-31  1995-07-29
Chirpy  Gwen    bird    f   1998-09-11  \N
Whistler    Gwen    bird    \N  1997-12-09  \N
Slim    Benny   snake   m   1996-04-29  \N

 示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>
#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"
 
int main() {
    const char* user = "root";
    const char* passwd = "";
    const char* host = "tcp://localhost:3306";
    const char* database = "test";
    try {
        sql::mysql::MySQL_Driver* driver =
                sql::mysql::get_mysql_driver_instance();
        sql::Connection* conn = driver->connect(host, user, passwd);
        conn->setSchema(database);
        std::cout << "status: " << conn->isClosed() << std::endl;
        sql::Statement *stmt = conn->createStatement();
        sql::ResultSet *res = stmt->executeQuery("select 1;");
        while (res->next()) {
            std::cout << res->getInt(1) << std::endl;
        }
 
        res = stmt->executeQuery("select * from pet;");
        while (res->next()) {
            std::cout << res->getString(1) << ",";
            std::cout << res->getString(2) << ",";
            std::cout << res->getString(3) << ",";
            std::cout << res->getInt(4) << ",";
            std::cout << res->getString(5) << ",";
            std::cout << res->getString(6) << std::endl;
        }
 
        delete res;
        delete stmt;
        delete conn;
    catch (sql::SQLException& e) {
        std::cout << "# ERR: SQLException in " << __FILE__;
        std::cout << "(" << __FUNCTION__ << ") on line " << __LINE__ << std::endl;
        std::cout << "# ERR: " << e.what();
        std::cout << " (MySQL error code: " << e.getErrorCode();
        std::cout << ", SQLState: " << e.getSQLState() << " )" << std::endl;
    }
    return 0;
}

 运行结果

1
2
3
4
5
6
7
8
9
10
status: 0
1
Fluffy,Harold,cat,0,1993-02-04,
Claws,Gwen,cat,0,1994-03-17,
Buffy,Harold,dog,0,1989-05-13,
Fang,Benny,dog,0,1990-08-27,
Bowser,Diane,dog,0,1979-08-31,1995-07-29
Chirpy,Gwen,bird,0,1998-09-11,
Whistler,Gwen,bird,0,1997-12-09,
Slim,Benny,snake,0,1996-04-29,

 

参考文档:

  1. 官方手册: http://dev.mysql.com/doc/refman/5.6/en/connector-cpp.html
  2. MySQL Connector/C++文档翻译: http://www.cnblogs.com/dvwei/archive/2013/04/18/3029464.html

 

 

//静态编译出错:
//g++ -I /usr/local/include/ -I /usr/local/boost_1_56_0/ test.cpp /usr/lib64/libmysqlcppconn-static.a -pthread -ldl -g
//
//动态库:
//g++ -I /usr/local/include/ -I /usr/local/boost_1_56_0/ test.cpp -L /usr/lib64/ -lmysqlcppconn -pthread -ldl -g
//
//
//

http://downloads.mysql.com/docs/connector-cpp-relnotes-en.pdf

http://downloads.mysql.com/docs/connector-cpp-en.pdf

 

get_driver_instance() is now only available in dynamic library builds; static builds do not have this symbol.

 

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.

 

 

http://www.cnblogs.com/dvwei/archive/2013/04/18/3029464.html

 

获取一个Statement对象

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

执行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.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(SQL异常),所以在代码中必须确保catch(捕捉)到这些异常

 

 

Statement *stmt;
ResultSet *res;

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

从结果集中获取数据

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

 

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

 

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

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

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

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

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,此函数没有参数。

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

复制代码
/* 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;
}
复制代码

 

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