npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

epii-db-orm

v1.1.5

Published

## 1. 框架简介

Readme

epii-db-orm 框架详细说明文档

1. 框架简介

epii-orm 是一个轻量级的 Node.js 数据库 ORM 框架,专注于提供简洁易用的数据库操作接口。它采用链式调用风格,支持自动 SQL 构建,使数据库操作更加直观和高效。

1.1 主要特点

  • 链式调用:支持流畅的链式方法调用,代码更加简洁易读
  • SQL 自动构建:自动生成 SQL 语句,减少手动编写 SQL 的工作量
  • 丰富的查询条件:提供多种查询条件构建方法,支持复杂查询
  • 事务支持:内置事务处理机制,确保数据操作的原子性
  • TypeScript 支持:使用 TypeScript 编写,提供完整的类型定义
  • 轻量级设计:核心代码精简,无依赖,易于集成和使用

1.2 适用场景

  • 小型到中型的 Node.js 项目
  • 需要简洁数据库操作接口的项目
  • 对 SQL 语句构建有需求的项目
  • 使用 TypeScript 的项目

2. 安装与配置

2.1 安装

npm i epii-db-orm -S

2.2 数据库连接配置

import { Db } from "epii-db-orm";

// 设置数据表的前缀
Db.config.tablePrefix = "";

// 设置数据库连接(单个连接)
Db.config.connection = mysqlConnection; // mysql2 或其他数据库连接对象

// 或设置连接池
// Db.config.connectionPool = mysqlPool; // 数据库连接池对象

// SQL 语句回调(可选)
Db.config.onSql = function (sql) {
  console.log(sql); // 打印执行的 SQL 语句
};

2.3 连接对象要求

连接对象需要实现以下接口:

interface IConnection {
  query<T>(sql: string, params?: Array<string | number>): Promise<T>;
  execute<T>(sql: string, params?: Array<string | number>): Promise<T>;
  beginTransaction(): Promise<void>;
  commit(): Promise<void>;
  rollback(): Promise<void>;
}

interface IPool extends IConnection {
  createConnection(): Promise<IConnection>;
}

3. 核心概念与架构

3.1 核心模块

| 模块 | 职责 | 文件位置 | |------|------|----------| | Db | 数据库连接管理,提供操作入口 | src/Db.ts | | Query | 查询构建器,提供链式查询方法 | src/Query.ts | | SqlBuilder | SQL 语句构建器 | src/SqlBuilder.ts | | WhereData | 条件构建器 | src/map/WhereData.ts | | FieldData | 字段数据构建器 | src/map/FieldData.ts |

3.2 工作流程

  1. 通过 Db.name() 创建 Query 实例
  2. 链式调用 Query 方法设置查询条件
  3. 调用执行方法(如 select、find、insert 等)
  4. SqlBuilder 生成 SQL 语句
  5. 通过数据库连接执行 SQL
  6. 返回执行结果

4. 基础操作

4.1 数据查询

查询单个数据

// 查询 id=1 的数据
const user = await Db.name("user").where("id", 1).find();
// 等价于: SELECT * FROM user WHERE id = 1 LIMIT 1

// 也可以直接传递 id
const user = await Db.name("user").find(1);

查询多条数据

// 查询所有数据
const users = await Db.name("user").select();
// 等价于: SELECT * FROM user

// 查询指定字段
const userNames = await Db.name("user").field("name").select();
// 等价于: SELECT name FROM user

// 查询多个字段
const userInfo = await Db.name("user").field("id, name, age").select();
// 等价于: SELECT id, name, age FROM user

条件查询

// 基本条件
const users = await Db.name("user").where("age", ">", 18).select();

// 复杂条件
const users = await Db.name("user")
  .where("status", 1)
  .whereLike("name", "张%")
  .whereBetween("age", 18, 30)
  .select();

4.2 数据插入

插入单条数据

// 插入单条数据
const insertId = await Db.name("user").insert({
  name: "张三",
  age: 25,
  email: "[email protected]"
});
// 等价于: INSERT INTO user (name, age, email) VALUES (?, ?, ?)

插入多条数据

// 插入多条数据
const count = await Db.name("user").insertAll([
  { name: "张三", age: 25 },
  { name: "李四", age: 26 },
  { name: "王五", age: 27 }
]);
// 等价于: INSERT INTO user (name, age) VALUES (?, ?), (?, ?), (?, ?)

