Security News
tea.xyz Spam Plagues npm and RubyGems Package Registries
Tea.xyz, a crypto project aimed at rewarding open source contributions, is once again facing backlash due to an influx of spam packages flooding public package registries.
zenorm
Advanced tools
Readme
Node.js 数据库 ORM 框架
ZenWeb 衍生的核心项目,此项目可以独立使用
本框架不主动创建数据库结构,而是根据已有数据库结构来生成操作代码,这么做的原因:
本框架并不是真正的 ORM 系统,而是类 ORM 的数据库操作层,几乎任何复杂查询都可实现(试试强大的 AB 工具类)
本框架诞生之因就是为了解决 SAAS 系统的单实例多租户问题,所以所有设计上都是从如何在一个系统中使用多个数据库服务器以及多个数据库而导向,
当然也支持传统的单体应用方式(配置 @zenorm/generate
的 bindQuery
即可)。
以下样例代码即是单体应用的使用方式
# 生产依赖
npm install zenorm mysql-easy-query
# 开发依赖
npm install @zenorm/generate @zenorm/generate-mysql --save-dev
在 package.json
的 scripts
中增加如下代码,用于执行 dbgen
命令
{
"scripts": {
"dbgen": "zenorm-generate .dbgen.js"
}
}
创建文件 .dbgen.js
用于生成数据库结构代码时连接到指定数据库
提示:运行时并不使用此配置
/** @type {import("@zenorm/generate").GenerateConfig} */
module.exports = {
host: "localhost",
port: 3306,
user: "root",
password: "",
bindQuery: "pool@../db",
database: "test"
};
以下数据库结构为演示用,在数据中创建表结构
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `profile` (
`id` int(11) NOT NULL,
`edu` varchar(255) DEFAULT NULL,
`work` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `message` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`content` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
运行命令开始生成数据库结构代码
npm run dbgen
编辑生成的模型文件 src/model/user.ts
import { model, join, many, propset } from 'zenorm';
import { UserTable } from './_tables';
import { Profile } from './profile';
import { Message } from './message';
@model({
pk: 'id',
table: 'user',
})
export default class User extends UserTable {
// 添加以下代码
// join 描述支持使用文件名,解决互相依赖问题
@join(__dirname + '/profile', { type: 'OneToMany', asList: false })
profile?: Profile;
@join(Message)
messages?: Message[];
@many(Message)
messageList?: Message[];
@propset(function (v) {
if (v === undefined) throw new Error('age is undefined');
if (v === 99) return false;
const date = new Date();
date.setFullYear(date.getFullYear() - v, 1, 1);
this.birthday = date;
return true;
})
age = this.birthday ? ((new Date().getFullYear()) - this.birthday.getFullYear()) : undefined;
// 结束
}
编辑生成的模型文件 src/model/profile.ts
import { model, join } from 'zenorm';
import { ProfileTable } from './_tables';
import User from './user';
@model({
pk: 'id',
table: 'profile',
})
export default class Profile extends ProfileTable {
// 添加以下代码
@join(User)
user?: User;
// 结束
}
创建代码 src/db.ts
import { createPoolCompatible } from 'mysql-easy-query';
import { Repositories } from './model';
// 创建数据库连接池
export const pool = createPoolCompatible({
pools: {
// 主库
MASTER: {
host: '10.0.0.1',
user: 'root',
database: 'test',
password: '',
},
// 如果需要读写分离,创建命令规则为 SLAVE* 的只读配置
/*
SLAVE1: {
host: '10.0.0.2'
},
*/
}
});
import { User, Message } from './model';
async function test() {
// create
const id = await User.create({ name: 'yf' });
console.log(id); // 1
// get and update
const user = await User.findByPk(id);
user.name = 'yefei';
user.age = 20;
await User.save(user);
// find all
const users = await User.find().all();
// find limit
const users = await User.find().limit(10).all();
// find by where
const users = await User.find({ name: { $like: `%y%` } }).all();
// get all count
const count = await User.find().count();
// page
const page = await User.find().page();
// exists
const exists = await User.find({ name: 'yf' }).exists();
// update
const updatedCount = await User.find({ id: 1 }).update({ name: 'yf', age: 11 });
// delete
const user = await User.findByPk(1);
const deletedCount = await user.delete();
// sql delete
await User.find({ name: 'aaa' }).delete();
// join 预定义
const user = await User.find().join("messages").get();
// join 模型(未定义的)
const user = await Message.find().join(User).all();
// many 独立查询功能
const userList = await User.find().many("messageList").all();
// 指定使用主从库
await User.find().of('MASTER').all();
await User.find().of('SLAVE*').all();
}
import { pool } from './db';
import { User, Message } from './model';
async function test() {
await pool.transaction(async tx => {
await User.query(tx).find().update({ some: 'data' });
await Message.query(tx).find().update({ some: 'data' });
});
}
FAQs
Easy ORM, easy query. easy typing! Auto generate typescript declaration.
The npm package zenorm receives a total of 46 weekly downloads. As such, zenorm popularity was classified as not popular.
We found that zenorm demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Tea.xyz, a crypto project aimed at rewarding open source contributions, is once again facing backlash due to an influx of spam packages flooding public package registries.
Security News
As cyber threats become more autonomous, AI-powered defenses are crucial for businesses to stay ahead of attackers who can exploit software vulnerabilities at scale.
Security News
UnitedHealth Group disclosed that the ransomware attack on Change Healthcare compromised protected health information for millions in the U.S., with estimated costs to the company expected to reach $1 billion.