1 Star 0 Fork 0

nickzhang / pg-dynamic-query

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
MIT

Table of Contents generated with DocToc

使用例子

Postgresql 例子

const {Postgresql, DynamicQuery, PageResponse, TableConfig} = require('pg-dynamic-query');

(async () => {
    //配置postgresql连接
    let postgresql = new Postgresql({
        "host": "****",
        "port": 1921,
        "database": "****",
        "user": "****",
        "password": "****"
    });  

  await postgresql.connect();
  const userConfig = new TableConfig("user_info", [
    "id",
    "name",
    "age"
  ]);
  const pageResponse = new PageResponse()
  const dynamicQuery = new DynamicQuery(userConfig, postgresql);
  const r = await dynamicQuery.save({name: 'zh', age: 13});
  await dynamicQuery.remove([r.id]);
  await dynamicQuery.find({}, pageResponse)
  console.log("pageResponse:")
  console.log(pageResponse)
})()

控制台输出如下

create
insert into "user_info"("name","age") values('zh',13) RETURNING id
findById
select *
                 from user_info
                 where id = '12'
remove
delete
               from user_info
               where id in (12)
findBySql countSql
select count(1)
 from user_info
findBySql findSql
select * 
 from user_info
 order by id  desc  limit 10 offset 0
pageResponse:
PageResponse {
  totalElements: 3,
  page: 0,
  size: 10,
  content: [
    { id: 3, name: 'zh', age: 13 },
    { id: 2, name: 'zh', age: 12 },
    { id: 1, name: 'zh', age: 13 }
  ],
  orderBy: 'id',
  direction: 'desc',
  totalPages: 1
}

MySql例子

const {MySql, DynamicQuery, PageResponse, switchSqlLog, TableConfig} = require('pg-dynamic-query');

(async () => {

  let mySql = new MySql({
      "host": "****",
      "port": 3306,
      "database": "****",
      "user": "****",
      "password": "****"
  });

  await mySql.connect();
  const userConfig = new TableConfig("user_info", [
    "id",
    "name",
    "age"
  ]);
  const pageResponse = new PageResponse()
  const dynamicQuery = new DynamicQuery(userConfig, mySql);
  const r = await dynamicQuery.save({id: 2, name: 'zh1', age: 13});
  await dynamicQuery.find({}, pageResponse)
  console.log("pageResponse:")
  console.log(pageResponse)
})()

详细说明

DynamicQuery

export class DynamicQuery {
    /**
     * 构造方法需要传入TableConfig和Postgresql.client属性
     */
    constructor(tableConfig: TableConfig, client: DbClient);

    /**
     * 传入query对象,和表别名(可不传),返回一个转化后的sql条件数组
     */
    getConditions(query: Query, tableAlias?: string): string[];

    /**
     *  传入query对象,和表别名(可不传),返回where sql 语句
     */
    getWhere(query: Query, tableAlias?: string): string

    /**
     * 传入OrderBy对象,返回order by sql 语句
     */
    static getOrderBy(orderBy: OrderBy): string

    /**
     * 单表分页查询方法,数据会在PageResponse.content属性中
     */
    find(query: Query, page: PageResponse): Promise<void>

    /**
     * 导航分页查询方法,前提需在TableConfig配置parents信息
     */
    navigationFind(query: Query, page: PageResponse): Promise<void>

    /**
     * 通过Sql对象分页查询
     */
    findBySql(sql: Sql, page: PageResponse): Promise<void>

    /**
     * 通过sql查询
     */
    findAllBySql(querySql: string): Promise<any[]>

    /**
     * 事务方法,func中的所有数据库操作都会在一个事务中
     */
    tx(func: () => Promise<any>): Promise<void>

    /**
     * 传入Query对象,和OrderBy,返回所有符合条件记录
     */
    findAll(query: Query, orderBy?: OrderBy): Promise<any>

    /**
     * 导航查询全部
     */
    navigationFindAll(query: Query, orderBy?: OrderBy): Promise<any>

    /**
     * 导航查询,返回第一个
     */
    navigationFindOne(query: Query): Promise<any>

    /**
     * 传入Query对象,返回第一个符合的对象
     */
    findOne(query: Query): Promise<any>

