npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

my-express-model

v1.1.6

Published

为 express 封装的 model 层。

Downloads

9

Readme

myExpressModel

1. 安装

    npm install --save my-express-model

2.使用:

在express项目的根目录下添加model文件夹,并添加一个所有数据表的父类,并在父类设置数据库配置。

通常做法是添加一个名为BaseModel.js文件,然后文件中声明一个类,代码如下

var Model = require("my-express-model");
var databaseConfig = require("../config/databaseConfig");
class BaseModel extends Model{
    constructor(){
        super(databaseConfig);
    }
    static instance: BaseModel ; // typescript 类静态属性,es6/7 无此语法。可以写成BaseModel.instacne
    static getInstance() {
        if (this.instance === undefined) {
            this.instance  = new this();
        }
        return this.instance;
    }
}
// 使用连接池长连接模式,创建持久复用的连接池
if(databaseConfig.connectType === "pool"){
    BaseModel.createPool(databaseConfig);
}

module.exports = BaseModel;

配置

在a步骤require进来的config文件里面配置数据库的端等参数:

 module.exports = {
	engin : "mysql",//开发中使用的数据库引擎,如果要更换数据库,修改配置即可(让然目前只提供mysql数据库)
	host : 'localhost',
	user : 'root',
	password : 'password',
	databaseName : 'databaseName',
    connectType : "pool" //连接类型,连接池最大请求数默认 为100个。需要自定义,可以通过limit 配置项修改
}

在models层下面建立Model类,继承BaseModel,设置fields和该Model在数据库中对应的table名称,例如:

var BaseModel = require("./BaseModel");
class CategoryModel  extends BaseModel{
    id : number
    name : string
    avatar : string
    static tableName: string = "FbUser"
    static fields: Object = {
        id: {
            type: 'integer',
            pk : true, // primary key 主键,当不设置任何条件的时候则按主键的值进行更新
            generated : true, // 自增字段,插入时跳过该字段
            validator: ['presence']
        },
        name: {
            type: 'string',
            validator: ['presence']
        },
        avatar: {
            type: 'string',
            validator: ['presence']
        }
    }
    constructor(options){
        super(options);
    }
};

module.exports = CategoryModel;

创建连接

在配置文件中,可以配置连接的方式:连接池和普通连接。

连接方式

1)连接池:长连接的方式。 connectType : "pool" //连接类型 2)普通连接:建议短连接的方式。 connectType : "connection" //连接类型。

创建连接-->连接池

在上述BaseModel 的例子中,统一创建了连接池。在后续的数据库操作的API中,会有限判断参数列表的connection 是否可用 如果不可用,并且pool 不为空,会自动创建。

if(databaseConfig.connectType === "pool"){
    BaseModel.createPool(databaseConfig);
}

创建连接-->短连接

遵循一次请求一个连接的方式:

import Model from xxxx;
(req,res) = >{
   let connection = Model.createConnection();
   try{
       await  connection.connect();
   }catch(e){}
   // Promise  的异步操作可以通过catch 来捕获,async await 只能通过try catch 来捕获 
  const insertOp = Model.getOperateObj("insert",connection);   
  //todo 
  connection.release();
}   

在controller中使用Model

获取操作数据库的对象 getOperateObj(type,connection?)

每个数据表类,继承Model之后,就继承了getOperateObj 的请求方法。 该方法提供了增删改查四个操作对象的获取。

参数 type

type 包括: 1)insert 增 2) update 改 3) delete 删 4) query 查

参数 connection

使用短连接的方式,需要传递connection 参数,使用连接池的方式,在connection 为空的时候,会使用连接池获取一个可用连接。

使用案例

1)使用连接池的方式: let insertOp = await Model.getOperateObj("insert"); 2)使用短简介方式

    let connection = Model.createConnection();
    await connection.connect();
    let insertOp = await Model.getOperateObj("insert",connection);
    connection.end();

添加记录

1.新增一条纪录:

