Qt之操作數據庫(SQLite)


SQLite

簡介

SQLite,是一款輕型的數據庫,是遵守ACID的關聯式數據庫管理系統,它的設計目標是嵌入式的,而且目前已經在很多嵌入式產品中使用了它,它占用資源非常的低,在嵌入式設備中,可能只需要幾百K的內存就夠了。它能夠支持Windows/Linux/Unix等等主流的操作系統,同時能夠跟很多程序語言相結合,比如Tcl、C#、PHP、Java等,還有ODBC接口,同樣比起Mysql、PostgreSQL這兩款開源世界著名的數據庫管理系統來講,它的處理速度比他們都快。SQLite第一個Alpha版本誕生於2000年5月。 至今已經有12個年頭,SQLite也迎來了一個版本SQLite3已經發布。

SQLite的功能

SQLite雖然很小巧,但是支持的SQL語句不會遜色於其他開源數據庫,它支持的SQL包括:

  ATTACH DATABASE

  BEGIN TRANSACTION

  comment

  COMMIT TRANSACTION

  COPY

  CREATE INDEX

  CREATE TABLE

  CREATE TRIGGER

  CREATE VIEW

  DELETE

  DETACH DATABASE

  DROP INDEX

  DROP TABLE

  DROP TRIGGER

  DROP VIEW

  END TRANSACTION

  EXPLAIN

  expression

  INSERT

  ON CONFLICT clause

  PRAGMA

  REPLACE

  ROLLBACK TRANSACTION

  SELECT

  UPDATE

同時它還支持事務處理功能等等。也有人說它象Microsoft的Access,有時候真的覺得有點像,但是事實上它們區別很大。比如SQLite 支持跨平台,操作簡單,能夠使用很多語言直接創建數據庫,而不象Access一樣需要Office的支持。如果你是個很小型的應用,或者你想做嵌入式開發,沒有合適的數據庫系統,那么現在你可以考慮使用SQLite。目前它的最新版本是3.7.8。它的官方網站是:http://www.sqlite.org或者http://www.sqlite .com .cn,能在上面獲得源代碼和文檔。同時因為數據庫結構簡單,系統源代碼也不是很多,也適合想研究數據庫系統開發的專業人士。

SQLite的特性

下面是訪問SQLite官方網站: http://www.sqlite. org/ 時第一眼看到關於SQLite的特性.

  1. ACID事務

  2. 零配置 – 無需安裝和管理配置

  3. 儲存在單一磁盤文件中的一個完整的數據庫

  4. 數據庫文件可以在不同字節順序的機器間自由的共享

  5. 支持數據庫大小至2TB

  6. 足夠小,大致3萬行C代碼,250K

  7. 比一些流行的數據庫在大部分普通數據庫操作要快

  8. 簡單,輕松的API

  9. 包含TCL綁定,同時通過Wrapper支持其他語言的綁定

  10. 良好注釋的源代碼, 並且有着90%以上的測試覆蓋率

  11. 獨立: 沒有額外依賴

  12. Source完全的Open,你可以用於任何用途,包括出售它

13. 支持多種開發語言,C、PHP、Perl、Java、C#、Python

SQLite類型

SQLite的數據類型

  首先你會接觸到一個讓你驚訝的名詞:Typelessness(無類型).對! SQLite是無類型的.這意味着你可以保存任何類型的數據到你所想要保存的任何表的任何列中,無論這列聲明的數據類型是什么(只有在一種情況下不是, 稍后解釋).對於SQLite來說對字段不指定類型是完全有效的. 如:

  Create Table ex1(a, b, c);

  誠然SQLite允許忽略數據類型,但是仍然建議在你的Create Table語句中指定數據類型.因為數據類型對於你和其他的程序員交流,或者你准備換掉你的數據庫引擎時能起到一個提示或幫助的作用.SQLite支持常見的數據類型,如:

  CREATE TABLE ex2(

  a VARCHAR(10),

  b NVARCHAR(15),

  c TEXT,

  d INTEGER,

  e FLOAT,

  f BOOLEAN,

  g CLOB,

  h BLOB,

  i TIMESTAMP,

  j NUMERIC(10,5)

  k VARYING CHARACTER (24),

  l NATIONAL VARYING CHARACTER(16)

  );

