es6 class实现的简易orm通过model基类统一管理表名与字段映射,支持自动识别主键、智能区分insert/update,封装find/findall等异步crud方法,并可扩展简单关联查询,体现模型定义、字段映射与基础操作抽象的核心思想。

用ES6 Class写一个简单ORM,核心是把类和数据库表映射起来,让开发者用操作对象的方式操作数据,不用直接写SQL。它不追求功能完整,但要体现ORM的关键思想:模型定义、字段映射、基础CRUD封装。
定义Model基类,统一管理表名和字段
所有业务模型都继承这个基类,它负责保存表名、字段配置,并提供通用的增删改查方法。
关键点在于用static属性声明表名和字段描述,避免每个实例重复计算;用constructor参数自动赋值实现数据初始化。
- 表名默认取类名小写(如User → "users"),支持手动覆盖
- 字段定义用
static fields = { id: 'INTEGER PRIMARY KEY', name: 'TEXT', email: 'TEXT' }格式,既描述类型也隐含是否为主键 - 构造时只接受合法字段,多余字段忽略,缺失字段设为
null或默认值
实现save()方法,自动区分插入与更新
调用save()时,根据实例是否有主键值(如id)决定执行INSERT还是UPDATE。这是ORM最基础的智能判断。
- 检查
this.constructor.fields中哪个字段标记为PRIMARY KEY(可通过正则匹配或约定字段名如id) - 若主键字段有值且非空,生成UPDATE语句;否则生成INSERT语句
- SQL参数用占位符(?)+ 数组方式传入,防止SQL注入(真实项目需配合底层驱动如sqlite3或mysql2)
封装find()和findAll(),支持简单条件查询
静态方法find(id)查单条,findAll({ where: { name: 'Alice' } })查列表。条件对象转WHERE子句,值自动绑定。
-
find(id)内部调用findAll({ where: { [primaryKey]: id } })复用逻辑 -
where对象的键对应字段名,值作为查询条件;支持=匹配,进阶可扩展like、in等 - 返回Promise,模拟异步数据库操作(实际对接knex、typeorm或原生driver)
添加简单的关联支持(可选增强)
比如User.hasMany(Post),在User实例上提供posts()方法,返回Post列表。不硬编码JOIN,而是用两次查询(N+1问题可后续优化)。
- 在Model类上定义
static associations = { posts: { model: Post, foreignKey: 'user_id' } } - 实例方法
posts()读取this.id,调用Post.findAll({ where: { user_id: this.id } }) - 关联方法返回Promise,保持调用一致性
不复杂但容易忽略细节:字段校验、异步流程控制、错误分类抛出、SQL注入防护。写完后用几个Model类试跑CRUD,再逐步加事务、迁移、验证等能力。











