SQLite-net 项目地址: https://github.com/praeclarum/sqlite-net
这个库支持Xamarin.*(iOS,Android等)、 .NET, .NET Core、Mono、UWP等主流系统和程序。支持对数据库文件的加密,其sqlcipher加密版为sqlite-net-sqlcipher
,可以从Nuget获取。
如果在开发iOS / macOS应用中使用的也是基于sqlcipher实现的sqlite加密的库,如
SQLite.swift
,那么这二种程序生成的数据文件应该是可以互相兼容的。
安装
使用VS新建一个UWP项目,右键解决方案资源管理器
中项目节点下的的引用
节点,选择管理Nuget程序包
,打开NuGet
包管理器。切换到浏览
标签,搜索sqlite-net-sqlcipher
,选择第一项,点击右侧的安装
,这个是sqlite-net带sqlcipher加密功能的版本。
SQL方式操作SQLite
创建和连接数据库
var connection = new SQLite.SQLiteConnection("Test.db", key: "Mandarava");
...
connection.Dispose();
直接实例一个SQLiteConnection
对象,并提供数据库的保存路径和加密密码(如果不需要可以提供null
)来连接数据库,如果数据库不存在,则会自动创建数据文件。这里我只提供了文件名称Test.db
,密码为Mandarava
。最后,可以使用connection.Dispose
方法来关闭数据库,当然,因为SQLiteConnection
派生自IDisposable
,所以使用using
语句会更简洁一下。
那么
Test.db
这个数据文件到底保存在了哪里呢?可以用下面的代码来取得它的实际目录:var currentLocalFolder = Windows.Storage.ApplicationData.Current.LocalFolder.Path;
所以最终的保存位置大概是:
C:\Users\[用户名]\AppData\Local\Packages\xxxx\LocalState
目录下。
创建表
var sql = @"CREATE TABLE [User] (
[Id] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
[Name] VARCHAR(50) NOT NULL,
[Sex] VARCHAR(10) NOT NULL)";
var command = connection.CreateCommand(sql);
command.ExecuteNonQuery();
使用connection.CreateCommand(sql)
来获得一个SQLiteCommand
实例,使用command.ExecuteNonQuery
来执行建表操作。这里创建一个User
表用于存放User
用户信息。这个表它有三个字段,分别是Id
字段(Integer类型,主键),Name
字段(字符串类型),Sex
字段(字符串类型)。然后,根据这个表,可以创建一个对应的User
实体类。
public class User
{
[SQLite.PrimaryKey, SQLite.AutoIncrement]
public int Id { get; set; }
public string Name { get; set; }
public string Sex { get; set; }
}
插入记录
sql = "INSERT INTO [User] VALUES(?, ?, ?)";
command = connection.CreateCommand(sql, null, "Manda", "M");
command.ExecuteNonQuery();
sql
中的?
表示需要接收参数的占位符,然后在connection.CreateCommand
方法中提供它们需要接收的参数值即可。
查询记录
sql = "SELECT * FROM [User]";
command = connection.CreateCommand(sql);
var userList = command.ExecuteQuery<User>();
foreach (var user in userList)
{
UWPConsole.Console.WriteLine($"{user.Id}\t{user.Name}\t{user.Sex}");
}
这里使用command.ExecuteQuery
方法来进行查询,查询时需要提供一个结果所对应的实体类型,这里就是User
类。
注:
UWPConsole.Console.WriteLine
是一个UWP控制台工具提供的方法,你可以在NuGet中查找并安装UWPConsole
后来使用。
问题:
command.ExecuteQuery<User>()
必须提供查询结果对应的实体类型,这里就是User
类,但如果我的sql是个join
查询,这就出现问题了,没有对应的类可用。尝试提供Dictionary<
obect, object>,List<object>
都是接收到不到任何数据的。看了一下ExecuteQuery
的实现,似乎确实没办法,而且ORM方式也似乎不支持join操作。
运行结果
到这里的全部代码如下:
//连接数据库,如果数据库不存在则自动创建
using (var connection = new SQLite.SQLiteConnection("Test.db", key: "Mandarava"))
{
//新建表
var sql = @"CREATE TABLE IF NOT EXISTS [User] (
[id] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
[name] VARCHAR(50) NOT NULL,
[sex] VARCHAR(10) NOT NULL)";
var command = connection.CreateCommand(sql);
command.ExecuteNonQuery();
//插入二条记录
sql = "INSERT INTO [User] VALUES(?, ?, ?)";
command = connection.CreateCommand(sql, null, "Manda", "M");
command.ExecuteNonQuery();
command = connection.CreateCommand(sql, null, "Flower", "F");
command.ExecuteNonQuery();
//查询记录
sql = "SELECT * FROM [User]";
command = connection.CreateCommand(sql);
var userList = command.ExecuteQuery<User>();
foreach (var user in userList)
{
UWPConsole.Console.WriteLine($"{user.Id}\t{user.Name}\t{user.Sex}");
}
}
运行结果如下,创建的二条记录成功被查询到了(控制台窗口由UWPConsole
呈现):
删除记录
sql = "DELETE FROM [User] WHERE ID = 1";
command = connection.CreateCommand(sql);
command.ExecuteNonQuery();
这个只需要提供Delete
语句即可。
ORM方式操作SQLite
这种方式就比较简洁了,避开了繁杂的SQL语句。
这种方式下就要创建表的实体类,本例只有一个表User
表,其对应的实体类就是User
类,在前文中已经创建过了。
public class User
{
[SQLite.PrimaryKey, SQLite.AutoIncrement]
public int Id { get; set; }
public string Name { get; set; }
public string Sex { get; set; }
}
在这个类中,用[SQLite.PrimaryKey, SQLite.AutoIncrement]
将Id
属性声明为数据库自动递增的主键字段。更多ORM属性可以查阅官方文档 ORM Attributes(注意MaxLength
属性)。
创建表
connection.CreateTable<User>();
创建表时提供表的实体类型即可,这里就是User
类,所创建的表的名称就是类的名称。
提示:这种ORM方式有一个问题,如果是C#/.Net app,如果想对代码进行混淆加密,混淆工具通常都会提供将类名、字段名混淆的功能,每次混淆后,类名、字段名很大可能都不同于上一次混淆结果(不过,有些工具似乎可以设置为相同),所以对于这种情况,就要禁止对相关类进行混淆了,否则你的app这次发布时运行正常,下次发布时可能就找不到原来的数据表了(因为相关的类名、字段名可能变了)。
插入记录
connection.Insert(new User() { Name = "钢蛋", Sex = "男" });
connection.Insert(new User() { Name = "约汉", Sex = "女" });
connection.Insert(new User() { Name = "铁锤", Sex = "男" });
插入很简单,就是提供一个User
类的实例即可。
查询记录
var users = connection.Table<User>().Where(u => u.Sex == "男");
foreach (var user in users)
{
UWPConsole.Console.WriteLine($"{user.Id}\t{user.Name}\t{user.Sex}");
}
查询也很简单,先用connection.Table<User>()
取得要查询的表,再给Where
方法一个查询条件即可。
删除记录
connection.Delete<User>(1);
删除记录时,只需要提供一个主键值即可。比如这里要删除第1条钢蛋
的记录,因为它的主键是Id
,钢蛋的Id
是1
,就提供其Id
值即1
即可。
其它
其它功能,比如异步处理、事务处理等可以参考官方文档。