    /**
     * 传入sql,返回第一个记录
     */
    findOneBySql(sql: string): Promise<any>

    /**
     * 传入Query,返回符合条件的数目
     */
    count(query: Query): Promise<number>

    /**
     * 导航查询数目
     */
    navigationCount(query: Query): Promise<number>

    /**
     * 传入from where sql,返回符合数目
     */
    countBySql(sql): Promise<number>

    /**
     * 创建新记录,hasReturn是否返回创建的记录,默认不返回
     */
    create(data: object, hasReturn?: boolean): Promise<any>

    /**
     * 保存方法,有则更新,无则创建,只能用于单主键,会返回结果
     */
    save(data: object): Promise<any>

    /**
     *批量保存
     */
    saveAll(entities: object[]): Promise<object[]>;

    /**
     * 更新方法,isAllUpdate为true为全部更新,false为部分更新,默认为true,会返回结果
     */
    update(data: object, isAllUpdate: boolean): Promise<any>

    /**
     * 根据ids更新,会返回更新结果集
     */
    updateByIds(data: object, ids: any[], isAllUpdate: boolean): Promise<any[]>

    /**
     * 根据Query更新数据,不会返回结果集
     */
    updateByQuery(data: object, query: Query, isAllUpdate: boolean): Promise<void>

    /**
     * 根据Query更新数据,返回结果集
     */
    updateByQueryWithResult(data: object, query: Query, isAllUpdate: boolean): Promise<any[]>

    /**
     * 根据id查询
     */
    findById(id: any): Promise<any>

    /**
     * 根据ids查询
     */
    findByIds(ids: any[]): Promise<any[]>

    /**
     * 根据ids删除
     */
    remove(ids: any[]): Promise<void>

    /**
     * 根据Query查询,删除相应记录
     */
    removeByQuery(query: Query): Promise<void>
}

DynamicQuery用到的参数类

export type Sql = {
    selectSql: string,
    formWhereSql: string,
    orderBySql: string
}

export type OrderBy = {
    orderBy: string,
    direction: Direction
}

export type Query = object;

export type PageRequest = {
    page: number, size: number, orderBy: string, direction: Direction
}

export type Direction = 'asc' | 'desc'

/**
 * DynamicQuery.tx传入的callback中获得
 */
export class Transaction {

}

Query要怎么写?

假定表格User,数据如下:

[
  {
    "id": 1,
    "name": "张三",
    "age": 10
  },
  {
    "id": 2,
    "name": "李四",
    "age": 12
  }
]

ps:Query的段名必须与数据库中字段名一样

基本用法
// 表示 name = "张三"的记录
let query = {name: "张三"}
// 表示 name like "%张%"
query = {name: "%张%"}
// 表示 name is null
query = {name: "$null"}
// 表示 name is not null
query = {name: "$nn"}
操作符
// 表示 name in ["张三"]
query = {name: {$in: ["张三"]}}
// 表示 name not in ["张三"]
query = {name: {$nin: ["张三"]}}
// 表示 name = "张三"
query = {name: {$eq: "张三"}}
// 表示 name != "张三"
query = {name: {$ne: "张三"}}
// 表示 age >= 18
query = {age: {$gte: 18}}
// 表示 age > 18
query = {age: {$gt: 18}}
// 表示 age <= 18
query = {age: {$lte: 18}}
// 表示 age < 18
query = {age: {$lt: 18}}
// 表示 age between 0 and 10
query = {age: {$between: [0, 10]}}
// 表示 name = "张三" or age = 18
query = {
  $or: {
    name: "张三",
    age: 18
  }
}
// 表示 name = "张三" and age = 18
query = {
  $and: {
    name: "张三",
    age: 18
  }
}
另一种or,and 和in
// 表示 (name = "张三") or (age = 18)
query = {
  $or: [
    {
      name: "张三"
    },
    {
      age: 18
    }
  ]
}
// 表示 (name = "张三") and (age = 18)
query = {
  $and: [
    {
      name: "张三"
    },
    {
      age: 18
    }
  ]
}
// 表示 name in ["张三"]
query = {
  name: ["张三"]
}

导航查询

以navigation开始的方法都是导航查询

使用导航查询需在TableConfig中配置好ParentConfig,例子:

假定表数据如下

table_user:

