MySql数据库的连接和事务处理
2016-08-16 23:22
761 查看
在写聊天工具的服务端的时候,需要使用到数据库对客户端相关信息的存储,例如用户信息、用户相关的好友信息、用户所加入的群,讨论组、聊天时的离线消息,消息的历史记录等。用户在对相应的操作时候,后台数据库要进行实时的更新。本次主要描述使用QT库进行MySql数据的连接和相关的事务处理。
1. MySql数据库连接
QSqldatabase进行对数据库的连接。QT使用驱动程序与MySql的接口进行通信。
(1)Qsqldatabase类提供了addDatabase(constQString &type, const QString &connectionName = QLatin1String(defaultConnection ))函数将type类型的数据库添加到连接列表。第一个参数为所要连接的数据库类型,MySql为QMYSQL。第二个为连接数据库的名称。如果缺省该参数,该连接为默认连接。使用Qsqldatabase::database()获取该默认连接。
(2)使用setDatabaseName()、setUserName()、setPassword()和setHostName()进行数据库的相关设置。
(3)使用open()函数进行物理连接。
2. 事务处理
QSqlQuery进行相应的事务的处理。在事务完成后,例如select执行完毕,需要使用QsqlQuery::commit()或者QsqlQuery::rollback()结束当前事务。
QsqlQuery::commit:提交当前事务。将该事务所做的更新在数据库中持久保存。在事务被提交后,一个新的事务自动开始。
QSqlQuery::rollback():回滚当前事务。撤销该事务中所有SQL语句对数据库的更新。
(1)创建数据表
实例化QSqlQuery一个对象query,并且传入QSqldatabase的对象,此时会调用QSqlQuery::QSqlQuery(QSqlDatabasedb)构造函数,完成query的初始化,说明对象query对db所连接的数据库进行相关事务。
(2)select查询操作
通过用户的好友ID来查询该好友的相关信息。在UserFriends表中外键为friendID,可通过该外键索引到UserInformation表中和主键userID相等的一个元组,所以SQL语句如下:
在SQL中采用了占位符,目的是绑定变量,这样可以减少数据SQL的硬解析,所以执行效率会提高不少。硬解析简言之即一条SQL语句没有被运行过,处于首次运行,则需要对其进行语法分析,语义识别,跟据统计信息生成最佳的执行计划,然后对其执行。
例如下一条SQL语句
QSqlQuery中提供了QSqlQuery::prepare()和QSqlQuery::addBindValue()函数或者QSqlQuery::bindValue()进行变量的绑定。
有如下绑定方法:
在查询到一个有确定元组个数的结果集中使用next进行向下索引。
a.如果结果集被定位在第一个记录之前,刚刚执行完一个查询就处于这种状态,那么可以用此函数来检索第一个记录。
b.如果结果集被定位在最后一个记录之后,那么什么都不会改变,返回FALSE。
c.如果结果集被定位在中间,此函数可以检索下一个记录。
最后将查询到的结果保存到变量。使用value返回域 i 的值。用SELECT 语句的文本,域被从左到右编号,比如:在"select forename, surname from people",域0是forename 而域1 是surname。
1. MySql数据库连接
QSqldatabase进行对数据库的连接。QT使用驱动程序与MySql的接口进行通信。
(1)Qsqldatabase类提供了addDatabase(constQString &type, const QString &connectionName = QLatin1String(defaultConnection ))函数将type类型的数据库添加到连接列表。第一个参数为所要连接的数据库类型,MySql为QMYSQL。第二个为连接数据库的名称。如果缺省该参数,该连接为默认连接。使用Qsqldatabase::database()获取该默认连接。
(2)使用setDatabaseName()、setUserName()、setPassword()和setHostName()进行数据库的相关设置。
(3)使用open()函数进行物理连接。
bool IMDatabaseCtrl::CreatConnection() { if (m_db -> isOpen()) // 是否已经连接数据库 return true; if (QSqlDatabase::contains("chatdb")) // 数据库连接列表中是否包含mysql m_db = QSqlDatabase::database("chatdb"); // 连接列表存在,获取该数据库 else { m_db = QSqlDatabase::addDatabase("QMYSQL"); //添加到数据库连接列表 if (m_db) m_db -> setDatabaseName("chatdb"); // 设置数据库名称 } if (m_db) { m_db -> setUserName("root"); m_db -> setPassword("123456"); m_db -> setHostName(QLatin1String("localhost")); if (!m_db -> open()) { // 连接是否成功 m_db -> close(); return false; } else return true; } }
2. 事务处理
QSqlQuery进行相应的事务的处理。在事务完成后,例如select执行完毕,需要使用QsqlQuery::commit()或者QsqlQuery::rollback()结束当前事务。
QsqlQuery::commit:提交当前事务。将该事务所做的更新在数据库中持久保存。在事务被提交后,一个新的事务自动开始。
QSqlQuery::rollback():回滚当前事务。撤销该事务中所有SQL语句对数据库的更新。
(1)创建数据表
实例化QSqlQuery一个对象query,并且传入QSqldatabase的对象,此时会调用QSqlQuery::QSqlQuery(QSqlDatabasedb)构造函数,完成query的初始化,说明对象query对db所连接的数据库进行相关事务。
static const QString CREATE_TABLE_USERINFORMATION_SQL = "create table UserInformation (" "userID varchar(10)" "head int" "nickName varchar(20)" "password varchar(15)" "sex char(4)" "birthday varchar(20)" "question varchar(50)" "answer varchar(20)" "name varchar(10)" "phone int" "address varchar(20)" "regDate varchar(20)" "status int" "primary key (userID))"; static const QString CREATE_TABLE_USERFRIENDS_SQL = "create table UserFriends (" "userID varchar(10)" "friendID varchar(10)" "groupName varchar(20)" "remarkName varchar(10)" "primary key (userID, friendID)" "foreign key (friendID) references UserInformation) "; bool IMDatabaseCtrl::createTable() { if (!CreatConnection()) return false; QSqlDatabase::database().transaction(); // 初始化事务 QSqlQuery query(*m_db); // 创建数据表 query.exec(CREATE_TABLE_USERINFORMATION_SQL); query.exec(CREATE_TABLE_USERFRIENDS_SQL); QSqlDatabase::database().commit(); // 提交事务 return true; }
(2)select查询操作
通过用户的好友ID来查询该好友的相关信息。在UserFriends表中外键为friendID,可通过该外键索引到UserInformation表中和主键userID相等的一个元组,所以SQL语句如下:
static const QString SEARCH_FRIENDS_IN_USERFRIENDS_USERINFORMATION_SQL = "select UserFriends.friendID, UserFriends.groupName, " "UserInformation.nickName, UserFriends.remarkName" "UserInformation.status, UserInformation.head" "from UserInformation, UserFriends" "where UserFriends.friendID = ?" "and UserInformation.userID = UserFriends.friendID;";
在SQL中采用了占位符,目的是绑定变量,这样可以减少数据SQL的硬解析,所以执行效率会提高不少。硬解析简言之即一条SQL语句没有被运行过,处于首次运行,则需要对其进行语法分析,语义识别,跟据统计信息生成最佳的执行计划,然后对其执行。
例如下一条SQL语句
select * fromUserInformation where userID = 1;如果要对很多userID的信息进行查询,会写很多相同的SQL的语句,而且每条语句都要被数据库解析一次,这样比较浪费资源。因此将1换成占位符 ? ,无论userID后面的值如何都不要重复解析。
QSqlQuery中提供了QSqlQuery::prepare()和QSqlQuery::addBindValue()函数或者QSqlQuery::bindValue()进行变量的绑定。
有如下绑定方法:
//使用命名占位符名称绑定: QSqlQuery query; query.prepare("INSERT INTO person (id, forename, surname) " "VALUES (:id, :forename, :surname)"); query.bindValue(":id", 1001); query.bindValue(":forename", "Bart"); query.bindValue(":surname", "Simpson"); query.exec(); //使用命名占位符位置绑定: QSqlQuery query; query.prepare("INSERT INTO person (id, forename, surname) " "VALUES (:id, :forename, :surname)"); query.bindValue(0, 1001); query.bindValue(1, "Bart"); query.bindValue(2, "Simpson"); query.exec(); //使用位置参数占位符位置绑定: QSqlQuery query; query.prepare("INSERT INTO person (id, forename, surname) " "VALUES (?, ?, ?)"); query.bindValue(0, 1001); query.bindValue(1, "Bart"); query.bindValue(2, "Simpson"); query.exec(); QSqlQuery query; query.prepare("INSERT INTO person (id, forename, surname) " "VALUES (?, ?, ?)"); query.addBindValue(1001); query.addBindValue("Bart"); query.addBindValue("Simpson"); query.exec();
在查询到一个有确定元组个数的结果集中使用next进行向下索引。
a.如果结果集被定位在第一个记录之前,刚刚执行完一个查询就处于这种状态,那么可以用此函数来检索第一个记录。
b.如果结果集被定位在最后一个记录之后,那么什么都不会改变,返回FALSE。
c.如果结果集被定位在中间,此函数可以检索下一个记录。
最后将查询到的结果保存到变量。使用value返回域 i 的值。用SELECT 语句的文本,域被从左到右编号,比如:在"select forename, surname from people",域0是forename 而域1 是surname。
int IMDatabaseCtrl::searchFriendSimpleInformationByID(const QString &id, FriendInformation &friInf) { if (!CreatConnection()) return GET_FRIEND_FAIL; QSqlDatabase::database().transaction(); QSqlQuery query(*m_db); query.prepare(SEARCH_FRIENDS_IN_USERFRIENDS_USERINFORMATION_SQL); query.addBindValue(id); query.exec(); QSqlDatabase::database().commit(); if (!query.isActive()) { m_db -> close(); return GET_FRIEND_FAIL; } if (query.size() <= 0) { m_db -> close(); return GET_FRIEND_FAIL; } if (query.isSelect()) { if (query.next()) { friInf.m_userID = query.value(0).toString(); friInf.m_groupName = query.value(1).toString(); friInf.m_nickname = query.value(2).toString(); friInf.m_remarkName = query.value(3).toString(); friInf.m_status = query.value(4).toInt(); friInf.m_headPortrait = query.value(5).toInt(); return GET_FRIEND_SUCCESS; } } return GET_FRIEND_FAIL; }
相关文章推荐
- WebSphere Application Server ND V7中如何处理容器管理的数据库事务中会话 Bean 的连接异常?
- PHP对MYSQL数据库进行事务处理及表锁定
- [原创]C#中使用ADO.NET连接SQL Server数据库,自动增长字段用作主键,处理事务时的基本方法
- MySQL数据库连接数问题及处理
- 利用连接池对MySql数据库连接处理
- 正文内容 mysql数据库添加添加事务处理为mysql数据库添加添加事务处理的方法-
- mysqli学习笔记 mysqli连接,multi_query多语句查询,SQL预处理stmt,事务处理
- Nhibernate中的连接超时时事务回滚引发异常的处理方法
- MYSQL数据库事务处理和锁机制
- JSP连接Mysql数据库详解及乱码处理
- 代码中进行事务处理 -多次新建连接导致的问题。
- MyGeneration连接MySql数据库的处理步履
- MySQL数据库连接超时(wait_timeout)问题的处理
- 为mysql数据库添加添加事务处理的方法
- 关于ADO 连接 SQLServer的事务处理。
- 使用proxool连接sybase时处理事务的问题
- 正好整理了一下,自己做了个连接数据库的组件,支持SQLSERVER,ACCESS,ORACLE,FoxPro,MySql,IBM DB2,DBF等数据库,并且支持事务处理
- MySQL数据库连接异常断开导致事务没提交的解决办法
- PHP对MYSQL数据库进行事务处理及表锁定
- JSP连接Mysql数据库详解及乱码处理