egg的学习笔记整理(自己学习用的)

1.Egg.js与Koa/Express 对比

Egg.js相对比Koa和Express框架的学习成本要高,但更适合企业级开发,有成熟的插件机制、扩展机制,还可以使用多进程管理。所以多付出一点学习成本是很划算的事情。我制作了一张图,对Egg.js和Express/Koa框架进行了对比

特征对比egg.jskoa和Express
代码规范性(mvc开发模式)符合mvc开发模式Controller/Service/View灵活编码,没有明确规范
学习成本
创建机制/扩展机制
多线程管理
HttpClient集成

2.Egg.js环境搭建

2.1 使用yarn命令进行安装

​ 以管理方式打开Windows中的PowerShell(如果不以管理员方式打开,没办新建目录),选择要创建目录的位置。然后创建目录。

mkdir egg      // 创建egg目录
cd egg         // 进入egg目录

使用yarn命令来创建一个egg项目,命令如下。

yarn create egg  --type=simple

如果你没安装yarn命令,可以使用下面这条命令进行安装。

npm install -g yarn 

这时候yarn会给我们去远程拉去egg.js框架和生成项目。其中有几项需要我们配置:项目名称、描述和作者。如果不愿意配置,也可以直接略过。

创建完成后,我们需要安装相关的项目依赖。

yarn install
yarn run dev|| yarn  dev

2.2 使用npm进行安装

​ 快速初始化

我们推荐直接使用脚手架,只需几条简单指令,即可快速生成项目(npm >=6.1.0):

$ mkdir egg-example && cd egg-example
$ npm init egg --type=simple$ npm i

启动项目:

$ npm run dev
$ open http://localhost:7001

2.3Egg的目录

- app                        - 项目开发的主目录,工作中的代码几乎都写在这里面
-- controller                -- 控制器目录,所有的控制器都写在这个里面
-- router.js                 -- 项目的路由文件
- config                     - 项目配置目录,比如插件相关的配置
-- config.default.js         -- 系统默认配置文件
-- plugin.js                 -- 插件配置文件
- logs                       -- 项目启动后的日志文件夹
- node_modules               - 项目的运行/开发依赖包,都会放到这个文件夹下面
- test                       - 项目测试/单元测试时使用的目录
- run                        - 项目启动后生成的临时文件,用于保证项目正确运行
- typings                    - TypeScript配置目录,说明项目可以使用TS开发
- .eslintignore              - ESLint配置文件
- .eslintrc                  - ESLint配置文件,语法规则的详细配置文件
- .gitignore                 - git相关配置文件,比如那些文件归于Git管理,那些不需要
- jsconfig.js                - js配置文件,可以对所在目录下的所有JS代码个性化支持
- package.json               - 项目管理文件,包含包管理文件和命令管理文件
- README.MD                  - 项目描述文件  

3. 尝试建立一个新的页面

对目录和操作命令了解后,我们再试着去创建一个新的 页面。打开/app/controller/home.js,可以看到如下的代码。

'use strict';

const Controller = require('egg').Controller;

class HomeController extends Controller {
  async index() {
    const { ctx } = this;
    ctx.body = 'Hello World';
  }
}

module.exports = HomeController;

这里需要注意的是Egg.js全部使用异步模式async。我们在第9行的位置回车,编写下面的代码。

'use strict';

const { Controller } = require('egg');

class HomeController extends Controller {
  async index() {
    const { ctx } = this;
    ctx.body = 'Hello World';
  }

  async MyStudy() {
    const { ctx } = this;
    ctx.body = '<h1>我的学习</h1>';
  }
}

module.exports = HomeController;