前面提到在某種情況下,SQLite的字段並不是無類型的.即在字段類型為”Integer Primary Key”時.

如何連接SQLite?

用PHP操作sqlite數據庫

  a、 如何連接sqlite數據庫?

  if ($db = sqlite_open('mysqlitedb', 0666, $sqliteerror)) {

  select * from sqlite_master;

  echo "數據庫連接成功!n

  ";

  } else {

  die($sqliteerror);

  }

  b、 如何列出數據庫中所有的表?

  if ($db = sqlite_open('mysqlitedb', 0666, $sqliteerror)) {

  $result = sqlite_array_query($db, 'select * from sqlite_master;');

  foreach ($result as $entry) {

  echo 'talbe name='.$entry['name']."

  n";

  echo 'sql='.$entry['sql']."

  n";

  echo "

  --------------------------------------------------------------------------------

  ";

  }

  sqlite_close($db);

  } else {

  die($sqliteerror);

  }}

  c、 對sqlite數據庫的查詢,以及結果集的顯示

  if ($db = sqlite_open('mysqlitedb', 0666, $sqliteerror)) {

  $result = sqlite_array_query($db, 'select name, email from user ', SQLITE_ASSOC);

  echo "user表查詢結果:

  n";

  echo " n name email

  n";

  foreach ($result as $entry) {

  echo ' '.$entry['name']." " $entry['email']."

  n";

  }

  echo ' ';

  sqlite_close($db);

  } else {

  die($sqliteerror);

  }

  d、 數據庫對象記錄的增加、刪除、修改

  sqlite_query($db, "INSERT INTO user VALUES('user".$i."'" ",'user".$i."@ hichina. com')");

  sqlite_query($db, "delete from user where user=’user99’");

sqlite_query($db, 'UPDATE user SET email="lilz@ hichina .com" where name="user1"');

用JAVA操作SQLite

開發所需依賴

  先下載SQLite數據庫的驅動包

  將下載到的包解壓后得到jar包sqlitejdbc-v033-nested.jar放到%JAVA_HOME%\lib 下,並且將其添加到classpath系統環境變量中,我的classpath系統環境變量現在為:

  .;%JAVA_HOME%\lib;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;%JAVA_HOME%\lib\sqlitejdbc-v033-nested.jar

  在你的代碼中引用這個驅動:

  Class.forName("org.sqlite.JDBC");

  Connection conn = DriverManager.getConnection("jdbc:sqlite:filename");//filename為你的SQLite數據名稱

  // ... use the database ...

conn.close();

或者在編寫代碼的時候進行外部jar包的導入。步驟:右擊工程->Build Path->Config Build Path->Libraries->Add External Jars選擇你要導入的SQLite的jar包

示例代碼

package wang.liang;

import java.sql.*;

 

public class TestSQLite {

       public static void main(String[] args) {

              try {

                     Class.forName("org.sqlite.JDBC");//連接SQLite的JDBC

                     //建立一個數據庫名testSQLite.db的連接,如果不存在就目錄下創建之

                     Connection conn =DriverManager.getConnection("jdbc:sqlite://E:/Program code/SQLite code/testSQLite.db");

                     Statement stat = conn.createStatement();

//創建一個表,兩列

                     stat.executeUpdate("create table table1(name varchar(20), salary int);");

//插入數據

                     stat.executeUpdate("insert into table1 values('ZhangSan',6000);");                             stat.executeUpdate("insert into table1 values('LiSi',7800);");

                     stat.executeUpdate("insert into table1 values('WangWu',8800);");

                     stat.executeUpdate("insert into table1 values('ZhaoLiu',9000);");

                     ResultSet rs = stat.executeQuery("select * from table1;");//查詢數據

                     while(rs.next()){//將查詢到的數據打印出來

                            System.out.print("name = "+ rs.getString("name")+" ");//列屬性一

                            System.out.println("salary = "+ rs.getString("salary"));//列屬性二

                     }

                     rs.close();

                     conn.close();//結束數據庫的連接

              }

              catch(Exception e ) {

                     e.printStackTrace();

              }

       }

}

