Gathering detailed insights and metrics for zenorm
Gathering detailed insights and metrics for zenorm
Gathering detailed insights and metrics for zenorm
Gathering detailed insights and metrics for zenorm
npm install zenorm
Typescript
Module System
Node Version
NPM Version
Cumulative downloads
Total Downloads
Last Day
0%
NaN
Compared to previous day
Last Week
0%
NaN
Compared to previous week
Last Month
0%
NaN
Compared to previous month
Last Year
0%
NaN
Compared to previous year
Node.js 数据库 ORM 框架
ZenWeb 衍生的核心项目,此项目可以独立使用
本框架不主动创建数据库结构,而是根据已有数据库结构来生成操作代码,这么做的原因:
本框架并不是真正的 ORM 系统,而是类 ORM 的数据库操作层,几乎任何复杂查询都可实现(试试强大的 AB 工具类)
本框架诞生之因就是为了解决 SAAS 系统的单实例多租户问题,所以所有设计上都是从如何在一个系统中使用多个数据库服务器以及多个数据库而导向,
当然也支持传统的单体应用方式(配置 @zenorm/generate
的 bindQuery
即可)。
以下样例代码即是单体应用的使用方式
1# 生产依赖 2npm install zenorm mysql-easy-query 3 4# 开发依赖 5npm install @zenorm/generate @zenorm/generate-mysql --save-dev
在 package.json
的 scripts
中增加如下代码,用于执行 dbgen
命令
1{ 2 "scripts": { 3 "dbgen": "zenorm-generate .dbgen.js" 4 } 5}
创建文件 .dbgen.js
用于生成数据库结构代码时连接到指定数据库
提示:运行时并不使用此配置
1/** @type {import("@zenorm/generate").GenerateConfig} */ 2export default { 3 host: "localhost", 4 port: 3306, 5 user: "root", 6 password: "", 7 bindQuery: "pool@../db", 8 database: "test" 9};
以下数据库结构为演示用,在数据中创建表结构
1CREATE TABLE `user` (
2 `id` int(11) NOT NULL AUTO_INCREMENT,
3 `name` varchar(255) NOT NULL,
4 `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
5 `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
6 PRIMARY KEY (`id`)
7) ENGINE=InnoDB DEFAULT CHARSET=utf8;
8
9CREATE TABLE `profile` (
10 `id` int(11) NOT NULL,
11 `edu` varchar(255) DEFAULT NULL,
12 `work` varchar(255) DEFAULT NULL,
13 PRIMARY KEY (`id`)
14) ENGINE=InnoDB DEFAULT CHARSET=utf8;
15
16CREATE TABLE `message` (
17 `id` int(11) NOT NULL AUTO_INCREMENT,
18 `user_id` int(11) NOT NULL,
19 `content` varchar(255) DEFAULT NULL,
20 PRIMARY KEY (`id`)
21) ENGINE=InnoDB DEFAULT CHARSET=utf8;
运行命令开始生成数据库结构代码
1npm run dbgen
编辑生成的模型文件 src/model/user.ts
1import { model, join, many, propset } from 'zenorm'; 2import { UserTable } from './_tables'; 3import { Profile } from './profile'; 4import { Message } from './message'; 5 6@model({ 7 pk: 'id', 8 table: 'user', 9}) 10export default class User extends UserTable { 11 // 添加以下代码 12 // join 描述支持使用文件名,解决互相依赖问题 13 @join(__dirname + '/profile', { type: 'OneToMany', asList: false }) 14 profile?: Profile; 15 16 @join(Message) 17 messages?: Message[]; 18 19 @many(Message) 20 messageList?: Message[]; 21 22 @propset(function (v) { 23 if (v === undefined) throw new Error('age is undefined'); 24 if (v === 99) return false; 25 const date = new Date(); 26 date.setFullYear(date.getFullYear() - v, 1, 1); 27 this.birthday = date; 28 return true; 29 }) 30 age = this.birthday ? ((new Date().getFullYear()) - this.birthday.getFullYear()) : undefined; 31 // 结束 32}
编辑生成的模型文件 src/model/profile.ts
1import { model, join } from 'zenorm'; 2import { ProfileTable } from './_tables'; 3import User from './user'; 4 5@model({ 6 pk: 'id', 7 table: 'profile', 8}) 9export default class Profile extends ProfileTable { 10 // 添加以下代码 11 @join(User) 12 user?: User; 13 // 结束 14}
创建代码 src/db.ts
1import { createPoolCompatible } from 'mysql-easy-query'; 2import { Repositories } from './model'; 3 4// 创建数据库连接池 5export const pool = createPoolCompatible({ 6 pools: { 7 // 主库 8 MASTER: { 9 host: '10.0.0.1', 10 user: 'root', 11 database: 'test', 12 password: '', 13 }, 14 // 如果需要读写分离,创建命令规则为 SLAVE* 的只读配置 15 /* 16 SLAVE1: { 17 host: '10.0.0.2' 18 }, 19 */ 20 } 21});
1import { User, Message } from './model'; 2 3async function test() { 4 // create 5 const id = await User.create({ name: 'yf' }); 6 console.log(id); // 1 7 8 // get and update 9 const user = await User.findByPk(id); 10 user.name = 'yefei'; 11 user.age = 20; 12 await User.save(user); 13 14 // find all 15 const users = await User.find().all(); 16 17 // find limit 18 const users = await User.find().limit(10).all(); 19 20 // find by where 21 const users = await User.find({ name: { $like: `%y%` } }).all(); 22 23 // get all count 24 const count = await User.find().count(); 25 26 // page 27 const page = await User.find().page(); 28 29 // exists 30 const exists = await User.find({ name: 'yf' }).exists(); 31 32 // update 33 const updatedCount = await User.find({ id: 1 }).update({ name: 'yf', age: 11 }); 34 35 // delete 36 const user = await User.findByPk(1); 37 const deletedCount = await user.delete(); 38 39 // sql delete 40 await User.find({ name: 'aaa' }).delete(); 41 42 // join 预定义 43 const user = await User.find().join("messages").get(); 44 45 // join 模型(未定义的) 46 const user = await Message.find().join(User).all(); 47 48 // many 独立查询功能 49 const userList = await User.find().many("messageList").all(); 50 51 // 指定使用主从库 52 await User.find().of('MASTER').all(); 53 await User.find().of('SLAVE*').all(); 54}
1import { pool } from './db'; 2import { User, Message } from './model'; 3 4async function test() { 5 await pool.transaction(async tx => { 6 await User.query(tx).find().update({ some: 'data' }); 7 await Message.query(tx).find().update({ some: 'data' }); 8 }); 9}
No vulnerabilities found.
No security vulnerabilities found.