写完这个,你可以尝试这去浏览器输入[http://127.0.0.1:7001/studyText](http://127.0.0.1:7001/studyText), 但非常抱歉,这时并不能给你返回正确的结果。因为写完页面以后,还需要去配置路由router.js

打开/app/router.js文件,然后再第9行的位置,加入下面的代码。

 router.get('/MyStudy', controller.home.MyStudy);

这样就设置完了路由,也就可以使用了。

'use strict';

//项目的路由文件
/**
 * @param {Egg.Application} app - egg application
 */
module.exports = app => {
  const { router, controller } = app;
  router.get('/', controller.home.index);
  router.get('/MyStudy', controller.home.MyStudy);
};


其实我们并没有作过多的配置,开发时只要安装Egg.js的约定去写,这些配置它已经为我们处理好了。这也就是框架的设计理念

4.Controller控制器的使用

4.1 Controller是什么

  • RESTful接口中,Controller接受用户的参数,从数据库中查找内容返回给用户或者将用户的请求更新到数据库中。
  • 在HTML页面请求中,Controller根据用户访问不同的URL,渲染不同的模板得到HTML返回给用户。
  • 在代理服务器中,Controller将用户的请求转发到其它服务器上,并将其它服务器的处理结果返回给用户。

官方给的建议是Controller层主要对用户的请求参数进行处理(校验、转换),然后调用对应的service方法处理业务,得到业务结果封装并返回。

这节课我们主要学习三种用途的第二中,在HTML页面请求中的使用。这也是简单、最好理解的一个使用方法。

4.2 创建一个新的Controller

​ 在/app/controller目录下,新建一个文件studyText .js,然后编写下面的代码。

//开启严格模式
'use strict';

//得到Controller

const Controller=require('egg').Controller;

//写一个类用于
class studyTextController extends Controller {
    async index(){
        const {ctx}=this
        ctx.body="<h1>I am Wtd</h1>"
    }
}

//把类暴露出去
module.exports=studyTextController

手写这个的目的就是为了让你熟悉Controller的最简单写法,写完这个Controller后,你在浏览器中是没办法访问到的,这时候你还需要去配置路由。

4.3 路由的配置

​ 打开/app目录下的router.js文件。这时候你不用引入,你只用增加如下代码就可以进行访问了。

//注册路由
  router.get('/my', controller.studyText.index);

5.Egg.js单元测试介绍

​ 工作中写完一个Controller之后,都需要进行单元测试。因为单元测试能够快速发现开发业务逻辑中一些隐藏的问题,越早发现问题,越好解决。这节就介绍一下Egg中的单元测试。

​ 单元测试分为同步单元测试和异步单元测试两种,先来看同步单元测试。

5.1 同步单元测试

​ Egg框架规定,所有的测试代码,都需要放在/test目录下面。如果是Controller相关的代码就需要放在/test/app/controller文件夹下面。所有的测试文件都需要以.test.js为后缀的。

这里要创建一个studyText.test.js文件,然后编写下面的测试文件。

'use strict';

const { app } = require('egg-mock/bootstrap');

describe('studyText index', () => {
  it('studyText index page', () => {
    return app.httpRequest()
      .get('/my')
      .expect(200)
      .expect('<h1>I am Wtd</h1>');
  });
});

这里的describe( )方法有两个参数,第一个是测试的描述(字符串类型),这个描述一般都是用文件的路径。第二个参数是一个回调函数,里边是对这个控制器里边的具体方法的测试用例。

写完上面的代码之后,在Powershell或终端输入yarn test或npm test就可以运行测试用例了,都是绿色的对号就是通过了单元测试,没通过就是红色的X。(视频中会演示错误的)

5.2异步单元测试

编写异步方法:

​ 写异步单元测试,需要有一个异步的Controller方法。所以回到回到/app/controller/studyText.js文件,编写一个新的方法getGirls的异步方法。

async getGirls(){
    const { ctx } = this;

    await new Promise(resolve => {
        setTimeout(()=>{
          resolve(ctx.body="<h1>杨幂,正在向你走来</h1>")
        },5000)
    })

  }

我们通过setTime( )方法来模拟数据需要5秒钟后,才会返回页面结果。

写完这个方法,再到/router.js里编写对应的路由。

router.get('/getGirls', controller.studyText.getGirls);

之后就可以在浏览器中通过http://127.0.0.1:7001/getGirls访问这个页面了,可以看到页面5秒后才会出现结果,杨幂,正在向你走来

单元测试方法:

当异步方法写完后,我们再返回到test/app/controller/studyText.test.js文件。继续编写异步的单元测试。

it('studyText getGirls', async () => {
    await app.httpRequest()
      .get('/getGirls')
      .expect(200)
      .expect('<h1>杨幂,正在向你走来</h1>');
  });

注意的是在代码的第一行,我们加入了一个async关键字,这就是异步代码测试的关键。

写完这个测试代码,再次回到PowerShell或终端,输入dev test进行测试,可以看到这次的测试用时变成了5000多毫秒。

总结:本节课我们主要讲了Egg.js中的单元测试,讲了一般情况下的同步测试,也讲了异步测试。为了讲异步单元测试,使用setTimeout( )方法,来模拟异步获取数据的情况。

6.Get请求和参数传递

6.1 get请求的特点

​ 通过URL来访问一个地址,比如http://127.0.0.1:7001,这种请求方式就是Get请求。Get请求也是我们最常用的请求方式。包括现在的扫码请求,其实也是变相的Get请求。

  • 优点:使用简单,清晰有条例。适合网站和对外App的使用。
  • 缺点:传递参数是有大小限制,安全性较差,不能完成重要数据的传递。

6.2 自由传参模式

​ Get请求我个人把它分为两种传参模式,一种是自由传参模式。这种传参模式和最早的传参模式相同。传递的参数个数和名称没有具体明确定义,设置不限制你是否传递参数。使用起来非常的灵活,所以就叫做自由传参模式。

下面写一个符合资源传参的Controller方法。上节课我们写了一个getGirls的方法,因为不能传参,所以为我们服务的女孩是固定的,这并不是我们想要的结果。这节课能传参了,这个女孩就可以根据我们自己的参数,进行显示了。

打开/app/controller/studyText.js文件,重新编写一个getGirl( )的方法。

async getGirl(){
    const {ctx} = this;
    ctx.body = ctx.query

  }

这里的ctx.query就是获得传递的参数。写完后还需要到router.js文件下,增加路由后才可以访问。

打开/app/router.js文件。

router.get('/getGirl', controller.studyText.getGirl);

你通过浏览器访问,URL为[http://127.0.0.1:7001/getGirl?name=小红](http://127.0.0.1:7001/getGirl?name=%E5%B0%8F%E7%BA%A2),这时候页面就会显示传你传递的参数。

那如何体现自由那,首先你可以不传递参数,只是页面什么都不显示了,只显示一个{ }。还可以传递多个参数,比如传递名字为小红,年龄为20岁, 页面就会完全的显示出来。

http://127.0.0.1:7001/getGirl?name=小红&age=20

6.3 严格传参模式

​ 和自由传参模式对应的就是严格传参模式,也就是你传递的参数个数是固定的,你传递参数顺序是固定的,你传递的参数名称是固定的。

Get的严格传参模式需要配合router.js文件进行设置。例如设置一个getGirl2的路径,然后必须传递一个name的参数,就可以这样设置。

router.get('/getGirl2/:name', controller.studyText.getGirl2);

设置好路由后,再到/app/controller/studyText.js。编写一个getGirl2的方法就可以。(此方法视频中会详细讲解)

async getGirl2(){
    const {ctx} = this;
    ctx.body=ctx.params.name
  }

ctx.params是获取所有的传递参数,ctx.params.name是获取传递参数的name值。

这时候的访问URL不在是用?来开始传递参数了,而是直接用/ 左斜杠来传递。

http://127.0.0.1:7001/getGirl2/小红

这时候如果你的url中不传参或者多传参数,都会报错。我们可以试着先不传参数。

http://127.0.0.1:7001/getGirl2

严格传参中的多参数传递

​ 会了严格传参之后,再来看一下在严格模式下如何传递多个参数,比如我们再传递一个年龄=20岁.

路由配置页面就可以这样设置。

router.get('/getGirl2/:name/:age', controller.studyText.getGirl2);

然后再修改对应的getGirl2( )方法,接受到姓名和年龄后,显示出来。这里就是完全动态的显示了。

async getGirl2(){
    const {ctx} = this;
    let name = ctx.params.name
    let age = ctx.params.age
    ctx.body='大哥你好,我是'+name+',今年'+age+'岁.欢迎光临红浪漫!'
  }

这样的应用是不是越来越好了那?现在程序就支持传递多个参数了。

总结:这篇文章,我们主要学习了Egg.js中的Get请求和传参方式,Get传参分为自由传参模式和严格传参模式。个人建议如果想让程序健壮性更强,可以多使用严格传参模式。

7.POST请求和参数的接收

7.1 编写post请求的Controller

​ 直接在/app/controller/studyText.js文件里,重新编写一个add( )方法。先写个最简单的,只要能用POST方法访问到就可以了。

async add(){
    const {ctx} = this
    ctx.body="add"
  }

然后配置路由/app/router.js文件。

router.post('/add', controller.studyText.add);

这时候就可以进行POST请求了,但是POST请求不是通过浏览器访问页面就可以访问到的,所以我们还需要用到VSCode插件。

7.2插件REST Client插件的使用

​ 你可以使用Postman这样的工具,但Postman需要重新打开一个软件,显得太重了,一点也不优雅。所以我这里推荐使用VSCode中的一个插件REST Client

安装方法和发送请求

直接打开VSCode中的插件管理,在搜索框查找REST Client,然后进行安装。安装完成后直接可以使用。

在项目根目录下,新建一个test.http(这个名字可以随意起,但是文件后缀名字不能变) , 此处注意后缀是http才可以和插件进行联动。

POST http:*//127.0.0.1:7001/add* 
Content-Type: application/x-www-form-urlencoded
name=study

你也可以使用JSON的格式进行上传。

POST http://127.0.0.1:7001/add  
Content-Type: application/json

{
    "name":"小红"
}
需要注意的是,这个插件你需要完全按照这个格式来写,不能随意多出空行,否则就会发送失败。得不到数据。

需要解决安全设置

​ 当你第一次请求时,可能会返回403错误,这是因为Egg.js默认开启了CSRF安全策略,学习阶段,我们可以关闭掉这个选项。

CSRF的全名为 Cross-site request forgery, 它的中文名为 伪造跨站请求。

关闭方法是,打开/config/config/default.js文件,也就是项目的默认配置文件。

然后设置配置项,关闭掉CSRF

config.security = {
    csrf :{
      enable:false,
    }
  }

写完这段配置代码后,CSRF安全策略就被关闭了。我们就可以发送请求了。

7.3 post参数的接收

​ 能发送POST请求后,需要在服务端接收请求。Egg.js已经给我们封装好了,直接使用ctx,request.body来获取。代码如下。

async add(){
    const ctx = this.ctx
    ctx.body={
      status: 200,
      data:ctx.request.body
    }
  }

写完代码后,再用REST Client来发送请求就可以得到返回的参数了。

总结:这节我们主要学些Egg.js中的POST请求和参数接收方法,还学习了用于发送请求的VSCode插件REST Client,并使用两种方式向后端传递数据。

7.4 service

Service就是在复杂业务场景下用于做业务逻辑封装的一个抽象层。

好处:保存controller中的逻辑更加的简洁

保存业务逻辑的独立性,抽象出来的Service可以被多个Controller调用

将逻辑和展现分离,更容易编写测试用例

1.创建第一个Service文件

​ Egg规定Service文件必须放在/app/service目录,所以我们在/app文件夹下面,新建一个service文件夹。然后在新建一个studyText.js文件。从代码中可以看出,命名规则和写法跟Controller是非常类似的。如果你能对比记忆,学习会简单很多。同样Service里的方法也全部是异步方法,所以要使用async关键字。

'use strict';

const Service=require("egg").Service;
class StudyTextService extends Service{
    async getGirl(id){
        return {
            id:id,
            name:'小红',
            age:18
        }
    }
}
module.exports=StudyTextService;

2.Controller 调用Service获取数据

​ 写完Service方法后,就可以在Controller中使用Service获取它提供的数据了。现在我们回到/app/controller/studyText.js文件中的getGirl( )方法

​ 编写代码前,我们并不需要把service进行引入,因为Egg已经为我们作好了这一切。直接使用ctxs上下文就可以进行使用了。

下面为Controller中的getGirl( )方法改写。

 //自由传参模式(想传几个参数都可以)
  async getGirl(){
    const ctx=this.ctx;
    const res=await ctx.service.studyText.getGirl('1818')
    ctx.body=res
  }

写完后,用yarn dev或npm run dev命令,启动服务。然后打开浏览器,输入[http://127.0.0.1:7001/getGirl?id=1818](http://127.0.0.1:7001/getGirl?id=1818) 就可以看到页面会呈现出service给我们返回的数据。

3.Service方法的可调用性

​ 当你写完一个service方法后,你可以在其它的Controller里进行使用。比如我们现在去home.js中进行使用。打开/app/controller/home.js文件下,新建一个testGetGirl( )方法。

 async testGetGirl(){
    const ctx=this.ctx;
    let id=ctx.query.id;
    const res=await ctx.service.studyText.getGirl(id)
    ctx.body=res;
  }

写完上面的代码,到/app/router.js文件里,增加一个新的路由。

router.get(‘/testGetGirl’, controller.home.testGetGirl);

写完后保存文件,然后在浏览器中输入URL[http://127.0.0.1:7001/testGetGirl?id=2000](http://127.0.0.1:7001/testGetGirl?id=2000)。可以看到,页面如愿以偿的获得了这些数据。

总结:这节课学习了Egg.js的Service的使用,Service应该放在/app/servcie文件夹下面,起名的时候最好和Controller对应起来。写法和Controller类似,并且在任何Controller下都可以得到Service提供的数据。

8.View中使用EJS模板引擎

8.1 View中使用EJS模板引擎一

​ Egg.js专注后端开发,但是也提供了View层的渲染,个人觉的这是有必要的,因为就算是这个时代,也并不是所有的开发都是前后端分离的。还是有很多应用需要服务端渲染的,比如博客就需要服务端渲染。

服务端渲染页面的好处:

​ 对SEO非常的友好,单页面应用,比如VUE 是客户端才生成的,这种应用对于国内的搜索硬引擎是无法抓取的,这样SEO就不会有好的结果,所以是官网,新闻网站,博客这些展示类的网站必须使用服务端渲染的技术。

对前后端分离模式的补充

EJS模板引擎的介绍:

​ EJS属于老牌的模板引擎,记得我在使用ThinkPHP的使用,用的就是EJS模板引擎。EJS模板引擎一直在维护,所以稳定性和生态上都比较好。所以最终选择用EJS给小伙伴讲解Egg中的View层。

EJS官方网站(英文)https://ejs.co/ 中文网站:https://ejs.bootcss.com/

EJS在Egg中的安装和配置:

​ Egg.js提供了EJS的插件egg-view-ejs,直接使用yarn或者npm安装。

​ npm 的安装方法:npm i egg-view-ejs --save

​ yarn 的安装方法:yarn add egg-view-ejs

安装完成后,并不能直接使用,需要再进行一些简单的配置。

配置/config/plugin.js文件:exports.ejs = {
enable :true,
package:“egg-view-ejs”
}

plugin.js文件配置完成后,再到/config /config.default.js文件里进行配置。

config.view = {
mapping : {
“.html”:“ejs”
}
};
config.ejs={
} 这两部配置完成后,就可以在Controller里使用EJS模板引擎了。

使用EJS模板引擎:

​ 当配置项都完成后,就可以使用模板EJS模板引擎了。打开/config/controller/studyTest.js文件。修改index( ),因为render( )方法返回的是Promise的对象,所以要使用关键字await

async index() {
const { ctx } = this;
await ctx.render('studyText.html')
}

这时候我们还没有studyText.html这个页面,所以需要马上建立一个。Egg.js规定view的引擎模板,必须写在/app/view/文件夹下面(如果没有view文件夹,可以自己建立)。在文件夹下面新建一个 文件studyText.js

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <h1>I am  studyText!</h1>
</body>
</html>

PowerShell里输入yarn dev开启服务,在浏览器中输入[http://127.0.0.1:7001/my](http://127.0.0.1:7001/my),可以看到输出了我们想要的结果

8.2 View中使用EJS模板引擎-2

  1. EJS模板中显示controller返回的数据

    ​ 在Controller中我们有一些动态的数据,需要在EJS模板中进行显示。这时候可以使用render( )第二个参数,第二个参数可以传递JavaScript中的对象,也就是说你可以任意的传递各种形式的参数过去。

    我们先到/app/controller/studyText.js文件下面。在index( )方法里,使用第二个render( )的参数,来传递参数。

    ​ 例如:async index() {
    const { ctx } = this;
    await ctx.render(
    ‘studyText.html’,{
    id:2021,
    name:‘小红’,
    age: 18,
    skill:‘泰式按摩’
    })
    }

    1. 有了这些数据后,就可以在/controller/view/studyText.html文件下使用这些参数了。默认使用的方法是<%= 参数 %>

    Document

    欢迎来到红浪漫~~

    现在由<%= id %>号技师,为你服务!

    你好,我是<%= name %><%= age %>岁,专业技能是<%= skill %>

通过这种方式,在EJS模板中就可以使用controller传递过来的变量了。

3**.EJS模板中的循环显示**

cotroller传递过来的数据是一个数组,如何利用列表来展示。

先来修改\app\controller\studyText.js文件中的index( )方法。

async index() {
  const { ctx } = this;
  await ctx.render(
    'studyText.html',{
      id:2021,
      name:'小红',
      age: 18,
      skills:[
        '泰式按摩',
        '精油搓背',
        '水疗SPA'
      ]
    })
}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" type="text/css" href="public/css/default.css"  />
    <title>Document</title>
</head>
<body>
   <%-include ('header.html') -%>
    <h2>现在由<%= id %>号技师,为你服务!</h2>
    <h3>你好,我是<%= name %><%= age %>岁</h3>
    <ul>
        <% for(var i=0;i<skills.length;i++){ %>
        <li><%= skills[i] %></li>
        <%}%>
    </ul>
</body>
</html>

这时候已经传递了一个数组到模板中,重点是如何再模板中用列表的形式进行展示。这里使用了for循环进行展示,这种写法跟php的写法也非常类似。

4.修改默认的分隔符符号

​ 其实很多前端小伙伴是不喜欢用这种<%%>的形式展示数据的,这很不前端。EJS也为我们提供了配置型方法,你可以根据你的喜好配置这个配置符。

打开/config/config.default.js文件,然后修改config.ejs选项。

config.ejs={
     delimiter: "$"
  }

然后再回到studyText.html文件,用全部地替换的方法,把%换车$,这样就更换成功了。建议这个还是在项目初级就规范好,不要随意改动。

EJS还提供了单独修改某个修饰符,但这里不建议这样修改,会让项目变的混乱不堪,也就是render的第三个参数。

总结:这节课我们学习了EJS模板引擎的基本使用方法,还学习了配置EJS的配置分隔符的方法。其实EJS是完全可定制的,有很多地方都可以根据需要自行修改。但是个人不建议作太多的个性化配置,这会给团队和项目带来混乱和跟多的学习成本。

8.3 View中使用EJS模板引擎-3

​ 如何在ESJ模板引擎中配置和使用静态资源文件。作为前端转全栈,肯定少不了CSS图片JS文件的引入,而这些全部属于静态资源。所以说静态资源也是项目开发中的一部分,也需要关注和学习的。

1.公共代码的使用:

​ 比如网站项目中的头部和底部往往都是一样的,这时候我们把公共的部分抽离出来,单独到一个文件夹中,然后在需要的页面直接引入。

/app/view/目录建立一个header.html文件。在文件里我们只需要写一些代码片段就可以了,没必须写出全部的html架构。

/app/view/header.html文件

<h1>欢迎来到红浪漫!</h1>

然后回到/app/view/studyText.html文件,直接使用<%-include ('header.html') -%>引入到模板里就可以了。

<body>
    <% include header.html %>
    <h2>现在由<%= id %>号技师,为你服务!</h2>
    <h3>你好,我是<%= name %><%= age %>岁</h3>
    <br/>
     我的技能如下:
     <ul>
         <% for(var i=0;i<skills.length;i++){ %>
         <li><%= skills[i] %></li>
         <%}%>
     </ul>
</body>

在终端中用yarn dev或npm run dev 启动服务,然后在浏览器中输入http://127.0.0.1/my。 可以看到公用部分的文件已经引入进来了。

2.配置静态资源

​ Egg中默认的静态资源文件在/app/public目录下,比如我们在public文件夹下新建一个css文件夹,然后新建default.css文件。

body{
color:red; 
}

​ 然后直接在浏览器中试着查看这个CSS文件。浏览器中输入地址http://127.0.0.1:7001/public/css/default.css 。正常情况css代码内容已经显示在浏览器里了

疑问:静态资源我们并没有配置路由,为什么就可以方法到那?

:不用配置,静态资源就可以方法到,是因为Egg使用了egg-static插件,这个插件是koa-static的升级版。我们可以打开node_modules 文件夹,直接搜索egg-static文件夹,就可以看到。

知道了这个道理,我们也可以猜测到,这个public前缀一定是可以修改的,比如修改为assets.

打开/config/config.default.js文件,然后写入如下配置。

onfig.static = {
    prefix:"/assets/"
  }

这时候再访问原来的URL就会报404错误,你这时候修改一下路径,把public改成assets就又可以访问到了。

甚至你可以配置静态文件放置的文件夹,但我个人不建议你修改,包括public的前缀也不建议你修改。

3.使用静态资源文件

​ 会配置静态资源了,我们就可以在EJS模板里使用这些资源了,比如现在引入刚才写的default.css文件。(先把刚才修改的配置删除掉,回归默认配置。)

然后到/app/view/studyText.html中引入这个CSS样式。引入方法和正常的HTML引入方法一样就可以了。

<link rel="stylesheet" type="text/css" href="public/css/default.css"  />

到浏览器进行查看,发现字体已经全部变成了红色。

总结:这节我们主要学习了在EJS模板中如何配置和使用静态资源。

9.cookie的增删改查

9.1cookie基础的操作

作用:Cookie的作用就是在浏览器客户端留下一些数据,比如我们经常使用的登录一个网站,下次再来的时候就不用再次登录了。但是Cookie是可以设置时间限制的,所以经常看到7天内不用重复登录,这样的信息

对Cookie的简单了解:HTTP请求是无状态的,但是在开发时,有些情况是需要知道请求的人是谁的。为了解决这个问题,HTTP协议设计了一个特殊的请求头:Cookie。服务端可以通过响应头(set-cookie)将少量数据响应给客户端,浏览器会遵循协议将数据保留,并在下一次请求同一个服务的时候带上。

​ 在实际开发中Cookie的操作应该放在服务端,而不是用客户端的JS操作

我们先来到上节课的/app/view/studyText.html模板中,编写四个按钮,分别是增加Cookie、删除Cookie、修改Cookie和查看Cookie。
	<div>
    <button onclick="add()">增加Cookie</button>
    <button onclick="del()">删除Cookie</button>
    <button onclick="editor()">修改Cookie</button>
    <button onclick="show()">查看Cookie</button>
</div>
写完按钮后,增加对应的方法JavaScript。
可以先写一个方法(function),然后其它的复制后进行修改。就可以快速写出这些代码了。
<script>
    function add(){
        fetch("/add",{
            method:"post",
            headers:{
                "Content-type":"application/json"
            }
        });
    }
    function del(){
        fetch("/del",{
            method:"post",
            headers:{
                "Content-type":"application/json"
            }
        });
    }
    function editor(){
        fetch("/editor",{
            method:"post",
            headers:{
                "Content-type":"application/json"
            }
        });
    }
    function show(){
        fetch("/show",{
            method:"post",
            headers:{
                "Content-type":"application/json"
            }
        });
    }
</script>
再去/app/controller/studyText.js文件下,增加这四个对应的方法。

async add(){
  const ctx = this.ctx
}
async del(){
  const ctx = this.ctx
}
async editor(){
  const ctx = this.ctx
}
async show(){
  const ctx = this.ctx
}
最后再到/app/router.js中配置对应的路由

router.post('/add', controller.studyText.add);
router.post('/del', controller.studyText.del);
router.post('/editor', controller.studyText.editor);
router.post('/show', controller.studyText.show);
作完上面这四步,我们的基本结构就有了,剩下就可以好好的学习Cookie的基本操作了。

9.2Cookie的增加操作

​ 先到/app/controller/studyText.js文件的add( )方法里编写代码。其实egg已经为我们准备好了操作Cookie的方法。直接使用就可以了。

async add(){
    const ctx = this.ctx
    ctx.cookies.set("user","studyText.com")
    ctx.body = {
    status:200,
    data:'Cookie添加成功'
	}
}
这部分代码写完后,就可以可以在终端中开启服务,输入yarn dev或npm run dev开启。
来到页面点击增加Cookie按钮,然后按F12打开调试模式,找到Application,可以看到Cookie值已经被加入进来了。

9.3 cookie的删除操作

再来看一下Cookie的删除操作,再来到/app/controller/studyText.js文件。修改del( )方法。
	async del(){
  const ctx = this.ctx
  ctx.cookies.set("user",null)
  ctx.body = {
    status:200,
    data:'Cookie删除成功'
  }
}
写好后,直接到浏览器中点击删除,就可以删除Cookie了。

9.4 Cookie的修改操作

​ 修改操作和删除和增加一样。直接修改值就可以了。

async editor(){
  const ctx = this.ctx
  ctx.cookies.set("user",'bilibili')
  ctx.body = {
    status:200,
    data:'Cookie修改成功'
  }
}

9.5 cookie显示

显示Cookie要使用ctx.cookies.get( )方法。

async show(){
  const ctx = this.ctx
  const user=ctx.cookies.get("user")
  console.log(user)
  ctx.body = {
    status:200,
    data:'Cookie显示成功'
  }
}
点击按钮后,可以在VSCode的终端中显示出结果。你可以试着让它显示在页面上。

10.Cookie的配置和加密

10.1 Cookie时效配置

ctx.cookies.set( ) 方法是有三个参数的,第一个参数是key,第二个参数是value,第三个参数就可以进行配置。比如你需要配置Cookie的有效时间,可以使用maxAge属性。(这个时间是毫秒。)

比如现在我们到/app/controller/studyText.js文件里,修改add( )方法,把maxAge设置为两秒,在添加Cookie两秒后,这个Cookie就会自己失效。

	async add(){
	const ctx = this.ctx
        ctx.cookies.set("user","studyText.com",{
        maxAge:1000*2
        })
        ctx.body = {
        status:200,
        data:'Cookie添加成功'
		}
	}

10.2 HttpOnly的设置

​ 伪造Cookie来绕过登录是黑客经常使用的一种手段,所以为了安全,Egg.js默认设置只允许服务端来操作Cookie

​ 比如现在你通过JS的方式document.cookie获取Cookie是不能获取的(需要在浏览器的控制台输入获取)。当我们想通过客户端操作Cookie时,可以通过下面的代码进行设置。

sync add(){
  const ctx = this.ctx
  ctx.cookies.set("user","studyText.com",{
    maxAge:1000*60,
    httpOnly:false
  })
  ctx.body = {
    status:200,
    data:'Cookie添加成功'
  }
}

上面设置了httpOnly:false,再次刷新页面,然后看浏览器控制台的HttpOnly就变成false属性了。

10.3 设置中文Cookie的方法

​ 有时候开发需求我们在Cookie里设置中文,如果直接设置&添加,服务端会直接报错的。比如我们在add( )方法里设置中文,然后再操作就会报错500

ctx.cookies.set("user","七彩幼儿园")

点击按钮后,会直接报500的错误。那下面就学习一下解决中文Cookie的方法。

设置中文Cookie的时候进行加密

加密只要在第三个参数中,加入encrypt:true,就可以加密成功。

ctx.cookies.set("user","七彩幼儿园",{
  encrypt:true
})

加密成功了,再来获取这个值。如果你直接通过ctx.cookies.get( )方法获取,获取的是undefind,也就是无法获取的。这时候需要再次配置解密才可以使用, 在show( )方法里配置代码如下。

const user=ctx.cookies.get("user",{
  encrypt:true
})

这时候到VSCode的终端中就可以获取这个解密后的值了。

当然你也可以使用base64对字符串进行加密解密。这个属于JavaScript的基础知识了,我这里就不做过多讲解了。

总结:本届主要讲了Egg.js中Cookie的有效期设置、服务端操作设置和中文Cookie的编写方法。

11.session的操作

11.1 Session的添加

​ 在开发中你可以理解为不重要的,公开的信息都可以临时存在Cookie里,但是隐私重要的信息,可以存在Session里,并且只允许在服务端进行操作。

先来看一下如何添加一个Session。打开/app/controller/studyText.js文件,在add( )方法里编写。

ctx.session.username='studyText'

11.2 session的获取

​ 添加完成后,我们在index( )方法里获取一下session并展示在页面上。

async index() {
  const { ctx } = this;

  //获取Session
  const username= ctx.session.username

  await ctx.render(
    'studyText.html',{
      id:2021,
      name:'小红',
      age: 18,
            //赋值给模板
      username:username,
      skills:[
        '泰式按摩',
        '精油搓背',
        '水疗SPA'
      ]
    })
}

在Session存在的情况下,我们已获得了Session的值,并且把获得的值发送给了模板。再到模板中修改模板,把值显示出来app/view/studyText.html

<h3><%=username%></h3>

作完后,我们到浏览器中输入http://127.0.0.1:7001/my,然后点击增加Cookie按钮,刷新页面后,可以在页面中看到出现studyText,说明已经添加Session和读取Session成功了。

这时候打开浏览器的控制台的Application标签,可以看到多了一个EGG_SESS的Cookie,这个就是我们刚才存储的Session了。

11.3 Session支持中文

​ 比如现在我们要把Session中username的值换成中问的技术胖,代码如下。

ctx.session.username='技术胖最帅'

删除所有Cookie,然后再次点击增加Cookie按钮,然后再次刷新按钮,页面显示出了技术胖最帅字样,说明中文的Session值也是完全可以使用的。

11.4 Session的删除

​ 删除Session非常简单,只需要把值设置为null就可以了。在del( )方法中编写下面的代码。

ctx.session.username=null

这样就可以删除session了。这时候到浏览器中,可以先点击增加Cookie按钮,再点击删除Cookie按钮,可以看到Session也被删除掉了,页面中的值就消失掉了。

Session的相关项配置

​ 配置Session的一些选项,需要到config.default.js文件中进行配置。

config.session = {
    key :"PANG_SESS",   // 设置Key的默认值
    httpOnly:true,      // 设置服务端操作
    maxAge:1000*60  ,   // 设置最大有效时间
    renew: true,        // 页面有访问动作自动刷新session 
}

总结:这节课我们主要学习了Egg中Session的增删改查和配置相关的操作。

12.Egg.js中间件的编写

12.1 中间件的编写

​ Egg.js约定中间件要写在/app/middleware文件夹下面,如果没有middleware可以自己建立。在文件夹下,新建一个counter.js的文件。我们来作一下访问页面的次数这样的计数器。由于我们还没学数据库,所以把这个计数器的值保存在Session当中。

module.exports = options =>{

    return async (ctx,next)=>{
        if(ctx.session.counter){
            ctx.session.counter++
        }else{
            ctx.session.counter=1
        }
        await next();
    }

};

12.2 中间件的全局使用

​ 写完这个之后,我们需要手动的挂载中间件。挂载方法是打开/config/config.default.js文件。

config.middleware = ['counter'];

这样配置之后,就是全局的中间件,无论访问那个页面,计数器都会增加。为了看到效果。分别在\app\controller\home.js文件的index( )方法中 和 \app\controller\studyText.jsindex( )方法中,加入控制台输出代码。

console.log(ctx.session.counter)

然后分别访问这两个页面,看到session都会增加。这就说明了中间件现在的作用域是全局的。

12.3 router中间件的使用

​ 如果只想让访问/my时,计数器才会增加,这时候就要使用在router(路由)中配置中间件的使用。直接在\app\router.js 中实例化和挂载。

我们先去掉全局的挂载,然后到router.js文件中挂载单个路由。

'use strict';
module.exports = app => {
  const counter = app.middleware.counter()
  const { router, controller } = app;
  router.get('/', controller.home.index);
  router.get('/my',counter ,controller.studyText.index);
};

这时候在访问首页,计数器虽然会显示,但是不会增加。只有在访问/my路径的时候才会继续增加。也就是说中间件才会起作用。

我这里使用的中间件非常简单,在实际开发中中间件还是有很多用处的,比如日志的记录、比如所有页面的Gzip压缩展示、比如全局埋点的使用。以后在实战项目中,我们还会学习更多的中间件使用方法。

13.Egg.js的Extend-application

​ Egg虽然给我们提供了很多内置的方法,但有时候还是感觉不够用,这时候就需要我们自己对Egg中的方法进行扩展和编写了。

多种对象进行扩展:

​ Egg.js可以对内部的五种对象进行扩展,我也作了一个表格。给出了可扩展的对象、说明、this指向和使用方式。

Ejj.js丰富的扩展方式
说明this指向使用方式
application全局应用对象app对象this.app
context 请求上下文ctx对象this.ctx
request请求级别的对象,提供了请求相关的属性和方法ctx.request对象this.ctx.request
response请求级别的对象,提供了相应的属性和方法ctx.response对象this.ctx.response
helper 帮助函数ctx.helper对象this.ctx.helper

13.1 对application对象方法的扩展

application对象的扩展。需求是作一个全局的获取时间的扩展。比如用app.currentTime( )这个全局的方法,就可以获得当前时间,并显示在页面上。

按照Egg的约定,扩展的文件夹文件的名字必须是固定的。比如我们要对application扩展,要在/app目录下,新建一个/extend文件夹,然后在建立一个application.js文件。

module.exports = {
//方法扩展*
currentTime(){
const current = getTime();
return current;
}
};
function getTime(){
let  now = new Date();
let year = now.getFullYear(); *//得到年份*
let  month = now.getMonth()+1;*//得到月份*
let date = now.getDate();*//得到日期*
let  hour= now.getHours();*//得到小时数*
let minute= now.getMinutes();*//得到分钟数*
let second= now.getSeconds();*//得到秒数*
let nowTime = year+'年'+month+'月'+date+'日 '+hour+':'+minute+':'+second;
return nowTime;
}
这样就完成了 一个application对象的方法扩展。扩展写好后,不用再作过多的配置,直接在一个Controller方法里使用就可以了。比如我们要在/app/controller/studyText.js的index( )方法里使用。

async index() {
  const { ctx ,app } = this;
  await ctx.render(
    'studyText.html',{
      nowTime: app.currentTime()
    })
}
这样就可以在/app/view/studyText.html模板中使用了。

<%=nowTime%>
这是Egg中对application方法的扩展,我们再来看看对属性的扩展。

13.2对application对象的属性扩展

​ 对属性( property) 的扩展的关键字是get,也需要写在application.js文件里。

	module.exports = {
	//方法扩展*
        currentTime(){
        const current = getTime();
        return current;
        },
        *//属性扩展*
        get timeProp(){
        return getTime();
		}
};

加入get,就会默认是一个属性,可以直接以属性的形式在controller方法里进行调用。

Egg.js中的扩展是经常使用的,写扩展时要遵照Egg的约束,方法扩展和平时写的方法一样,属性扩展以get为关键字。

14 Egg.js的Extend-context

​ 学习一下Egg.js中对Context(上下文)的扩展。

14.1编写一个方法

​ 为了学习更简单明了,在/app/controller/studyText.js文件里重新编写一个方法newContext( )。先用最简单的方式,在页面显示一个方法名称newContext就可以了。

async newContext(){
  const {ctx} = this ; 
  ctx.body = 'newContext';
}

写完方法,到/app/router.js里,配置路由。

router.get('/newContext',controller.studyText.newContext);

路由配置完成后,可以在终端中用yarn devnpm run dev 打开测试服务,然后在浏览器里输入[http://127.0.0.1:7001/newContext](http://127.0.0.1:7001/newContext)如果能正常在页面中显示出newContext就说明正常了,可以继续下面的操作。

14.2编写Contenxt扩展

/app/extend文件夹下,新建一个文件context.js(此文件名称是Egg.js要求的固定写法,不能改变)。然后编写下面的代码。

module.exports = {
  params(key){
    const method = this.request.method
    if(method ==='GET'){
      return key ? this.query[key]:this.query;
    }else{
      return key? this.request.body[key] :this.request.body;
    }
  }  
};

写完之后,打开/app/controller/studyText.js文件,使用刚编写的params获取参数,然后打印在服务端控制台。

async newContext(){
  const {ctx} = this ; 
  const params = ctx.params();
  console.log(params)
  ctx.body = 'newContext';
}

这样写完,理论上就可以接收postget请求的参数都可以了。

14.3测试请求参数获得情况

直接在浏览器里输入

http://127.0.0.1:7001/newContext?username=studyText

在到VSCode的终端中查看结果,是可以接收到{ username: 'studyText' }参数的。

14.4post请求参数获取

get请求没问题了,先修改router.js,把请求方式改为post

router.post('/newContext',controller.studyText.newContext);

这里继续使用第06节中讲过的REST Client插件进行Post请求测试。在根目录下,打开test.http文件,然后编写测试代码。

POST http://127.0.0.1:7001/newContext  
Content-Type: application/json

{
    "name":"小红"
    "age":18
}

写好后,点击Send Request按钮测试,可以看到也是可以接收到POST传递的参数的。

这节课我们讲解了Egg.js中对Context(上下文对象)的方法扩展,我们编写了一个可以同时接受POSTGET的请求的参数Context扩展方法,并进行了基本的测试。下节课继续学习Egg.js中的请求。

15.Egg.js 的 Extend-request

​ Egg.js 中 Request 对象的扩展,Request 中的扩展一般是扩展的属性。比如扩展 Request 中的一个属性,通过属性直接得到请求头中的 token 属性。

15.1开发前的准备

​ 我们新写一个方法,用来获取请求头中的token属性。所以我们在/app/controller/studyText.js中添加一个方法。

async newRequest(){
  const { ctx } = this;
  const token = ctx.request.token
  ctx.body = {
    status:200,
    body:token
  }

}

然后再到router.js中设置路由。

router.post("/newRequest", controller.studyText.newRequest);

15.2 request对象扩展token属性

​ Egg.js 对 Request 的扩展也需要在/app/extend文件夹下,新建一个request.js文件,然后在这个文件里写扩展属性。

module.exports = {
  get token() {
    console.log("token", this.get("token"));
    return this.get("token");
  },
};

15.3使用 REST Client 进行测试

POST http://127.0.0.1:7001/newRequest
Content-Type: application/json
token: 'studyText'

{
    "name":"小红",
    "age":18
}

在点击send Request按钮,在 VSCdoe 控制台和请求后返回的数据中,就可以看到token了。这样一个简单的 Request 扩展就完成了。

16.Egg.js的Extend-response、helper

​ response对象和helper对象的扩展。

16.1编写Response扩展

​ 在/app/extend文件夹下,新建立一个response.js文件。我们的需求是和上节课向对应的,作一个设置token的扩展。打开response.js文件,编写下面的代码。

module.exports={
  set token(token){
    this.set('token',token)
  }
};

需要设置的方法以set关键字开头,然后用this.set( )就可以设置返回的token了。

16.2编写使用方法和路由

async newResponse(){
  const {ctx} = this;
  ctx.response.token='studyText.com'
  ctx.body = 'newRespose'
}

然后设置路由,router.js 。

router.get('/newResponse',controller.studyText.newResponse);

在终端里开启服务yarn dev,然后输入http://127.0.0.1/newResponse。然后按F12打开浏览器的调试模式,然后进入Network标签,再次刷新浏览器,再选择All,点击newResponse。就可以看到token

16.3 编写helper扩展

​ 我们紧接着再来学一下helper对象的扩展。我们作一个把字符串进行base64加密的方法。在/app/extend/文件夹下,新建一个helper.js文件。

module.exports = {
  base64Encode(str = '' ){
    return   new Buffer(str).toString('base64');
  } 
}

虽然Buffer( )方法显示已经弃用,但是你还是可以使用的。

使用Helper扩展

async newResponse(){
  const {ctx} = this;
  ctx.response.token='studyText.com'
  const testBase64 = ctx.helper.base64Encode('studyText.com')
  ctx.body = testBase64
}

然后到浏览器,刷新一下页面。就可以看到输出的结果编程了base64加密的文字了。学习了Egg.js中的Extend扩展。需要学习一下Egg.js中的插件机制。

17.Egg.js中的定时任务编写

17.1 定时任务的编写

​ 定时任务需要按照Egg的约定,/app目录下,新建shedule文件夹。然后再shedule文件夹下,新建一个get_time.js文件。设置每3秒钟,在控制台输出当前时间戳。

const Subscription = require('egg').Subscription
    class GetTime extends Subscription{
    static get schedule(){
    return {
    interval:'10s',
    type:'worker'
    };
    }
    async subscribe(){
    console.log(Date.now())
    }
};
module.exports =GetTime;

17.2 更复杂的定时

​ 我们也可以使用更复杂的cron属性进行定时。cron属性有6个参数。

*    *    *    *    *    *
┬    ┬    ┬    ┬    ┬    ┬
│    │    │    │    │    |
│    │    │    │    │    └ day of week (0 - 7) (0 or 7 is Sun)
│    │    │    │    └───── month (1 - 12)
│    │    │    └────────── day of month (1 - 31)
│    │    └─────────────── hour (0 - 23)
│    └──────────────────── minute (0 - 59)
└───────────────────────── second (0 - 59, optional)

比如我们还是要设置每3秒钟,返回时间戳,就可以写成下面的样子。

static get schedule(){
  return {
    cron: '*/3 * * * * *',
    type:'worker'
  };
}

18 Egg.js配置连接MySql数据库

18.1 安装egg-mysql 插件

​ 打开VSCode中的终端,然后在项目根目录下输入yarn命令进行安装。正常来讲安装的速度是非常快的。

yarn add egg-mysql -S  或npm i egg-mysql -S

安装完成后,在终端中,再启动这个项目(你也可以先不启用)。

yarn dev || npm run dev 

然后在项目根目录,找到并打开package.json文件,查看安装是否成功和对应的版本。

"dependencies": {
    "egg": "^2.15.1",
    "egg-mysql": "^3.0.0",
    "egg-scripts": "^2.11.0",
    "egg-view-ejs": "^2.0.1"
  },

可以看到,我这里的egg-mysql版本为3.0.0.

18.2 配置egg-mysql插件

​ 安装完的插件并不能正常使用,需要在plugin.js中配置插件。打开/config/plugin.js文件,然后在最后面编写。

exports.mysql = {
  enable:true,
  package:'egg-mysql'
}

然后再到/config/config.default.js当中进行 进一步配置。

config.mysql ={
    app:true,     //是否挂载到app下面
    agent:false,  //是否挂载到代理下面
    client:{
      host:'127.0.0.1',      // 数据库地址
      prot:'3306',           // 端口
      user:'root',           // 用户名
      password:'root123',    // 密码
      database:'test-egg'    // 连接的数据库名称
    }
  }

如果这些连接信息正确,就可以连接成功了。

18.3新建数据库test-egg

​ 我这里使用的软件MySql界面管理软件是Navicat for MySql 当然,你使用什么都可以,个人只是习惯于使用这个软件了。

利用软件,新建一个数据库test, 在新建一个test-egg`表。

CREATE TABLE `test-egg` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(10) NOT NULL,
  `age` int(11) NOT NULL,
  `skill` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

数据表建完,这节课就先到这里,下节课我们继续学习,如何用Egg-mysql插件,对数据表的增删改查。

19 Egg.js 操作 MySql 数据库

19.1 基础准备

​ 在/service文件夹下面,新建一个文件testdb.js文件,专门用于操作数据库。在文件中编写下面的方法。方法分别代表增、删、改、查。

"use strict";
const Service = require("egg").Service;
    class testdbService extends Service {
    *// 添加数据库*
    async addGirl() {}
    *// 删除数据库*
    async delGirl() {}
    *// 修改数据库*
    async updateGirl() {}
    *// 查询数据库*
    async getGirls(id) {}
    }
module.exports = testdbService;

写完之后在/controller文件夹下面新增一个控制器girlsManage.js文件,是对女孩的管理。

"use strict";

const Controller = require("egg").Controller;

class GirlManage extends Controller {
  async addGirl() {
    const { ctx } = this;

    ctx.body = "添加女孩";
  }

  async delGirl() {
    const { ctx } = this;

    ctx.body = "删除女孩";
  }

  async updateGirl() {
    const { ctx } = this;

    ctx.body = "修改女孩";
  }

  async getGirls() {
    const { ctx } = this;

    ctx.body = "查询女孩";
  }
}

module.exports = GirlManage;

配置相关路由,这里我们全部使用get请求方式,在router.js文件下加入下面的代码。

router.get("/addGirl", controller.girlManage.addGirl);
router.get("/delGirl", controller.girlManage.delGirl);
router.get("/updateGirl", controller.girlManage.updateGirl);
router.get("/getGirls", controller.girlManage.getGirls);

然后打开终端,开启服务,然后打开浏览器,输入地址,查看写的方法是否可用[http://127.0.0.1:7001/addGirl](http://127.0.0.1:7001/addGirl)

19.2 查询方法的编写

​ 我们先来学习一个最简单的方法,就是查询方法。进入/servic/testdb.js文件下的getGirls( )方法。然后编写代码。

// 查询数据库
   async getGirl(id){
    try{
      const app = this.app;
      const res= await app.mysql.select('girls')
      return res

    }catch(error){
      console.log(error)
      return null
    }
   }

写完代码以后,再编写/controller/girlManage.js文件下的getGirls( )方法。

async getGirls() {
    const { ctx } = this;

    const res = await ctx.service.testdb.getGirl()

    ctx.body = '查询女孩:'+JSON.stringify(res);
  }

这时候再到浏览器中进行预览,就可以看到可以返回数据了

19.3 添加数据操作

​ 打开/app/service/testdb.js文件,在addGirl( ) 方法下,编写下面的代码。这里插入使用的insert( )方法,

// 添加数据库
async addGirl(params){
  try {
    const { app } = this;
    const res = await app.mysql.insert('girls',params);
    return res;
  } catch (error) {
    console.log(error);
    return null;
  }
}

insert( ) 方法接收两个参数,第一个参数是表名称,第二个参数是插入到表里的值。

然后再到/app/controller/girlManage.js文件里addGirl( )方法里编写代码。

async addGirl() {
  const { ctx } = this;
  const params = {
    name:'小白',
    age:18,
    skill:'头疗'
  }
  const res =  await ctx.service.testdb.addGirl(params)
  ctx.body = '添加女孩-成功!';
}

写完之后打开终端,运行yarn dev开启服务,然后在浏览器中输入http://127.0.0.1/addGirl就可以看到结果了。再打开Navicat for MySQL查看数据表的内容。如果没有任何错误,应该是可以顺利添加成功的。

19.4 修改数据的操作

​ 会了添加,我们再来看一下如何来修改数据。打开/app/service/testdb.js文件,在updateGirl( )方法中编写代码。

// 修改数据库
async updateGirl(params){
  try {
    const { app } = this;
    const res= await app.mysql.update('girls',params);
    return res;
  } catch (error) {
    console.log(error);
      return null;
  }
}

然后再到/app/controller/girlManage.js文件中的updateGirl( )方法中,编写代码如下。

async updateGirl() {
  const { ctx } = this;
  const params = {
    id:3,
    name:'小白',
    age:20,
    skill:'头疗'
  }
  const res  = await ctx.service.testdb.updateGirl(params)
  if(res){
    ctx.body = '修改女孩-成功';
  }else{
    ctx.body = '修改失败';
  }
}

写完以后,就可以到浏览器中访问,http://127.0.0.1/updateGirl

19.5 删除数据的操作

​ 最后我们再看一下如何删除数据。还是到/app/service/testdb.js文件下的delGirl( )方法。编写下面的代码。

// 删除数据库
async delGirl(id){
  try {
      const { app } = this;
      const res = await app.mysql.delete('girls',id)
      return res;
  } catch (error) {
      console.log(error);
      return null;
  }

}

然后再到controller里边,进行编写delGirl( )方法。

async delGirl() {
    const { ctx } = this;
    const id={"id":3};
    const res = await ctx.service.testdb.delGirl(id)
    console.log(res)
    if(res){
      ctx.body = '删除女孩-成功';
    }else{
      ctx.body = '删除失败';
    }

  }

写好后,我们到浏览器里访问http://127.0.0.1/delGirl就可以了。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值