4.3 数据更新

// 更新数据
const affectedRows = await Db.name("user")
  .where("id", 1)
  .update({ name: "张三(更新)", age: 26 });
// 等价于: UPDATE user SET name = ?, age = ? WHERE id = ?

// 使用 FieldData 进行复杂更新
import { FieldData } from "epii-db-orm";

const fieldData = new FieldData();
fieldData.put("name", "张三")
         .putInc("age", 1); // age = age + 1

const affectedRows = await Db.name("user")
  .where("id", 1)
  .update(fieldData);

4.4 数据删除

// 删除指定 ID 的数据
const affectedRows = await Db.name("user").delete(1);
// 等价于: DELETE FROM user WHERE id = 1

// 删除符合条件的数据
const affectedRows = await Db.name("user")
  .where("age", "<", 18)
  .delete();
// 等价于: DELETE FROM user WHERE age < ?

注意:删除操作必须设置 where 条件,否则会抛出错误。

5. 高级查询

5.1 排序

// 升序排序
const users = await Db.name("user").order("age", "asc").select();
// 等价于: SELECT * FROM user ORDER BY age asc

// 降序排序
const users = await Db.name("user").order("create_time", "desc").select();
// 等价于: SELECT * FROM user ORDER BY create_time desc

// 多字段排序
const users = await Db.name("user")
  .order("age", "asc")
  .order("create_time", "desc")
  .select();
// 等价于: SELECT * FROM user ORDER BY age asc, create_time desc

5.2 分组与聚合

// 分组查询
const result = await Db.name("order")
  .field("user_id, COUNT(*) as order_count, SUM(amount) as total_amount")
  .group("user_id")
  .select();
// 等价于: SELECT user_id, COUNT(*) as order_count, SUM(amount) as total_amount FROM order GROUP BY user_id

// 分组加筛选
const result = await Db.name("order")
  .field("user_id, COUNT(*) as order_count")
  .group("user_id")
  .having("order_count > 5")
  .select();
// 等价于: SELECT user_id, COUNT(*) as order_count FROM order GROUP BY user_id HAVING order_count > 5

5.3 表连接

// 左连接
const result = await Db.name("user")
  .alias("u")
  .field("u.id, u.name, r.role_name")
  .leftJoin("role as r", "u.role_id = r.id")
  .select();
// 等价于: SELECT u.id, u.name, r.role_name FROM user as u LEFT JOIN role as r ON u.role_id = r.id

// 右连接
const result = await Db.name("user")
  .rightJoin("profile", "user.id = profile.user_id")
  .select();

// 内连接
const result = await Db.name("user")
  .innerJoin("order", "user.id = order.user_id")
  .select();

5.4 复杂条件

使用 WhereData

import { WhereData } from "epii-db-orm";

const where = new WhereData();
where.put("status", "1")
     .putLike("name", "张%")
     .putBetween("age", "18", "30")
     .putIn("id", [1, 2, 3, 4, 5])
     .putSymbol("score", ">", "80");

const users = await Db.name("user").where(where).select();
// 等价于: SELECT * FROM user WHERE status = 1 AND name like '张%' AND age between 18 and 30 AND id in (1,2,3,4,5) AND score > 80

逻辑或条件

const users = await Db.name("user")
  .where("status", "1")
  .whereOr("age", "<", "18")
  .whereOr("age", ">", "60")
  .select();
// 等价于: SELECT * FROM user WHERE status = 1 OR age < 18 OR age > 60

6. 事务处理

6.1 基本事务

import { DbTransaction } from "epii-db-orm";

try {
  const result = await DbTransaction(async (db) => {
    // 在事务中执行操作
    const userId = await db.name("user").insert({
      name: "张三",
      age: 25
    });

    await db.name("profile").insert({
      user_id: userId,
      address: "北京市"
    });

    return { success: true, userId };
  });

  console.log("事务执行成功:", result);
} catch (error) {
  console.error("事务执行失败:", error);
  // 事务会自动回滚
}

6.2 手动事务

const connection = await Db.createConnection();

