金融類的網(wǎng)站怎么做杭州網(wǎng)絡(luò)推廣有限公司
? ? ? 一:讓 SQLiteExpert? 支持(cipher)加密數(shù)據(jù)庫(kù)
?????????SQLiteExpert? 作為SQlite?的管理工具,默認(rèn)不支持加密數(shù)據(jù)庫(kù)的,使其成為支持(cipher)加密數(shù)據(jù)庫(kù)的管理工具,需要添加e_sqlcipher.dll (復(fù)制到SQLiteExpertPro32/64.exe?同級(jí)目錄即可,從哪里來(lái)的這個(gè)問(wèn)題:你可以直接往后面下載鏈接下,也可以跟隨文章知道從哪里來(lái)的。最好是知道從哪里來(lái)的,也許我放鏈接的版本在未來(lái)有新版本更替,我也就不更新下載鏈接了。),并在其設(shè)置里面進(jìn)行勾選就能激活加密數(shù)據(jù)庫(kù)支持。如下圖所示(幾個(gè)關(guān)鍵點(diǎn)已經(jīng)標(biāo)記),需要注意的是SQLiteExpert? 32位/64位需要與e_sqlcipher.dll 32位/64位匹配,否則在32位版的SQLiteExpert? 是看不到64位的e_sqlcipher.dll。
加入成功后,打開(kāi)或者新建數(shù)據(jù)庫(kù)都有加密選項(xiàng)
(新建數(shù)據(jù)庫(kù))
(打開(kāi)加密數(shù)據(jù)庫(kù))
這樣到此可以完整的處理了SQLiteExpert?支持加密
????????由于SQLiteExpert?只有windows?版本,linux?平臺(tái)的cipher加密支持庫(kù)也就不打包了。對(duì)于跨平臺(tái)的SQLite?gui?也許類似,上傳的壓縮包就只有windows平臺(tái)dll。
下載鏈接在頂部,壓縮包結(jié)構(gòu)如下:
二. .Net C#?連接(cipher)加密的SQlite數(shù)據(jù)庫(kù)
nuget
1、SQLitePCLRaw.bundle_e_sqlcipher
2、Microsoft.Data.Sqlite
3、Costura.Fody (如果不需要考慮發(fā)布潔癖(單文件,全部外圍DLL聚合),就沒(méi)必要。)
直接debug,生成一堆內(nèi)容,我隨便建立了個(gè)VS 工程(sqlitedemo)?debug目錄大致如下:
runtime?內(nèi)容如下:(也就是各種平臺(tái)的(cipher)sqlite?lib),前面的e_sqlcipher.dll取材就是從這里取得。
debug?生成的很多,也就是剛才說(shuō)的發(fā)布生成潔癖的問(wèn)題,如果你在意,發(fā)布時(shí)候選擇輸出好平臺(tái),runtime可以自動(dòng)減少,但是依舊會(huì)生成其他dll。
那就采用Costura.Fody
編輯項(xiàng)目?jī)?nèi) FodyWeavers.xml?文件(nuget過(guò)了會(huì)自動(dòng)生成該文件),文件內(nèi)容修改如下:
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"><Costura ><Unmanaged64Assemblies>e_sqlciphere_sqlite3</Unmanaged64Assemblies><Unmanaged32Assemblies>e_sqlciphere_sqlite3</Unmanaged32Assemblies></Costura>
</Weavers>
再編輯?解決方案文件(右邊第一箭頭那里雙擊)
主要語(yǔ)句加入 (我選擇的x64版本的Exe)
?<RuntimeIdentifier>win-x64</RuntimeIdentifier>
????????這樣,右鍵點(diǎn)擊?解決方案->重新生成解決方案 (這里要注意,要重新整個(gè)解決方案才行。更改解決方案文件,直接debug會(huì)有問(wèn)題。)
? ? ? ? 最終生成輸出內(nèi)容如下:
其他亂七八糟的dll沒(méi)有了,清爽吧?!?
再來(lái)看相關(guān)C#?連接Sqlite?操作的代碼:先上SqliteHelper,順便也推薦一下 Cody?AI生成的,我用了很長(zhǎng)時(shí)間,免費(fèi)且好用(面向編程)。
public class SQLiteHelper{private readonly string _connectionString;public SQLiteHelper(string dbPath, string password = null){var builder = new SqliteConnectionStringBuilder{DataSource = dbPath,Mode = SqliteOpenMode.ReadWriteCreate};if (!string.IsNullOrEmpty(password)){builder.Password = password;}_connectionString = builder.ConnectionString;}public int ExecuteNonQuery(string sql, List<SqliteParameter> parameters = null){using (var connection = new SqliteConnection(_connectionString)){connection.Open();using (var command = connection.CreateCommand()){command.CommandText = sql;if (parameters != null){command.Parameters.AddRange(parameters);}return command.ExecuteNonQuery();}}}public T ExecuteScalar<T>(string sql, List<SqliteParameter> parameters = null){using (var connection = new SqliteConnection(_connectionString)){connection.Open();using (var command = connection.CreateCommand()){command.CommandText = sql;if (parameters != null){command.Parameters.AddRange(parameters);}var result = command.ExecuteScalar();return (T)Convert.ChangeType(result, typeof(T));}}}public List<T> ExecuteQuery<T>(string sql, List<SqliteParameter> parameters = null) where T : new(){var result = new List<T>();using (var connection = new SqliteConnection(_connectionString)){connection.Open();using (var command = connection.CreateCommand()){command.CommandText = sql;if (parameters != null){command.Parameters.AddRange(parameters);}using (var reader = command.ExecuteReader()){while (reader.Read()){var item = new T();for (int i = 0; i < reader.FieldCount; i++){var property = typeof(T).GetProperty(reader.GetName(i), BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);if (property != null && !reader.IsDBNull(i)){property.SetValue(item, Convert.ChangeType(reader.GetValue(i), property.PropertyType));}}result.Add(item);}}}}return result;}public void ExecuteTransaction(Action<SqliteConnection> action){using (var connection = new SqliteConnection(_connectionString)){connection.Open();using (var transaction = connection.BeginTransaction()){try{action(connection);transaction.Commit();}catch{transaction.Rollback();throw;}}}}}
}
調(diào)用如下:
SQLiteHelper?構(gòu)造函數(shù),第一個(gè)參數(shù)數(shù)據(jù)庫(kù)路徑文件全名,第二個(gè)參數(shù)數(shù)據(jù)庫(kù)密碼
SQLiteHelper SLH = new SQLiteHelper("D:\\Manage\\Documents\\db", "TEST");const int batchSize = 100000;const string insertSql = "INSERT INTO Student (F_ID, F_Name) VALUES (@F_ID, @F_Name)";SLH.ExecuteTransaction(connection =>{using var command = connection.CreateCommand();command.CommandText = insertSql;command.Parameters.Add("@F_ID", SqliteType.Text);command.Parameters.Add("@F_Name", SqliteType.Text);for (int i = 0; i < batchSize; i++){command.Parameters["@F_ID"].Value = Guid.NewGuid().ToString();command.Parameters["@F_Name"].Value = $"John{i}";command.ExecuteNonQuery();}});
密碼錯(cuò)誤則在這里報(bào)錯(cuò):
這樣既可以C#?開(kāi)發(fā)加密數(shù)據(jù)庫(kù)又可以在外部用外部工具直接編輯加密數(shù)據(jù)庫(kù)的環(huán)境就達(dá)成了。
后話:
? ? ? ? 選擇SQLiteExpert?是界面要黑一點(diǎn),可能不是最好用的,但黑色看起來(lái)眼睛舒服一點(diǎn),歡迎推薦一些。