總結:本文介紹了嵌入式數據庫SQLite在Java中的應用,通過創建表、插入數據、查詢等操作介紹了在Java中對數據庫的操縱。

用C、C++操作SQLite

核心對象和接口

SQL數據庫引擎的最主要任務是解析SQL語句。為了達成這個目的,開發者需要了解兩個對象:

* 數據庫連接對象:sqlite3

* 預處理語句對象:sqlite3_stmt

嚴格來講,預處理語句對象並不是必須的,因為能夠使用sqlite_exec或者sqlite3_get_table這些便於使用的封裝接口,而這些接口封裝並隱藏了預處理語句對象。盡管如此,對預處理對象的理解有助於我們更充分的使用SQLite。

數據庫連接對象和預處理對象是由下列的一組C/C++接口調用操縱的:

* sqlite3_open()

* sqlite3_prepare()

* sqlite3_step()

* sqlite3_column()

* sqlite3_finalize()

* sqlite3_close()

這6個C/C++接口例程和上述的兩個對象構成了SQLite的核心功能。開發者對於它們的理解能夠更好的使用SQLite。

注意,這個接口例程列表更多是概念上的意義而不是實際的接口。許多這些接口都出現在各個版本之中。例如,上述列表中的sqlite3_open()例程實際上有三個不同的接口以略微不同的方式實現相同的功能:slqite3_open(),sqlite3_open16()和sqlite3_open_v2()。列表中的實際上並不存在sqlite3_column()這個接口。顯示在列表中的“sqlite3_column()”僅僅是一個占位,表示一整套用於從表中查詢出各種數據類型的列記錄接口。

這里說明下核心接口的主要功能:

sqlite3_open() 該接口打開與一個SQLite數據庫文件的連接並返回一個數據庫連接對象。這通常是應用程序調用的第一個SQLite API接口而且也是調用其他SQLite API接口前需要調用的接口。許多SQLite接口需要一個指向數據庫連接對象的指針作為它們的第一個參數,因而這些接口也可以理解成是數據庫連接對象的操作接口。該接口就是創建了這樣一個數據庫連接對象。

sqlite3_prepare() 該接口把一個SQL語句文本轉換成一個預處理語句對象並返回一個指向該對象的指針。這個接口需要一個由先前調用sqlite3_open()返回的數據庫連接對象指針以及一個預處理的SQL語句文本字符串為參數。這個API並不實際解析SQL語句,僅僅是為后續的解析而對SQL語句進行的預處理。

注意:新的應用中不建議使用sqlite3_prepare(),應該使用另一個接口sqlite3_prepare_v2()。

sqlite3_step() 該接口用於解析一個由先前通過sqlite3_prepare()接口創建的預處理語句,直至返回第一列結果為止。通過再次調用sqlite3_step()可以返回下一列的結果,繼續不斷地調用sqlite3_step()直至整個語句完成為止。對於那些並不返回結果的語句(例如:INSERT,UPDATE,DELETE語句)一次調用sqlite3_step()就完成了語句的處理。

sqlite3_column() 該接口返回一個由sqlite3_step()解析的預處理語句結果集中當前行某一列數據。每次執行sqlite3_step()都返回一個新結果集中的一行。可以多次調用sqlite3_column()接口返回那一行中所有列的數據。就像上面所說的那樣,SQLite API中並沒有sqlite3_column()這樣的接口。取而代之的是一組用於從結果集中查詢出各個列項各種數據類型數據的函數接口。在這組函數接口中,有些接口返回結果集的大小,有些返回結果集的列數。

*sqlite3_column_blob()

*sqlite3_column_bytes()

*sqlite3_column_bytes16()

*sqlite3_column_count()

*sqlite3_column_double()

sqlite3_column_int()

*sqlite3_column_int64()

*sqlite3_column_text()

*sqlite3_column_text16()

*sqlite3_column_type()

*sqlite3_column_value()

