一、 SQLite簡介
SQLite是遵守ACID的關聯式資料庫管理系統,它包含在一個相對小的C庫中。它是D.RichardHipp建立的公有領域項目。
不像常見的客戶-伺服器範例,SQLite引擎不是個程式與之通訊的獨立進程,而是串連到程式中成為它的一個主要部分。所以主要的通訊協定是在程式設計語言內的直接API調用。這在消耗總量、延遲時間和整體簡單性上有積極的作用。整個資料庫(定義、表、索引和資料本身)都在宿主主機上儲存在一個單一的檔案中。它的簡單的設計是通過在開始一個事務的時候鎖定整個資料檔案而完成的。
這個介紹就不說了,反正它就是個小型的SQL資料庫,有點類似於ACCESS。先來試試它的功能吧。
二、建立sqlite資料庫
1、建立空的sqlite資料庫。
//資料庫名的尾碼你可以直接指定,甚至沒有尾碼都可以
//方法一:建立一個空sqlite資料庫,用IO的方式
FileStream fs = File.Create(“c:\\test.db“);
//方法二:用SQLiteConnection
SQLiteConnection.CreateFile(“c:\\test.db“);
建立的資料庫是個0位元組的檔案。
2、建立加密的空sqlite資料庫
//建立一個密碼為password的空的sqlite資料庫
SQLiteConnection.CreateFile(“c:\\test2.db“);
SQLiteConnection cnn = new SQLiteConnection(“Data Source=c:\\test2.db“);
SQLiteConnection cnn = new SQLiteConnection(“Data Source=D:\\test2.db“);
cnn.Open();
cnn.ChangePassword(“password“);
3、給未加密的資料庫加密
SQLiteConnection cnn = new SQLiteConnection(“Data Source=c:\\test.db“);
cnn.Open();
cnn.ChangePassword(“password“);
4、開啟加密sqlite資料庫
//方法一
SQLiteConnection cnn = new SQLiteConnection(“Data Source=c:\\test2.db“);
cnn.SetPassword(“password“);
cnn.Open();
//方法二
SQLiteConnectionStringBuilder builder = new SQLiteConnectionStringBuilder();
builder.DataSource = @”c:\test.db“;
builder.Password = @”password“;
SQLiteConnection cnn = new SQLiteConnection(builder.ConnectionString);
cnn .Open();
分頁
select * from messages limit 10,100;
表示跳過10行,取100行的返回結果。
三、 初步試探
經過多方搜尋,我找到了SQLite在.NET平台的支援庫,點擊 這裡 下載。我按照預設安裝,路徑為:”c://program files/sqlite.net”,安裝後進入這個檔案夾,裡面有好多檔案,我們只需要”System.Data.SQLite.DLL”,很小,只有605K。開啟VS,建立一個控制台程式sqlitetest。引用剛才提到的DLL檔案。然後引用”System.Data.SQLite”命名空間。現在就可以試試了。
從網上查詢到了一些資料,現在運用一下,看看行不行。
第一步,建立資料庫檔案。
我聲明了一個全域字串變數”dbName”,方面以後使用。
建立資料庫檔案的相關代碼為:
SQLiteConnection.CreateFile(dbName);
是不是超級簡單。接下來就是串連了。同樣是SQLiteConnection這個類。這個類有3個建構函式,一個是空參數,另一個是SQLiteConnection類型,就是複製一個串連了,最後一個是字串類型(連接字串),這個連接字串包含資料庫資訊已經密碼(這個輕量級的資料庫也支援密碼哦,好厲害),我現在還不懂格式是什麼,先試試預設建構函式。網上給的是使用SQLiteConnectionStringBuilder這個類構造連接字串。它有很多屬性,現在要用的是DataSource屬性,把dbName賦給它。還有Password屬性,沒有密碼吧,賦給它””吧。然後就是開啟資料庫了。所有代碼如下:
//建立資料庫連接並開啟資料庫
SQLiteConnection conn = new SQLiteConnection();
SQLiteConnectionStringBuilder connsb = new SQLiteConnectionStringBuilder();
connsb.DataSource = dbName;
connsb.Password = "";
conn.ConnectionString = connsb.ToString();
conn.Open();
接下來理所當然地要插入張表試試。
SQLite有個跟SQLCommand類似的SQLiteCommand,用法也差不多,這就不多說了,直接給出代碼吧:
//添加表
SQLiteCommand cmd = new SQLiteCommand(conn);
string cmdText = "CREATE TABLE TEST(ID int,name varchar(20))";
cmd.CommandText = cmdText;
cmd.ExecuteNonQuery();
一起把插入資料的代碼也貼了,都一樣的東西:
//插入測試資料
cmd.CommandText = "INSERT INTO [TEST] (ID,name) VALUES (1,'acen')";
cmd.ExecuteNonQuery();
cmd.CommandText = "INSERT INTO [TEST] (ID,name) VALUES (2,'unique')";
cmd.ExecuteNonQuery();
接下來就要查詢資料了,看看結果如何。網上教程用的是SQLiteReader,是不是和SQLReader很像?對啊,其實用法也是一樣的,看來這東西做得還是很方便的,代碼如下:
//查詢結果
cmd.CommandText = "SELECT * FROM [TEST]";
SQLiteDataReader dr = cmd.ExecuteReader();
StringBuilder sb = new StringBuilder();
while (dr.Read())
{
sb.Append(dr.GetInt32(0)).Append(""n").Append(dr.GetString(1));
}
Console.WriteLine(sb);
只要用過ADO.NET的看懂上面的代碼都沒問題吧,行,我們運行一下吧!
等啊等,哦,出錯了:Invalid ConnectionString format for parameter "Password".原來這句有問題,那好吧,刪掉試試。行了,呵呵,成功了!再看看網上的文章,注釋為“設定密碼”,意思這一步是設定密碼?試試。真行了,與此相關的東西接下來再測試。
好吧,首戰告捷,現在我們進一步對其進行測試!進行之前把完整代碼貼出來吧。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SQLite;
namespace sqlitetest
{
class Program
{
private const string dbName="sqlitetest.db";
static void Main(string[] args)
{
//建立資料庫檔案
SQLiteConnection.CreateFile(dbName);
//建立資料庫連接並開啟資料庫
SQLiteConnection conn = new SQLiteConnection();
SQLiteConnectionStringBuilder connsb = new SQLiteConnectionStringBuilder();
connsb.DataSource = dbName;
connsb.Password = "acen";
conn.ConnectionString = connsb.ToString();
conn.Open();
//添加表
SQLiteCommand cmd = new SQLiteCommand(conn);
string cmdText = "CREATE TABLE TEST(ID int,name varchar(20))";
cmd.CommandText = cmdText;
cmd.ExecuteNonQuery();
//插入測試資料
cmd.CommandText = "INSERT INTO [TEST] (ID,name) VALUES (1,'acen')";
cmd.ExecuteNonQuery();
cmd.CommandText = "INSERT INTO [TEST] (ID,name) VALUES (2,'unique')";
cmd.ExecuteNonQuery();
//查詢結果
cmd.CommandText = "SELECT * FROM [TEST]";
SQLiteDataReader dr = cmd.ExecuteReader();
StringBuilder sb = new StringBuilder();
while (dr.Read())
{
sb.Append(dr.GetInt32(0)).Append(""n").Append(dr.GetString(1));
}
Console.WriteLine(sb);
Console.ReadKey();
}
}
}
三、串連部分深入測試
第二部分基本是照著網上的一篇文章弄的,現在來點自己的測試。這次就不能再建立資料庫了吧,別把剛才的給蓋了。好的,開始,把建立資料庫檔案和添加表那一部分刪除。先直接運行,有四條記錄了。說明檔案串連正常,已經起到儲存的作用了。
研究一下SQLiteConnection的相關內容。
首先是它那幾個建構函式。複製串連那個就不管了,看它剩下的那個建構函式吧,看看是什麼格式。狂試自然不行,單步調試吧,不是有一步是把connsb(SQLiteConnectionStringBuilder)的值轉換為string後賦值給conn(SQLiteConnection)嗎,看看connsb的值,發現了,是”Data Source=sqlitetest.db;Password=acen”,應該就是這個了,試試。測試通過,那麼把密碼去掉試試。”File opened that is not a database file .file is encrypted or is not a database”,不出所料,出錯了。剛才查看SQLiteConnection屬性的時候,看到有DataSource項,莫非不用藉助SQLiteConnectionStringBuilder直接賦值也行?嘿嘿,不用得意得太早,這是唯讀,行不通。我要修改密碼怎麼辦呢?再認真看看,從連接字串一定是不可能的了,那就從SQLiteConnection這個類看看吧,有個SetPassword方法,這個方法有兩種參數,一種是位元組數組,另一種是字串形式,用第二種吧,改為”imacen”,能運行,問題是能多次運行,不對吧,密碼沒改到?把新密碼加到連接字串,果真出錯了。我剛才是放在開啟資料庫之前,莫非不能這樣?那放在後面吧,還是錯了,提示設定密碼應當在資料庫開始之前,莫非這隻是設定串連時的密碼?嗨,我錯了,我沒認真看,它還有個changePassword的方法,這個才是啊,而且要放在資料庫開啟後。那我就納悶了,為什麼有setPassword方法卻沒有setDataSource方法呢?把連接字串的密碼部分刪了,再試試setPassword方法。成功,它真的是設定串連密碼的,我想它為什麼要加入這個方法呢,可能考慮到安全新問題吧,其它都是使用明文,只是猜測罷了。行,這部分就這樣了,能連了就得。
總結一下:
1. 可以使用SQLiteConnectionStringBuilder類構建連結字串,然後轉換為string賦給SQLiteConnection的ConnectionString屬性,密碼沒有就別寫成””了。
2. 在構造SQLiteConnection時直接用連接字串,格式為”Data Source=xxx;Password=xxx”;其中密碼部分可以在setPassword方法中設定。
3. 修改密碼使用SQLiteConnection的changePassword方法,需在資料庫開啟之後。
四、 插入資料測試
SQLite不支援預存程序,雖然它的類SQLiteCommand有一個CommandType屬性,但其明確寫著目前僅支援CommandType.Text.那我要測試什麼呢?參數功能。開始啦!
記得在前面給出的代碼中有插入資料部分,現在把插入語句換成” INSERT INTO [TEST] (ID,name) VALUES (@ID,@name)";有Parameters這個屬性吧,真的有,不好意思了,連Add,AddWithValue都有,好啊,先用AddWithValue這種最簡單的試試。
//插入測試資料
cmd.CommandText = "INSERT INTO [TEST] (ID,name) VALUES (@ID,@name)";
cmd.Parameters.AddWithValue("@ID", 5);
cmd.Parameters.AddWithValue("@name","testtest");
cmd.ExecuteNonQuery();
運行,顯然行。那我們就和SQLCommand對比一下吧。粗略看了一下,SQLCommand有的SQLiteCommand都有,莫非SQLiteCommand就是繼承自SQLCommand?或者兩者是繼承自同一個介面,從”System.Data.SQLite”,”System.Data.SQLClient”來看,這兩者應該是繼承自同一個介面了。看看能不能找著證據。
很明顯,他們確實是繼承自同一個類或介面,那就沒什麼好說的啦,這個測試也差不多就這樣啦,其它讀取,更新那些也應該就一樣了。
後來我還分析了一下,這個SQLite應該就是把各個類重寫了一下,再把SQL Server的功能精簡後編譯成DLL檔案。我沒用過ACCESS,但我覺得SQLite跟ACCESS應該就是同類的東西了吧。這個我不敢下斷言。
用SQLite的好處在於,它能執行大部分SQL語句,而且網上評論認為它的效能是相當高的,另外一個最重要的原因是,它很小,1M不到的體積對於小型資料運用是非常方便的了。
select * from messages limit 10,100;
表示跳過10行,取100行的返回結果。