• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

lubejs: Lubejs 是一个用于 node.js 诣在方便使用SQL数据库连接

原作者: [db:作者] 来自: 网络 收藏 邀请

开源软件名称:

lubejs

开源软件地址:

https://gitee.com/jovercao/lubejs

开源软件介绍:

Lubejs

Lubejs 是一个用于 node.js 诣在方便使用SQL数据库连接.取名为lube意为润滑,即作为js与sql间的润滑剂般的存在,我们可以尽情使用优雅的 js/ts来 替代拼接 sql 字符串。

本库部分灵感来自于EFTypeORM,致谢

English

lubejs是什么

lubejs 是一套类型化sql构建、执行工具,亦是一套强大易用的Typescript ORM开发框架。

  • 完备的SQL构建工具,使用最贴近SQL的语法编写SQL,极低的学习成本
  • 强大的Typescript类型支持,支持反向类型推导,返回明确类型,拥有完整类型安全体系,智能语法提示,提高开发效率以及预排除类型错误,强烈建立在typescript项目中使用lubejs。
  • ORM配套工具,Code first、数据迁移
  • 匹配多种数据库(目前只支持mssql)
  • 跨数据库兼容,为此,lubejs建立了标准行为库,把大多数常用的,而在各个数据库中又不尽相同的操作行为,包括在其中。

lubejs理念

  • 简洁,极简api,极易上手
  • 贴近自然,语法与标准sql极为接近,大大降低学习成本
  • 渐进式,lubejs分为两个层级的引用,core及完整功能包
  • 多数据库方言统一兼容,建立中间标准操作库并不断丰富。
  • 完整的typescript类型安全

快速开始

安装

使用 npm 安装:

# 安装lubejs库npm install lubejs --save# 安装lubejs-mssql驱动npm install lubejs-mssql

开始

Hello world!

// hello-world.tsimport { connect, SQL } from 'lubejs'// 导入mssql驱动import 'lubejs-mssql'(async () => {  // 创建连接  const db = await connect('mssql://user:password@localhost:1433/database');  // SELECT 'hello world'  console.log(await db.queryScalar(SQL.select('hello world!')));  // => 'hello world'  await db.close();})()

完整范例

