QT操作sqlite数据库汇总
QT自帶的QSqlite數據庫中實現id主鍵自增長
QSqlite是QT自帶的輕量級數據庫,使用起來非常方便,對系統環境也沒有任何的環境要求,可移植性非常好,適合數據量不是太大,要求不是太高的程序。本文中,就介紹一點,怎么實現在QSqlite中的數據表實現id自增長,方法很簡單。
一、創建數據表時,主鍵設置為id,并且數據類型設置為integer。設置成integer的主鍵,默認自增長。
create table m_table (id integer primary key,m_equip varchar(10),m_place varchar(10))
二、使用插入命令的時候,要注意對應關系。
QString(insert into %1 (Name,Place) value(’%2’,’%3’)").arg(“computer”).arg(“office”);
Name和Place是我生成的表的列名,后面是數值。一開始我為了圖省事,省略了列名,如下
QString(insert into %1 value(’%2’,’%3’)").arg(“computer”).arg(“office”);//錯誤示范
因此一直無法實現自增長插入。
SQLite設置主鍵自動增長及插入語法
SQLite中,一個自增長字段定義為INTEGER PRIMARY KEY AUTOINCREMENT,那么在插入一個新數據時,只需要將這個字段的值指定為NULL,即可由引擎自動設定其值,引擎會設定為最大的rowid+1。如果表為空,那麼將會插入1。
比如,有一張表ID為自增:
CREATE TABLE Product
(
ID INTEGER PRIMARY KEY AUTOINCREMENT,
Name NVARCHAR(100) NOT NULL
)
那麼,插入的SQL就是:
INSERT INTO Product VALUES(NULL, '產品名稱')
GO
SQLite中不支持關鍵字top
select top 1 oid from orderinfo order by oid desc ;?(×)
select oid from orderinfo order by oid desc limit 0,1;(√)
?網上查到資料說,從 SQLite 的 2.3.4 版本開始,如果將一個表中的一個字段聲明為 INTEGER PRIMARY KEY,那么只需向該表的該字段插入一個 NULL 值,這個 NULL 值將自動被更換為比表中該字段所有行的最大值大 1 的整數;如果表為空,那么將被更換為 1。
CREATE TABLE "ProcessList"([Id] integer(4) PRIMARY KEY,[Type] varchar(20),[Name] varchar(30),[IsUse] int ?) ? ?執行insert into processlistvalues(null,'a','b',1) ? ?在邏輯意義上等價于:insert into processlist VALUES((SELECT max(Id) FROM processlist)+1, 'a','b',1);
insert into processlistvalues(null,'aa','bb',1) ? ?執行兩條插入語句后再查詢表中數據:select * from processlist ? ?結果如下:
Id Type Name IsUse1 ?a ? ? ? b ? ? ? 1 2 ?aa ? ? bb ? ? 1 ? ? 一個新的API函數 sqlite3_last_insert_rowid() 返回最近的插入操作的整形鍵.注意這個整型鍵始終比之前插入表中的最后一個鍵大1。新鍵相對于表中的已有鍵來說是唯一的, 但它可能與之前從表中刪除的鍵值重疊。要始終得到在整個表中唯一的鍵,在INTEGER PRIMARY KEY的聲明之前加關鍵詞AUTOINCREMENT.這樣被選的鍵將總是比表中已存在的最大鍵大1。若可能的最大鍵已存在于表中,INSERT操作將失敗并返回一個SQLITE_FULL錯誤碼
?
創建數據表格,設置主鍵自增
創建數據庫時,啟用主鍵自增加特性
Create table testTable (id INTEGER PRIMARY KEY AUTOINCREMENT,。。。。
注意事項:設置主鍵自增時(AUTOINCREMENT),主鍵類型必須是INTEGER,不能使用INT,否則會報錯。
插入數據后,獲取自增的主鍵值
QSqlQuery::exec(“SELECT last_insert_rowid()”);
QSqlQuery::next();
int id = QSqlQuery::value(0).toInt(&ok);
或者使用
QSqlQuery::lastInsertId()).toInt();
//*************************************************************sqlite操作概念2
QT & sqlite3:
先說一下QT自帶數據庫sqlite3和另外用sqlite3插件的區別,他們的功能是一樣的,但是代碼就不一樣了。QT對數據庫具有完善的支持,不需要加任何其他插件就可以直接使用,但是如果你要是加了sqlite3插件,調用數據庫就跟直接調用一個驅動一樣,直接調用接口函數:open、close、……,換言之QT自帶的數據庫語言就用不上了。
一、使用Qt自帶的數據庫sqlite3
Qt自帶了很多常用的數據庫驅動,使用起來非常方便如下圖所示:
使用Qt自帶數據庫SQLite3的代碼實例:
Connect to Sqlite and do insert, delete, update and select
Foundations of Qt Development\Chapter13\sqltest\sqlite\main.cpp /** Copyright (c) 2006-2007, Johan Thelin* * All rights reserved.* * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met:* * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer.* * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution.* * Neither the name of APress nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission.* * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.**/#include <QApplication>#include <QtSql> #include <QtDebug>int main( int argc, char **argv ) {QApplication app( argc, argv );//創建連接QSqlDatabase db = QSqlDatabase::addDatabase( "QSQLITE" );//第二個參數可以設置連接名字,這里為defaultdb.setDatabaseName( "./testdatabase.db" );//?設置數據庫名與路徑,?此時是放在上一個目錄//打開連接if( !db.open() ){qDebug() << db.lastError();qFatal( "Failed to connect." );}qDebug( "Connected!" );//各種操作QSqlQuery qry;//創建tableqry.prepare( "CREATE TABLE IF NOT EXISTS names (id INTEGER UNIQUE PRIMARY KEY, firstname VARCHAR(30), lastname VARCHAR(30))" );if( !qry.exec() )qDebug() << qry.lastError();elseqDebug() << "Table created!";//增qry.prepare( "INSERT INTO names (id, firstname, lastname) VALUES (1, 'John', 'Doe')" );if( !qry.exec() )qDebug() << qry.lastError();elseqDebug( "Inserted!" );qry.prepare( "INSERT INTO names (id, firstname, lastname) VALUES (2, 'Jane', 'Doe')" );if( !qry.exec() )qDebug() << qry.lastError();elseqDebug( "Inserted!" );qry.prepare( "INSERT INTO names (id, firstname, lastname) VALUES (3, 'James', 'Doe')" );if( !qry.exec() )qDebug() << qry.lastError();elseqDebug( "Inserted!" );qry.prepare( "INSERT INTO names (id, firstname, lastname) VALUES (4, 'Judy', 'Doe')" );if( !qry.exec() )qDebug() << qry.lastError();elseqDebug( "Inserted!" );qry.prepare( "INSERT INTO names (id, firstname, lastname) VALUES (5, 'Richard', 'Roe')" );if( !qry.exec() )qDebug() << qry.lastError();elseqDebug( "Inserted!" );qry.prepare( "INSERT INTO names (id, firstname, lastname) VALUES (6, 'Jane', 'Roe')" );if( !qry.exec() )qDebug() << qry.lastError();elseqDebug( "Inserted!" );qry.prepare( "INSERT INTO names (id, firstname, lastname) VALUES (7, 'John', 'Noakes')" );if( !qry.exec() )qDebug() << qry.lastError();elseqDebug( "Inserted!" );qry.prepare( "INSERT INTO names (id, firstname, lastname) VALUES (8, 'Donna', 'Doe')" );if( !qry.exec() )qDebug() << qry.lastError();elseqDebug( "Inserted!" );qry.prepare( "INSERT INTO names (id, firstname, lastname) VALUES (9, 'Ralph', 'Roe')" );if( !qry.exec() )qDebug() << qry.lastError();elseqDebug( "Inserted!" ); //查詢qry.prepare( "SELECT * FROM names" );if( !qry.exec() )qDebug() << qry.lastError();else{qDebug( "Selected!" );QSqlRecord rec = qry.record();int cols = rec.count();for( int c=0; c<cols; c++ )qDebug() << QString( "Column %1: %2" ).arg( c ).arg( rec.fieldName(c) );for( int r=0; qry.next(); r++ )for( int c=0; c<cols; c++ )qDebug() << QString( "Row %1, %2: %3" ).arg( r ).arg( rec.fieldName(c) ).arg( qry.value(c).toString() );}qry.prepare( "SELECT firstname, lastname FROM names WHERE lastname = 'Roe'" );if( !qry.exec() )qDebug() << qry.lastError();else{qDebug( "Selected!" );QSqlRecord rec = qry.record();int cols = rec.count();for( int c=0; c<cols; c++ )qDebug() << QString( "Column %1: %2" ).arg( c ).arg( rec.fieldName(c) );for( int r=0; qry.next(); r++ )for( int c=0; c<cols; c++ )qDebug() << QString( "Row %1, %2: %3" ).arg( r ).arg( rec.fieldName(c) ).arg( qry.value(c).toString() );}qry.prepare( "SELECT firstname, lastname FROM names WHERE lastname = 'Roe' ORDER BY firstname" );if( !qry.exec() )qDebug() << qry.lastError();else{qDebug( "Selected!" );QSqlRecord rec = qry.record();int cols = rec.count();for( int c=0; c<cols; c++ )qDebug() << QString( "Column %1: %2" ).arg( c ).arg( rec.fieldName(c) );for( int r=0; qry.next(); r++ )for( int c=0; c<cols; c++ )qDebug() << QString( "Row %1, %2: %3" ).arg( r ).arg( rec.fieldName(c) ).arg( qry.value(c).toString() );}qry.prepare( "SELECT lastname, COUNT(*) as 'members' FROM names GROUP BY lastname ORDER BY lastname" );if( !qry.exec() )qDebug() << qry.lastError();else{qDebug( "Selected!" );QSqlRecord rec = qry.record();int cols = rec.count();for( int c=0; c<cols; c++ )qDebug() << QString( "Column %1: %2" ).arg( c ).arg( rec.fieldName(c) );for( int r=0; qry.next(); r++ )for( int c=0; c<cols; c++ )qDebug() << QString( "Row %1, %2: %3" ).arg( r ).arg( rec.fieldName(c) ).arg( qry.value(c).toString() );}//更新qry.prepare( "UPDATE names SET firstname = 'Nisse', lastname = 'Svensson' WHERE id = 7" );if( !qry.exec() )qDebug() << qry.lastError();elseqDebug( "Updated!" );qry.prepare( "UPDATE names SET lastname = 'Johnson' WHERE firstname = 'Jane'" );if( !qry.exec() )qDebug() << qry.lastError();elseqDebug( "Updated!" );//刪除qry.prepare( "DELETE FROM names WHERE id = 7" );if( !qry.exec() )qDebug() << qry.lastError();elseqDebug( "Deleted!" );qry.prepare( "DELETE FROM names WHERE lastname = 'Johnson'" );if( !qry.exec() )qDebug() << qry.lastError();elseqDebug( "Deleted!" );db.close();return 0; }二、Qt中使用sqlite3插件
1、安裝sqlite3插件
從官方網站http://www.sqlite.org下載完整版本。
2、安裝sqlite3
網上可以看到很多修改下載之后的源代碼的論壇,我估計那些帖子比較老一點,最新版的代碼已經不存在那些bug了,可以直接編譯
?*注意復制粘貼庫函數的時候有的動態鏈接庫如果單獨復制會丟失之間的鏈接關系,所以需要一塊復制
cp -arf libsqlite3.so libsqlite3.so.0 libsqlite3.so.0.8.6?。。。
3、移植sqlite3
在QTE的include文件中建立新文件夾sqlite3,將頭文件放到里面;把庫文件放到QTE的lib文件中
4、編程代碼實例:
(1)?QT生成的.pro文件中添加庫指令:?LIBS += -lsqlite3
(2)?在調用數據庫的文件的頭文件里添加頭文件和變量
?#include "sqlite3/sqlite3.h"? ???????? ?
?sqlite3 *db;??????? //數據庫
?char *zErrMsg;????? //出錯信息
?char? **resultp;??? //調用時的保存位置
?int? nrow;????????? //列數
int? ncolumn;?????? //行數
?char? *errmsg;????? //出錯信息
(3)新建或打開數據庫? ? ??
if( (sqlite3_open("people.db", &db)) != 0 ){
qDebug()<<"sqlite3 open is false";
?}
else {
qDebug()<<"sqlite3 open is OK";
?}
(4)?建立表格
sqlite3_exec(db, "create table person(name varchar(30) PRIMARY KEY, age int);", NULL, NULL, &zErrMsg);
*添加?PRIMARY KEY?是指定主鍵,每個數據庫只能有一個,主鍵的值不能重復,比方說你設定name為主鍵,則相同名字的人只能保存第一個,其他的忽略不計。若想避免這種情況,則去掉主鍵或者設定id號為主鍵(id號一直加一,不會重復)。
(5)往表格里寫入信息
?a.直接添加數據??
?sqlite3_exec(db, "insert into person values('張翼', 30)", NULL, NULL, &zErrMsg);
?sqlite3_exec(db, "insert into person values('hongdy', 28)", NULL, NULL, &zErrMsg);????????????????? ???
?b.添加數字變量
?int? data=10;
?char sql2[100];? //必須寫明大小,劃分內存,如果只寫一個?char *sql2,會出現段錯誤
?sprintf(sql2,"insert into person values('張翼',%d);",data);
sqlite3_exec(db,sql2,NULL,NULL,&zErrMsg);
*sprintf的作用是字串格式化命令,主要功能是把格式化的數據寫入某個字符串中
?c.添加字符串變量
?char data[]="張翼";
?char sql2[100];
?sprintf(sql2,"insert into person values('%s',10);",data);
sqlite3_exec(db,sql2,NULL,NULL,&zErrMsg);
?* %s需要用單引號注釋?????????????
d.添加text中的變量到數據庫中
?這里需要漢字編碼的問題,Windows下默認GBK或GB2312編碼,Linux下默認UTF-8編碼,所以如果沒有設置好會出現亂碼
d1.?在main.cpp中添加以下指令,支持中文顯示?
?#include <QTextCodec>
QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
d2.?讀取保存
?char *abc=ui->lineEdit->text().toUtf8().data();?? //QString?轉char*
?sprintf(sql2,"insert into person values('%s',%d);",abc,data);
sqlite3_exec(db,sql2,NULL,NULL,&zErrMsg);
*在調試的時候如果用串口超級終端調試的話,在ARM上顯示正常,但是在串口是亂碼,不要被迷惑
(6)查詢、調用數據庫
a.?查詢全部
sqlite3_get_table(db, "select * from person", &resultp, &nrow, &ncolumn, &errmsg);
*resultp保存數據庫信息,nrow返回列數,ncolumn返回列數
b.?查詢部分信息
sqlite3_get_table(db, "select * from person where name='zhang'", &resultp, &nrow, &ncolumn, &errmsg);
c.?變量查詢查詢
?char data[]="張翼";
?char sql3[100];
?sprintf(sql3,"select * from person where name='zhang';",data);
?sqlite3_get_table(db, sql3, &resultp, &nrow, &ncolumn, &errmsg);
?*查詢時使用變量的方法和添加時一樣
(7)關閉數據庫
?sqlite3_close(db);
三、VS+QT使用SQL驅動
//1.添加SQL庫:"Qt project setting"-->"Qt Modules",在SQL library復選框前打勾.或者在vs項目屬性--》連接器--》輸入里加入Qt5Sqllib
//2.添加頭文件
//#include<QtSql>//這樣寫會報Cannot open include file: 'QtSql': No such file or directory,奇葩錯誤,因為QtSql只是一個文件夾
#include <QtSql/QSqlDatabase>//這樣寫可以
#include <QtSql/QSqlTableModel>
#include<QtSql/QSqlError>
//3.創建連接
qDebug()<<"available driver:";
?QStringList drivers=QSqlDatabase::drivers();
?foreach(QString driver,drivers)
???qDebug()<<"/t"<<driver;
?QSqlDatabase db=QSqlDatabase::addDatabase("SQLITE");
?qDebug()<<"SQLITE driver?"<<db.isValid();
?QString dsn=QString::fromLocal8Bit("DRIVER={SQL SERVER};SERVER=192.168.0.123;DATABASE=test");????? db.setHostName("192.168.0.123");
?db.setDatabaseName(dsn);
?db.setUserName("sa");
?db.setPassword("111111");
?if(!db.open())
?{
???qDebug()<<db.lastError().text();
????QMessageBox::critical(0,QObject::tr("Database Error"),db.lastError().text());
????returnfalse;
?}
//4.查詢數據
QSqlQuery query;
query.exec("select * from mytable");
while(query.next())
{
.........
}
//***********************C++對數據庫sqlite3的增、刪、查、改基本操作
1、頭文件定義
在頭文件中聲明以下變量和函數:
// 實現
public:
void initSqlite(); //初始化數據庫
void initWindowShow();
void refreshList(); //刷新列表
public:
CString m_NameString; //姓名
CString m_ChineseString;
CString m_MathString;
CString m_EnglishString;
protected:
HICON m_hIcon;
// 生成的消息映射函數
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
CListCtrl m_ListCtrl;
afx_msg void OnBnClickedInsertBtn();
afx_msg void OnBnClickedDeleteBtn();
afx_msg void OnBnClickedModifyBtn();
CEdit m_sName;
CEdit m_sChinese;
CEdit m_sMath;
CEdit m_sEnglish;
afx_msg void OnLvnItemchangedList1(NMHDR *pNMHDR, LRESULT *pResult);
2、初始化數據庫
void CSqlite3Dlg::initSqlite()
{
//打開數據庫
const string studentDB = "student.db";
//創建表格
string create_student_table = "CREATE TABLE " + student_table + "(" +
"Name TEXT," +
"Chinese INTEGER," +
"Math INTEGER," +
"English INTEGER"
");";
CSDDb::GetInstance().SetDBFileName(studentDB);
bool ret = CSDDb::GetInstance().CreateTable(create_student_table, student_table);
if (!ret)
{
MessageBox("數據庫表格創建失敗!");
}
}
3、插入操作
//插入數據
void CSqlite3Dlg::OnBnClickedInsertBtn()
{
// TODO: 在此添加控件通知處理程序代碼
CString name_str, chinese_str, math_str, english_str, str;
string sql, tmp_str;
m_sName.GetWindowText(name_str);
m_sChinese.GetWindowText(chinese_str);
m_sMath.GetWindowText(math_str);
m_sEnglish.GetWindowText(english_str);
str.Format("Values('%s',%s,%s,%s)", name_str, chinese_str, math_str, english_str);
tmp_str = str.GetBuffer();
sql = "insert into " + student_table + "(Name,Chinese,Math,English) " + tmp_str;
CSDDb::GetInstance().InsertData(sql);
//將當前插入的數據顯示到列表控件中
m_ListCtrl.InsertItem(0, name_str);
m_ListCtrl.SetItemText(0, 1, chinese_str);
m_ListCtrl.SetItemText(0, 2, math_str);
m_ListCtrl.SetItemText(0, 3, english_str);
m_ListCtrl.SetTextBkColor(RGB(155, 155, 155));
m_ListCtrl.Invalidate(); //刷新列表
}
4、刪除數據
//刪除數據
void CSqlite3Dlg::OnBnClickedDeleteBtn()
{
// TODO: 在此添加控件通知處理程序代碼
if (m_NameString.IsEmpty())
{
MessageBox("請選擇要刪除的選項!");
return;
}
string selectName = m_NameString.GetBuffer();
string sql = "delete from " + student_table + " where Name=" + "'" + selectName + "'";
CSDDb::GetInstance().DeleteData(sql);
refreshList(); //重新刷新列表
}
5、修改數據
//修改數據
void CSqlite3Dlg::OnBnClickedModifyBtn()
{
// TODO: 在此添加控件通知處理程序代碼
if (m_NameString.IsEmpty())
{
MessageBox("請選擇要更新的選項!");
return;
}
string name_str, chinese_str, math_str, english_str;
m_sName.GetWindowText(m_NameString);
m_sChinese.GetWindowText(m_ChineseString);
m_sMath.GetWindowText(m_MathString);
m_sEnglish.GetWindowText(m_EnglishString);
name_str = m_NameString.GetBuffer();
chinese_str = m_ChineseString.GetBuffer();
math_str = m_MathString.GetBuffer();
english_str = m_EnglishString.GetBuffer();
string sql = "UPDATE " + student_table + " SET " + "Chinese=" + chinese_str + ", " + "Math=" + math_str + ", " + "English=" + english_str + " WHERE " + "Name=" + "'" + name_str + "'";
CSDDb::GetInstance().UpdataData(sql);
refreshList();
}
6、效果如下圖所示:
//******************************************
前言
SQLite(sql)是一款開源輕量級的數據庫軟件,不需要server,可以集成在其他軟件中,非常適合嵌入式系統。
Qt5以上版本可以直接使用SQLite(Qt自帶驅動)。
用法
1 準備
引入SQL模塊
在Qt項目文件(.pro文件)中,加入SQL模塊:
引用頭文件
在需要使用SQL的類定義中,引用相關頭文件。例如:
#include <QSqlDatabase>
#include <QSqlError>
#include <QSqlQuery>
2 使用
1. 建立數據庫
檢查連接、添加數據庫驅動、設置數據庫名稱、數據庫登錄用戶名、密碼。
QSqlDatabase database;
if (QSqlDatabase::contains("qt_sql_default_connection"))
{
database = QSqlDatabase::database("qt_sql_default_connection");
}
else
{
database = QSqlDatabase::addDatabase("QSQLITE");
database.setDatabaseName("MyDataBase.db");
database.setUserName("XingYeZhiXia");
database.setPassword("123456");
}
上述代碼解釋:
(1)第一行中,建立了一個QSqlDatabase對象,后續的操作要使用這個對象。
(2)if語句用來檢查指定的連接(connection)是否存在。這里指定的連接名稱(connection name)是qt_sql_default_connection,這是Qt默認連接名稱。實際使用時,這個名稱可以任意取。如果判斷此連接已經存在,那么QSqlDatabase::contains()函數返回true。此時,進入第一個分支,QSqlDatabase::database()返回這個連接。
(3)如果這個連接不存在,則進入else分支,需要創建連接,并添加數據庫。在else分支第一行,addDatabase()的參數QSQLITE是SQLite對應的驅動名,不能改。而且需要注意的是,addDatabase()的第二個參數被省略了,第二個參數的默認參數就是上面提到的Qt默認連接名稱qt_sql_default_connection。如果需要使用自定義的連接名稱(如果程序需要處理多個數據庫文件的話就會這樣),則應該加入第二個參數,例如
這個時候,如果在另一個地方需要判斷my_sql_connection連接是否存在,就應該使用if (QSqlDatabase::contains("my_sql_connection"))。
(4)else分支第二行中,setDatabaseName()的參數是數據庫文件名。如果這個數據庫不存在,則會在后續操作時自動創建;如果已經存在,則后續的操作會在已有的數據庫上進行。
(5)else分支后面兩行,設置用戶名和密碼。用戶名,密碼都可以隨便取,也可以省略。
2. 打開數據庫
使用open()打開數據庫,并判斷是否成功。注意,在第一步檢查連接是否存在時,如果連接存在,則在返回這個連接的時候,會默認將數據庫打開。
if (!database.open())
{
qDebug() << "Error: Failed to connect database." << database.lastError();
}
else
{
// do something
}
如果打開成功,則進入else分支。對數據庫的操作都需要在else分支中進行。
3. 關閉數據庫
數據庫操作完成后,最好關閉。
database.close();4. 操作數據庫
對數據庫進行操作需要用到QSqlQuery類,操作前必須定義一個對象。下面舉例說明操作方法。操作需要使用SQLite語句,本文中的幾個例子會使用幾個常用的語句,關于SQLite語句的具體信息請參考SQLite相關資料。
例1:創建表格
創建一個名為student的表格,表格包含三列,第一列是id,第二列是名字,第三列是年齡。
QSqlQuery sql_query;
QString create_sql = "create table student (id int primary key, name varchar(30), age int)";
sql_query.prepare(create_sql);
if(!sql_query.exec())
{
qDebug() << "Error: Fail to create table." << sql_query.lastError();
}
else
{
qDebug() << "Table created!";
}
代碼解釋:
(1)第一行定義一個QSqlQuery對象。
(2)第二行是一個QString,其中的內容是SQLite語句。對數據庫的操作,都是用SQLite的語句完成的,把這些指令以QString類型,通過prepare函數,保存在QSqlQuery對象中。也可將指令,以QString形式直接寫在exec()函數的參數中,例如:
創建表格語句:create table <table_name> (f1 type1, f2 type2,…);
create table是創建表格的語句,也可用大寫CREATE TABLE;student是表格的名稱,可以任意取;括號中是表格的格式,上述指令表明,表格中有三列,第一列的名稱(表頭)是id,這一列儲存的數據類型是int,第二列名稱是name,數據類型是字符數組,最多有30個字符(和char(30)的區別在于,varchar的實際長度是變化的,而char的長度始終是給定的值),第三列的名稱是age,數據類型是int。
如果sql_query.exec()執行成功,則創建表格成功。
例2:插入數據
在剛才創建的表格中,插入一行數據。
QString insert_sql = "insert into student values (?, ?, ?)";
sql_query.prepare(insert_sql);
sql_query.addBindValue(max_id+1);
sql_query.addBindValue("Wang");
sql_query.addBindValue(25);
if(!sql_query.exec())
{
qDebug() << sql_query.lastError();
}
else
{
qDebug() << "inserted Wang!";
}
if(!sql_query.exec("INSERT INTO student VALUES(3, \"Li\", 23)"))
{
qDebug() << sql_query.lastError();
}
else
{
qDebug() << "inserted Li!";
}
插入語句:insert into <table_name> values (value1, value2,…);
insert into是插入語句,student是表格名稱,values()是要插入的數據。這里,我們插入了2組數據。插入第一組數據的時候,用addBindValue來替代語句中的?,替代的順序與addBindValue調用的順序相同。插入第二組數據的時候,則是直接寫出完整語句。
例3:更新數據(修改數據)
QString update_sql = "update student set name = :name where id = :id";
sql_query.prepare(update_sql);
sql_query.bindValue(":name", "Qt");
sql_query.bindValue(":id", 1);
if(!sql_query.exec())
{
qDebug() << sql_query.lastError();
}
else
{
qDebug() << "updated!";
}
語句:update <table_name> set <f1=value1>, <f2=value2>… where <expression>;
更新(修改)的語句是update...set...,其中student是表格名稱,name是表頭名稱(即第二列),:name是待定的變量,where用于確定是哪一組數據,:id也是待定變量。
bindValue(" ", " ")函數用來把語句中的待定變量換成確定值。
例4:查詢數據
(1)查詢部分數據
QString select_sql = "select id, name from student";
if(!sql_query.exec(select_sql))
{
qDebug()<<sql_query.lastError();
}
else
{
while(sql_query.next())
{
int id = sql_query.value(0).toInt();
QString name = sql_query.value(1).toString();
qDebug()<<QString("id:%1 name:%2").arg(id).arg(name);
}
}
語句select <f1>, <f2>, ... from <table_name>;
select是查詢指令;<f1>?等等是要查詢的變量(即表頭),中間用逗號隔開;from ...指定表格。
上述語句是說查詢student表中的 id 和 name 。執行查詢之后,用sql_query.value(int)來獲得數據。同樣地,value(0)表示第一個數據,即 id,value(1)表示name。注意:value()函數的返回值類型是QVariant,因此要用toInt()等函數轉換成特定的類型。
(2)查詢全部數據
QString select_all_sql = "select * from student";
sql_query.prepare(select_all_sql);
if(!sql_query.exec())
{
qDebug()<<sql_query.lastError();
}
else
{
while(sql_query.next())
{
int id = sql_query.value(0).toInt();
QString name = sql_query.value(1).toString();
int age = sql_query.value(2).toInt();
qDebug()<<QString("id:%1 name:%2 age:%3").arg(id).arg(name).arg(age);
}
}
語句select * from <table_name>;
查詢所有數據用 * 表示。用while(sql_query.next())用來遍歷所有行。同樣用value()獲得數據。
(3)查詢最大id
QString select_max_sql = "select max(id) from student";
int max_id = 0;
sql_query.prepare(select_max_sql);
if(!sql_query.exec())
{
qDebug() << sql_query.lastError();
}
else
{
while(sql_query.next())
{
max_id = sql_query.value(0).toInt();
qDebug() << QString("max id:%1").arg(max_id);
}
}
這個就是在語句中用max來獲取最大值。
例5:刪除與清空
(1)刪除一條數據
QString delete_sql = "delete from student where id = ?";
sql_query.prepare(delete_sql);
sql_query.addBindValue(0);
if(!sql_query.exec())
{
qDebug()<<sql_query.lastError();
}
else
{
qDebug()<<"deleted!";
}
語句delete from <table_name> where <f1> = <value>
delete用于刪除條目,用where給出限定條件。例如此處是刪除 id = 0的條目。
(2)清空表格(刪除所有)
QString clear_sql = "delete from student";
sql_query.prepare(clear_sql);
if(!sql_query.exec())
{
qDebug() << sql_query.lastError();
}
else
{
qDebug() << "table cleared";
}
這里沒有用where給出限制,就會刪除所有內容。
?
總結
以上是生活随笔為你收集整理的QT操作sqlite数据库汇总的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Mybatis 中更新方法: updat
- 下一篇: VUE - get 、post 请求后