月盾的博客

sequelize定义实体对象

月盾

sequelize定义实体对象

var sequelize = require("../utils/sequelizeDB");//连接数据库 var Sequelize = require("sequelize"); var User = sequelize.define("User", {  
user_id:{ type: Sequelize.STRING, primaryKey: true},  
name: Sequelize.STRING,  
phone: Sequelize.STRING,  
create_date: Sequelize.DATE,  
update_date: Sequelize.DATE  
}, {  
freezeTableName: true, // 默认false修改表名为复数,true不修改表名,与数据库表名同步  
tableName: "user",  
timestamps: false  
});

define函数的第一个参数’User’就是定义一个实体对象,名称不必与数据库表名一致,只是为了确定该对象没有重复 { type: Sequelize.STRING, primaryKey: true}将属性作为主键 freezeTableName禁用修改表名;默认情况下,sequelize会自动将模型名称(第一个参数定义‘User’)为复数。值为ture时不修改 tableName数据库表名 timestamps是否自动添加时间戳createAt,updateAt

mysql一个字段为空时使用另一个字段排序

月盾

表中有两个日期字段createDate,updateDate。其中updateDate可以为空,要求使用updateDate排序,如果updateDate为空则使用createDate排序,结果要顺序排下来。

按照常规方法:

select * from table order by updateDate desc;

这样的结果是为空的数据排在了最下面,不符合要求。

这样试试:

select * from table order by updateDate desc, createDate desc;

这样排的结果是先按updateDate排序,updateDate为空的排在最下面,然后按createDate排序,这样也不符合要求。

正确方法:

select * from table order by IFNULL(updateDate, createDate) desc;

这种排序的结果是正确的,用ifnull函数判断updateDate如果为空的话就使用createDate排。

2015年计划

月盾

去年底换了工作就没时间更新博客了,新公司中叶使用了新技术,不过自身也欠缺太多,html,css只知皮毛,需要加强学习。bootstrap也是一个快速开发的css框架,但还是要把基础的css学会了才能更快的掌握。公司打算把app从原生转型到html5开发,那么HTML5也是必学的,然后还有angularjs感觉也不错,怎么能不会!

node.js作为微信接口服务器

月盾

前端时间用node改写了下去年用Java练习时写的微信接口,可能是因为微信接口看的多了更加熟悉了,也可能是node开发更快速,反正不到一小时就搞定了微信token的验证,放到博客项目中,新增了一个URL请求,在微信公众平台上测试了下,没想到调试两三次就通过了,想当初用Java测试时各种问题不断。想起来可惜的是去年Java版的微信接口做的自定义菜单,自动回复等功能,由于BAE收费的缘故就废掉了。

/**  
 * Created by huopanpan on 2014/10/10.  
 */  
var crypto = require("crypto");  
/**  
 * 验证token  
 * @param req  
 * @param res  
 */  
function validateToken(req, res) {  
    var query = req.query;  
    var signature = query.signature;//微信服务器加密字符串  
    var echostr = query.echostr;//随机字符串  
    var timestamp = query["timestamp"];//时间戳  
    var nonce = query.nonce;//nonce  
    var oriArray = new Array();  
    oriArray[0] = nonce;  
    oriArray[1] = timestamp;  
    oriArray[2] = "hale";//token  
    oriArray.sort();  
    var original = oriArray[0]+oriArray[1]+oriArray[2];  
    console.log("Original Str:"+original);  
    console.log("signature:"+signature);  
    var scyptoString = sha1(original);//将三个参数拼接加密字符串,并与服务器发送的字符串对比  
    if (signature == scyptoString) {  
        res.send(echostr);  
    }  
    else {  
        res.send("Bad Token!");  
    }  
}

/**  
 * sha1加密  
 * @param str  
 * @returns {*}  
 */  
function sha1(str) {  
    var md5sum = crypto.createHash("sha1");  
    md5sum.update(str);  
    str = md5sum.digest("hex");  
    return str;  
}  
/**  
 * 重新获取access_token  
 * @type {validateToken}  
 */  
function getAccessToken(){  
    var appid = "";  
    var appsecret = "";  
    var url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=fdgf&secret=dfdsgfrf";

}  
exports.validateToken = validateToken;

mongodb启动服务失败的解决办法之一

月盾

在执行下面第一行启动mongodb服务的时候,命令行一闪而过,具体看了下输出内容看不出端倪来,不过解决办法却是有的,就是直接删除掉D:\Data\db下面的mongod.lock文件可以了