// example.tsimport {  connect,  SQL,  Decimal,  Uuid,  Connection,  DbType,  outputCommand,} from "lubejs";import "lubejs-mssql";interface Table1 {  id: number;  name: string;  stringField?: string;  floatField?: number;  dateField?: Date;  decimalField?: Decimal;  uuidField?: Uuid;  updatedAt: Date;  binaryField?: ArrayBuffer;  createdAt: Date;  operator?: string;}interface Pay {  id?: number;  year: number;  month: number;  amount: Decimal;  personId: number;}interface Person {  id?: number;  name: string;  age: number;}/** * 初始化数据库 */async function initDb(db: Connection) {  await db.query(    SQL.if(SQL.std.existsTable('table1')).then(SQL.dropTable("table1"))  );  await db.query(    SQL.createTable("table1").as(({ column }) => [      column("id", DbType.int32).identity().primaryKey(),      column("name", DbType.string(100)).notNull(),      column("stringField", DbType.string(100)).null(),      column("floatField", DbType.float).null(),      column("dateField", DbType.datetimeoffset).null(),      column("decimalField", DbType.decimal(18, 6)),      column("uuidField", DbType.uuid),      column("updatedAt", DbType.datetimeoffset).default(SQL.std.now()),      column("binaryField", DbType.binary(DbType.MAX)),      column("createdAt", DbType.datetimeoffset).default(SQL.std.now()),      column("operator", DbType.string(100)).null(),    ])  );  await db.query(    SQL.if(SQL.std.existsTable('pay')).then(SQL.dropTable("pay"))  );  await db.query(    SQL.createTable("pay").as(({ column }) => [      column("id", DbType.int32).identity().primaryKey(),      column("year", DbType.int32),      column("month", DbType.int32),      column("amount", DbType.decimal(18, 2)),      column("personId", DbType.int32),    ])  );  await db.query(    SQL.if(SQL.std.existsTable('person')).then(SQL.dropTable("person"))  );  await db.query(    SQL.createTable("person").as(({ column }) => [      column("id", DbType.int32).identity().primaryKey(),      column("name", DbType.int32).notNull(),      column("age", DbType.int32),    ])  );}/** * Table1表声明 */// 这是一个范例async function example(db: Connection) {  //---------------插入数据------------------  /*   * INSERT INTO table1 (stringField, floatField, dateField)   * VALUES ('value1-1', 2, Convert(DATETIMEOFFSET, '2019-11-18 00:00:00'))   * ('value1-2', 1, Convert(DATETIMEOFFSET, '2019-11-18 00:00:00'))   * ('value1-3', 45, Convert(DATETIMEOFFSET, '2019-11-18 00:00:00'))   */  const insertSql = SQL.insert<Table1>("table1").values([    {      name: "item1",      stringField: "value1-1",      floatField: 3.14,      dateField: new Date(),      decimalField: new Decimal("3.1415"),      uuidField: Uuid.new(),      binaryField: Buffer.from('abcdefeg')    },    {      name: "item2",      stringField: "value1-2",      floatField: 1.132,      dateField: new Date(),      decimalField: new Decimal("3.1415"),      uuidField: Uuid.new(),      binaryField: Buffer.from('abcdefeg')    },    {      name: "item3",      stringField: "value1-3",      floatField: 45.2656,      dateField: new Date(),      decimalField: new Decimal("3.1415"),      uuidField: Uuid.new(),      binaryField: Buffer.from('abcdefeg')    },  ]);  await db.query(insertSql);  // 你还以使用以下方式插入,等效于上面的写法  await db.insert<Table1>("table1", [    {      name: "item1",      stringField: "value1-1",      floatField: 3.14,      dateField: new Date(),      decimalField: new Decimal("3.1415"),      uuidField: Uuid.new(),      binaryField: Buffer.from('abcdefeg')    },    {      name: "item2",      stringField: "value1-2",      floatField: 1.132,      dateField: new Date(),      decimalField: new Decimal("3.1415"),      uuidField: Uuid.new(),      binaryField: Buffer.from('abcdefeg')    },    {      name: "item3",      stringField: "value1-3",      floatField: 45.2656,      dateField: new Date(),      decimalField: new Decimal("3.1415"),      uuidField: Uuid.new(),      binaryField: Buffer.from('abcdefeg')    },  ]);  //---------------更新数据------------------  // UPDATE t SET updatedAt = Convert(DateTime, '2019-11-18 00:00:00') FROM table1 t WHERE id = 1  const t = SQL.table<Table1>("table1").as("t");  const updateSql = SQL.update(t)    .set({ updatedAt: new Date(), operator: "your name" })    .where(t.id.eq(1));  await db.query(updateSql);  // 你还以使用以下方式更新,等效于上面的写法  await db.update<Table1>(    "table1",    { updatedAt: new Date(), operator: "your name" },    { id: 1 }  );  //---------------删除数据-------------------  // DELETE t FROM table1 t WHERE t.id = 1  const deleteSql = SQL.delete(t).from(t).where(t.id.eq(1));  await db.query(deleteSql);  // 你还以使用以下方式删除  // DELETE table1 WHERE id = 1  await db.delete("table1", { id: 1 });  //----------------查询数据--------------------  // SELECT t.* FROM table1 AS t WHERE t.id = 1 AND t.name = 'name1'  const selectSql = SQL.select(t.star)    .from(t)    .where(SQL.and(t.id.eq(1), t.name.eq("name1")));  console.log((await db.query(selectSql)).rows);  //  You can also select in this way  // SELECT * FROM table1 WHERE id = 1 AND name = 'name1'  console.log(    await await db.select("table1", {      where: {        id: 1,        name: "item1",      },    })  );  // //---------------以下是一个复合查询------------  const p = SQL.table<Person>("person").as("p");  const pay = SQL.table<Pay>("pay");  const sql = SQL.select({        year: pay.year,        month: pay.month,        name: p.name,        age: p.age,        total: SQL.std.sum(pay.amount),  })    .from(pay)    .join(p, pay.personId.eq(p.id))    .where(p.age.lte(18))    .groupBy(p.name, p.age, pay.year, pay.month)    .having(SQL.std.sum(pay.amount).gte(new Decimal(100000)))    .orderBy(pay.year.asc(), pay.month.asc(), SQL.std.sum(pay.amount).asc(), p.age.asc())    .offset(20)    .limit(50);  console.log((await db.query(sql)).rows);}(async () => {  // 创建一个Lube连接  const db = await connect("mssql://sa:[email protected]/Test");  // 打开连接  await db.open();  // 输出日志  db.on('command', (cmd) => outputCommand(cmd, process.stdout))  try {    await initDb(db);    await example(db);  } finally {    await db.close();  }})();

版本说明

注意: lubejs目前仍为预览版,内部会有部分调整,公共API可能会有小许调整,但不会有大调整。

渐进式分离

  • lubejs/core 为核心包,包括sql构建以及sql执行工具。
  • lubejs则为完整包,包括lubejs/core的所有内容以及orm功能,数据迁移cli等。

数据库支持列表

  • mssql - 目前支持microsoft sqlserver 2012 或更高版本, 库基于 node-mssql开发.
  • mysql - 当前正在开发中
  • postgresql - 计划于2021年底开发

NodeJs版本支持

nodejs >= 12.0

概念