sqlite3_finalize() 該接口銷毀之前調用sqlite3_prepare()創建的預處理語句。每一個預處理語句都必須調用這個接口進行銷毀以避免內存泄漏。

sqlite3_close() 該接口關閉一個由之前調用sqlite3_open()創建的數據庫連接。所有與該連接相關的預處理語句都必須在關閉連接之前銷毀。

開發所需依賴

下載地址:http://www.sqlite.org/download.html

在該頁面上下載Source Code中的sqlite-amalgamation-3071300.zip,該包有含有兩個頭文件,兩個實現文件。

下載Precompiled Binaries For Windows中的sqlite-dll-win32-x86-3071300.zip,該包中含有一個def文件,一個dll文件。

新建一個win32控制台應用程序sqlite,選擇空項目。

方法一:將所得dll、sqlite3.h、sqlite3.lib文件拷貝到../工程/sqlite/下,點擊頭文件,選擇添加現有項,選擇拷貝的sqlite.h文件,選擇工程->屬性->鏈接器->輸入->附加依賴項,填寫sqlite3.lib,再在原文件中編寫自己的主程序。

方法二:將sqlite3.h、sqlite3.c、sqlite3.lib文件拷貝../工程/sqlite/下,點擊頭文件,選擇添加現有項,選擇拷貝的sqlite3.h文件。點擊源文件添加現有項,選擇拷貝的sqlite3.c文件,選擇工程->屬性->鏈接器->輸入->附加依賴項,填寫sqlite3.lib,然后便攜自己的主程序。

示例代碼

示例代碼一:

#include 

#include "sqlite3.h"

using namespace std;

 

int main( )

{

     sqlite3 *db=NULL; //定義SQLite的連接

     const char *zErrMsg = 0;//錯誤信息

     int rc;

     rc = sqlite3_open("E:/Program code/SQLite code/testSQLite.db", &db);

     if(rc != SQLITE_OK) //如果打開數據庫失敗

     {

         zErrMsg = sqlite3_errmsg(db); //獲取錯誤信息

         cout<<zErrMsg<<endl;

         sqlite3_close(db); //關閉數據庫連接

         return -1;

     }

     cout<<"open testSQLite.db successfully!"<<endl;

     sqlite3_close(db);

     return 0;

}

示例代碼二:

頭文件:my_db.h、sqlite3.h

源文件:sqlitedb.cpp、main.cpp

My_db.h代碼:

#ifndef MY_DB_H

#define MY_DB_H

 

int open_db();

int create_table();

int drop_table();

int insert_data(int id,char *name,int age);

int search_data(int id);

int search_data(char *name);

int delete_data(int age);

 

#endif

Sqlitedb.cpp代碼:

#include "sqlite3.h"

#include "my_db.h"

#include 

using namespace std;

 

sqlite3 *db = NULL; //定義數據庫連接

const char *errMsg = 0; //定義錯誤信息

char *zerrMsg = 0; //定義錯誤信息

 

//打開數據庫

int open_db()

{

     int rc = sqlite3_open("E:/Program code/SQLite code/sqlitejdbc.db",&db); //打開數據庫

     if(rc != SQLITE_OK)    //數據庫打開失敗

     {

         errMsg = sqlite3_errmsg(db); //獲取錯誤信息

         cout<<errMsg<<endl;

         sqlite3_close(db); //關閉數據庫連接

         return -1;

     }

     cout<<"open database successfully!"<<endl;

     return 0;

}

 

//創建表

int create_table()

{

     if(open_db() != 0)

     {

         open_db();

     }

     char *sql = "create table tab(id int primary key ,name varchar(20) ,age int)";

 

     

     int rc = sqlite3_exec(db,sql,NULL,NULL,&zerrMsg);

     if(rc != SQLITE_OK)

     {

         errMsg = sqlite3_errmsg(db);

         cout<<errMsg<<endl; // cout<<zerrMsg<<endl;

         sqlite3_close(db);

         return -1;

     }

     cout<<"創建表成功!"<<endl;

     return 0;

}

 

//刪除表

int drop_table()