C:\Program Files\MongoDB 2.6 Standard\bin>mongod –dbpath=D:\Data\db
2014-11-16T11:35:43.244+0800
2014-11-16T11:35:43.252+0800 warning: 32-bit servers don"t have journaling enabl
ed by default. Please use –journal if you want durability.
2014-11-16T11:35:43.253+0800
2014-11-16T11:35:43.282+0800 [initandlisten] MongoDB starting : pid=8272 port=27
017 dbpath=D:\Data\db 32-bit host=hp
2014-11-16T11:35:43.283+0800 [initandlisten]
2014-11-16T11:35:43.284+0800 [initandlisten] ** NOTE: This is a 32 bit MongoDB b
inary.
2014-11-16T11:35:43.284+0800 [initandlisten] ** 32 bit builds are limited
to less than 2GB of data (or less with –journal).
2014-11-16T11:35:43.284+0800 [initandlisten] ** Note that journaling defau
lts to off for 32 bit and is currently off.
2014-11-16T11:35:43.285+0800 [initandlisten] ** See http://dochub.mongodb.
org/core/32bit
2014-11-16T11:35:43.286+0800 [initandlisten]
2014-11-16T11:35:43.286+0800 [initandlisten] targetMinOS: Windows XP SP3
2014-11-16T11:35:43.286+0800 [initandlisten] db version v2.6.4
2014-11-16T11:35:43.287+0800 [initandlisten] git version: 3a830be0eb92d772aa855e
bb711ac91d658ee910
2014-11-16T11:35:43.287+0800 [initandlisten] build info: windows sys.getwindowsv
ersion(major=6, minor=1, build=7601, platform=2, service_pack=“Service Pack 1”)
BOOST_LIB_VERSION=1_49
2014-11-16T11:35:43.290+0800 [initandlisten] allocator: system
2014-11-16T11:35:43.292+0800 [initandlisten] options: { storage: { dbPath: “D:\D
ata\db” } }
**************
Unclean shutdown detected.
Please visit http://dochub.mongodb.org/core/repair for recovery instructions.
*************
2014-11-16T11:35:43.360+0800 [initandlisten] exception in initAndListen: 12596 o
ld lock file, terminating
2014-11-16T11:35:43.362+0800 [initandlisten] dbexit:
2014-11-16T11:35:43.364+0800 [initandlisten] shutdown: going to close listening
sockets…
2014-11-16T11:35:43.365+0800 [initandlisten] shutdown: going to flush diaglog…

搞懂了七牛文件存储

月盾
由于工作没时间,博客搭建起来以后一直没有添加文件上传功能,瞬间感觉不完美了。这两天外包项目结束,要出项目组,在交接工作之余,用中午休息时间写好了文件上传功能,具体是图片上传。在本地测试好发布到BAE上,居然没法上传了,初步推断应该是服务器没有写权限,原来一直想试试百度云存储来做图片存储,但是翻看了文档发现暂不支持node.js上传,只能先上传好再引用链接,感觉好麻烦。

由于一直在node中文社区混,发现用的是七牛存储,也想跟着大牛的步伐去试试,对开发文档进行两轮战斗,愣是没看懂,今天没事干,就从头到尾认认真真看了一遍,动手写了个测试程序,可以上传,激动万分,真想分享出来,但是测试程序还不完善,还没有把回调搞定,也没有完整的例子拿出来给大家看,等完全搞定了以后再写个教程卖弄一下。

oracle decode和nvl的用法

月盾

Oracle 中 decode 函数用法

含义解释: decode(条件,值1,返回值1,值2,返回值2,…值n,返回值n,缺省值)

该函数的含义如下:

IF 条件=值1 THEN
    RETURN(翻译值1)
ELSIF 条件=值2 THEN
    RETURN(翻译值2)
    ......
ELSIF 条件=值n THEN
    RETURN(翻译值n)
ELSE
    RETURN(缺省值)
END IF

decode(字段或字段的运算,值1,值2,值3)

这个函数运行的结果是,当字段或字段的运算的值等于值1时,该函数返回值2,否则返回值3 当然值1,值2,值3也可以是表达式,这个函数使得某些sql语句简单了许多

使用方法: 1、比较大小 select decode(sign(变量1-变量2),-1,变量1,变量2) from dual; --取较小值 sign()函数根据某个值是0、正数还是负数,分别返回0、1、-1 例如: 变量1=10,变量2=20 则sign(变量1-变量2)返回-1,decode解码结果为“变量1”,达到了取较小值的目的。

2、此函数用在SQL语句中,功能介绍如下:

Decode函数与一系列嵌套的 IF-THEN-ELSE语句相似。base_exp与compare1,compare2等等依次进行比较。如果base_exp和 第i 个compare项匹配,就返回第i 个对应的value 。如果base_exp与任何的compare值都不匹配,则返回default。每个compare值顺次求值,如果发现一个匹配,则剩下的compare值(如果还有的话)就都不再求值。一个为NULL的base_exp被认为和NULL compare值等价。如果需要的话,每一个compare值都被转换成和第一个compare 值相同的数据类型,这个数据类型也是返回值的类型。

Decode函数在实际开发中非常的有用

结合Lpad函数,如何使主键的值自动加1并在前面补0 select LPAD(decode(count(记录编号),0,1,max(to_number(记录编号)+1)),14,'0') 记录编号 from tetdmis

eg:

select decode(dir,1,0,1) from a1_interval