SQL构造器(SQL对象)

所有的SQL构造,均由 SQL对象发起,几乎所有的SQL的语句,均可从SQL对象创建,例如SQL.selectSQL.update,SQL.delete等。

// 导入SQL对象import { SQL } from 'lubejs';

为了更贴近sql语法,您还可以使用解构来引入需要的关键字

const {    insert,    delete: $delete // 关键字delete需要使用别名} = SQL// 构建插入张三、李四两条记录到table1的语句const sql = insert('table1').values([{ name: '张三', age: 19, sex: '' }, { name: '李四', age: 25, sex: '' }]);// 构建table1表中删除id为1记录的sql语句const sql = $delete('table1').where({ id: 1 })

更多SQL对象用法,请翻阅《api参考》

注意:deletejs关键字,需要使用别名代替,其它关键字亦是如此

标准行为(SQL.std)

lubejs为了更大程序的兼容多数据库,专门定义了标准行为,用于统一在跨数据库时的操作,避免在跨方言数据库迁移是的重复劳动。

SQL.std中定义了许多常用的函数、操作等行为

常用函数

说明函数备注
类型转换SQL.std.convert(expr, dbType)Expression.prototype.to(dbType)
当值为空时返回默认值SQL.std.nvl(value, defaultValue)

聚合函数

说明函数备注
计数SQL.std.count(expr)
平均SQL.std.avg(expr)
求和SQL.std.sum(expr)
最大值SQL.std.max(expr)
最小值SQL.std.min(expr)

日期函数

说明函数备注
当前时间SQL.std.now(expr)
UTC当前时间SQL.std.utcNow(expr)
切换时区SQL.std.switchTimezone(date, offset)
格式化日期SQL.std.formatDate(date, format)
取日期中的年份SQL.std.yearOf(date)
取日期中的月份SQL.std.monthOf(date)
取日期中的日期SQL.std.dayOf(date)
取两个日期之间的天数SQL.std.daysBetween(star, end)
取两个日期之间的月数SQL.std.monthsBetween(star, end)
取两个日期之间的年数SQL.std.yearsBetween(star, end)
取两个日期之间的小时数SQL.std.hoursBetween(star, end)
取两个日期之间的分钟数SQL.std.minutesBetween(star, end)
取两个日期之间的秒钟数SQL.std.secondsBetween(star, end)
获取加天数后的日期SQL.std.addDays(date, days)
获取加月数后的日期SQL.std.addMonths(date, months)
获取加年数后的日期SQL.std.addYears(date, years)
获取加小时数后的日期SQL.std.addHours(date, hours)
获取加分钟数后的日期SQL.std.addMinutes(date, minutes)
获取加秒钟数后的日期SQL.std.addSeconds(date, seconds)

字符串函数

说明函数备注
获取字符串字符数SQL.std.strlen(str)
获取字符串字节数
截取字符串SQL.std.substr(str, start, len)
替换字符串SQL.std.replace(str, search, text)
删除两侧空格SQL.std.trim(str)
删除右侧空格SQL.std.trimEnd(str)
转换成小写字母SQL.std.lower(str)
转换成大写字母SQL.std.upper(str)
获取字符串在另一个字符串中的位置SQL.std.strpos(str, search, startAt)
获取一个字符的ascii码SQL.std.ascii(str)
将一个ascii码转换成一个字符SQL.std.asciiChar(code)
获取一个字符的unicode码SQL.std.unicode(str)
将一个unicode码转换成一个字符SQL.std.unicodeChar(code)

数学函数

说明函数备注
求绝对值SQL.std.abs(value)
指数曲线SQL.std.exp(value)
向上取整SQL.std.ceil(value)
向下取整SQL.std.floor(value)
自然对数SQL.std.ln(value)
对数SQL.std.log(value)
圆周率(π)SQL.std.pi()
乘幂SQL.std.power(value, mi)
radiansSQL.std.radians(value)
degreesSQL.std.degrees(value)
随机数SQL.std.random(value)
四舍五入SQL.std.round(value)
sign函数SQL.std.sign(value)
开平方SQL.std.sqrt(value)
cos函数SQL.std.cos(value)
sin函数SQL.std.sin(value)
tan函数SQL.std.tan(value)
acos函数SQL.std.acos(value)
asin函数SQL.std.asin(value)
atan函数SQL.std.atan(value)
cot函数SQL.std.cot(value)

常用操作

说明方法备注
返回条件:是否存在表SQL.std.existsTable(tableName)
返回条件:是不存在数据库SQL.std.existsDatabase(dbName)
返回条件:是不存在视图SQL.std.existsView(viewName)
返回条件:是不存在函数SQL.std.existsFunction(functionName)
返回条件:是不存在存储过程SQL.std.existsProcedure(procedureName)

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap