# Room **Repository Path**: mlethe/Room ## Basic Information - **Project Name**: Room - **Description**: 鸿蒙 room 数据库 - **Primary Language**: TypeScript - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2024-08-09 - **Last Updated**: 2026-02-01 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Room数据库(API12) ### 简介 (支持鸿蒙多线程使用)持久性库在 SQLite 的基础上提供了一个抽象层,让用户能够在充分利用 SQLite 的强大功能的同时,获享更强健的数据库访问机制,支持表自动创建。 ### 下载安装 ```cmd ohpm install @mlethe/room ``` 1.模块oh-package.json5文件中引入依赖 ```json { "dependencies":{ "@mlethe/room": "version" } } ``` ### 使用 #### 1、初始化 ```typescript import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; import { Room } from '@mlethe/room'; import { DemoDatabase } from '../db/DemoDatabase'; import BuildProfile from 'BuildProfile'; export default class EntryAbility extends UIAbility { onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { // 可以在AbilityStage、UIAbility中初始化 Room.init(this.context, DemoDatabase, BuildProfile.DEBUG) } onDestroy(): void { // 关闭数据库 Room.close(DemoDatabase) } } ``` #### 2、创建数据库管理 ```typescript import { Database, RoomDatabase } from '@mlethe/room'; import relationalStore from '@ohos.data.relationalStore'; import { User } from '../entity/User'; @Database({ entities: [User], name: "demo.db", version: 1 }) export class DemoDatabase implements RoomDatabase { async onCreate(db: relationalStore.RdbStore): Promise { } async onUpgrade(db: relationalStore.RdbStore, oldVersion: number, newVersion: number): Promise { // 表是自动创建,删除、修改表及数据处理在这个处理 } } ``` #### 3、创建User表 ```typescript import { Columns, ColumnType, Convert, Entity, PrimaryKey, Unique } from '@mlethe/room'; import { LoginWayConvert } from './LoginWayConvert'; /** * 用户信息 */ @Entity({ name: "user" }) export class User { @PrimaryKey() @Columns({ type: ColumnType.int }) id: number = 0; /** * 昵称 */ @Unique() @Columns({ type: ColumnType.str }) nickname: string = ''; /** * 头像 */ @Columns({ type: ColumnType.str }) avatar: string = ''; /** * 登录方式 */ @Convert({ converter: LoginWayConvert }) @Columns({ name: "login_way", type: ColumnType.object }) loginWay: Array = [] } export class LoginWay { /** * 类型 */ type: number = 0; constructor(type?: number) { if (type) { this.type = type; } } } ``` #### 4、创建UserDao ```typescript import { ColumnType, Dao, Delete, Insert, Update, MapInfo, OnConflictStrategy, Params, PromiseNull, Query, RawQuery, Transaction } from '@mlethe/room'; import { DemoDatabase } from '../db/DemoDatabase'; import { User } from '../entity/User'; import { HashMap } from '@kit.ArkTS'; @Dao({ database: DemoDatabase, entity: User }) export class UserDao { @Delete async delete(user: User): Promise { return PromiseNull(); } @Delete async deleteList(users: Array): Promise { return PromiseNull(); } @Insert({ onConflict: OnConflictStrategy.REPLACE }) async insert(user: User): Promise { return PromiseNull(); } @Insert({ onConflict: OnConflictStrategy.REPLACE }) async insertAll(users: Array): Promise { return PromiseNull(); } @Update({ onConflict: OnConflictStrategy.REPLACE }) async update(users: User): Promise { return PromiseNull(); } @Update({ onConflict: OnConflictStrategy.REPLACE }) async updateAll(users: Array): Promise { return PromiseNull(); } @Query({ entity: User, isArray: true, sql: "SELECT * FROM user WHERE id IN(:userIds);" }) async selectUser(@Params("userIds") userIds: Array): Promise> { return PromiseNull(); } @MapInfo({ keyColumn: "nickname", keyType: ColumnType.str }) @Query({ entity: User, isArray: false, sql: "SELECT * FROM user WHERE id IN(:userIds);" }) async selectUserMap(@Params("userIds") userIds: Array): Promise> { return PromiseNull(); } /** * 自定义sql * * @param sql * @returns */ @RawQuery({ entity: User, isArray: true }) async selectUserAll(sql: string): Promise> { return PromiseNull(); } /** * 事务 * * @param user * @param that * @returns */ @Transaction async transaction(user: User, that: UserDao): Promise { await that.insert(user); user.id = 2; user.nickname = user.nickname + "New"; return that.insert(user); } } ``` #### 5、获取UserDao ```typescript import { UserDao } from '../dao/UserDao'; userDao: UserDao = Room.getDao(UserDao); this.userDao.insert(new User(2, "李四", "url", [new LoginWay(1), new LoginWay(2)])); ``` #### 6、支持多数据源 ```typescript import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; import { Room } from '@mlethe/room'; import { DemoDatabase } from '../db/DemoDatabase'; import { SecondDemoDatabase } from '../db/SecondDemoDatabase'; import BuildProfile from 'BuildProfile'; export default class EntryAbility extends UIAbility { onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { // 初始化默认数据库 Room.init(this.context, DemoDatabase, BuildProfile.DEBUG) // 初始化第二个数据库 Room.init(this.context, SecondDemoDatabase, BuildProfile.DEBUG) } onDestroy(): void { // 关闭数据库 Room.close(DemoDatabase) Room.close(SecondDemoDatabase) } } ``` #### 7、创建Converter ```typescript import { PropertyConverter } from '@mlethe/room'; import { LoginWay } from './User'; export class LoginWayConvert extends PropertyConverter { /** * 数据库数据转为实体对象 * * @param databaseValue * @returns */ convertToEntityProperty(databaseValue: string): LoginWay[] { if (databaseValue == undefined) { return []; } if (databaseValue.length <= 0) { return []; } let list: LoginWay[] | undefined = JSON.parse(databaseValue); if (!list) { return []; } return list; } /** * 实体对象转为数据库数据 * * @param entityProperty * @returns */ convertToDatabaseValue(entityProperty: LoginWay[]): string { let json = JSON.stringify(entityProperty); if (!json) { return ""; } return json } } ``` #### 8、鸿蒙多线程使用 在子线程中不用重新初始化数据库,按照以上使用方法正常使用即可。 ### API说明 #### Room方法 ```typescript /** * 初始化数据库 * * @param context 上下文 * @param clazz 数据库类 * @param isDebug 是否打印日志,默认打印。true:打印,false:不打印 * @returns true 初始化成功,false 初始化失败 */ init(context: Context, clazz: ClassConstructor, isDebug: boolean): Promise; /** * 关闭数据库连接 * * @param clazz */ close(clazz: ClassConstructor); /** * 获取Dao * * @param clazz Dao类 * @param context 上下文 * @returns */ getDao(clazz: ClassConstructor): T; /** * 获取数据库操作对象RdbStore * * @returns */ getRdbStore(clazz: ClassConstructor): Promise; ``` #### Database注解参数 - 数据库注解 ```typescript export interface DatabaseValue { /** * 表实体类 */ entities: ClassConstructor[]; /** * 数据库名称 */ name: string; /** * 数据库版本 */ version: number; /** * 数据库安全级别 * S1:表示数据库的安全级别为低级别,当数据泄露时会产生较低影响。例如,包含壁纸等系统数据的数据库。 * S2:表示数据库的安全级别为中级别,当数据泄露时会产生较大影响。例如,包含录音、视频等用户生成数据或通话记录等信息的数据库。 * S3:表示数据库的安全级别为高级别,当数据泄露时会产生重大影响。例如,包含用户运动、健康、位置等信息的数据库。 * S4:表示数据库的安全级别为关键级别,当数据泄露时会产生严重影响。例如,包含认证凭据、财务数据等信息的数据库。 */ securityLevel?: relationalStore.SecurityLevel; /** * 数据库是否加密,默认不加密。true:加密,false:非加密 */ encrypt?: boolean; /** * 数据库自定义路径。 * 使用约束: 数据库路径大小限制为128字节,如果超过该大小会开库失败,返回错误。 * 从API version 11开始,支持此可选参数。 * 数据库将在如下的目录结构中被创建:context.databaseDir + "/rdb/" + customDir,其中context.databaseDir是应用沙箱对应的路径,"/rdb/"表示创建的是关系型数据库,customDir表示自定义的路径。当此参数不填时,默认在本应用沙箱目录下创建RdbStore实例。 */ customDir?: string; /** * 应用组ID,需要向应用市场获取,详见dataGroupId申请流程。基于dataGroupId的数据共享支持两种场景:1.同一应用的不同进程间共享,只支持三方应用中输入法和输入法的扩展场景使用;2.不同应用间的数据共享,只支持系统应用使用。 */ dataGroupId?: string; /** * 指定是否自动清理云端删除后同步到本地的数据,true表示自动清理,false表示手动清理,默认自动清理。 * 对于端云协同的数据库,当云端删除的数据同步到设备端时,可通过该参数设置设备端是否自动清理。手动清理可以通过cleanDirtyData接口清理。 */ autoCleanDirtyData?: boolean; /** * 指定数据库是否支持异常时自动删除,并重建一个空库空表,默认不删除。 * true:自动删除。 * false:不自动删除。 */ allowRebuild?: boolean; /** * 指定数据库是否只读,默认为数据库可读写。 * true:只允许从数据库读取数据,不允许对数据库进行写操作,否则会返回错误码801。 * false:允许对数据库进行读写操作。 */ isReadOnly?: boolean; /** * 表示包含有fts(Full-Text Search,即全文搜索引擎)等能力的动态库名的数组。 */ pluginLibs?: Array; } ``` #### 实体对象注解说明 ##### ColumnType枚举 ```javascript export enum ColumnType { /** * 字符串类型 * 对应 SQLite 的 TEXT 类型 */ str = 'string', /** * 整数类型 * 对应 SQLite 的 INTEGER 类型 * 存储整数值,范围通常为 -2^31 到 2^31-1 */ int = 'integer', /** * 大整数类型 * 对应 SQLite 的 integer 类型 * 存储超出普通整数范围的大整数值 */ bigint = 'bigint', /** * 双精度浮点数类型 * 对应 SQLite 的 REAL 类型 * 存储浮点数值,具有双精度 */ double = 'double', /** * 布尔 * 布尔类型 * 在 SQLite 中使用 INTEGER 存储(0 表示 false,1 表示 true) */ bool = 'boolean', /** * 二进制大对象类型 * 对应 SQLite 的 BLOB 类型 * 存储二进制数据,如图片、文件、序列化对象等 */ blob = 'blob', /** * 对象 * 非 SQLite 原生类型,序列化为string类型后存储 */ object = 'object' } ``` ##### Entity注解 - 表注解 ```typescript export interface EntityValue { /** * 表名 */ name: string; /** * 联合主键 */ primaryKeys?: Array; /** * 索引 */ indexes?: Array; } /** * 索引 */ export interface Index { /** * 字段列表 */ values: Array; /** * 索引名称 */ name?: string; /** * 索引排序 */ orders?: Array; /** * 是否唯一 */ unique?: boolean; } /** * 排序 */ export enum Order { ASC = "ASC", DESC = "DESC", } ``` ##### Columns注解 - 属性注解 ```typescript export interface ColumnsValue { /** * 表字段名称 */ name?: string; /** * 表字段类型 */ type: ColumnType; /** * 表字段默认值 */ defaultValue?: string; } ``` ##### PrimaryKey注解 - 主键注解 ```typescript /** * PrimaryKey注解参数 */ export interface PrimaryKeyValue { /** * 是否自增 */ autoGenerate: boolean; } ``` ##### Unique注解 - 唯一属性注解,true 唯一,false 不唯一 ##### Convert注解 ```typescript /** * 属性类型转换实现 */ export abstract class PropertyConverter

{ /** * 数据库数据转为实体对象 * * @param databaseValue * @returns */ abstract convertToEntityProperty(databaseValue: string): P; /** * 实体对象转为数据库数据 * * @param entityProperty * @returns */ abstract convertToDatabaseValue(entityProperty: P): string; } /** * Convert注解参数 */ export interface ConvertValue { /** * 转换器类 */ converter: ClassConstructor>; } ``` #### Dao相关注解说明 ##### Dao注解 ```typescript /** * Dao注解参数 */ export interface DaoValue { /** * 数据库类 */ database: ClassConstructor; /** * 表实体类 */ entity: ClassConstructor; } ``` ##### Inset注解 - 插入数据注解,支持对象和数组插入 ```typescript /** * Inset注解参数 */ export interface InsertValue { /** * 冲突解决模式 */ onConflict?: OnConflictStrategy; /** * 每次插入条数,分页插入(为了处理数据库内存不能超过2M的问题) */ pageSize?: number; } /** * 插入和修改接口的冲突解决模式 */ export enum OnConflictStrategy { /** * 表示当冲突发生时,不做任何处理。 */ NONE = 0, /** * 表示当冲突发生时,中止SQL语句并回滚当前事务。 */ ROLLBACK = 1, /** * 表示当冲突发生时,中止当前SQL语句,并撤销当前 SQL 语句所做的任何更改,但是由同一事务中先前的 SQL 语句引起的更改被保留并且事务保持活动状态。 */ ABORT = 2, /** * 表示当冲突发生时,中止当前 SQL 语句。但它不会撤销失败的 SQL 语句的先前更改,也不会结束事务。 */ FAIL = 3, /** * 表示当冲突发生时,跳过包含违反约束的行并继续处理 SQL 语句的后续行。 */ IGNORE = 4, /** * 表示当冲突发生时,在插入或更新当前行之前删除导致约束违例的预先存在的行,并且命令会继续正常执行。 */ REPLACE = 5, } ``` ##### Update注解 - 修改数据注解,支持对象和数组删除 ```typescript /** * Update注解参数 */ export interface UpdateValue { /** * 冲突解决模式 */ onConflict?: OnConflictStrategy; } ``` ##### Delete注解 - 删除数据注解,没有参数,支持对象和数组删除 ##### Query注解 - 查询数据注解 ```typescript /** * Query注解参数 */ export interface QueryValue { /** * 返回值类型(@MapInfo 映射值的列的类型) */ entity: ColumnType | ClassConstructor; /** * 返回值是否为数组(@MapInfo 映射值的列是否为数组) */ isArray?: boolean; /** * 返回值是否为Sendable数组(基础数据类型使用) */ isSendable?: boolean; /** * 每页条数,分页查询所有数据(为了处理数据库内存不能超过2M的问题) */ pageSize?: number; /** * SQL 语句,参数使用(:参数名称)的方式 * 示例:"SELECT * FROM user WHERE id IN(:userIds);" * :userIds 是自定义参数,userIds 是参数名称@Params("userIds") * 示例:(@Params("userIds") userIds: Array) */ sql: string; } ``` ##### Params注解 - 查询数据sql的自定义参数注解,参数为sql中定义的名称。 ##### RawQuery注解 - 查询数据注解,支持对象和数组删除 ```typescript /** * RawQuery注解参数 */ export interface RawQueryValue { /** * 返回值类型(@MapInfo 映射值的列的类型) */ entity: ColumnType | ClassConstructor; /** * 返回值是否为数组(@MapInfo 映射值的列是否为数组) */ isArray?: boolean; /** * 返回值是否为Sendable数组(基础数据类型使用) */ isSendable?: boolean; /** * 每页条数,分页查询所有数据(为了处理数据库内存不能超过2M的问题) */ pageSize?: number; } ``` ##### MapInfo注解 - 查询数据多重映射注解,返回HashMap对象 ```typescript /** * MapInfo注解参数 */ export interface MapInfoValue { /** * 用于映射键的列的名称 */ keyColumn?: string; /** * 用于映射键的列为string类型时的列的类型 */ keyType: ColumnType | ClassConstructor; /** * 用于映射值的列的名称 */ valueColumn?: string; } ``` ##### Transaction注解 - sql事务注解