1.1 save(connection?,callback?);

使用连接池的方式,不需要传递connection. save 返回值是一个Promise对象,也支持回调函数的方式调用。 当Model 对象执行save操作的时候,会判断是id属性是否为空或者该id在数据库是否已经存在。 满足两个否条件,则执行插入操作,否则执行更新操作

var CategoryModel = require("../../models/Category");
var categoryModel = new CategoryModel();
 categoryModel.set("id",0);
 categoryModel.set("name","JiangquanWu");
 categoryModel.set("time",new Date());
 categoryModel.save(function(err,result){
	 //to do
 }).then(({errmsg,result})=>{

 });

1.2 insertRecord(record,connection?);

使用连接池的方式,则不需要connection。否则需要传递connection.并且在响应用户请求之前结束连接。

var CategoryModel = require("../../models/Category");
CategoryModel.insertRecord({
    id : 0,
    name : "JiangquanWu",
    time : new Date()
})
.then(({errmsg,result})=>{

})

2. 通过insert对象批量新增 insertOp.batchInsert(records,callback?)

2.1 参数records

records 是要批量插入的对象

2.2 返回值

返回提供了Promise 和 回调函数两种方式。 callback(errmsg,result); resolve({errmsg,result});

2.3 调用案例

var insertOp = CategoryModel.getOperateObj("insert",connection);//连接池模式不需要connection 参数
insertOp.batchInsert(categories,function(err,result){
	 //to do
});

修改纪录:

1. 跟新增纪录一样,修改一条记录。

使用方式参考上面的save操作,区别在于,当前Model 的实例的主健是否为空。

2. 通过update对象根据条件更新 updateRecord(record,callback?)

2.1 参数records

records 需要更新的对象

2.2 返回值

返回提供了Promise 和 回调函数两种方式。 callback(errmsg,result); resolve({errmsg,result});

2.3 调用案例

//修改所有品类名称为“衣服”的时间
var categoryModel = new CategoryModel();
categoryModel.set("time",new Date());
var updateOp = CategoryModel.getOperateObj("update",connection?);//连接池的方式不需要传递conection
updateOp.equalTo("name","衣服");
updateOp.updateRecord(categoryModel,function(err,result){
	 //to do
});

3. 批量更新多条记录,batchUpdateById(records,callback?)

3.1 参数records

records 需要更新的对象

3.2 返回值

返回提供了Promise 和 回调函数两种方式。 callback(errmsg,result); resolve({errmsg,result});

3.3 调用案例

var categoryModel = new CategoryModel();
var updateOp = categoryModel.getOperateObj("update",connection?);//连接池的方式不需要传递conection
//@parameter categories 是一个categoryModel数组,所有categoryModel都必须有id属性;
updateOp.batchUpdateById(categories,function(err,result){
	//to do
});

查找:

1. 通过model对象简单的查找,Model.get(connection?,callback?);

1.1 参数connection

使用连接池的时候不需要传递这个参数,否则需要。

1.2 参数callback

回调函数,也可以使用Promise 的异步处理方式处理回调

1.3 案例

比如查找id等于1的品类:

CategoryModel.get("id=1",callback);
//CategoryModel.get(callback);则返回所有记录

2. 通过model对象获取所有的记录 getAll(connection?,callback?)

方法1如果只传入一个回调函数作为参数,也可以获取所有记录

2.1 参数connection

使用连接池的时候不需要传递这个参数,否则需要。

2.2 参数callback

回调函数,也可以使用Promise 的异步处理方式处理回调

2.3 案例

CategoryModel.getAll(callback);

3. 复杂的条件查询,Model.getOperateObj("query",connection?)

3.1 参数type

在前面介绍过getOperateObj的使用,查找类的type 为 “query”

3.2 参数connection

使用连接池的时候不需要传递这个参数,否则需要。

3.3 查询条件的设置

可以通过下面的条件设置罗列的API设置条件。 这个例子中使用了limit、skip、descending、notMoreThan 等API

