该项目git地址:https://github.com/ht-sauce/dream-admin前端
惯例:我的的废话部分vue
我的是前端开发,可是公司有时候比较闲。因此就想着本身写点东西,老摸鱼,太没意思了,还有一个就是装逼和加薪。java
后端这块我比较早之前用过express,本身开发过简单的后端管理系统。node
最近一年多正式作了开发,一开始我先搭建了个人前端博客页面(如今想起来是单页面项目,并不完美,最好是用服务端渲染来开发的)。后面博客系统确定须要有后端因此,继续用nodejs是没错的。我不打算用java,或者go语言之类的。对于我这样的菜鸟,贪多嚼不烂。并且java是我见过最笨重的语言之一。java的开发很繁琐,历史包袱重。新手教程很是不友好。自学难度入门很难。进门以后又容易被不完美的教程带偏(缺这个少那个)。mysql
java主要缘由是由于早期没有一个包管理系统(目前的go语言等没有这个问题),致使了java在包管理上的混乱。致使新手不友好。react
总体项目我是模拟大项目的。git
项目目前分为四大块。程序员
博客系统(我的生活展现平台,记录平台)github
会员系统(负责登陆和权限的统一管理,将登陆和人员部分单独分离)算法
接口管理系统(就是一个接口记录平台)
后端管理平台
想法上很是美好,可是我目前为止后端才刚开始搞。前端基本页面差很少,可是没有后端的数据配合,写了总感受缺乏什么。虽然也能写啦,可是和后端不一样,前端我写了一年多。感受没有什么大挑战了。只是写的慢和快的问题,加上公司也不必定会有一些我设想中的东西。因此本身写后端,本身玩。(可是本身仍是很懒,三个月才这么点)。
express确定不会用了,因此后端我也就剩下koa框架了。(这块主要是参考招聘网站中经常使用的框架,并且结合市场去学习选型)
koa框架我官网看过,比express好不少。可是koa有种react的感受,什么都须要本身弄。express也是同样的。
后面在逛论坛(cnode社区)下,发现cnode基本放弃express使用koa,jest和eggjs框架。其中eggjs是最多的。而后也去官网看了看。
eggjs最大的优势是他是阿里的,它用于双十一了。还有eggjs帮初学者和新手继承了很是多的功能。就像vue脚手架,初始就给你把架子搭建好了。你再也不须要本身去作那些繁琐的事情,并且是业界大神帮你搭建的。
举例:
基础安全机制
日志系统
多进程负载
等……
其中多进程负载是我很看重的,由于这个新手老手都不必定能搞定。这是nodejs能利用多核cpu的关键。
推荐个人这个文章看看,很好的入门视频教程。下载不了的请留言。我找时间本身上传百度云看看。
https://juejin.im/post/5d6c872ae51d4561f64a0862
由于egg对后端的基础环境作了很是良好的集成。因此咱们再也不须要作繁琐的初始工做注重开发就好了。可是仍是须要作基础的选型。主要是数据库链接上。
我说句很差听的,为何后端程序员经常会被嘲讽为增删改查工程师。甚至是一些后端人员认为本身很牛逼(实际上只是会增删改查)。这不懂后端的你们不知道,懂了的会发现。后端入门以后基本上的事情就是链接数据库查询结果,插入数据,返回数据。就是这么简单会sql,甚至是部分代码只须要复制黏贴就好了。格式整齐划一。因此后端我认为主要牛逼在多年经验和算法。一个初级的后端程序员比前端简单,可是后端比前端工资高。为何呢?由于前端没了后端走不了业务,后端能够离开前端(简单的页面)。其实很是不公平,若是二者分开,初级前端比初级后端强。特别是当下的前端环境。
说了这么多,其实全部的一切在初级后端下,咱们只须要搞定框架和数据库链接插件就ok了。恩,还有写接口。
在数据库上面nodejs目前分为两大块,一个是mongdb和mysql。一个是nosql一个是关系型数据库。二者我都用过,可是在nosql上我表示本身不够熟练,还有就是在数据库建模方面总以为有问题因此我放弃了。
那么只有mysql了。
mysql的选择很少,主要是mysql官方插件和orm插件(sequelize)
比较方面:
egg-mysql:
就是传统的sql语句,主要缺点是开发人员容易发生数据库语句拼接,发生sql注入。
egg-sequelize
不少人说性能问题,这个能够忽略不计。最大问题在于非关系型语句操做。所有是封装好的对象编写方式。关键在于学习了sql语句以后还须要学习这个。可是不得不说,orm框架简化了一些sql的编写问题。
graphql:
很是不喜欢,文档少,并且繁琐。总感受目前而已意义不大。虽然很诱人的感受。
基础的数据库安装我就不教了。我用mysql8.X
数据库链接很简单,egg封装上都作好了。
先执行
npm install --save egg-sequelize mysql2复制代码
而后配置数据库链接
\dream-admin\config\plugin.js
'use strict';
/** @type Egg.EggPlugin */
module.exports = {
static: {
enable: true,
},
sequelize: {
enable: true,
package: 'egg-sequelize',
},
};复制代码
\dream-admin\config\plugin.js\config.default.js
/* eslint valid-jsdoc: "off" */
'use strict';
module.exports = appInfo => {
const config = exports = {
static: { prefix: '/dreamdht/' },
keys: appInfo.name + '_1568770372144_7988',
security: {
csrf: {
ignore: () => true,
},
},
};
config.sequelize = {
dialect: 'mysql', // support: mysql, mariadb, postgres, mssql
database: 'dream',
host: 'localhost',
port: 9906,
username: 'root',
password: '1111',
timezone: '+08:00',
// 时间格式转化
dialectOptions: {
dateStrings: true,
typeCast: true,
},
};
return config;
};复制代码
orm框架和传统数据库插件相比,多了模型的编写这一步。至关于数据库建表,建模。
egg框架全部业务模型都放在app\model文件下面
个人是这样的
拿出一个模型例子:userInfo
这里我不作多余延伸。由于这篇文章主要是记录数据库操做的问题。整篇文章涉及不少知识点。每一项都须要很大的精力去阅读文档。特别是没有后端基础那更加是看不了的。
'use strict';
module.exports = app => {
const { STRING, INTEGER, DATE, ENUM } = app.Sequelize;
const UserInfo = app.model.define('consumer-userInfos', {
userid: {
type: INTEGER,
primaryKey: true,
comment: 'user帐号表id',
},
nickname: {
type: STRING(30),
allowNull: false,
defaultValue: '',
comment: '昵称',
},
portrait: {
type: STRING(200),
comment: '用户头像',
},
sex: {
type: ENUM('男', '女'),
comment: '性别',
},
phone: {
type: STRING(15),
comment: '联系电话',
unique: true,
},
birthday: {
type: DATE,
comment: '生日',
},
provinceAndCity: {
type: STRING(30),
comment: '省市区域码',
},
address: {
type: STRING(100),
comment: '详细住址',
},
qq: {
type: STRING(100),
comment: 'qq或微信信息',
},
email: {
type: STRING(50),
comment: '邮箱地址',
unique: true,
},
}, { comment: '用户信息表,每一个用户惟一' });
return UserInfo;
};复制代码
这里同样说文章主要目的。
下面的语句包含两部分,一个是sql事务,还有一个是关于现代nodejs框架配合async\await如何处理错误。
await ctx.model.Consumer.UserInfo.create(data, { transaction });复制代码
错误的方式:
await ctx.model.Consumer.UserInfo.create(data, transaction );复制代码
eggjs在错误处理上和传统的后端很像了,主要是靠try\catch捕获错误。
而后我这里的逻辑调用在于我是控制层访问——服务层——访问——数据库
那么服务层其实就能捕获数据库错误了。可是在控制层我同样是用try\catch来捕获错误。那么你应该在我下面代码同样。用
// 返回错误信息
return Promise.reject(e);
// 或throw e;复制代码
来返回错误结果,保证控制层也正常的报错
直接上代码:
'use strict';
const Service = require('egg').Service;
class UserService extends Service {
async find() {
const { ctx, app } = this;
const sequelize = app.Sequelize;
const query = [[ sequelize.fn('COUNT', sequelize.col('id')), 'num' ]];
// console.log(result[0].dataValues.num);
return await ctx.model.Consumer.User.findAll({
attributes: query,
});
}
// 建立用户帐号和用户信息
async create(data) {
// 获取当前条目数加1做为主键id
const { ctx, app } = this;
const sequelize = app.Sequelize;
const query = [[ sequelize.fn('COUNT', sequelize.col('id')), 'num' ]];
const count = await ctx.model.Consumer.User.findAll({
attributes: query,
});
const id = count[0].dataValues.num + 1;
data.id = id;
data.userid = id;
let transaction;
try {
// 启用事务
transaction = await ctx.model.transaction();
// 建立帐号
await ctx.model.Consumer.UserInfo.create(data, { transaction });
await ctx.model.Consumer.User.create(data, { transaction });
// 提交事务
await transaction.commit();
return true;
} catch (e) {
// 错误事务回滚
await transaction.rollback();
// 返回错误信息
return Promise.reject(e);
}
}
}
module.exports = UserService;复制代码
文章主要三点:
Sequelize下面事务的使用。格式很标准。
// 启用事务
transaction = await ctx.model.transaction();
// 建立帐号
sql业务操做
//提交事务
transaction.commit();
当发生错误的时候进行回滚
await transaction.rollback();
而后是事务使用的时候注意事项。代码格式别错了。
还有就是mysql时区致使查询出来的结果时间格式不对
感谢eggjs团队开源框架
参考文章:
sequelize中文文档:https://demopark.github.io/sequelize-docs-Zh-CN/
参考博客:https://blog.csdn.net/awhlmcyn/article/details/79816494
参考博客:https://blog.csdn.net/clearlxj/article/details/94597734