[关闭]
@2890594972 2018-04-21T02:59:25.000000Z 字数 8862 阅读 1080

koa2+mysql demo

demo


koa2脚手架搭建

初始化项目

创建项目安装依赖 mkdir koa2&&cd koa2&&npm init -y&& npm install koa --save

主页 touch app.js

  1. const Koa = require('koa')
  2. const app = new Koa()
  3. app.use(ctx => {
  4. ctx.body = `您的网址路径为:${ctx.request.url}`
  5. })
  6. app.listen(3000)
  7. console.log(`koa2 已启动 , 端口 : 3000`)

启动:node app.js -->访问 http://localhost:3000/hhhhh

es6

依赖 npm install babel-core babel-polyfill babel-register babel-preset-env --save-dev
配置 touch .babelrc

  1. {
  2. "presets": ["env"]
  3. }

touch server.js

  1. require('babel-register');
  2. require('babel-polyfill');
  3. require('./app.js');

启动:node server.js -->访问 http://localhost:3000/hhhhh

nodemon自动重启node服务

依赖 npm install nodemon -g
启动:nodemon server.js -->访问 http://localhost:3000/hhhhh

修改package.json

  1. "scripts": {
  2. "start": "nodemon server.js"
  3. }

启动:npm start

 忽略文件

touch .gitignore

  1. node_modules/
日志

npm install --save koa-logger koa-convert

  1. const koaLogger = require('koa-logger')
  2. const convert = require('koa-convert')
  3. app.use(convert(koaLogger()))

2.路由与Controller

项目结构 mkdir controller&&touch controller/user.js controller/hello.js router.js
依赖 npm install koa-router koa-bodyparser --save
改造app.js

  1. const Koa = require('koa')
  2. const Router = require('koa-router')
  3. const bodyParser = require('koa-bodyparser')
  4. const app = new Koa()
  5. const koaLogger = require('koa-logger')
  6. const convert = require('koa-convert')
  7. const router = new Router()
  8. app.use(convert(koaLogger()))
  9. // app.use(ctx => {
  10. // ctx.body = `网址路径为:${ctx.request.url}`
  11. // })
  12. app.use(bodyParser())
  13. router.get('/', ctx => {
  14. ctx.body = `这是主页`
  15. })
  16. router.get('/user', ctx => {
  17. ctx.body = `这是user页`
  18. })
  19. router.get('/post', ctx => {
  20. ctx.body = ctx.request.body
  21. })
  22. router.get('/async', async ctx => {
  23. const sleep = async (ms) => {
  24. return new Promise(resolve => {
  25. setTimeout(() => {
  26. resolve(true)
  27. }, ms)
  28. })
  29. }
  30. await sleep(1000)
  31. ctx.body = `这是异步处理页`
  32. })
  33. app.use(router.routes())
  34. .use(router.allowedMethods())
  35. app.listen(3000)
  36. console.log(`koa2 已启动 , 端口 : 3000`)
  37. module.exports = app;

重启应用-->访问 /, /user,/async

分离路由文件

// index.js

  1. const Koa = require('koa')
  2. const app = new Koa()
  3. const router = require('./router')
  4. const bodyParser = require('koa-bodyparser')
  5. app.use(bodyParser())
  6. app.use(router.routes())
  7. .use(router.allowedMethods())
  8. app.listen(3000, (err) => { if (err) { console.error(err); } else { console.log(`koa2 已启动 , 端口 : 3000`); } });

// router.js

  1. const Router = require('koa-router')
  2. const router = new Router()
  3. const user = require('./controller/user')
  4. const hello = require('./controller/hello');
  5. router.post('/user/login', user.login)
  6. router.get('/user/profile', user.profile)
  7. router.use('/hello', hello.routes(), hello.allowedMethods());
  8. module.exports = router

// controller/user.js

  1. const sleep = async (ms) => {
  2. return new Promise(resolve => {
  3. setTimeout(() => {
  4. resolve(true)
  5. }, ms)
  6. })
  7. }
  8. module.exports = {
  9. login (ctx) {
  10. ctx.body = {
  11. username: ctx.request.body.username
  12. }
  13. },
  14. async profile (ctx) {
  15. await sleep(1000)
  16. ctx.body = {
  17. username: '相学长',
  18. sex: 'man',
  19. age: '999'
  20. }
  21. }
  22. }

controller/hello.js

  1. var router = require('koa-router')();
  2. //const router = Router({ prefix: '/hello'})
  3. router.get('/', async function(ctx, next) {
  4. ctx.state = {
  5. title: 'abc '
  6. };
  7. ctx.response.body = `<h1>hello world!</h1>`;
  8. })
  9. router.get('/:name', async function(ctx, next) {
  10. let name = ctx.params.name;
  11. ctx.state = {
  12. title: 'abc '
  13. };
  14. console.log(ctx.render.path);
  15. await ctx.render('index', { hello: `abc ${name}` });
  16. })
  17. module.exports = router;