{

     if(open_db() != 0)

     {

         open_db();

     }

     char *sql = "drop table tab";

     int rc = sqlite3_exec(db,sql,NULL,NULL,&zerrMsg);

     if(rc != SQLITE_OK)

     {

         errMsg = sqlite3_errmsg(db);

         cout<<errMsg<<endl; // cout<<zerrMsg<<endl;

         sqlite3_close(db);

         return -1;

     }

     cout<<"刪除表成功"<<endl;

     return 0;

}

 

//數據添加

int insert_data(int id,char *name,int age)

{

     if(open_db() != 0)

     {

         open_db();

     }

     sqlite3_stmt *stmt = NULL; //准備語句對象

     char *sql = "insert into tab(id,name,age) values(?,?,?)";

     

     int rc = sqlite3_prepare_v2(db,sql,strlen(sql),&stmt,NULL);

     if(rc != SQLITE_OK)

     {

         errMsg = sqlite3_errmsg(db);

         cout<<errMsg<<endl;

         if(stmt)

         {

              sqlite3_finalize(stmt);

         }

         sqlite3_close(db);

         return -1;

     }

     sqlite3_bind_int(stmt,1,id);

     //參數一:准備語句對象參數二:序號(從開始)參數三:字符串值參數四:字符串長度參數五:函數指針,SQLITE3執行完操作后回調此函數,通常用於釋放字符串占用的內存。(這個函數指針參數具體怎么使用,我現在還不清楚

     sqlite3_bind_text(stmt,2,name,strlen(name),NULL);

     sqlite3_bind_int(stmt,3,age);

     

     if(sqlite3_step(stmt) != SQLITE_DONE)

     {

         sqlite3_finalize(stmt);

         sqlite3_close(db);

         return -1;

     }

     cout<<"數據插入成功!"<<endl;

     sqlite3_reset(stmt);

     sqlite3_finalize(stmt);

     sqlite3_close(db);

     return 0;

}

 

//數據查詢根據id唯一性查詢

int search_data(int id)

