QT操作sqlite數據庫匯總
標簽: QT
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" );//第二個參數可以設置連接名字,這里為default db.setDatabaseName( "./testdatabase.db" );// 設置數據庫名與路徑, 此時是放在上一個目錄 //打開連接 if( !db.open() ) { qDebug() << db.lastError(); qFatal( "Failed to connect." ); } qDebug( "Connected!" ); //各種操作 QSqlQuery qry; //創建table qry.prepare( "CREATE TABLE IF NOT EXISTS names (id INTEGER UNIQUE PRIMARY KEY, firstname VARCHAR(30), lastname VARCHAR(30))" ); if( !qry.exec() ) qDebug() << qry.lastError(); else qDebug() << "Table created!"; //增 qry.prepare( "INSERT INTO names (id, firstname, lastname) VALUES (1, 'John', 'Doe')" ); if( !qry.exec() ) qDebug() << qry.lastError(); else qDebug( "Inserted!" ); qry.prepare( "INSERT INTO names (id, firstname, lastname) VALUES (2, 'Jane', 'Doe')" ); if( !qry.exec() ) qDebug() << qry.lastError(); else qDebug( "Inserted!" ); qry.prepare( "INSERT INTO names (id, firstname, lastname) VALUES (3, 'James', 'Doe')" ); if( !qry.exec() ) qDebug() << qry.lastError(); else qDebug( "Inserted!" ); qry.prepare( "INSERT INTO names (id, firstname, lastname) VALUES (4, 'Judy', 'Doe')" ); if( !qry.exec() ) qDebug() << qry.lastError(); else qDebug( "Inserted!" ); qry.prepare( "INSERT INTO names (id, firstname, lastname) VALUES (5, 'Richard', 'Roe')" ); if( !qry.exec() ) qDebug() << qry.lastError(); else qDebug( "Inserted!" ); qry.prepare( "INSERT INTO names (id, firstname, lastname) VALUES (6, 'Jane', 'Roe')" ); if( !qry.exec() ) qDebug() << qry.lastError(); else qDebug( "Inserted!" ); qry.prepare( "INSERT INTO names (id, firstname, lastname) VALUES (7, 'John', 'Noakes')" ); if( !qry.exec() ) qDebug() << qry.lastError(); else qDebug( "Inserted!" ); qry.prepare( "INSERT INTO names (id, firstname, lastname) VALUES (8, 'Donna', 'Doe')" ); if( !qry.exec() ) qDebug() << qry.lastError(); else qDebug( "Inserted!" ); qry.prepare( "INSERT INTO names (id, firstname, lastname) VALUES (9, 'Ralph', 'Roe')" ); if( !qry.exec() ) qDebug() << qry.lastError(); else qDebug( "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(); else qDebug( "Updated!" ); qry.prepare( "UPDATE names SET lastname = 'Johnson' WHERE firstname = 'Jane'" ); if( !qry.exec() ) qDebug() << qry.lastError(); else qDebug( "Updated!" ); //刪除 qry.prepare( "DELETE FROM names WHERE id = 7" ); if( !qry.exec() ) qDebug() << qry.lastError(); else qDebug( "Deleted!" ); qry.prepare( "DELETE FROM names WHERE lastname = 'Johnson'" ); if( !qry.exec() ) qDebug() << qry.lastError(); else qDebug( "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());
return
false
;
}
//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模塊:QT += 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
。如果需要使用自定義的連接名稱(如果程序需要處理多個數據庫文件的話就會這樣),則應該加入第二個參數,例如
database = QSqlDatabase::addDatabase("QSQLITE", "my_sql_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()
函數的參數中,例如:
sql_query.exec("create table student (id int primary key, name varchar(30), age int)");
創建表格語句: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數據庫
前言 SQLite(sql)是一款開源輕量級的數據庫軟件,不需要server,可以集成在其他軟件中,非常適合嵌入式系統。 Qt5以上版本可以直接使用SQLite(Qt自帶驅動)。 用法 1 準備 引入SQL模塊 在Qt項目文件(.pro文件)中,加入SQL模塊: 引用頭文件 在需要使用SQL的類定義中,引用相關頭文件。例如: 2 使用 1. 建立數據庫 檢查連接、添加數據庫驅動、設置數據庫名稱、數...
Qt操作SQLite數據庫——創建、打開、關閉、增加、刪除和修改操作
QtSql模塊提供了與平臺以及數據庫種類無關的訪問SQL數據庫的接口,這個接口由利用Qt的模型視圖結構將數據庫與用戶界面集成的一套類來支持。QSqlDatabase對象象征了數據庫的關聯。Qt使用驅動程序與各種數據庫的應用編程接口進行通信。Qt的桌面版(Desktop Edition)包括如下一些驅動程序: 驅動程序 數據庫 QDB2 I...
iOS——SQLite數據庫操作
iOS——SQLite數據庫操作 首先介紹一下SQLite數據庫以及為什么要用ta: SQLite是一款輕型的嵌入式數據庫,它占用資源非常的低,在嵌入式設備中,可能只需要幾百K的內存就夠了。它的處理速度比Mysql、PostgreSQL這兩款著名的數據庫都還快。 數據庫的存儲結構和excel很像,以表(table)為單位 新建數據庫文件 新建一張表(table) 添加多個字...
python操作sqlite數據庫
SQLite數據庫是一款輕量級的數據庫,無服務器、零配置、事務性的SQL數據庫引擎。SQLite是世界上最廣泛部署的SQL數據庫引擎,而且SQLite的源代碼不受版權限制,是小型項目和簡單web應用的理想選擇。SQLite數據庫是一個單一的,不依賴于其他模塊與組件的數據庫文件,它允許我們直接訪問存儲文件。而且,SQLite也不需要針對特定的系統進行設置。python的標準庫中已經包含了支持SQLi...
猜你喜歡
SQLite數據庫的CRUD操作
1.新建名為DbHelper的SQLite數據庫打開助手類 2.新建名為MyDAO的數據庫訪問類 3.列表控件ListView使用的布局list_item.xml 4.最后編寫MainActivity 運行效果如下 參考文獻. 實驗代碼:MySQLite....
freemarker + ItextRender 根據模板生成PDF文件
1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...
電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!
Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...
requests實現全自動PPT模板
http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...