引言
nodejs
开发框架有很多种,比如Express
,Koa
, Egg
,它们之间又有什么关系,关联呢?
可以这么说,Express
是爷爷,那Koa
就是儿子,而Egg
就是孙子,当然这里并不是说它们的能力,而是说它们的来历。
Koa
是一个新的web
框架,由Express
幕后的原班人马打造, 致力于成为web
应用和API
开发领域中的一个更小、更富有表现力、更健壮的基石。 通过利用async
函数,Koa
帮你丢弃回调函数,并有力地增强错误处理。Koa
并没有捆绑任何中间件, 而是提供了一套优雅的方法。
egg.js
是阿里旗下的一个基于nodejs
和koa2
的企业级应用框架,基于es6,es7 和nodejs,是『约定优先于配置』的一个Node.js
web
框架
Egg
奉行『约定优于配置』,按照一套统一的约定进行应用开发,团队内部采用这种方式可以减少开发人员的学习成本,开发人员不再是『钉子』,可以流动起来。没有约定的团队,沟通成本是非常高的,比如有人会按目录分栈而其他人按目录分功能,开发者认知不一致很容易犯错。但约定不等于扩展性差,相反Egg
有很高的扩展性,可以按照团队的约定定制框架。使用Loader
可以让框架根据不同环境定义默认配置,还可以覆盖Egg
的默认约定。
到这里大家应该都明白它们之间的关系了,但是它们之间又有什么区别呢?
一句话总结: koa
,express
,都是偏底层的无态度的Web框架;egg.js
是在koa
的基础上做了一层很好的面向大型企业级应用的框架封装, 中小型项目推荐egg.js
,上手快,概念易懂。
而这里,我们不需要关心那么多,直接用最原生的Express
框架+Sequelize
链接Mysql
数据库。
安装环境
本地数据库
小白推荐大家安装,phpstudy
,里面集成了Apache,Nginx,MySql,Ftp等
本地数据库管理工具,大家可以自行下载,有的可以忽略
链接:https://pan.baidu.com/s/15VSP0lgU7MXzqszWCFYXDQ
提取码:4hhz
支持链接数据库种类非常之多,免费、免费、免费。
(1)安装完成后,开始连接数据库
(2)双击打开连接后,右击连接名称,新建数据库
(3)库建好后,可以点击上面的新建表
(4)新建表时,点击添加字段,每个表都需要添加一个主键,可以默认勾选下面的自增
,这样没插入一条数据,就会自动增长,不需要人工干预
(4)时间自动,create_time
是每次插入都会记录插入的时间,update_time
是每次更新数据时都会记录更新时间。记住设置的区别。
ok,有了第一个表,开始撸码时间
Express搭建一个web服务
1、本地工程下面新建一个package.json
{
"name": "node-orm",
"version": "1.0.0",
"description": "",
"author": "javan(www.javanx.cn)",
"private": true,
"scripts": {
"dev": "cross-env NODE_ENV=development nodemon index.js --watch ./",
"start": "cross-env NODE_ENV=production node index.js"
}
}
2、安装插件
npm install express sequelize mysql2 cross-env --save
npm install nodemon --save-dev
3、根目录新建index.js
const express = require('express')
const app = express()
// 定义端口8111
app.listen('8111', function () {
console.log("The server is running at *: 8111");
});
4、启动服务
npm run dev
打印"The server is running at *: 8111
服务已经启动,打开浏览器,输入http://localhost:8111/
服务正常,接下来连接数据
Sequelize连接数据库
1、更目录新建config
目录,存放项目的一些配置js,然后新建config/db.js
/**
* mysql 数据库配置
*/
// 生成环境
let sqlConfig = {
host: 'localhost',
user: 'root',
password: 'root',
database: 'test',
port: 3306
}
// 本地环境
// process.env.NODE_ENV 取决于package.json里面的配置
if(process.env.NODE_ENV !== 'production'){
sqlConfig = {
host: 'localhost',
user: 'root',
password: 'root',
database: 'test',
port: 3306
};
}
module.exports = sqlConfig
2、更目录新建db
目录,存放数据库model
以及sequelize
配置
此时项目目录
3、db/sequelize.js
配置
var Sequelize = require('sequelize')
// 导入数据库配置
var db = require('../config/db')
var sequelize = new Sequelize(db.database, db.user, db.password, {
logging: function(sql) {
// logger为log4js的Logger实例
if(process.env.NODE_ENV !== 'production'){
console.log(sql)
}
},
port:db.port,
host: db.host,
dialect: 'mysql',
dialectOptions: {
dateStrings: true,
typeCast: true
},
pool: {
max: 20,
min: 1,
acquire: 60000,
idle: 10000
},
timezone: '+08:00' //东八时区
});
exports.sequelize = sequelize;
exports.defineModel = function (name, attributes) {
var attrs = {};
for (let key in attributes) {
let value = attributes[key];
if (typeof value === 'object' && value['type']) {
value.allowNull = value.allowNull || false;
attrs[key] = value;
} else {
attrs[key] = {
type: value,
// allowNull: false
};
}
}
attrs.version = {
type: Sequelize.BIGINT,
// allowNull: false
};
attrs.createUser = {
type: Sequelize.STRING,
allowNull: false
};
attrs.updateUser = {
type: Sequelize.STRING,
allowNull: false
};
return sequelize.define(name, attrs, {
tableName: name,
timestamps: true,
paranoid: true,
charset: 'utf8mb4',
collate: 'utf8mb4_general_ci',
hooks: {
beforeBulkCreate: function(obj){
obj.version = 0 ;
},
beforeValidate: function(obj){
if(obj.isNewRecord){
console.log('first');
obj.version = 0 ;
}else{
console.log('not first');
obj.version = obj.version + 1 ;
}
}
}
});
};
4、db/model/user.js
配置,这里的字段和数据库对应起来
/**
* 用户
*/
var Sequelize = require('sequelize');
var {sequelize} = require('../sequelize.js');
var user = sequelize.define('user',{
id: {
type: Sequelize.BIGINT(20),
primaryKey: true,
allowNull: false,
unique: true,
autoIncrement: true
},
name: Sequelize.STRING(255), // 名字
age: Sequelize.BIGINT(11), // 年龄
sex: Sequelize.BIGINT(1), // 性别
create_time: Sequelize.DATE,
update_time: Sequelize.DATE
},{
timestamps: false, // 不要默认时间戳 数据库没有时间戳字段时,设置为false,否则报错 SequelizeDatabaseError: Unknown column 'createdAt' in 'field list'
freezeTableName: true
});
module.exports = user;
Sequelize数据类型与数据库类型对应关系
Sequelize.STRING // VARCHAR(255)
Sequelize.STRING(1234) // VARCHAR(1234)
Sequelize.STRING.BINARY // VARCHAR BINARY
Sequelize.TEXT // TEXT
Sequelize.TEXT('tiny') // TINYTEXT
Sequelize.INTEGER // INTEGER
Sequelize.BIGINT // BIGINT
Sequelize.BIGINT(11) // BIGINT(11)
Sequelize.FLOAT // FLOAT
Sequelize.FLOAT(11) // FLOAT(11)
Sequelize.FLOAT(11, 12) // FLOAT(11,12)
Sequelize.REAL // REAL 仅限于PostgreSQL.
Sequelize.REAL(11) // REAL(11) 仅限于PostgreSQL.
Sequelize.REAL(11, 12) // REAL(11,12) 仅限于PostgreSQL.
Sequelize.DOUBLE // DOUBLE
Sequelize.DOUBLE(11) // DOUBLE(11)
Sequelize.DOUBLE(11, 12) // DOUBLE(11,12)
Sequelize.DECIMAL // DECIMAL
Sequelize.DECIMAL(10, 2) // DECIMAL(10,2)
Sequelize.DATE // DATETIME 针对 mysql / sqlite, TIMESTAMP WITH TIME ZONE 针对 postgres
Sequelize.DATE(6) // DATETIME(6) 针对 mysql 5.6.4+. 小数秒支持多达6位精度
Sequelize.DATEONLY // DATE 不带时间.
Sequelize.BOOLEAN // TINYINT(1)
Sequelize.ENUM('value 1', 'value 2') // 一个允许具有 “value 1” 和 “value 2” 的 ENUM
Sequelize.ARRAY(Sequelize.TEXT) // 定义一个数组。 仅限于 PostgreSQL。
Sequelize.ARRAY(Sequelize.ENUM) // 定义一个 ENUM 数组. 仅限于 PostgreSQL。
Sequelize.JSON // JSON 列. 仅限于 PostgreSQL, SQLite and MySQL.
Sequelize.UUID // PostgreSQL 和 SQLite 的 UUID 数据类型, CHAR(36) BINARY 针对于 MySQL (使用默认值: Sequelize.UUIDV1 或 Sequelize.UUIDV4 来让 sequelize 自动生成 ID)
Sequelize.GEOMETRY // 空间列. 仅限于 PostgreSQL (具有 PostGIS) 或 MySQL.
Sequelize.GEOMETRY('POINT') // 具有几何类型的空间列. 仅限于 PostgreSQL (具有 PostGIS) 或 MySQL.
Sequelize.GEOMETRY('POINT', 4326) // 具有几何类型和SRID的空间列. 仅限于 PostgreSQL (具有 PostGIS) 或 MySQL.
5、测试连接
index.js导入db/model/user.js
测试一波
...
const user = require('./db/model/user')
user.findAll().then(data=>{
console.log(data)
})
...
打印执行的sql,和结果,由于我们新建数据库没有插入数据,此时打印的是一个空数组[]
我们去数据库新建一条数据,大家看好我们只填入姓名、性别和年龄,id和时间都会自动插入
在查询一次,直接修改index.js,保存程序自动热更新
数据查询回来了,本节就到此结束了,希望大家都有所收获。