try {
  await connection.beginTransaction();
  
  // 执行操作
  await connection.query("INSERT INTO user (name) VALUES (?)", ["张三"]);
  await connection.query("UPDATE user SET age = ? WHERE name = ?", [25, "张三"]);
  
  await connection.commit();
  console.log("事务执行成功");
} catch (error) {
  await connection.rollback();
  console.error("事务执行失败:", error);
} finally {
  // 释放连接(如果使用连接池)
  // connection.release();
}

7. 高级功能

7.1 数据映射

// 映射查询结果
const users = await Db.name("user")
  .where("status", "1")
  .map(user => ({
    id: parseInt(user.id),
    name: user.name,
    age: parseInt(user.age),
    isActive: user.status === "1",
    createdAt: new Date(user.create_time)
  }))
  .select();

// 结果会自动应用映射函数

7.2 字段操作

import { FieldData } from "epii-db-orm";

// 使用 FieldData 进行复杂更新
const fieldData = new FieldData();
fieldData.put("name", "张三")
         .putInc("login_count", 1) // login_count = login_count + 1
         .putDec("points", 5)      // points = points - 5
         .putExp("update_time", "NOW()"); // update_time = NOW()

await Db.name("user").where("id", 1).update(fieldData);

7.3 原生 SQL

// 执行原生 SQL 查询
const users = await Db.query("SELECT * FROM user WHERE age > ?", [18]);

// 执行原生 SQL 语句
const result = await Db.execute("UPDATE user SET status = ? WHERE id = ?", [1, 1]);

8. 性能优化

8.1 最佳实践

  1. 使用索引:确保查询条件中的字段有适当的索引
  2. 限制查询字段:只查询需要的字段,使用 field 方法
  3. 限制结果集:使用 limit 限制返回数据量
  4. 批量操作:使用 insertAll 进行批量插入
  5. 使用连接池:高并发场景下使用连接池
  6. 避免全表扫描:始终设置 where 条件
  7. 合理使用缓存:对频繁查询的数据使用缓存

8.2 性能对比

| 操作 | 传统 SQL | epii-orm | |------|----------|----------| | 简单查询 | 直接编写 SQL | 链式调用,自动生成 SQL | | 复杂查询 | 复杂 SQL 语句 | 模块化条件构建 | | 批量操作 | 多条 SQL 语句 | 单次批量操作 | | 事务处理 | 手动管理 | 自动事务管理 |

9. 常见问题与解决方案

9.1 连接问题

问题:执行操作时提示 "connection is null"

解决方案:确保在操作前设置了数据库连接或连接池

9.2 事务问题

问题:事务执行失败

解决方案

  • 检查数据库引擎是否支持事务(如 MySQL 的 MyISAM 不支持)
  • 确保所有操作都在事务回调中执行
  • 检查是否有未捕获的异常

9.3 性能问题

问题:查询速度慢

解决方案

  • 添加适当的索引
  • 限制查询字段和结果集
  • 使用连接池
  • 优化查询条件

9.4 类型问题

问题:TypeScript 类型错误

解决方案

  • 查看类型定义文件了解正确的类型
  • 使用泛型指定返回类型
  • 确保传递正确类型的参数

10. 完整示例

10.1 用户管理系统示例

import { Db, WhereData, DbTransaction } from "epii-db-orm";

// 配置数据库连接
Db.config.connectionPool = mysqlPool;

// 用户服务类
class UserService {
  // 创建用户
  async createUser(userData) {
    return await DbTransaction(async (db) => {
      const userId = await db.name("user").insert({
        name: userData.name,
        email: userData.email,
        age: userData.age,
        create_time: new Date().toISOString()
      });

      await db.name("user_profile").insert({
        user_id: userId,
        address: userData.address,
        phone: userData.phone
      });

      return userId;
    });
  }

  // 获取用户列表
  async getUserList(params) {
    const where = new WhereData();
    
    if (params.status) {
      where.put("status", params.status);
    }
    
    if (params.keyword) {
      where.putLike("name", `%${params.keyword}%`);
      where.putLike("email", `%${params.keyword}%`);
    }

    return await Db.name("user")
      .where(where)
      .order("create_time", "desc")
      .limit(params.pageSize, (params.page - 1) * params.pageSize)
      .select();
  }

  // 获取用户详情
  async getUserDetail(userId) {
    return await Db.name("user")
      .alias("u")
      .field("u.*, p.address, p.phone")
      .leftJoin("user_profile as p", "u.id = p.user_id")
      .where("u.id", userId)
      .find();
  }