访问:/user/login /user/profile /hello /hello/page

动态注册 路由文件

router.js

  1. const Router = require('koa-router')
  2. const router = new Router()
  3. const user = require('./controller/user')
  4. // const hello = require('./controller/hello');
  5. router.post('/user/login', user.login)
  6. router.get('/user/profile', user.profile)
  7. // router.use('/hello', hello.routes(), hello.allowedMethods());
  8. const fs = require('fs');
  9. let addControllers = (router, dir) => {
  10. dir = dir || 'controller';
  11. fs.readdirSync(__dirname + '/' + dir).filter((f) => {
  12. return f.endsWith('.js');
  13. }).forEach((f) => {
  14. const model = require(__dirname + '/' + dir + '/' + f);
  15. if (model.constructor == Router) {
  16. // constructor 更加精确地指向对象所属的类,而对 instanceof 而言,即使是父类也会返回true
  17. const modelStr = f.replace(/.js/, '');
  18. router.use(`/${modelStr}`, model.routes(), model.allowedMethods());
  19. }
  20. })
  21. }
  22. addControllers(router);
  23. module.exports = router
路由使用中间件

编辑中间件 mkdir middleware&&touch middleware/articles.js

  1. module.exports = {
  2. async edit(ctx, next) {
  3. const locals = {
  4. title: '编辑',
  5. nav: 'article'
  6. }
  7. await ctx.render('articles/edit', locals)
  8. },
  9. async checkLogin(ctx, next) {
  10. if(!ctx.state.isUserSignIn){
  11. ctx.status = 302
  12. ctx.redirect('/')
  13. return
  14. }
  15. await next()
  16. }
  17. }

在路由中使用中间件

  1. const articles = require('./middleware/articles')
  2. router.get('/:id/edit', articles.checkLogin, articles.edit)
模板解析器

依赖 npm i -S ejs koa-views
app.js

  1. const views = require('koa-views');
  2. app.use(views(__dirname + '/views', { extension: 'html',map: { html: 'ejs' }}));

mkdir views&&touch views/index.html

  1. <h1><%= hello %></h1>

访问 /hello/美女

静态资源

npm install koa-static --save-dev

  1. const koaStatic = require('koa-static')
  2. const path= require("path")
  3. app.use(koaStatic(
  4. path.join( __dirname, './static')
  5. ))

cookie、session

  1. cookie
  1. router.get('/cookie', async function(ctx, next) {
  2. ctx.cookies.set("demo", "demoValue", {
  3. name: 'abc',
  4. age: '20',
  5. token: 'xyz'
  6. })
  7. console.log(ctx.cookies.get("demo"));
  8. ctx.response.body = `cookie`;
  9. })
  1. session
    npm install koa-session-minimal koa-mysql-session --save-dev
    app.js
  1. const session = require('koa-session-minimal')
  2. const MysqlSession = require('koa-mysql-session')
  3. // 配置存储session信息的mysql
  4. let store = new MysqlSession({
  5. user: 'root',
  6. password: 'abc123',
  7. database: 'koa_demo',
  8. host: '127.0.0.1'
  9. })
  10. // 存放sessionId的cookie配置
  11. let cookie = {
  12. maxAge: '', // cookie有效时长
  13. expires: '', // cookie失效时间
  14. path: '', // 写cookie所在的路径
  15. domain: '', // 写cookie所在的域名
  16. httpOnly: '', // 是否只用于http请求中获取
  17. overwrite: '', // 是否允许重写
  18. secure: '',
  19. sameSite: '',
  20. signed: ''
  21. }
  22. // 使用session中间件
  23. app.use(session({
  24. key: 'SESSION_ID',
  25. store: store,
  26. cookie: cookie
  27. }))

hello.js

  1. router.get('/session', async function(ctx, next) {
  2. // 读取session信息
  3. ctx.session.count = ctx.session.count + 1
  4. ctx.response.body = ctx.session;
  5. })
  6. router.get('/session/set', async function(ctx, next) {
  7. ctx.session = {
  8. user_id: Math.random().toString(36).substr(2),
  9. count: 0
  10. }
  11. ctx.response.body = ctx.session;
  12. })

mysql

npm install --save mysql
mkdir db&&touch db/mysqlUtil.js db/mysqlUser.js

