mysql connector 教程_MySQL Connector/C++入门教程(上)

目录

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

Connector/C++可用于连接MySQL5.1及其以后版本。

在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:

Create Table: CREATE TABLE `City` ( `CityName` varchar(30) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=ascii

然后向City表中添加一些数据。最后表的内容为:

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

#include

#include

#include

#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<: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.

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<: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.h */

Statement* Connection::createStatement();

下面的的代码段通过调用Connection对象的createStatemenet来获取一个Statement对象:

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()使游标移到结果集中的下一条或上一条记录。

Statement执行SQL语句返回ResultSet对象后,ResultSet就变成一个独立的对象,与原先的Statement再也没有联系,即使Statement对象关闭,重新执行其他sql语句,或者获取多个结果集中的下一个。ResultSet将一直有效,除非显式或隐式地将其关闭。

在撰写本文时,对于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上执行调用该方法。

未完待续!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/539693.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

14-项目开发总结报告(GB8567——88)

项目开发总结报告&#xff08;GB8567——88&#xff09;1引言1.1编写目的说明编写这份项目开发总结报告的目的&#xff0c;指出预期的阅读范围。1.2背景说明&#xff1a;a&#xff0e; 本项目的名称和所开发出来的软件系统的名称&#xff1b;b&#xff0e; 此软件的任务提出者、…

Oracle 并行查询

所谓并行执行&#xff0c;是指能够将一个大型串行任务&#xff08;任何DML&#xff0c;一般的DDL&#xff09;物理的划分为叫多个小的部分&#xff0c;这些较小的部分可以同时得到处理。 何时使用并行执行: 1、必须有一个非常大的任务 2、必须有充足的资源&#xff08;CPU,I…

python中求二维数组元素之和_python二维列表求解所有元素之和

相信很多初学小伙伴都会遇到二维列表求解所有元素之和问题,下面给出两种两种常见的求和方法。 方法1: 思想:遍历整个二维列表元素,然后将所有元素加起来 1 def Sum_matrix(matrix): 2 sum=0 3 for i in range(len(matrix)): 4 for j in range(len(matrix[i])): 5 sum+=matr…

maven 国内私服

2019独角兽企业重金招聘Python工程师标准>>> <repositories> <repository> <id>aliyun-cache</id> <name>aliyun-cache</name> <url>http://maven.aliyun.com/nexus/content/groups/public&…

mysql添加约束之前不满足_MySQL:添加约束(如果不存在)

小编典典有趣的问题。您可能需要在调用CREATE TABLE语句之前禁用外键&#xff0c;然后再启用它们。这将允许您直接在CREATE TABLEDDL中定义外键&#xff1a;例&#xff1a;SET FOREIGN_KEY_CHECKS 0;Query OK, 0 rows affected (0.00 sec)CREATE TABLE IF NOT EXISTS rabbits …

oracle函数trunc的使用

原文&#xff1a;http://blog.csdn.net/eleven204/article/details/6712538 -------------------------------------- 1、日期比较时精确到日&#xff0c;可以使用 TRUNC(sysdate,dd)函数。 函数支持格式有&#xff1a;yyyy MM dd hh Mi&#xff0c;没有精确到 秒 可以用 se…

Mycat快速入门

1.Mycat介绍 Mycat 是一个开源的分布式数据库系统&#xff0c;是一个实现了 MySQL 协议的的Server&#xff0c;前端用户可以把它看作是一个数据库代理&#xff0c;用 MySQL 客户端工具和命令行访问&#xff0c;而其后端可以用MySQL 原生&#xff08;Native&#xff09;协议与多…

python字符串常量有什么区别_Python经典面试题:is与==的区别

is用于判断两个对象是否为同一个对象&#xff0c;具体来说是两个对象在内存中的位置是否相同。python为了提高效率&#xff0c;节省内存&#xff0c;在实现上大量使用了缓冲池技术和字符串intern技术。整数和字符串是不可变对象&#xff0c;也就意味着可以用来共享&#xff0c;…

left join、right join、inner join的区别

left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录 right join(右联接) 返回包括右表中的所有记录和左表中联结字段相等的记录 inner join(等值连接) 只返回两个表中联结字段相等的行 举例如下&#xff1a; ----------------------------------------…

Javascript Proxy对象 简介

Javascript Proxy对象 简介 本文转载自&#xff1a;众成翻译 译者&#xff1a;eJayYoung 链接&#xff1a;http://www.zcfy.cc/article/4755 原文&#xff1a;https://blog.campvanilla.com/advanced-guide-javascript-proxy-objects-introduction-301c0fce9432 Javascript …

App架构经验总结

原文地址&#xff1a;http://www.iteye.com/news/31472-------------------------------------------------------------架构因人而异&#xff0c;不同的架构师大多会有不同的看法&#xff1b;架构也因项目而异&#xff0c;不同的项目需求不同&#xff0c;相应的架构也会不同。…

python数字排序 循环_【python-leetcode448-循环排序】找到所有数组中消失的数字

问题描述&#xff1a;给定一个范围在 1 ≤ a[i] ≤ n ( n 数组大小 ) 的 整型数组&#xff0c;数组中的元素一些出现了两次&#xff0c;另一些只出现一次。找到所有在 [1, n] 范围之间没有出现在数组中的数字。您能在不使用额外空间且时间复杂度为O(n)的情况下完成这个任务吗…

saiku+kettle整合(六)olap操作

title: saikukettle整合&#xff08;六&#xff09;olap操作 tags: categories: saiku date: 2016-08-25 18:18:54 使用saiku可以对应使用相关olap操作 OLAP的基本操作 我们已经知道OLAP的操作是以查询——也就是数据库的SELECT操作为主&#xff0c;但是查询可以很复杂&#xf…

携程Docker实践

原文地址&#xff1a;http://www.iteye.com/news/31468 请点击原文阅读 ---------------------以下是原文---------------------- 从去年底开始&#xff0c;携程开始计划把Docker引入到携程的云平台&#xff0c;这是系统研发部一部分的工作任务&#xff0c;携程系统研…

mysql全文索引thinkphp_ThinkPHP5 使用迅搜 (XunSearch) 实现全文检索实例指导

前期准备入坑了一天&#xff0c;折腾的无语&#xff0c;个人观点&#xff1a;【文档太差&#xff0c;适合学习思路&#xff0c;不建议入坑】背景最近在整理全文检索解决方案注意到 xunsearch 的评价很高&#xff0c;在此记录一番场景描述此处作为对 xunsearch 的初次使用&#…

为何有些程序员总是想要“干掉”产品经理?

好了&#xff0c;我准备去和产品经理做斗争去了&#xff0c;请祝我好运吧&#xff01;小编花了大量时间收集了很多干货编程学习资源&#xff0c;其中资源包括 算法&#xff0c;大数据&#xff0c;人工智能&#xff0c;Python&#xff0c;Android&#xff0c;iOS&#xff0c;Jav…

多个left join 产生多个结果

select a.*,to_char(To_date(20160403000000, yyyyMMddhh24miss),yyyy/mm/dd) as omc_start_time,to_char(To_date(20160404000000, yyyyMMddhh24miss),yyyy/mm/dd) as omc_end_time,ROUND(sc."切换成功率",2) AS "OMC-源小区切换成功率%",ROUND(sc."…

查看进程占用,并kill掉

今天发现8899端口被占&#xff0c;服务器启动失败&#xff0c;用了下面的命令解决。 [rootltesqm Toolbox]# netstat -tunlp |grep 8899 tcp 0 0 :::8899 :::* LISTEN 28279/java [rootltesqm Toolbox]…

Spark算子篇 --Spark算子之combineByKey详解

一。概念 rdd.combineByKey(lambda x:"%d_" %x, lambda a,b:"%s%s" %(a,b), lambda a,b:"%s$%s" %(a,b))三个参数&#xff08;都是函数&#xff09;第一个参数&#xff1a;给定一个初始值&#xff0c;用函数生成初始值。第二个参数&#xff1a;c…

mysql proxy 主从_【MYSQL知识必知必会】MySQL主从复制读写分离(基于mysql-proxy实现)...

MySQL主从复制读写分离(基于mysql-proxy实现)http://mirror.bit.edu.cn/mysql/Downloads/MySQL-Proxy/mysql-proxy-0.8.4-linux-glibc2.3-x86-64bit.tar.gz解压tar zxvf mysql-proxy-0.8.4-linux-glibc2.3-x86-64bit.tar.gz创建mysql-proxy帐号并授权分别在主从数据库中创建mys…