我們在開發應用是經常會需要用到一些數據的存儲,存儲的方式有多種,使用數據庫是一種比較受大家歡迎的方式。但是對於一些小型的應用,如一些移動APP,通常的數據庫過於龐大,而輕便的SQLite則能解決這一問題。不但操作方便,而且只需要要一個文件即可,在這里我們來說一說使用C#語言操作SQLite數據庫。
1、SQLite簡介
SQLite,是一款輕型的數據庫,是遵守ACID的關系型數據庫管理系統,它包含在一個相對小的C庫中。它是D.RichardHipp建立的公有領域項目。它的設計目標是嵌入式的,而且目前已經在很多嵌入式產品中使用了它,它占用資源非常的低,在嵌入式設備中,可能只需要幾百K的內存就夠了。它能夠支持Windows/Linux/Unix等等主流的操作系統,同時能夠跟很多程序語言相結合,比如 Tcl、C#、PHP、Java等,還有ODBC接口,同樣比起MySQL、PostgreSQL這兩款開源的世界著名數據庫管理系統來講,它的處理速度比他們都快。
如果想了解更多關於SQLite的問題,可以訪問它的官方網站:http://www.sqlite.org/
2、開始前的准備
在開始之前我們需要准備必要的開發環境,這次咱們使用的是Visual Studio 2015開發環境,但是我們開發基於SQLite的應用光有VS2015還不夠。我需要到SQLite的官方網站下載並安裝SQLite。
在SQLite官網找到下載,有應用於各種環境的SQLite組件及源碼,我們選擇Precompiled Binaries for .NET,這是應用於.NET開發環境的,點擊進入會看到應用於.NET2.0直至4.6以及32位和64位平台的各個版本。我們選擇Setups for 32-bit Windows (.NET Framework 4.6)下載安裝即可。
3、C#操作SQLite的封裝
在完成開發環境的准備之后,我們接下來實現對SQLite操作的必要封裝,以進一步降低在具體應用中的使用難度。在這里我們只是封裝一些常用而且必要的功能。
1 public class SQLiteHelper 2 { 3 //創建數據庫文件 4 public static void CreateDBFile(string fileName) 5 { 6 string path = System.Environment.CurrentDirectory + @"/Data/"; 7 if (!Directory.Exists(path)) 8 { 9 Directory.CreateDirectory(path); 10 } 11 string databaseFileName = path + fileName; 12 if (!File.Exists(databaseFileName)) 13 { 14 SQLiteConnection.CreateFile(databaseFileName); 15 } 16 } 17 18 //生成連接字符串 19 private static string CreateConnectionString() 20 { 21 SQLiteConnectionStringBuilder connectionString = new SQLiteConnectionStringBuilder(); 22 connectionString.DataSource = @"data/ScriptHelper.db"; 23 24 string conStr = connectionString.ToString(); 25 return conStr; 26 } 27 28 /// <summary> 29 /// 對插入到數據庫中的空值進行處理 30 /// </summary> 31 /// <param name="value"></param> 32 /// <returns></returns> 33 public static object ToDbValue(object value) 34 { 35 if (value == null) 36 { 37 return DBNull.Value; 38 } 39 else 40 { 41 return value; 42 } 43 } 44 45 /// <summary> 46 /// 對從數據庫中讀取的空值進行處理 47 /// </summary> 48 /// <param name="value"></param> 49 /// <returns></returns> 50 public static object FromDbValue(object value) 51 { 52 if (value == DBNull.Value) 53 { 54 return null; 55 } 56 else 57 { 58 return value; 59 } 60 } 61 62 /// <summary> 63 /// 執行非查詢的數據庫操作 64 /// </summary> 65 /// <param name="sqlString">要執行的sql語句</param> 66 /// <param name="parameters">參數列表</param> 67 /// <returns>返回受影響的條數</returns> 68 public static int ExecuteNonQuery(string sqlString, params SQLiteParameter[] parameters) 69 { 70 string connectionString=CreateConnectionString(); 71 using (SQLiteConnection conn = new SQLiteConnection(connectionString)) 72 { 73 conn.Open(); 74 using (SQLiteCommand cmd = conn.CreateCommand()) 75 { 76 cmd.CommandText = sqlString; 77 foreach (SQLiteParameter parameter in parameters) 78 { 79 cmd.Parameters.Add(parameter); 80 } 81 return cmd.ExecuteNonQuery(); 82 } 83 } 84 } 85 86 /// <summary> 87 /// 執行查詢並返回查詢結果第一行第一列 88 /// </summary> 89 /// <param name="sqlString">SQL語句</param> 90 /// <param name="sqlparams">參數列表</param> 91 /// <returns></returns> 92 public static object ExecuteScalar(string sqlString, params SQLiteParameter[] parameters) 93 { 94 string connectionString = CreateConnectionString(); 95 using (SQLiteConnection conn = new SQLiteConnection(connectionString)) 96 { 97 conn.Open(); 98 using (SQLiteCommand cmd = conn.CreateCommand()) 99 { 100 cmd.CommandText = sqlString; 101 foreach (SQLiteParameter parameter in parameters) 102 { 103 cmd.Parameters.Add(parameter); 104 } 105 return cmd.ExecuteScalar(); 106 } 107 } 108 } 109 110 /// <summary> 111 /// 查詢多條數據 112 /// </summary> 113 /// <param name="sqlString">SQL語句</param> 114 /// <param name="parameters">參數列表</param> 115 /// <returns>返回查詢的數據表</returns> 116 public static DataTable GetDataTable(string sqlString,params SQLiteParameter[] parameters) 117 { 118 string connectionString = CreateConnectionString(); 119 using (SQLiteConnection conn = new SQLiteConnection(connectionString)) 120 { 121 conn.Open(); 122 using (SQLiteCommand cmd = conn.CreateCommand()) 123 { 124 cmd.CommandText = sqlString; 125 foreach (SQLiteParameter parameter in parameters) 126 { 127 cmd.Parameters.Add(parameter); 128 } 129 DataSet ds = new DataSet(); 130 SQLiteDataAdapter adapter = new SQLiteDataAdapter(cmd); 131 adapter.Fill(ds); 132 return ds.Tables[0]; 133 } 134 } 135 } 136 }
4、應用實例
上面封裝完了之后,我們就是使用上面封裝的函數來實際操作SQLite數據庫。對數據庫的應用實例無非就是對各種對象的增、刪、改、查。我沒列舉一個對源碼類型對象的各種操作實例如下:
1 public class ScriptTypeDAL 2 { 3 public ScriptTypeM ToScriptType(DataRow row) 4 { 5 ScriptTypeM type = new ScriptTypeM(); 6 type.ScriptTypeId = (Guid)row["ScriptTypeId"]; 7 type.ScriptType = (string)row["ScriptType"]; 8 type.IsUsing = (bool)row["IsUsing"]; 9 return type; 10 } 11 12 public void Insert(ScriptTypeM Type) 13 { 14 SQLiteHelper.ExecuteNonQuery(@"insert into TB_ScriptType(ScriptTypeId,ScriptType,IsUsing) 15 Values(@ScriptTypeId,@ScriptType,1)", 16 new SQLiteParameter("ScriptTypeId", Type.ScriptTypeId), 17 new SQLiteParameter("ScriptType", Type.ScriptType)); 18 19 } 20 21 public void Update(ScriptTypeM Type) 22 { 23 SQLiteHelper.ExecuteNonQuery(@"update TB_ScriptType set ScriptType=@ScriptType, 24 IsUsing=@IsUsing where ScriptTypeId=@ScriptTypeId", 25 new SQLiteParameter("ScriptType", Type.ScriptType), 26 new SQLiteParameter("IsUsing", Type.IsUsing), 27 new SQLiteParameter("ScriptTypeId", Type.ScriptTypeId)); 28 } 29 30 public ScriptTypeM GetbyId(Guid id) 31 { 32 DataTable table = SQLiteHelper.GetDataTable("select * from TB_ScriptType where ScriptTypeId=@id", 33 new SQLiteParameter("id", id)); 34 if (table.Rows.Count <= 0) 35 { 36 return null; 37 } 38 else if (table.Rows.Count > 1) 39 { 40 throw new Exception("Id重復!"); 41 } 42 else 43 { 44 return ToScriptType(table.Rows[0]); 45 } 46 } 47 48 public ScriptTypeM GetbyName(string name) 49 { 50 DataTable table = SQLiteHelper.GetDataTable("select * from TB_ScriptType where ScriptType=@name", 51 new SQLiteParameter("name", name)); 52 if (table.Rows.Count <= 0) 53 { 54 return null; 55 } 56 else if (table.Rows.Count > 1) 57 { 58 throw new Exception("類型名稱重復!"); 59 } 60 else 61 { 62 return ToScriptType(table.Rows[0]); 63 } 64 } 65 66 public ScriptTypeM[] ListAll() 67 { 68 DataTable table = SQLiteHelper.GetDataTable("select * from TB_ScriptType where IsUsing=1"); 69 ScriptTypeM[] type = new ScriptTypeM[table.Rows.Count]; 70 for (int i = 0; i < table.Rows.Count; i++) 71 { 72 type[i] = ToScriptType(table.Rows[i]); 73 } 74 return type; 75 } 76 77 public ScriptTypeM[] Search(string sql, List<SQLiteParameter> parameterList) 78 { 79 DataTable table = SQLiteHelper.GetDataTable(sql, parameterList.ToArray()); 80 ScriptTypeM[] type = new ScriptTypeM[table.Rows.Count]; 81 for (int i = 0; i < table.Rows.Count; i++) 82 { 83 type[i] = ToScriptType(table.Rows[i]); 84 } 85 return type; 86 } 87 }
SQLite數據庫小巧而且應用方便,在一些小型應用和嵌入式應用中很有優勢,當然如何應用的得心應手就看個人了。