dir 的值是1变为0,是0则变为1

比如我要查询某班男生和女生的数量分别是多少?

通常我们这么写:

select count(*) from 表 where 性别 = 男;

select count(*) from 表 where 性别 = 女;

要想显示到一起还要union一下,太麻烦了

考虑学习前端开发

月盾

从开始学习nodejs就关注了前端方面的技术,主要就是HTML,css,现在还真有想法深入学习一下。以前一直从事着后端开发,到现在已有三年,但是感觉自己遇到了一下瓶颈,虽然在工作中没什么难倒的技术问题,但是做着重复的工作实在是没有提升。之前的公司没有值的学习的东西,现在的公司有东西可以学习,但是作为外包可能不会待太长时间,就现在来说,也没有做过核心的东西,所以感觉自己这样下去没有什么竞争力,于是决定从宽度上拓展,下决心学习了nodejs,当初为了学习不知不觉就建立了这个博客,由于没有前端功底,就照搬了一个模板,想要修改点样式却发现很吃力,再看看nodejs,就像是给前端开发的服务端语言,而我却不懂前端,就算学习了好像也派不上用场,好尴尬的存在啊,没办法,还是该学习一下前端知识,至少要能够轻松的修改一个已有的页面吧,要纯粹的搞设计估计还要重新来过,又要花个三五年时间,还是划不来,不过应该主攻后端,兼顾前端,前后通吃。那么我想就从HTML5,CSS3开始吧。

对于这些发点牢骚的内容就想在新浪博客上有个备份,复制一遍感觉好麻烦,新浪博客提供了对外接口,周末的时候看能不能对接一下

Nodejs核心常用工具

月盾

内容摘自《nodejs开发指南》

util 是一个 Node.js 核心模块,提供常用函数的集合,用于弥补核心 JavaScript 的功能
过于精简的不足。
util.inherits
util.inherits(constructor, superConstructor)是一个实现对象间原型继承
的函数。JavaScript 的面向对象特性是基于原型的,与常见的基于类的不同。JavaScript 没有
提供对象继承的语言级别特性, 而是通过原型复制来实现的, 具体细节我们在附录A中讨论,
在这里我们只介绍 util.inherits 的用法,示例如下:

var util = require("util");   
  
function Base() {   
  this.name = "base";   
  this.base = 1991;   
  
  this.sayHello = function() {   
    console.log("Hello " + this.name);   
  };   
}   
  
Base.prototype.showName = function() {   
  console.log(this.name);   
  
};   
  
function Sub() {   
  this.name = "sub";   
}   
  
util.inherits(Sub, Base);   
  
var objBase = new Base();   
objBase.showName();   
objBase.sayHello();   
console.log(objBase);   
  
var objSub = new Sub();   
objSub.showName();   
//objSub.sayHello();   
console.log(objSub);  

我们定义了一个基础对象 Base 和一个继承自 Base 的 Sub,Base 有三个在构造函数
内定义的属性和一个原型中定义的函数,通过 util.inherits 实现继承。运行结果如下:

base   
Hello base   
{ name: "base", base: 1991, sayHello: [Function] }   
sub   
{ name: "sub" } 

注意,Sub 仅仅继承了 Base 在原型中定义的函数,而构造函数内部创造的 base 属
性和 sayHello 函数都没有被 Sub 继承。同时,在原型中定义的属性不会被 console.log 作
为对象的属性输出。如果我们去掉 objSub.sayHello(); 这行的注释,将会看到:

BAE上连接mongodb每隔十多小时就不能连接的问题(二)

月盾

前段时间写了《BAE上连接mongodb每隔十多小时就不能连接的问题(一)》之后暂时的解决了连不上的问题,每隔十小时重启一次,但是这个方法却没有彻底解决问题,偶尔还会出现三四小时就连不上,实在搞不懂问题到底出在哪,到底是bae的mongodb的问题还是mongoose中间件的问题,现象是有做open操作,但是却没有open事件发出,那么我想是不是mongoose存在bug,翻看了源码也没看出来个所以然,不过大概是觉得要重新打开需要保证连接已经关闭的,那么干脆在监听到error事件时就将状态直接改为disconnected,反正是要调用db.close()方法进行关闭连接的,可能close()方法不好使,没有完全关闭,如果我手动将状态设为disconnected,close方法中也会判断是否是这个状态,如果是就直接返回,省的多走其他步骤了。不过这样一来就不会有close事件发出了,根据我所写代码的逻辑,那就不会调用open()方法了,但实际情况确实程序可以正常运行,说明已经重连上了,原来在代码中添加了这个属性:

Js代码 :

var opts = { 
db: { 
  native_parser: true  
}, 
server: { 
  poolSize:4, 
  auto_reconnect: true  
}, 
user: username, 
  pass: password 
};

上面的红色字体,只能说是可能这个参数起作用了。

不过由此看来,auto_reconect这个参数要起作用必须是在连接断开的情况下,说明close()方法有时候并没有完全断开连接。