  // 更新用户信息
  async updateUser(userId, updateData) {
    return await Db.name("user").where("id", userId).update(updateData);
  }

  // 删除用户
  async deleteUser(userId) {
    return await DbTransaction(async (db) => {
      await db.name("user_profile").where("user_id", userId).delete();
      await db.name("user").where("id", userId).delete();
      return true;
    });
  }
}

export default new UserService();

11. API 参考

11.1 Db 类

| 方法 | 描述 | 参数 | 返回值 | |------|------|------|--------| | name(tableName) | 创建 Query 实例 | tableName: string 表名 | Query 实例 | | table(tableName) | 创建 Query 实例(不使用前缀) | tableName: string 表名 | Query 实例 | | query(sql, params) | 执行原生 SQL 查询 | sql: string SQL 语句params: Array 参��� | Promise 查询结果 | | execute(sql, params) | 执行原生 SQL 语句 | sql: string SQL 语句params: Array 参数 | Promise 执行结果 | | createConnection() | 创建数据库连接 | 无 | Promise 连接对象 |

11.2 Query 类

| 方法 | 描述 | 参数 | 返回值 | |------|------|------|--------| | where(field, value) | 添加 WHERE 条件 | field: string 字段名value: any 值 | Query 实例 | | where(field, op, value) | 添加带操作符的条件 | field: string 字段名op: string 操作符value: any 值 | Query 实例 | | where(condition) | 添加条件字符串 | condition: string 条件字符串 | Query 实例 | | where(whereData) | 添加 WhereData 条件 | whereData: WhereData 条件对象 | Query 实例 | | whereId(id) | 添加 ID 条件 | id: number ID 值 | Query 实例 | | whereOp(field, op, value) | 添加操作符条件 | field: string 字段名op: string 操作符value: any 值 | Query 实例 | | whereLike(field, value) | 添加 LIKE 条件 | field: string 字段名value: string 匹配值 | Query 实例 | | whereBetween(field, start, end) | 添加 BETWEEN 条件 | field: string 字段名start: any 开始值end: any 结束值 | Query 实例 | | whereIn(field, values) | 添加 IN 条件 | field: string 字段名values: Array 值数组 | Query 实例 | | whereOr(field, value) | 添加 OR 条件 | field: string 字段名value: any 值 | Query 实例 | | field(fields) | 指定查询字段 | fields: string 字段列表 | Query 实例 | | order(field, direction) | 添加排序 | field: string 字段名direction: string 方向 (asc/desc) | Query 实例 | | limit(limit, offset) | 限制结果集 | limit: number 数量offset: number 偏移量 | Query 实例 | | group(field) | 添加分组 | field: string 分组字段 | Query 实例 | | having(condition) | 添加分组条件 | condition: string 条件 | Query 实例 | | alias(alias) | 设置表别名 | alias: string 别名 | Query 实例 | | join(table, condition, type) | 添加表连接 | table: string 表名condition: string 连接条件type: string 连接类型 | Query 实例 | | leftJoin(table, condition) | 添加左连接 | table: string 表名condition: string 连接条件 | Query 实例 | | rightJoin(table, condition) | 添加右连接 | table: string 表名condition: string 连接条件 | Query 实例 | | innerJoin(table, condition) | 添加内连接 | table: string 表名condition: string 连接条件 | Query 实例 | | map(func) | 设置结果映射函数 | func: Function 映射函数 | Query 实例 | | data(data) | 设置数据 | data: Object/FieldData 数据 | Query 实例 | | select() | 查询多条数据 | 无 | Promise<Array> 结果数组 | | find(id) | 查询单条数据 | id: number (可选) ID 值 | Promise<T|null> 结果对象或 null | | value(field, defaultValue) | 获取单个字段值 | field: string 字段名defaultValue: any 默认值 | Promise 字段值 | | count() | 统计记录数 | 无 | Promise 记录数 | | column(field) | 获取单列数据 | field: string 字段名 | Promise<Array> 字段值数组 | | insert(data) | 插入数据 | data: Object/FieldData 数据 | Promise 插入 ID | | insertAll(dataList) | 批量插入数据 | dataList: Array<Object/FieldData> 数据列表 | Promise 影响行数 | | update(data) | 更新数据 | data: Object/FieldData 数据 | Promise 影响行数 | | delete(id) | 删除数据 | id: number (可选) ID 值 | Promise 影响行数 |

