当前位置: 首页 > news >正文

在Unity中使用SQLite(Sqlite-net-pcl)

https://github.com/praeclarum/sqlite-net

  • sqlite-net-pcl:标准的 SQLite .NET 支持库,适用于大部分场景。

  • sqlite-net-sqlcipher:支持加密的 SQLite 版本,适用于需要加密数据库的场景。

  • sqlite-net-static:使用 P/Invoke 调用平台提供的 SQLite 实现,适合希望使用系统本地 SQLite 的场景。

  • sqlite-net-base:没有内嵌的 SQLitePCLRaw,适合需要自定义 SQLite 提供者的场景。

通常情况我们使用第一个

一. 简介

SQLite-net 是一个开源的轻量级库,允许 .NET.NET CoreMono 应用程序将数据存储到 SQLite 3 数据库中。最初设计是为了与 Xamarin.iOS 一起工作,但后来扩展到支持所有平台(包括 Xamarin.NETUWPAzure 等)。

SQLite-net 被设计为一个快速且方便的数据库层。其设计目标如下:

  • 非常容易与现有项目集成,并支持所有 .NET 平台。

  • 是一个对 SQLite 的轻量级封装,既快速又高效。(该库不应成为查询性能的瓶颈。)

  • 提供非常简单的方法来安全地执行 CRUD 操作和查询(使用参数),并以强类型的方式检索查询结果。

  • 无需强迫你修改类即可与数据模型配合使用。(包含一个小型的反射驱动的 ORM 层。)

二. 安装

推荐使用Nuget For Unity安装该库(因为有很多依赖),在Unity中仅安装该库还不够

先使用VS创建一个控制台或者类库,引入这个库然后编译一下,在bin目录找到

将里面的DLL放到Plugins下,你还需要发布到那个平台则将那个平台的依赖放进去(推荐保留目录结构)

三. 示例

完整文档:https://github.com/praeclarum/sqlite-net/wiki

该库包含了一些简单的属性,使用这些属性来控制表的构建。在一个简单的股票程序中,可能会这样使用:

public class Stock
{[PrimaryKey, AutoIncrement]public int Id { get; set; }public string Symbol { get; set; }
}public class Valuation
{[PrimaryKey, AutoIncrement]public int Id { get; set; }[Indexed]public int StockId { get; set; }public DateTime Time { get; set; }public decimal Price { get; set; }[Ignore]public string IgnoreField { get; set; }
}

一旦定义了模型中的对象,可以选择使用不同的 API。可以使用 "同步 API",其中每个调用会阻塞执行一个接一个;或者使用 "异步 API",它不会阻塞调用。

1.同步 API

一旦你定义了实体类,可以通过调用 CreateTable 自动在数据库中生成表:

// 获取数据库文件的绝对路径
var databasePath = Path.Combine(Application.streamingAssetsPath, "MyData.db");var db = new SQLiteConnection(databasePath);
db.CreateTable<Stock>();
db.CreateTable<Valuation>();
插入数据

可以使用 Insert 方法向数据库中插入数据。如果表中包含一个自动递增的主键,那么插入后该主键的值将自动返回:

public static void AddStock(SQLiteConnection db, string symbol) {var stock = new Stock() {Symbol = symbol};db.Insert(stock);Debug.Log(stock.Id);Debug.Log(stock.Symbol);}
更新和删除

类似地,也有用于更新 (Update) 和删除 (Delete) 的方法。

查询数据

最直接的查询数据方式是使用 Table 方法。你可以通过传递谓词来约束查询条件,或者添加 ORDER BY 子句:

var query = db.Table<Stock>().Where(v => v.Symbol.StartsWith("A"));foreach (var stock in query)Debug.Log("Stock: " + stock.Symbol);
低级查询

还可以使用 Query 方法进行低级查询,这允许你执行原生 SQL 查询:

public static IEnumerable<Valuation> QueryValuations (SQLiteConnection db, Stock stock) {return db.Query<Valuation>("select * from Valuation where StockId = ?", stock.Id);
}

在这个例子中,Query 方法的泛型参数指定了要为每一行创建的对象类型。它可以是你的表类之一,也可以是任何其他类,只要该类的公共属性与查询返回的列匹配。例如,我们可以将上面的查询重写为:

public class Val
{public decimal Money { get; set; }public DateTime Date { get; set; }
}public static IEnumerable<Val> QueryVals(SQLiteConnection db, Stock stock) {return db.Query<Val>("select \"Price\" as \"Money\", \"Time\" as \"Date\" from Valuation where StockId = ?", stock.Id);
}
低级数据库更新

你可以使用 Execute 方法执行低级的数据库更新。例如:

db.Execute("UPDATE Stock SET Symbol = ? WHERE Id = ?", "GOOG", stockId);

2.异步 API

异步库使用 任务并行库(Task Parallel Library, TPL),因此你可以正常使用 Task 对象以及 asyncawait 关键字。

创建表

一旦你定义了实体类,可以通过调用 CreateTableAsync 异步方法自动生成数据库表:

// 获取数据库文件的绝对路径
var databasePath = Path.Combine(Application.streamingAssetsPath, "MyData.db");var db = new SQLiteAsyncConnection(databasePath);// 异步创建表
await db.CreateTableAsync<Stock>();Debug.Log("Table created!");
插入数据

你可以使用 InsertAsync 方法异步插入数据。如果表中包含一个自动递增的主键,那么插入后该主键的值将返回给你:

var stock = new Stock()
{Symbol = "AAPL"
};// 异步插入数据
await db.InsertAsync(stock);Debug.Log(stock.Id);

类似的,UpdateAsyncDeleteAsync 方法也可以用于异步更新和删除。

查询数据

查询数据最直接的方式是使用 Table 方法。它返回一个 AsyncTableQuery 实例,你可以添加谓词来进行 WHERE 条件约束,或者添加 ORDER BY 排序。直到你调用 ToListAsyncFirstAsyncFirstOrDefaultAsync 等特殊检索方法时,数据库才会真正执行查询。

var query = db.Table<Stock>().Where(s => s.Symbol.StartsWith("A"));// 异步执行查询并返回列表
var result = await query.ToListAsync();foreach (var s in result)Debug.Log("Stock: " + s.Symbol);
低级查询

你还可以通过 QueryAsync 方法直接执行 SQL 查询。除了 InsertAsync 等提供的修改操作外,你还可以使用 ExecuteAsync 方法直接在数据库中修改一组数据。

public static async Task QueryValuationsAsync(SQLiteAsyncConnection db, Stock stock)
{var valuations = await db.QueryAsync<Valuation>("select * from Valuation where StockId = ?", stock.Id);foreach (var valuation in valuations){Debug.Log($"Valuation Price: {valuation.Price}, Time: {valuation.Time}");}
}
获取标量值

ExecuteScalarAsync 方法允许你从数据库中轻松返回一个标量值(例如,计数、总和等):

var count = await db.ExecuteScalarAsync<int>("select count(*) from Stock");Debug.Log(string.Format("Found '{0}' stock items.", count));

3.手动 SQL

通常,sqlite-net 用作轻量级的 ORM(对象关系映射),使用 CreateTableTable 方法来操作数据库。然而,你也可以通过手动执行 SQL 查询来使用它,这提供了更灵活的控制。

示例:创建表、插入数据并查询
// 创建一个名为 Stock 的表,包含一个 Symbol 字段
db.Execute("create table Stock(Symbol varchar(100) not null)");// 使用参数化的 SQL 插入数据
db.Execute("insert into Stock(Symbol) values (?)", "MSFT");// 查询所有 Stock 表中的数据
var stocks = db.Query<Stock>("select * from Stock");

在这个例子中:

  • 使用 Execute 方法执行创建表和插入数据的 SQL 语句。

  • Execute 方法执行 SQL 查询时使用参数化语句,避免了 SQL 注入问题。

  • 使用 Query 方法查询表中的所有数据并返回结果。


4.加密

如果你需要使用加密数据库,可以通过安装 sqlite-net-sqlcipher NuGet 包来实现。SQLCipher 为 SQLite 数据库提供了加密支持。

设置加密数据库
var options = new SQLiteConnectionString(databasePath, true, key: "password");
var encryptedDb = new SQLiteAsyncConnection(options);

在这个例子中:

  • SQLiteConnectionStringkey 参数用于设置数据库的加密密码。

  • 创建了一个 SQLiteAsyncConnection 实例来连接加密数据库。

使用 PRAGMA 设置加密选项

你还可以通过 PRAGMA 设置来控制加密的行为。例如,控制加密的密钥导出函数(KDF)迭代次数等:

var options2 = new SQLiteConnectionString(databasePath, true, key: "password", preKeyAction: db => db.Execute("PRAGMA cipher_default_use_hmac = OFF;"),postKeyAction: db => db.Execute("PRAGMA kdf_iter = 128000;"));var encryptedDb2 = new SQLiteAsyncConnection(options2);

在这个例子中:

  • preKeyAction 设置了加密时的一些前置操作,如关闭 HMAC。

  • postKeyAction 设置了加密时的后续操作,如设置 KDF 迭代次数为 128000

这些设置可以帮助你自定义数据库加密的行为,增加安全性。

四. 可视化工具

推荐免费开源的可视化工具SqliteStudio

https://github.com/pawelsalawa/sqlitestudio

http://www.dtcms.com/a/399819.html

相关文章:

  • 杭州做网站公司排名百度网页下载
  • 学习优秀的项目 —— MST++
  • 建设网站需要的ftp资源石家庄房产网
  • 开发避坑指南(55):基于路由守卫的Vue2/Vue3 Tab页查询状态保留方案
  • 如何设计一个版本统一的前端接入层来适配多版本验证码
  • 电子商务网站开发问题研究山西手机网站建设
  • 【Vue3】 - 解析Markdown内容生成侧边栏Toc目录索引
  • wordpress 用法成都优化网站厂家
  • 从零开始循序渐进地学习Conda环境管理
  • 网站服务费怎么做分录四川城乡与建设厅网站
  • uniapp 打包安卓apk。同时安装正式和测试的apk。
  • 中和华丰建设有限责任公司网站c 能用来做网站吗
  • 使用python的加权Jaccard分析流程
  • 网站开发需要掌握哪些技术wordpress登录链接
  • 学习Java四十五天
  • 从android compose动画研究带接收者的函数类型(Receiver Function Type)
  • 佛山网站建设玲念建站平面设计和电商设计
  • 南通网站建设规划书深圳家居网站建设公司
  • 大模型agent综述:A Survey on Large Language Model based Autonomous Agents
  • 重庆网站设计最加科技网站开发怎么学
  • 【淘宝API接口】如何获取淘宝商品的详细信息?
  • 突破限制!AI智能体网页交互利器:Playwright MCP与Bright Data Web MCP
  • IT 疑难杂症诊疗室:从现象到根因的系统化故障排查指南
  • 网站怎么做子网页flash网站开发用什么语言
  • 做户外运动的网站广州做网站公司排名
  • 公用通信网
  • 上海外贸营销网站建设python3的网站开发
  • 新网站制作市场重庆网站设计建设
  • 大模型灾难性的原因和缓解方法?
  • 【深度学习-Day 49】注意力机制:让模型像人一样“划重点”,告别Seq2Seq信息瓶颈