3.4 案例

var queryObj = CategoryModel.getOperateObj("query");
queryObj.limit(pageSize);//分页;
queryObj.skip((pageNumber-1)*pageSize);//跳过前几条;
queryObj.descending("time");//根据时间降序;
queryObj.notMoreThan("time",time);//查找所有time时间点之前添加的品类
queryObj.find(callback);

4. 连接查询

通过model对象的 opSqlSetament 方法进行

var sql = "连接查询语句";
CategoryModel.opSqlSetament(sql,callback);

删除:

1. 通过model对象简单地根据id条件删除,Model.deleteByIds(id,connection?,callback?)

1.1 参数id

需要删除的ID

1.2 参数connection

使用连接池的时候不需要传递这个参数,否则需要。

1.3 参数callback

回调函数,也可以使用Promise 的异步处理方式处理回调

1.4 案例

CategoryModel.deleteByIds(1,callback);
//CategoryModel.deleteByIds([1,2,3,4,5,6,7,8],callback);

2. 通过delete对象执行复杂的条件判断删除,delete(connection?,callback?)

Model.getOperateObj("delete",conection?);

2.1 参数connection

使用连接池的时候不需要传递这个参数,否则需要。

2.2 参数callback

回调函数,也可以使用Promise 的异步处理方式处理回调

2.3 案例

var deleteOp = CategoryModel.getOperateObj("delete");
deleteOp.equalTo("name",'衣服');//更多的条件设置方法请看后面文档;
deleteOp.delete(cllback);

3. 通过delete对象 批量删除所有ID deleteInBatchByIds(ids,connection?,callback?)

3.1 参数ids

需要删除的ID

3.2 参数connection

使用连接池的时候不需要传递这个参数,否则需要。

3.3 参数callback

回调函数,也可以使用Promise 的异步处理方式处理回调

3.4 案例

var deleteOp = CategoryModel.getOperateObj("delete");
deleteOp.deleteInBatchByIds([1,2,3],callback);

条件设置

上面的删查改都可能要设置复杂的条件,通过model对象的getOperateObj方法获取的数据库操作对象可以执行的设置复杂条件的方法

说明:每个方法最后都有一个logic参数,是用来设置数据库语句中条件之间的与或逻辑的.如果是或,参数值设置"or"。如果是与,参数值为"and"。缺省值为and.

equalTo(fieldName,value,logic)

参数1.是字段名,参数2是 字段值。字段名等于某值

notEqualTo(fieldName,value,logic)

参数1.是字段名,参数2是 字段值。字段名不等于某值

lessThan(fieldName,value,logic)

参数1.是字段名,参数2是 字段值。字段名小于某值

moreThan(fieldName,value,logic)

参数1.是字段名,参数2是 字段值。字段名大于某值

notLessThan(fieldName,value,logic)

参数1.是字段名,参数2是 字段值。字段名大于等于某值

notMoreThan(fieldName,value,logic)

参数1.是字段名,参数2是 字段值。字段名小于等于某值

between(fieldName,startValue,endvalue,logic)

参数1是字段名,参数2和参数3是字段值的开区间(不包含开始值和结束值),

like(fieldName,charList)

模糊查询。参数1字段名,参数2.模糊值

likeStartAs(fieldName,charList)

以某值开头的模糊查询。参数1字段名,参数2.模糊值

likeEndWidth(fieldName,charList);

以某值结束的模糊查询。参数1字段名,参数2.模糊值

in(fieldName,valueArray,logic)

查找某只段在valueArray数组的所有记录.参数1字段名,参数2.字段的值数组

查找操作还有下面这些特殊的条件设置方法:

skip(count); 跳过前count条查询,参数count是跳过条数的数值

limit(count);

限制查询的条数, 参数count是查询条数的数值

ascending(fieldName);

查询结果根据某字段升序排列. 参数fieldName是字段名

descending(fieldName);

查询结果根据某字段降序排列。参数fieldName是字段名