HarmonyOS APP开发---“记一笔“记账App,需要用到这个库
HarmonyOS APP开发—"记一笔"记账App,需要用到这个库
做一个记账 App,交易记录、分类、预算、账户……表与表之间全是关联关系。手写 SQL 字符串拼装又丑又容易错——
@ohos/dataorm用注解定义实体,链式 API 拼查询,一行代码增删改查。
📦 仓库地址:https://gitcode.com/CPF-ApplicationTPC/ohos_dataorm | 安装:
ohpm install @ohos/dataorm
写在前面
"记一笔"的数据模型说复杂不复杂,说简单也不简单:
- 交易表:每笔收支记录(金额、时间、备注)
- 分类表:餐饮、交通、工资……每个分类有图标和颜色
- 账户表:微信、支付宝、银行卡……
- 预算表:每月每个分类的预算上限
这些表之间有关联:交易 → 分类(多对一)、交易 → 账户(多对一)、预算 → 分类(多对一)。用原生relationalStore写,你得手写 SQL 建表、手写 JOIN 查询、手写结果集映射……每个操作都是一坨字符串拼接。
@ohos/dataorm基于 Android greenDAO 思路:注解定义实体 → 编译生成 Dao → 链式 API 查询。
这篇文章聊什么
- 注解定义实体——交易、分类、账户三张表
- 链式查询——查"本月餐饮支出,按日期降序"
- 关联查询——交易带出分类名称(多对一)
第一步:安装
ohpminstall@ohos/dataorm第二步:注解定义实体
import{Entity,Id,NotNull,Column,ToOne}from'@ohos/dataorm'// 分类表@Entity({tableName:'CATEGORY'})exportclassCategory{@Id()@Column({columnName:'ID'})id:number=0@Column({columnName:'NAME'})name:string=''@Column({columnName:'ICON'})icon:string=''@Column({columnName:'COLOR'})color:string=''@Column({columnName:'TYPE'})type:string='expense'// expense/income}// 账户表@Entity({tableName:'ACCOUNT'})exportclassAccount{@Id()@Column({columnName:'ID'})id:number=0@Column({columnName:'NAME'})name:string=''@Column({columnName:'BALANCE'})balance:number=0}// 交易表@Entity({tableName:'TRANSACTION'})exportclassTransaction{@Id()@Column({columnName:'ID'})id:number=0@NotNull()@Column({columnName:'AMOUNT'})amount:number=0@Column({columnName:'CATEGORY_ID'})categoryId:number=0@Column({columnName:'ACCOUNT_ID'})accountId:number=0@Column({columnName:'NOTE'})note:string=''@Column({columnName:'DATE'})date:number=0// 时间戳// 关联:交易 → 分类(多对一)@ToOne({joinColumn:'CATEGORY_ID'})category:Category=newCategory()// 关联:交易 → 账户(多对一)@ToOne({joinColumn:'ACCOUNT_ID'})account:Account=newAccount()}注解定义完,DataORM 会自动生成建表语句和 Dao 类。不用手写一行 CREATE TABLE SQL。
第三步:初始化 + 增删改查
import{DataORM,DatabaseOptions}from'@ohos/dataorm'// 初始化数据库constdb=DataORM.init({name:'accounting.db',version:1,entities:[Category,Account,Transaction],})consttxDao=db.dao(Transaction)constcatDao=db.dao(Category)// ===== 新增一笔支出 =====consttx=newTransaction()tx.amount=35.5tx.categoryId=1// 餐饮tx.accountId=1// 微信tx.note='午餐'tx.date=Date.now()awaittxDao.insert(tx)// ===== 查询:本月餐饮支出,按日期降序 =====constmonthStart=getMonthStartTimestamp()constlist=awaittxDao.queryBuilder().where(Transaction.CATEGORY_ID.eq(1))// 分类=餐饮.and(Transaction.DATE.ge(monthStart))// 本月.orderDesc(Transaction.DATE)// 按日期降序.list()list.forEach((t)=>{console.info(`${formatDate(t.date)}${t.category.name}-¥${t.amount}${t.note}`)// 关联的 category 自动带出,不用再查一次!})// ===== 更新 =====tx.note='午餐(公司附近)'awaittxDao.update(tx)// ===== 删除 =====awaittxDao.deleteById(tx.id)链式查询是 dataorm 的核心体验——.where().and().orderDesc().list()一气呵成,不用拼 SQL 字符串,类型安全编译期就能发现错误。
第四步:预算超额检查
// 查本月餐饮总支出consttotalExpense=awaittxDao.queryBuilder().where(Transaction.CATEGORY_ID.eq(1)).and(Transaction.DATE.ge(monthStart)).count(Transaction.AMOUNT)// 求和// 查预算constbudget=awaitbudgetDao.queryBuilder().where(Budget.CATEGORY_ID.eq(1)).and(Budget.MONTH.eq(currentMonth)).unique()if(totalExpense>budget.limit){promptAction.showToast({message:'本月餐饮预算已超支!'})}为什么"记一笔"选了 dataorm?
| 需求 | 原生 relationalStore | @ohos/dataorm |
|---|---|---|
| 建表 | 手写 CREATE TABLE | 注解自动生成 |
| 查询 | 拼 SQL 字符串 | 链式 API |
| 关联 | 手写 JOIN + 映射 | @ToOne自动带出 |
| 类型安全 | ❌ 字符串无约束 | ✅ 编译期检查 |
| 迁移 | 手写 ALTER TABLE | Migration API |
| 代码量 | 100% | ~30% |
总结
"记一笔"这个场景里,@ohos/dataorm解决了三件事:
- 注解建表——
@Entity+@Column定义实体,建表语句自动生成 - 链式查询——
.where().and().orderDesc().list(),告别 SQL 字符串 - 关联自动带出——
@ToOne让交易记录自动带出分类名称,不用手写 JOIN
如果你也在做记账、笔记、任务管理等需要本地数据库的 App,@ohos/dataorm让你专注业务逻辑,把 SQL 的脏活累活全交出去。