mysqlUtil.js

  1. const mysql = require('mysql')
  2. const pool = mysql.createPool({
  3. user: 'root',
  4. password: 'root',
  5. database: 'demo2',
  6. host: '127.0.0.1'
  7. })
  8. let query = function(sql, values) {
  9. return new Promise((resolve, reject) => {
  10. pool.getConnection(function(err, connection) {
  11. if (err) {
  12. reject(err)
  13. } else {
  14. connection.query(sql, values, (err, rows) => {
  15. if (err) {
  16. reject(err)
  17. } else {
  18. resolve(rows)
  19. }
  20. connection.release()
  21. })
  22. }
  23. })
  24. })
  25. }
  26. module.exports = { query }

mysqlUser.js

  1. const { query } = require('./mysqlUtil')
  2. async function getUsers( ) {
  3. let sql = 'SELECT * FROM user'
  4. return await query( sql )
  5. }
  6. async function getUser( userId) {
  7. let sql = 'select * from user where id = ?'
  8. return await query( sql,userId )
  9. }
  10. module.exports = { getUsers,getUser }

controller.js

  1. const { getUsers,getUser } = require('../db/mysqlUser')
  2. router.get('/users', async function(ctx, next) {
  3. return ctx.response.body = await getUsers();
  4. })
  5. router.get('/user/:id', async function(ctx, next) {
  6. var id = ctx.params.id;
  7. return ctx.response.body = await getUser(id);
  8. })

mongoose

npm install --save mongoose

touch db/mongoUtil.js

  1. var mongoose = require('mongoose');
  2. mongoose.Promise = global.Promise;
  3. mongoose.connect('mongodb://localhost:27017/demo2');
  4. mongoose.connection.on('error', function(error) {
  5. console.log('数据库连接失败:' + error);
  6. });
  7. mongoose.connection.on('open', function() {
  8. console.log('——数据库连接成功!——');
  9. });
  10. exports.mongoose = mongoose;

touch db/mongoEmp.js

  1. const mongodb = require('./mongoUtil');
  2. const Schema = mongodb.mongoose.Schema;
  3. // schema 数据库模型骨架,不具备操作数据库能力
  4. var dept = new Schema({
  5. id: String, //部门编号
  6. name: String //名称
  7. });
  8. var emp = new Schema({
  9. id: Number, //工号
  10. name: String, //姓名
  11. age: { type: Number, default: 0 }, //年龄
  12. // dep_id: String //部门
  13. dep: {
  14. type: Schema.Types.ObjectId,
  15. ref: 'dept'
  16. }
  17. });
  18. // 添加实例方法
  19. emp.methods.printInfo = function() {
  20. let greeting = this.name;
  21. console.log("Testing methods defined in schema:" + greeting);
  22. }
  23. // 添加静态方法,在Model层就能使用
  24. emp.statics.findbyId = function(id, callback) {
  25. return this.model('employee').find({ id: id }, callback);
  26. }
  27. // model 由Schema构造生成的模型,类似于管理数据库属性、行为的类。
  28. var employee = mongodb.mongoose.model("employee", emp);
  29. var department = mongodb.mongoose.model('department', dept);
  30. //Entity —— 由Model创建的实体,能影响数据库操作
  31. var empEntity = new employee({
  32. id: 1,
  33. name: '姓名'
  34. });
  35. console.log(empEntity.name, empEntity.id);
  36. empEntity.save(function(err, doc) {
  37. if (err) {
  38. console.log("error :" + err);
  39. } else {
  40. console.log(doc);
  41. }
  42. })
  43. var empDAO = function() {};
  44. empDAO.prototype.findAll = async function(callback) {
  45. console.log(await employee.find({}));
  46. return await employee.find({}, callback)
  47. // .populate({ path: 'dep', select: { id: 1 } }).exec();
  48. }
  49. module.exports = new empDAO();

controller.js

  1. const empDAO = require('../db/mongoEmp')
  2. router.get('/emp', async function(ctx, next) {
  3. let result = await empDAO.findAll();
  4. await ctx.render('list', {
  5. empList: result
  6. })
  7. })

touch views/list.html

  1. <p>雇员列表</p>
  2. <ul>
  3. <% empList.forEach(function(item){%>
  4. <li>
  5. <%=item.id %>
  6. <%=item.name %>
  7. </li>
  8. <% }) %>
  9. </ul>

开发中间件

1.generator 中间件

generator 中间件为koa1 直接使用的中间件
在koa2 使用:

  1. const convert = require('koa-convert')
  2. const loggerGenerator = require('./middleware/logger-generator')
  3. app.use(convert(loggerGenerator()))
2.async中间件开发

async 中间件开发

  1. function log( ctx ) {
  2. console.log( ctx.method, ctx.header.host + ctx.url )
  3. }
  4. module.exports = function () {
  5. return async function ( ctx, next ) {
  6. log(ctx);
  7. await next()
  8. }
  9. }

async 中间件只能在 koa v2中使用

  1. const loggerAsync = require('./middleware/logger-async')
  2. app.use(loggerAsync())

#
#

浏览器自动刷新

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注