[
  {
    "id": 1,
    "name": "张三",
    "age": 10,
    "department_id": 1
  },
  {
    "id": 2,
    "name": "李四",
    "age": 12,
    "department_id": 2
  }
]

table_department

[
  {
    "id": 1,
    "name": "部门1"
  },
  {
    "id": 2,
    "name": "部门2"
  }
]

TableConfig配置如下

const UserConfig = new TableConfig('table_user', [
  'id',
  'name',
  'age',
  'department_id',
]);
UserConfig.parents.push({
  parentId: 'department_id',
  parentIdName: 'id',
  parentObject: 'department',
  parentTable: 'table_department'
})

导航查询可对于父表字段进行过滤,query如下:

// 表示 department.name = "部门1"
query = {
  department: {
    name: "部门1",
  }
}

事务

// 将方法传入DynamicQuery实例的tx方法中,方法中会获得transaction对象,然后将它传入需要在同一事务的方法中
await dynamicQuery.tx(async transaction => {
    const r = await dynamicQuery.save({name: 'zh', age: 13}, transaction);
    throw new Error("test")
    await dynamicQuery.remove([r.id], transaction);
    await dynamicQuery.find({}, pageResponse, transaction)
    console.log("pageResponse:")
    console.log(pageResponse)
})

switchSqlLog()

/**
 * 设置是否打印sql
 */
export function switchSqlLog(b: boolean);

PageResponse

export class PageResponse {
    /**
     * 分页查询所使用的类
     * totalElements 总条数
     * page 页码,从0开始
     * size 每页展示数据条数
     * content 具体数据的数组
     * totalPages 总页数
     * orderBy 根据什么字段排序,多字段会以','隔开
     * direction 正逆序,值为:'asc' | 'desc'
     */
    totalElements: number;
    page: number;
    size: number;
    content: any[];
    totalPages: number;
    orderBy: string;
    direction: Direction;

    constructor()

    /**
     * of方法可从req.query获取
     * PageRequest对象{page: number, size: number, orderBy: string, direction: Direction},
     * 并返回一个PageResponse对象
     */
    static of(req): PageResponse

    /**
     * 从req.query获取PageRequest对象
     */
    static getPageAndSize(req): PageRequest
}

TableConfig

export class TableConfig {
    /**
     * table 是设置表名
     * columnSet 是设置所有字段名
     * idName 是设置id字段名,默认为id
     * jsonColumn 是设置json格式的所有字段名
     * createTime 设置创建时间字段名,设置后,会自动添加创建时间
     * updateTime 设置更新时间字段名,设置后,会自动添加或更新更新时间
     * parents 用来配置父表相关信息,这些信息会在ParentConfig中说明,这些信息是用来导航查询用的
     */
    table: string;
    columnSet: string[];
    idName: string;
    jsonColumn: string[]
    createTime: string;
    updateTime: string;
    parents: ParentConfig[];

    constructor(table: string, columnSet: string[]);
}

ParentConfig

export type ParentConfig = {
    /**
     * parentId 设置表中的父表的id字段,也即外键字段
     * parentObject 设置导航查询中,父表数据所在字段
     * parentTable 设置父表表名
     * parentIdName 设置父表主键字段名
     */
    parentId: string;
    parentObject: string;
    parentTable: string;
    parentIdName: string;
}

DbClient,Postgresql,MySql

// Postgresql是DbClient具体实现
export class Postgresql extends DbClient {

}

// MySql是DbClient具体实现,构造方法,可以额外配置connectionLimit参数
export class MySql extends DbClient {
    constructor({host, port, database, user, password, connectionLimit})
}

export class DbClient {
    /**
     * host, port, database, user, password用来配置连接信息
     */
    host: string
    port: number
    database: string
    user: string
    password: string

    constructor({host, port, database, user, password})

    /**
     * 连接方法
     */
    connect(): Promise<any>
}
MIT License Copyright (c) 2022 nickzhang Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

简介

暂无描述 展开 收起
JavaScript 等 2 种语言
MIT
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
JavaScript
1
https://gitee.com/zhanghao161512/pg-dynamic-query.git
git@gitee.com:zhanghao161512/pg-dynamic-query.git
zhanghao161512
pg-dynamic-query
pg-dynamic-query
master

搜索帮助