# orm_lite **Repository Path**: penll/orm_lite ## Basic Information - **Project Name**: orm_lite - **Description**: 一款非常容易上手的HarmonyOS数据库工具。在鸿蒙Next中实现orm初始化数据库和表,并支持直接使用sql语句/条件方式操作、获取表数据。 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 0 - **Created**: 2025-02-10 - **Last Updated**: 2025-08-25 ## Categories & Tags **Categories**: Uncategorized **Tags**: HarmonyOS组件, HarmonyNEXT, Database, ORM, 鸿蒙数据库 ## README # @pll/orm_lite 一款非常容易上手的HarmonyOS数据库工具。在鸿蒙Next中实现orm初始化数据库和表,并支持直接使用sql语句/条件方式操作、获取表数据。 ## 以下是 @pll/orm_lite.core 的拓展功能包 “@pll/orm_lite” @pll/orm_lite支持数据库增删改查,并且扩展了诸如分页等常用操作 。与typeorm不同,这里获取/操作数据时采用.get(conditionSql,...)方式处理。适合对sql更熟悉的同学。而且简化了大量orm相关操作,如:外健约束、\ 对比@pll/orm_lite.core组件额外扩展了crud常见操作(安装 @pll/orm_lite 后无需另外安装@pll/orm_lite.core)。典型例子如: ```typescript const data = await context.get("id=?",[2]) // 查询符合条件的单条数据 const data1 = await context.get("id>1","id desc") // 查询符合条件的单条数据,排序后第一条 const dataList = await context.getList("id>0") // 查询符合条件的数据集合 const dataListByLimitCountSort = await context.getList('id>10', 20, 'updateDate desc')// 查询数据限制数量+排序 const dataListByParam = await context.getList("id=?", [1]) // 参数化查询 const dataListByPagination = await context.getList("id>?", 10, 0, [1]) // 参数化查询 + 分页 await context.deleteById(1) // 根据 主键 删除数据 await context.delete("id=1") // 根据 条件 删除数据 await context.delete("id=?",[1]) // 根据 条件 删除数据 by 参数化 // ... 更多操作。滚动到下方,详见Demo [项目Gitee地址](https://gitee.com/penll/orm_lite)) ``` ### 特性 1. 支持获取@Entity绑定的数据项或数据列表,如:Array 2. 支持使用@Entity更新数据,如:data.title ='newTitle'; context.update(data); 3. 支持获取分页列表 4. 支持查询Count、delete等操作 ### 安装(⚠️注意:无需另外安装@pll/orm_lite.core,内部已包含引用@pll/orm_lite.core所有功能) ```shell ohpm i @pll/orm_lite ``` ### @pll/orm_lite 示例Demo 以下是demo代码,或直接运行App(可见实际页面demo:entry/src/main/ets/pages/Index.ets,[项目Gitee地址](https://gitee.com/penll/orm_lite)) ### Demo 定义简单实体 ```typescript @Entity("sample01_post")//自定义表名,不传参则默认类名如Post作为表名 @Index("unique_title", ["title"],{ unique: true })//建立单字段唯一索引,采用自定义索引命名 export class Post { /** * id主键,该字段非自增 */ // @PrimaryColumn({ type: 'integer' }) @PrimaryGeneratedColumn() id: number = 0 @Column({ length: 100, type: 'varchar' }) title: string = '' @Column({ length: 200, type: 'varchar' }) text: string = '' @Column({ nullable: false, type: 'integer' }) likesCount: number = 0 @Column("date") dateColumn: Date = new Date() @Column("datetime") dateTimeColumn: Date = new Date() @Column("boolean") isBooleanColumn: boolean = false } ``` 1. 执行插入: ```typescript const options: DataSourceOptions = { type: "sqlite", database: "Default.db", isLogSql: true,//打印sql语句执行日志 entities: [Post, EverythingEntity], } // 使用@pll/orm_lite的OrmLiteDB方式初始化(仅crud) await OrmLiteDB.init({ dataSourceOptions: options, context: getContext(this), isDebug: true }) // const context = OrmLiteDB.getDbContext(() => new Post(), dataSource) // 多数据库时,需要指定数据配置用于读取 const context = OrmLiteDB.getDbContext(() => new Post()) //统一使用OrmLiteDB管理 (单数据库时,只需传定义表实体的实例) let post = new Post()//自增主键,插入数据时,无须赋值主键id post.text = "Hello how are you?" post.title = "hello" post.likesCount = 1 await context.add(post) //默认 ON_CONFLICT_IGNORE console.log('插入数据结束') post = new Post() post.text = "Hello how are you?1111" post.title = "hello" post.likesCount = 2 await context.add(post, relationalStore.ConflictResolution.ON_CONFLICT_IGNORE) ``` 2. 批量执行插入: ```typescript const array = new Array() let post = new Post()//自增主键,插入数据时,无须赋值主键id post.text = "[batch]Hello how are you?1111" post.title = "[batch]hello1111" post.likesCount = 111 post.dateColumn = new Date(2011, 11, 1) post.dateTimeColumn = new Date(2011, 11, 1, 12, 12, 13) post.isBooleanColumn = true array.push(post) post = new Post()//自增主键,插入数据时,无须赋值主键id post.text = "[batch]Hello how are you?2222" post.title = "[batch]hello2222" post.likesCount = 222 post.dateColumn = new Date(2022, 11, 1) post.dateTimeColumn = new Date(2022, 11, 1, 12, 12, 13) post.isBooleanColumn = false array.push(post) post = new Post()//自增主键,插入数据时,无须赋值主键id post.text = "[batch-conflict-ignore]Hello how are you?3333" post.title = "hello" // title 唯一索引,触发忽略 该记录不插入 post.likesCount = 333 post.dateColumn = new Date(2023, 6, 1) post.dateTimeColumn = new Date(2023, 6, 1, 12, 12, 13) post.isBooleanColumn = false array.push(post) await context.add(array, relationalStore.ConflictResolution.ON_CONFLICT_IGNORE) ``` 3. 执行查询列表实体(List): ```typescript const allData = await context.getList("id>0") // 查询符合条件的数据 const dataByLimitCountSort = await context.getList('id>10', 20, 'updateDate desc')// 查询数据限制数量+排序 const dataByParam = await context.getList("id=?", [1]) // 参数化查询 const dataByPagination = await context.getList("id>?", 10, 0, [1]) // 参数化查询 + 分页 // 更多使用方式,见调用.dbContext.时重载的其他方法 ``` 4. 执行更新、删除: ```typescript const data = await context.getList("id>0") if (data) { data[0].title = 'hello10000-1' data[0].likesCount = 53 await context.update(data[0]) } await context.deleteById(1) // 根据 主键 删除数据 await context.delete("id=1") // 根据 条件 删除数据 await context.delete("id=?",[1]) // 根据 条件 删除数据 by 参数化 ``` 5. 执行查询数据量: ```typescript const num = await context.count("id>0") ``` 6. 仅sql语句时,执行(可查询/更新/插入/删除 等): ```typescript const dataSource = await OrmLiteDB.init({ dataSourceOptions: options, context: getContext(this), isDebug: true })//返回dataSource,多库时getDbContext使用参数定位表 // 使用context执行sql语句 const context = OrmLiteDB.getDbContext(() => new Post()) //统一使用OrmLiteDB管理 (单数据库时,只需传定义表实体的实例) await context.query(`INSERT OR IGNORE INTO sample01_post (title, text, likesCount,dateColumn,dateTimeColumn,isBooleanColumn) VALUES ('sql - hello', 'sql - helloduplicate',122,'2014-01-01','2014-05-05 15:22:02',1), ('sql - 标题2', 'sql - new 2222',222,'2015-05-05','2015-06-06 16:33:02',0);`) // 直接使用dataSrouce执行sql语句(core & crud) dataSource.driver.queryRunner?.query(`INSERT OR IGNORE INTO sample01_post (title, text, likesCount,dateColumn,dateTimeColumn,isBooleanColumn) VALUES ('sql - hello', 'sql - helloduplicate',122,'2014-01-01','2014-05-05 15:22:02',1), ('sql - 标题2', 'sql - new 2222',222,'2015-05-05','2015-06-06 16:33:02',0);`) ``` ## @pll/orm_lite.core 基础功能库(其他详见@pll/orm_lite) 实现采用orm+装饰器方式初始化数据库,支持创建、初始化数据库与表。且支持原始sql查询与执行操作。\ 组件参照typeorm(地址:[GitHub](https://github.com/typeorm/typeorm))的大部分实现,但是仅保留了初始化数据库+表并改造支持了鸿蒙Next数据库相关操作(即使配置数据库、配置@Entity方式创建表),节省了大量配置数据库与表的重复工作量。 1. 初始化并创建数据库 2. 根据模型创建对应表 a. 设置主键、支持自增列 b. 支持常见数据类型列(如:integer、varchar、text、float、double、decimal、date、datetime、boolean) c. 索引、唯一索引 3. 执行原始sql语句 ### 安装 ```shell ohpm i @pll/orm_lite.core ``` ## Getting started ### Demo 以下是demo代码,或直接运行App(可见实际页面demo:entry/src/main/ets/pages/Index.ets,[项目Gitee地址](https://gitee.com/penll/orm_lite)) 1. 创建一个模型(core): ```typescript /** * 当前支持所有类型字段例子 */ @Index(["dateColumn"])//采用默认命名策略 IDX_sample11_everything_entity_dateColumn @Index("index_with_id_and_name", ["id", "name"])//建立索引,采用自定义索引命名 @Index("unique_with_integerColumn_floatColumn", ["integerColumn", "floatColumn"],{ unique: true })//建立多字段索引,采用自定义索引命名 @Index(["integerColumn", "decimalColumn"],{ unique: true })//建立单字段唯一索引,采用默认命名策略 IDX_sample11_everything_entity_decimalColumn_integerColumn @Entity("sample11_everything_entity")//自定义表名,不传参则默认类名如EverythingEntity作为表名 export class EverythingEntity { /** * 声明GeneratedColumn自增列后,类型默认integer * TODO: 待支持rowid uuid */ @PrimaryGeneratedColumn() id: number = 0 @Column({ length: 100, type: 'varchar' }) name: string = '' @Column({ type: 'text' }) text: string = '' @Column("integer") integerColumn: number = 0 @Column("float") floatColumn: number = 0 @Column("double") doubleColumn: number = 0 @Column("decimal") decimalColumn: number = 0 @Column("date") dateColumn: Date = new Date() @Column("datetime") dateTimeColumn: Date = new Date() @Column("boolean") isBooleanColumn: boolean = false // TODO: 待支持 创建时间列(当创建一条记录,createDate更新,后续不再更新) // @CreateDateColumn() // createdDate: Date // // TODO: 待支持 更新时间列(当创建一条记录,updatedDate更新,后续更新记录时同时更新) // @UpdateDateColumn() // updatedDate: Date } ``` 2. 数据库基础配置与表配置(core): ```typescript const options: DataSourceOptions = { type: "sqlite", database: "Default.db", isLogSql: true,//打印sql语句执行日志 entities: [Post, EverythingEntity], } ``` 3. 执行初始化(core): ```typescript // 使用DataSource方式初始化(core) const dataSource = new DataSource(options) dataSource.initialize(getContext(this)).then( async (dataSource) => { console.log('建库建表结束') }, ).catch((error: Error) => { console.error("[ORM_LITE]Cannot save. Error: ", error.message, error.stack) }) // 直接使用dataSrouce执行sql语句(core) dataSource.driver.queryRunner?.query(`INSERT OR IGNORE INTO sample01_post (title, text, likesCount,dateColumn,dateTimeColumn,isBooleanColumn) VALUES ('sql - hello', 'sql - helloduplicate',122,'2014-01-01','2014-05-05 15:22:02',1), ('sql - 标题2', 'sql - new 2222',222,'2015-05-05','2015-06-06 16:33:02',0);`) ``` ## 沟通与交流 使用过程中发现任何问题都可以提 Issue [https://gitee.com/penll/orm_lite](https://gitee.com/penll/orm_lite)