{

     if(open_db() != 0)

     {

         open_db();

     }

     char *sql = "select * from tab where id = ?";

     sqlite3_stmt  *stmt = NULL;

     int rc = sqlite3_prepare_v2(db,sql,strlen(sql),&stmt,NULL);

     if(rc != SQLITE_OK)

     {

         errMsg = sqlite3_errmsg(db);

         cout<<errMsg<<endl;

         if(stmt)

         {

              sqlite3_finalize(stmt);

         }

         sqlite3_close(db);

         return -1;

     }

     sqlite3_bind_int(stmt,1,id);

     int nColumn = sqlite3_column_count(stmt); //獲取數據庫表的列數

     int type; //表字段所對應的類型

     rc = sqlite3_step(stmt);

     if(rc == SQLITE_ROW)

     {

         for(int i=0;i

         {

              type = sqlite3_column_type(stmt,i);

              if(type == SQLITE_INTEGER)

              {

                   cout<<sqlite3_column_name(stmt,i)<<"\t"<<sqlite3_column_int(stmt,i)<<endl;

              }

              if(type == SQLITE_TEXT)

              {

                   cout<<sqlite3_column_name(stmt,i)<<"\t"<<sqlite3_column_text(stmt,i)<<endl;

              }

              else if(type == SQLITE_NULL)

              {

                   cout<<"no value"<<endl;

              }

 

         }

     }

     else if(rc == SQLITE_DONE)

     {

         cout<<"select finish!"<<endl;

     }

     else

     {

         cout<<"select fail"<<endl;

         sqlite3_finalize(stmt);

     }

     sqlite3_finalize(stmt);

     sqlite3_close(db);

     return 0;

}

 

 

//數據查詢根據姓名批量查詢

int search_data(char *name)

{

     if(open_db() != 0)

     {

         open_db();

     }

     char *sql = "select * from tab where name = ?";

     sqlite3_stmt  *stmt = NULL;

     int rc = sqlite3_prepare_v2(db,sql,strlen(sql),&stmt,NULL);

     if(rc != SQLITE_OK)

     {

         errMsg = sqlite3_errmsg(db);

         cout<<errMsg<<endl;

         if(stmt)

         {

              sqlite3_finalize(stmt);

         }

         sqlite3_close(db);

         return -1;

     }

     sqlite3_bind_text(stmt,1,name,strlen(name),NULL);

     int nColumn = sqlite3_column_count(stmt);

     int type;

     rc = sqlite3_step(stmt);//如果是select語句,且有還有記錄,則應該返回SQLITE_ROW

     while(true) {

         if(rc == SQLITE_ROW)

         {   

              cout<<"--------------"<<endl;

              for(int i=0;i

              {

                   type = sqlite3_column_type(stmt,i);

                   if(type == SQLITE_INTEGER)

                   {

                       cout<<sqlite3_column_name(stmt,i)<<"\t"<< sqlite3_column_int(stmt,i)<<endl;

                   }

                   if(type == SQLITE_TEXT)

                   {

                       cout<<sqlite3_column_name(stmt,i)<<"\t"<< sqlite3_column_text(stmt,i)<<endl;

                   }

                   else if(type == SQLITE_NULL)

                   {

                       cout<<"no value"<<endl;

                   }

 

              }

         }

         else if(rc == SQLITE_DONE)

         {

              cout<<"select finish!"<<endl;

         }

         else

         {

              cout<<"select fail"<<endl;

              sqlite3_finalize(stmt);

         }

 

         if (sqlite3_step(stmt) != SQLITE_ROW)

              break;

     }

 

     sqlite3_finalize(stmt);

     sqlite3_close(db);

     return 0;

}

 

//刪除數據

int delete_data(int age)

{

     if(open_db() != 0)

     {

         open_db();

     }

     char *sql = "delete from tab where age = ?";

     sqlite3_stmt  *stmt = NULL;

     int rc = sqlite3_prepare_v2(db,sql,strlen(sql),&stmt,NULL);

     if(rc != SQLITE_OK)

     {

         errMsg = sqlite3_errmsg(db);

         cout<<errMsg<<endl;

         if(stmt)

         {

              sqlite3_finalize(stmt);

         }

         sqlite3_close(db);

         return -1;

     }

     sqlite3_bind_int(stmt,1,age);   

     rc  = sqlite3_step(stmt);//如果是update, delete, insert等語句,正常應該返回SQLITE_DONE

     if(rc == SQLITE_DONE)//SQLITE_DONE意味着已成功完成執行該語句

     {

         cout<<"刪除數據成功"<<endl;

     }   

     sqlite3_finalize(stmt);

     sqlite3_close(db);

     return 0;

}

main.cpp代碼:

#include "my_db.h"

#include 

using namespace std;

int main()

{

     //open_db();

     //create_table();

     //drop_table();

     //insert_data(3,"wang",25);

     //search_data(1);

     //search_data("wang");

     //delete_data(28);

     return 0;

}

SQLite加密解密

對數據庫而言,加密無非是必不可少了一個環節,如何才能讓自己更安全更放心的使用SQLite呢?加密!但是在這里還是很不好意思的說,如果是面向公眾開放的開源性SQLite,他是不能實現加密的,當然,除非你付款。此前我也很想研究下加密部分,當看到資料上存在可以加密、解密的方法時,很興奮的試了試,結果卻很讓人很糾結。

進入sqlite3.h頭文件當中,搜索sqlite3_key(sqlite3 *db,const void *pKey,int nKey)加密方法、sqlite3_rekey(sqlite3 *db,const void *pKey,int nKey)解密方法時,可以看到主要的注釋——The code to implement this API is not available in the public release of SQLite.

雖然加密解密方法對於開源用戶來說不能使用,但是我們畢竟也了解到SQLite本身是提供加密、解密方法的。所以先了解一下加密、解密方法的使用吧。

加密:

給一個未加密的數據庫添加密碼:如果想要添加密碼,則可以在打開數據庫文件之后,關閉數據庫文件之前的任何時刻調用sqlite3_key函數即可,

該函數有三個參數,其中參數一:數據庫對象 參數二:要設定的密碼 參數三:密碼的長度。例:sqlite3_key(db,"123456",6);

解密:

sqlite3_rekey是變更密碼或給沒有加密的數據庫添加密碼或清空密碼,變更密碼或清空密碼前必須先正確執行sqlite3_key。

在正確執行sqlite3_rekey之后在sqlite3_close關閉數據庫之前可以正常操作數據庫,不需要再執行sqlite3_key。

sqlite3_rekey( sqlite3 *db, const void *pKey, int nKey),參數同上。清空密鑰為sqlite3_rekey( db, NULL, 0)。

如果實在是想進行加密解密的話,那么我也不妨提出自己的兩個建議吧!

建議一:掏錢購買吧!沒什么可說的。

建議二:自己實現加密解密方法。對即將存入數據庫的數據進行加密之后再進行保存,取數據的時候先進行解密再進行獲取。

SQLite的管理

管理工具也有不少,這里介紹幾款:

1、SQLite Manager是開放源代碼SQLite管理工具,用來管理本地電腦上的SQLite數據庫,可以獨立運行(以XULRunner方式),也可以作為Firefox、Thunderbird、Seamonkey、Songbird、Komodo、Gecko等的插件。

2、SQLite Administrator是一個用來管理 SQLite 數據庫文件的圖形化工具,可進行創建、設計和管理操作。提供代碼編輯器具有自動完成和語法着色,支持中文,適合初學者。 

3、SQLite Database browser是一個 SQLite 數據庫的輕量級GUI客戶端,基於Qt庫開發,界面清潔,操作簡單,主要是為非技術用戶創建、修改和編輯SQLite數據庫的工具,使用向導方式實現。

QtSql模塊提供了與平台以及數據庫種類無關的訪問SQL數據庫的接口,這個接口由利用Qt的模型視圖結構將數據庫與用戶界面集成的一套類來支持。

    QSqlDatabase對象象征了數據庫的關聯。Qt使用驅動程序與各種數據庫的應用編程接口進行通信。Qt的桌面版(Desktop Edition)包括如下一些驅動程序:
 
 驅動程序  數據庫 
 QDB2  IBM DB2 7.1版以及更新的版本 
 QIBASE  Borland InterBase
 QMYSQL  MySql 
 QOCI  甲骨文公司(Oracle Call Interface)
 QODBC   ODBC(包括微軟公司的QSL服務)
 QPSQL   PostgreSQL的7.3版以及更高版本 
 QSQLITE  QSLite第3版 
 QSQLITE2  QSLite第2版
 QTDS   Qybase自適應服務器 
    
    由於授權的許可限制,Qt的開源版本無法提供所有的驅動程序,當配置Qt時,即可以選擇Qt本身包含的SQL驅動程序,也可以以查件的形式建立驅動程序,公共領域中不斷發展的SQLite數據庫將向Qt提供支持。
    如下討論關於Qt進行SQLite的基本操作。
 
代碼如下:
 
  1 //添加數據庫驅動、設置數據庫名稱、數據庫登錄用戶名、密碼
  2 QSqlDatabase database = QSqlDatabase::addDatabase("QSQLITE"); 
  3 database.setDatabaseName("database.db");
  4 database.setUserName("root");  
  5 database.setPassword("123456");
  6  
  7 //打開數據庫
  8 if(!database.open())
  9 {  
 10 qDebug()<<database.lastError();
 11 qFatal("failed to connect.") ;
 12 }
 13 else
 14 {
 15 //QSqlQuery類提供執行和操作的SQL語句的方法。
 16 //可以用來執行DML(數據操作語言)語句,如SELECT、INSERT、UPDATE、DELETE, 
 17 //以及DDL(數據定義語言)語句,例如CREATE TABLE。
 18 //也可以用來執行那些不是標准的SQL的數據庫特定的命令。
 19 QSqlQuery sql_query; 
 20  
 21 QString create_sql = "create table student (id int primary key, name varchar(30), age int)";
 22 QString select_max_sql = "select max(id) from student";
 23 QString insert_sql = "insert into student values (?, ?, ?)";
 24 QString update_sql = "update student set name = :name where id = :id";
 25 QString select_sql = "select id, name from student";
 26 QString select_all_sql = "select * from student";
 27 QString delete_sql = "delete from student where id = ?";
 28 QString clear_sql = "delete from student";
 29  
 30 sql_query.prepare(create_sql);
 31 if(!sql_query.exec())
 32 {
 33 qDebug()<<sql_query.lastError();
 34 }
 35 else
 36 {
 37 qDebug()<<"table created!";
 38 }
 39  
 40 //查詢最大id
 41 int max_id = 0;
 42 sql_query.prepare(select_max_sql);
 43 if(!sql_query.exec())
 44 {
 45 qDebug()<<sql_query.lastError();
 46 }
 47 else
 48 {
 49 while(sql_query.next())
 50 {
 51 max_id = sql_query.value(0).toInt();
 52 qDebug()<<QString("max id:%1").arg(max_id);
 53 }
 54 }
 55 //插入數據
 56 sql_query.prepare(insert_sql);
 57 sql_query.addBindValue(max_id+1);
 58 sql_query.addBindValue("name");
 59 sql_query.addBindValue(25);
 60 if(!sql_query.exec())
 61 {
 62 qDebug()<<sql_query.lastError();
 63 }
 64 else
 65 {
 66 qDebug()<<"inserted!";
 67 }
 68  
 69 //更新數據
 70 sql_query.prepare(update_sql);
 71 sql_query.bindValue(":name", "Qt");
 72 sql_query.bindValue(":id", 1);
 73 if(!sql_query.exec())
 74 {
 75 qDebug()<<sql_query.lastError();
 76 }
 77 else
 78 {
 79 qDebug()<<"updated!";
 80 }
 81  
 82 //查詢部分數據
 83 if(!sql_query.exec(select_sql))
 84 {
 85 qDebug()<<sql_query.lastError();
 86 }
 87 else
 88 {
 89 while(sql_query.next())
 90 {
 91 int id = sql_query.value("id").toInt();
 92 QString name = sql_query.value("name").toString();
 93  
 94 qDebug()<<QString("id:%1    name:%2").arg(id).arg(name);
 95 }
 96 }
 97  
 98 //查詢所有數據
 99 sql_query.prepare(select_all_sql);
100 if(!sql_query.exec())
101 {
102 qDebug()<<sql_query.lastError();
103 }
104 else
105 {
106 while(sql_query.next())
107 {
108 int id = sql_query.value(0).toInt();
109 QString name = sql_query.value(1).toString();
110 int age = sql_query.value(2).toInt();
111  
112 qDebug()<<QString("id:%1    name:%2    age:%3").arg(id).arg(name).arg(age);
113 }
114 }
115  
116 //刪除數據
117 sql_query.prepare(delete_sql);
118 sql_query.addBindValue(max_id);
119 if(!sql_query.exec())
120 {
121 qDebug()<<sql_query.lastError();
122 }
123 else
124 {
125 qDebug()<<"deleted!";
126 }
127  
128 //清空表
129 sql_query.prepare(clear_sql);
130 if(!sql_query.exec())
131 {
132 qDebug()<<sql_query.lastError();
133 }
134 else
135 {
136 qDebug()<<"cleared";
137 }
138 }
139  
140 //關閉數據庫
141 database.close();
142  
143 //刪除數據庫
144 QFile::remove("database.db");

 

 
可以通過一些工具對SQLite進行管理,如下:
 
Qt之操作數據庫(SQLite)
 
SQLite的管理
管理工具挺多的,這里簡單介紹幾款:
  • SQLite Manager:開放源代碼的SQLite管理工具,用來管理本地電腦上的SQLite數據庫,可以獨立運行(以XULRunner方式),也可以作為Firefox、Thunderbird、Seamonkey、Songbird、Komodo、Gecko等的插件。
  • SQLite Administrator:一個用來管理SQLite數據庫文件的圖形化工具,可進行創建、設計和管理操作。提供代碼編輯器具有自動完成和語法着色,支持中文,適合初學者。
  • SQLite Database browser:一個SQLite數據庫的輕量級GUI客戶端,基於Qt庫開發,界面清潔,操作簡單,主要是為非技術用戶創建、修改和編輯SQLite數據庫的工具,使用向導方式實現。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM