没有人比我更懂Flutter第三方依赖鸿蒙化了之Sqflite

最近又折腾了一波鸿蒙,发现鸿蒙的数据库支持SQLite,于是乎,就想着把Sqflite鸿蒙化,于是乎,就有了这个系列。

在此之前先打个广告,有鸿蒙5+的设备朋友帮我刷个下载量,在AppGallery下载以下app打开并运行一下子,感谢:

  • 乐活伴侣
  • 阿默宠物

和Sqflite无关的东西

先说点和鸿蒙相关的其他的小知识点,不算什么新知识,但是可能会帮到你。 作为后起之秀,鸿蒙算是站在不少巨人的肩膀上的,因此,一些权限管理的相对比较严格,以下内容仅对上架华为应用市场的手机app有效,对于非上架华为应用市场的app及其他类型设备本人没有研究。

应用读取剪贴板

对剪切板的主动读取,不像Android那样,直接调用ClipboardManager就可以。 在鸿蒙中,应用读取剪贴板是不仅要在module.json5中申请权限:

json 复制代码
      {
        "name": "ohos.permission.READ_PASTEBOARD",
        "reason": "$string:request_paste_reason",
        "usedScene": {
          "abilities": ["EntryAbility"],
          "when": "inuse"
        }
      },

还要在申请Profile时申请ACL权限,得等ACL权限申请通过后,才能使用这个权限。目前,官方允许使用该权限的只有符合以下场景:

  • 银行卡号复制:银行类应用需要读取剪贴板中的银行卡号自动生成卡片。
  • 口令复制:应用需要读取剪贴板中特定格式口令,自动打开应用内对应页面。
  • 文档编辑类应用。
  • 输入法:系统级输入法需要读取剪贴板信息实现自动填充。应用内置输入法不能申请此权限。

同时,官方也给出了一个解决方案,使用"粘贴控件"读取剪贴板数据,使用方式请参考:使用粘贴控件,但这是一个原生组件,Flutter中似乎无法使用(当然我也没有试过)。

以下是我在申请时,给我的答复:

makefile 复制代码
审核意见: 开发者您好:

受限权限仅少量符合特殊场景的应用可在通过审批后使用,您的场景不符合权限使用要求,请使用非权限的替代方案实现功能。

粘贴场景ArkUI输入框支持长按拉起toolbar,可以直接粘贴剪切板内的第一条内容,无需申请ohos.permission.READ_PASTEBOARD权限,如您使用的是三方框架,请在申请理由中描述并重新提交申请,感谢您的理解与支持!

其他权限

还有一些权限,在我看起来好像并不需要声明,但实际上你还是要在module.json5中声明一下,比如调用系统的打印服务:

bash 复制代码
 {
        "name": "ohos.permission.PRINT",
        "reason": "$string:request_print_reason",
        "usedScene": {
          "abilities": ["EntryAbility"],
          "when": "inuse"
        }
      }

不声明是无法使用的。关于权限具体可以参看:应用权限管控,文档说的很详细了,不赘述了。

Sqflite鸿蒙化

起初,我以为flutter_sqflite已经支持鸿蒙了,那理应问题不大,但是,当我尝试使用时,还是给我了一些小小的惊喜。

INTEGER变blob了?

用flutter_sqflite库建表时候,字段为INTEGER,理论上sqlite的INTEGER兼容long型。并且dart中 int也是兼容long。但是现在dart模型中int字段(比如:DateTime.now().millisecondsSinceEpoch),存入数据库,会被强制转成blob类型,然后查询上来的数据是unmodifiableUint8arrayview。

如何解决?

答:像时间戳这种比较大的数据类型字段要用UNLIMITED INT,不能用INTEGER ,例如:

sql 复制代码
CREATE TABLE $_tableName(id INTEGER PRIMARY KEY, name TEXT, age INTEGER, create_t UNLIMITED INT)

不支持REAL

有一个字段的类型是REAL,在鸿蒙中是不支持的,因此,我又把其类型改成DOUBLE类型。结果我发现,我取出来的值全成成了整数,精度全部丢失了,我不太清楚是哪个环节出现了问题,是数据库本身的问题还是插件层的代码出现了问题,总之,精度确实丢了。评论区如果有知道原因的,可以告诉我。没办法,我又把其类型改成TEXT类型,用字符串存储,然后在dart层进入解析才算完事。

兼容性

我从flutter_sqflite中摘抄了部分文档,大家可以参考一下:

属性

!TIP\] "ohos Support"列为 yes 表示 ohos 平台支持该属性;no 则表示不支持;partially 表示部分支持。使用方法跨平台一致,效果对标 iOS 或 Android 的效果。

存储类型

Name Description Type ohos Support
String 存储字符串值 String yes
int 存储整数值 int yes
real 存储浮点数值 double no
bool 存储布尔值 bool yes
null null yes
date_time 储存时间值 date_time yes

OpenDatabaseOptions

Name Description Type ohos Support
version 数据库版本 int? yes
onConfigure 数据库配置回调 OnDatabaseConfigureFn? yes
onCreate 数据库首次创建回调 OnDatabaseCreateFn? yes
onUpgrade 数据库版本升级回调 OnDatabaseVersionChangeFn? yes
onDowngrade 数据库版本降级回调 OnDatabaseVersionChangeFn? yes
onOpen 数据库成功打开回调 OnDatabaseOpenFn? yes
readOnly 是否以只读模式打开数据库 bool? yes
singleInstance 是否强制单例模式 bool? yes

API

!TIP\] "ohos Support"列为 yes 表示 ohos 平台支持该属性;no 则表示不支持;partially 表示部分支持。使用方法跨平台一致,效果对标 iOS 或 Android 的效果。

DatabaseFactory

Name return value Description Type ohos Support
openDatabase(String path, {OpenDatabaseOptions? options}) Future 打开指定路径的数据库,可配置打开选项 function yes
getDatabasesPath Future 获取数据库默认存储路径 function yes
setDatabasesPath(String path) Future 设置默认数据库存储路径 function yes
deleteDatabase(String path) Future 删除指定路径的数据库 function yes
databaseExists(String path) Future 检查指定路径的数据库是否存在 function yes

DatabaseExecutor

Name return value Description Type ohos Support
execute(String sql, [List<Object?>? arguments]) Future 执行 SQL 语句 function yes
rawInsert(String sql, [List<Object?>? arguments]) Future 直接执行插入 SQL 返回行数 function yes
insert(String table, Map<String, Object?> values, {String? nullColumnHack,ConflictAlgorithm? conflictAlgorithm}) Future 插入 SQL 返回行数 function yes
query(String table, {bool? distinct, List? columns, String? where, List<Object?>? whereArgs, String? groupBy, String? having, String? orderBy, int? limit, int? offset}); Future<List<Map<String, Object?>>> 查询返回结果集列表 function yes
rawQuery(String sql, [List<Object?>? arguments]) Future<List<Map<String, Object?>>> 直接执行 SQL 查询返回结果集列表 function yes
rawQueryCursor(String sql, List<Object?>? arguments, {int? bufferSize}) Future 执行原始 SQL 查询返回游标对象 function yes
queryCursor(String table, {bool? distinct, List? columns, String? where, List<Object?>? whereArgs, String? groupBy, String? having, String? orderBy, int? limit, int? offset, int? bufferSize}) Future 查询返回游标对象 function yes
rawUpdate(String sql, [List<Object?>? arguments]) Future 直接执行更新 SQL 返回影响行数 function yes
update(String table, Map<String, Object?> values, {String? where, List<Object?>? whereArgs, ConflictAlgorithm? conflictAlgorithm}) Future 执行更新 SQL 返回影响行数 function yes
rawDelete(String sql, [List<Object?>? arguments]) Future 直接执行SQL删除符合条件的数据行 function yes
delete(String table, {String? where, List<Object?>? whereArgs}) Future 删除符合条件的数据行 function yes
batch Batch 获取批处理操作对象 function yes
get database Database 获取底层数据库实例 function yes

Batch

Name return value Description Type ohos Support
commit({ bool? exclusive, bool? noResult, bool? continueOnError, }) Future<List<Object?>> 提交批量操作 function yes
apply({bool? noResult, bool? continueOnError}) Future<List<Object?>> 执行批量操作并自动提交 function yes
rawInsert(String sql, [List<Object?>? arguments]) void 执行SQL插入语句 function yes
insert(String table, Map<String, Object?> values, {String? nullColumnHack, ConflictAlgorithm? conflictAlgorithm}) void 执行SQL插入语句 function yes
rawUpdate(String sql, [List<Object?>? arguments]) void 执行SQL更新语句 function yes
update(String table, Map<String, Object?> values, {String? where, List<Object?>? whereArgs, ConflictAlgorithm? conflictAlgorithm}) void 执行SQL更新语句 function yes
rawDelete(String sql, [List<Object?>? arguments]) void 执行SQL删除语句 function yes
delete(String table, {String? where, List<Object?>? whereArgs}) void 执行SQL删除语句 function yes
execute(String sql, [List<Object?>? arguments]) void 执行通用SQL语句 function yes
query(String table, {bool? distinct, List? columns, String? where, List<Object?>? whereArgs, String? groupBy, String? having, String? orderBy, int? limit, int? offset}) void 执行 SQL 查询语句 function yes
rawQuery(String sql, [List<Object?>? arguments]) void 执行 SQL 查询语句 function yes
get length int 获取累计操作数量 function yes
相关推荐
Tencent_TCB4 小时前
AI Coding全流程教程——0基础搭建“MEMO”健康打卡全栈Web应用(附提示词)
前端·人工智能·ai·ai编程·codebuddy·claude code·cloudbase
小猪猪屁4 小时前
权限封装不是写个指令那么简单:一次真实项目的反思
前端·javascript·vue.js
hteng4 小时前
跨域 Iframe 嵌套:调整内部 Iframe 高度的终极指南 (以及无解的真相)
前端
Polaris_o4 小时前
轻松上手Bootstrap框架
前端
1024小神4 小时前
微信小程序前端扫码动画效果绿色光效移动,四角椭圆
前端
C_心欲无痕4 小时前
网络相关 - 强缓存与协商缓存讲解
前端·网络·网络协议·缓存
用户904706683574 小时前
初来乍到公司,git不会用,怎么在团队里写代码?
前端
我的写法有点潮4 小时前
如何取消Vue Watch监听
前端·javascript·vue.js
童心虫鸣4 小时前
如何在Vue中传递函数作为Prop
前端·vue.js
用户6600676685394 小时前
用 React + TailwindCSS 打造高体验登录页面
前端·react.js