ThinkJs 如何操作MSSQL数据库

ThinkJs(https://thinkjs.org/)是个非常不错的NodeJs的MVC开发框架,它本身提供了操作多种数据库的方法,但目前还不支持MSSQL数据库,而我在做开源项目CmPage(http://git.oschina.net/defans/cmpage)的时候,为了提高一点开发效率,觉得还是用熟悉一点的数据库较好,而且很多场景的数据处理用SQL语言的话可以很简练,因此问题就来了,在thinkjs中如何操作mssql 并且和 thinkjs 本身的数据库操作方法在一定程度上兼容呢?

网上查了一下,目前较好地用Promise方式来实现MSSQL连接的ORM框架是 Sequelize,虽然我没有用到ORM的特性,数据操作还是SQL语句拼接后用 query 方法执行,但难保以后不会改变主意,因此基本思路就有了: 从 think.base 继承类,然后加入 sequelize ,实现 think.model.base 的一些方法,如 add,update,where,find,select等等,为了可以链式调用,在 field 和 where 方法中返回自身(return this;),而为了实现子类中能够这样调用:this.model('t_emp').xxx,也实现了model方法,以上方法的实现逻辑很简单,就是定义一些成员变量表示SQL语句的各部分组成,比如:tableName,fields,_where,pk等;然后在相应方法中赋值后返回自身(this)。具体请参见代码: http://git.oschina.net/defans/cmpage/blob/master/src/cmpage/model/base.js?dir=0&filepath=src%2Fcmpage%2Fmodel%2Fbase.js&oid=10eba62a6f3ab3de95d3aeb8530a5fedc3ad518e&sha=10eb12139d697c1d4f25125e64966b029c2cf97e

如果以后 thinkjs 实现了mssql想换回来的话也很简单,把 page.js 改为从 think.model.base 继承就可以了。

还是在这里贴一下代码吧:

'use strict';
// +----------------------------------------------------------------------
// | CmPage [ 通用页面框架 ]
// +----------------------------------------------------------------------
// | Licensed under the Apache License, Version 2.0
// +----------------------------------------------------------------------
// | Author: defans 
// +----------------------------------------------------------------------

/**
 @module cmpage.model
 */

/**
 * 业务模块的基类,通过ORM框架 Sequelize 连接各个业务数据库
* 连接参数配置于各个module的配置文件中,xxxx/config/db.config
* 为了和thinkjs.model的常用方法名保持一致,以下实现了相关方法,通过转换成sql语句用 sequelize.query(sql) 执行
* 如果想使用 sequelize 的ORM方法,可以在子类中通过 this.sequelize.xxxx 来调用
* 子类中用think.model,或者cmpage.model来实例化其他类其他模块,本类中的 model 用于设置表名以便生成SQL语句,也为了兼容 thinkjs.model(表名).xxx 的调用方式
* 如果以后版本的 ThinkJS能支持mssql,以上兼容可以使得将 page.js 改回从 think.model.base 继承的时候不需要做太大改动
* @class cmpage.model.base */ import Sequelize from 'Sequelize'; export default class extends think.base { sequelize = null; _model = null; //thinkjs.model.base , 目前暂时不用 _field = ''; _where = ''; _tableName = ''; pk = 'id'; /** * constructor * @param {[type]} name [description] * @param {Object} config [description] * @return {[type]} [description] */ constructor(name, config = {}) { super(); if (think.isObject(name)) { config = name; name = ""; } this._tableName = name; this.config = think.parseConfig(config); //debug(this.config, 'base.constructor - this.config'); //debug(this.name, 'base.constructor - this.name'); } /** * 创建连接 * @return {[type]} [description] */ getConnection() { this.sequelize = new Sequelize( this.config.database, this.config.user, this.config.password, { host:this.config.host || "127.0.0.1", port:this.config.port || 3306, dialect: this.config.type || 'mysql', benchmark:true, logging:this.log, pool: { max: 5, min: 0, idle: 10000 } }); return this.sequelize; } log(msg){ cmpage.debug(msg,'SQL'); } setTableName(name){ this._tableName = name; return this; } model(name){ this.setTableName(name); // if(this.config.type != 'mssql' && (name.indexOf('t_') ===0 || name.indexOf('vw_') ===0 || name.indexOf('fw_') ===0) ){ // this._model = new think.model.base(name,this.config); // } return this; } setPk(pk){ this.pk = pk; if(this._model) this._model.pk = pk; return this; } field(fields){ this._field = fields; if(this._model) this._model.field(fields); return this; } where(where){ if(this._model){ this._model.where(where); return this; } this._where = ''; if(think.isObject(where)){ let arr = []; for(let p in where){ arr.push(p+'='+this.parseValue(where[p])); } if(arr.length >0) this._where = `where ${arr.join(' and ')}`; }else { this._where = 'where '+ where; } return this; } /** * 执行原生SQL语句,取结果集返回 * @return {array} 查询结果集 * @param {string} sql * @param {object} options 参数设置 */ async query(sql,options) { if(this._model){ return await this._model.query(sql); } if (!this.sequelize) { this.getConnection(); } let list = await this.sequelize.query(sql,options); if(list.length >0) return list[0]; return []; } async select(){ if(this._model){ return await this._model.select(); } let sql = `select ${think.isEmpty(this._field) ? '*': this._field} from ${this._tableName} ${this._where} `; return await this.query(sql); } async find(){ if(this._model){ return await this._model.find(); } let list = await this.select(); if(list.length >0) return list[0]; return {}; } async delete(){ //为了避免误操作,条件语句不能为空,当然,可以用 where 1=1 if(think.isEmpty(this._where)) return; if(this._model){ return await this._model.delete(); } let sql = `delete from ${this._tableName} ${this._where}`; let ret = await this.query(sql); //debug(ret,'base.delete - ret'); } async count(){ if(this._model){ return await this._model.count(); } let sql = `select count(*) as cnt from ${this._tableName} ${this._where}`; let list = await this.query(sql); return list[0]['cnt']; } async add(rec){ if(this._model){ return await this._model.add(rec); } let values = []; let _field = []; for(let key in rec){ if(/^c_\w+/.test(key) && key !=this.pk) { let val = rec[key]; val = this.parseValue(val); values.push(val); _field.push(key); } } let sql = `INSERT INTO ${this._tableName}( ${_field.join(',')} ) VALUES( ${values.join(',')} ); `; let list = await this.query(sql); list = await this.query('select @@IDENTITY as id;'); // debug(list); if(list.length >0){ return list[0]['id']; } return 0; } async update(rec){ if(this._model){ return await this._model.update(rec); } let _field = []; for (let key in rec) { if (/^c_\w+/.test(key) && key != this.pk) { let val = rec[key]; val = this.parseValue(val); _field.push(key + '=' + val); } } if(think.isEmpty(this._where)) this._where = ` where ${this.pk}=${rec[this.pk]}`; let sql = `UPDATE ${this._tableName} SET ${_field.join(',')} ${this._where}`; //debug(sql,'base.update - sql'); await this.query(sql); } parseValue(value){ if (think.isString(value)) { value = `'${value.replace(/\'/g,'\\\'')}'`; }else if(think.isArray(value)){ if (/^exp$/.test(value[0])) { value = value[1]; }else{ value = value.map(item => this.parseValue(item)); } }else if(think.isBoolean(value)){ value = value ? 'TRUE' : 'FALSE'; }else if (value === null) { value = 'null'; } return value; } }


你可能感兴趣的:(企业信息化框架)