Qt连接数据库(sqlite)并操作数据,封装数据库类,详细讲解和错误总结(Qt sqlite driver not load)

917 阅读2分钟

前言

本文是关于如何在windows用qt连接并操作sqlite的说明,以便于大家能够更多地投入开发中。

sqlite安装

下载sqlite

SQLite 下载页面下载  sqlite-dll-win64-*.zip 或者  sqlite-dll-win32-*.zip (你用多少位就下哪种)和sqlite-tools-win32- *.zip压缩文件

image.png

解压:
我是解压到自建的D:\sqlite image.png

配置PATH环境变量

  1. 在“搜索”中,搜索以下内容并进行选择:系统(控制面板)
  2. 单击高级系统设置链接。
  3. 单击环境变量。 在系统变量部分中,找到并选择 PATH 环境变量。 单击编辑。 ...
  4. 在编辑系统变量(或新建系统变量)窗口中,指定 PATH 环境变量的值,编辑。 image.png

image.png

winR+cmd 命令行中输入sqlite3

进入sqlite命令即为配置成功 image.png

添加系统变量

QT_PLUGIN_PATH = path(找到自己的plugins目录)

不然一会儿操作数据库报错,会显示Qt sqlite driver not load image.png

数据库连接和操作

右键项目属性,在qt project settings里面勾选modules
tip: linux是在pro文件添加语句 QT += sql: image.png

核心代码

QSqlDatabase db = QSqlDataBase::addDatabase("QSLITE");//添加数据库驱动
db.setDatabaseName("");//数据库文件名称

db.setHostName("");//通过网络访问,设置主机名
db.setUserName("");//连接用户名
db.setPassword("");//连接密码

数据库设置的文件要为应用文件目录。不然连上了数据库,各种sql操作都会不成功

如果不设置目录,db文件在源代码文件中生成:

image.png

//注意这里用的绝对路径
QString dbPath = QCoreApplication::applicationDirPath() + "//名.db";
db.setDatabaseName(dbPath);

QT中QDir::currentPath()和QAppllication::appllicationDirPath()用法区别 设置后,db文件在应用文件目录中生成:

image.png

运用
#include <QSqlError>
#include <QDebug>
以助于帮我们了解错误和调试

数据库的打开和关闭

	if (db.open()) {
		qDebug() << "success";
	}
        else {
		qDebug() << "connection error";
	}
        db.close()

增删改查

QSqlQueryModel封装了执行SELECT语句从数据库查询数据的功能,但是QSqlQueryModel只能作为只读数据源使用不可以编辑数据

    QSqlQueryModel model;
    QString str = QString("SELECT * FROM student");
    model.setQuery(str);
    ui->tableView->setModel(&model);

QSqlQuery是能执行任意SQL语句的类,如select、insert、update、delete等。能和QSqlQueryModel一起联合使用。

    QSqlQuery query;
    QString str = QString("CREATE TABLE student ("
                          "id INT PRIMARY KEY NOT NULL,"
                          "name TEXT NOT NULL,"
                          "score REAL NOT NULL)");
    if(query.exec(str) == false){
        qDebug() << str;
    }
    else{
        qDebug() << "创建数据表成功!";
    }

封装

void SqliteDb::SetName(QString &dbName) {
	if (dbName.contains(".db", Qt::CaseInsensitive)) {
		dbName = "//" + dbName;
	}else {
		dbName = "//" + dbName + ".db"; 
	}
	dbName =  QCoreApplication::applicationDirPath() + dbName;
}//获取路径名

void* SqliteDb::ConnectDB (QString DatabaseName)
{
	bool isHaveDriver = false;
	QStringList drig = QSqlDatabase::drivers();
	for (QStringList::iterator iter = drig.begin(); iter != drig.end(); iter++)
	{
		if (*iter == "QSQLITE")
		{ 
			isHaveDriver = true;
			break;
		}
	}

	if(!isHaveDriver)
	{
		m_LastError = "没有SQLITE驱动!";
		return false;
	}
	//GetDBinfo();

	//db->setHostName(DBIP);
	//db->setUserName(UserName);
	//db->setPassword(Password);
	//db->setPort(Port);
	SetName(DatabaseName);
	if (QSqlDatabase::contains("qt_sql_default_connection")) { 
		db = new QSqlDatabase(QSqlDatabase::database("qt_sql_default_connection")); 
	} else { 
		db = new QSqlDatabase(QSqlDatabase::addDatabase("QSQLITE"));  
		db->setDatabaseName(DatabaseName);
	}
	if (db->open())
	{
		return (void*)db;
	}
	else
	{
		QSqlError er = db->lastError();
		m_LastError = er.text();
		delete db;
		db = nullptr;
	}
	return nullptr;
}//连接数据库

void SqliteDb::DisConnectDB (void* handle)
{
	if (handle != nullptr)
	{
		QSqlDatabase* db = (QSqlDatabase*)handle;
		db->close();
		delete db;
		db = nullptr;
	}
}//断开数据库

也可以封装便于项目指执行的sql语句,以基础的sql执行为例:

bool SqliteDb::ExecuteSql( void* handle, QString sql )
{
	if (handle != nullptr) {
		QSqlDatabase* db = (QSqlDatabase*)handle;
		QSqlQuery transOper(*db);
		if (!transOper.exec("begin"))
		{
			m_LastError = "事物开启失败";
			return false;
		}
		QSqlQuery query(*db);
		query.prepare(sql);
		if (!query.exec()){
			QString errstr = "SQL语句执行失败!错误提示:";
			errstr += query.lastError().databaseText();
			errstr += "执行回滚操作";
			if (!transOper.exec("ROLLBACK"))
			{
				errstr += "事物回滚失败!";
			}
			m_LastError = errstr;
			return false;
			}
		}
		if (!transOper.exec("COMMIT"))
		{
			m_LastError = "事物提交失败";
			return false;
		}
		return true;
	}
	return false;
}

其他的根据具体需求,合理分装。 最后使用实例:

SqliteDb *sqlite = SqliteDb::getInstance();

if (QSqlDatabase* db = (QSqlDatabase*)sqlite->ConnectDB("qt")) {
...
...
sqlite->DisConnectDB(db);
}