11.3 WhereData 类

| 方法 | 描述 | 参数 | 返回值 | |------|------|------|--------| | put(field, value) | 添加等于条件 | field: string 字段名value: any 值 | WhereData 实例 | | putExp(field, exp) | 添加表达式条件 | field: string 字段名exp: string 表达式 | WhereData 实例 | | putLike(field, value) | 添加 LIKE 条件 | field: string 字段名value: string 匹配值 | WhereData 实例 | | putIn(field, values) | 添加 IN 条件 | field: string 字段名values: Array 值数组 | WhereData 实例 | | putNotIn(field, values) | 添加 NOT IN 条件 | field: string 字段名values: Array 值数组 | WhereData 实例 | | putSymbol(field, op, value) | 添加带操作符的条件 | field: string 字段名op: string 操作符value: string 值 | WhereData 实例 | | putBetween(field, start, end) | 添加 BETWEEN 条件 | field: string 字段名start: string 开始值end: string 结束值 | WhereData 实例 | | putNotBetween(field, start, end) | 添加 NOT BETWEEN 条件 | field: string 字段名start: string 开始值end: string 结束值 | WhereData 实例 | | static make(key, value) | 创建 WhereData 实例 | key: string 字段名value: string 值 | WhereData 实例 |

11.4 FieldData 类

| 方法 | 描述 | 参数 | 返回值 | |------|------|------|--------| | put(field, value) | 添加字段值 | field: string 字段名value: any 值 | FieldData 实例 | | put(fieldData) | 添加多个字段值 | fieldData: Object/Map 字段数据 | FieldData 实例 | | putInc(field, step) | 添加自增操作 | field: string 字段名step: number 步长 | FieldData 实例 | | putDec(field, step) | 添加自减操作 | field: string 字段名step: number 步长 | FieldData 实例 | | putExp(field, exp) | 添加表达式操作 | field: string 字段名exp: string 表达式 | FieldData 实例 | | static make(key, value) | 创建 FieldData 实例 | key: string/Object/Map 字段名或数据value: any 值 | FieldData 实例 |

12. 版本历史

| 版本 | 日期 | 主要变更 | |------|------|----------| | 1.1.4 | 2024-01 | 优化 SQL 构建逻辑 | | 1.1.3 | 2024-01 | 修复事务处理问题 | | 1.1.2 | 2024-01 | 添加数据映射功能 | | 1.1.1 | 2024-01 | 完善 TypeScript 类型定义 | | 1.1.0 | 2024-01 | 增加事务支持 | | 1.0.0 | 2024-01 | 初始版本 |

13. 贡献与开发

13.1 开发环境搭建

# 克隆代码
git clone <repository-url>

# 安装依赖
npm install

# 编译 TypeScript
npm run build

# 运行测试
npm test

13.2 目录结构

epii-orm/
├── src/             # 源代码
│   ├── libs/        # 工具库
│   ├── map/         # 映射类
│   ├── Db.ts        # 数据库连接管理
│   ├── Query.ts     # 查询构建器
│   ├── SqlBuilder.ts # SQL 构建器
│   └── index.ts     # 导出入口
├── dist/            # 编译产物
├── package.json     # 包配置
├── tsconfig.json    # TypeScript 配置
└── readme.md        # 说明文档

13.3 提交规范

  • 代码风格:遵循 TypeScript 标准风格
  • 提交信息:使用清晰的提交信息
  • 测试:确保所有测试通过
  • 文档:更新相关文档

14. 许可证

本项目采用 ISC 许可证。详见 LICENSE 文件。

15. 联系与支持

  • 问题反馈:在 GitHub 仓库提交 Issue
  • 功能请求:在 GitHub 仓库提交 Issue
  • 代码贡献:Fork 仓库并提交 Pull Request

结语:epii-orm 是一个轻量级但功能强大的数据库 ORM 框架,它提供了简洁易用的 API,使数据库操作更加直观和高效。通过本文档的学习,您应该已经掌握了 epii-orm 的核心功能和使用方法。如果您有任何问题或建议,欢迎随时反馈。