HarmonyOS APP开发---“记一笔“记账App,需要用到这个库

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 查询

这篇文章聊什么

  1. 注解定义实体——交易、分类、账户三张表
  2. 链式查询——查"本月餐饮支出,按日期降序"
  3. 关联查询——交易带出分类名称(多对一)

belongs_to

belongs_to

limits

TRANSACTION

int

id

PK

float

amount

int

category_id

FK

int

account_id

FK

text

note

int

date

CATEGORY

int

id

PK

text

name

text

icon

text

color

ACCOUNT

int

id

PK

text

name

float

balance

BUDGET


第一步:安装

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 TABLEMigration API
代码量100%~30%

总结

"记一笔"这个场景里,@ohos/dataorm解决了三件事:

  1. 注解建表——@Entity+@Column定义实体,建表语句自动生成
  2. 链式查询——.where().and().orderDesc().list(),告别 SQL 字符串
  3. 关联自动带出——@ToOne让交易记录自动带出分类名称,不用手写 JOIN

如果你也在做记账、笔记、任务管理等需要本地数据库的 App,@ohos/dataorm让你专注业务逻辑,把 SQL 的脏活累活全交出去。