文章目录

  • 一、创建、初始化项目
    • 1、在对应的文件夹下,执行
    • 2、选择simple - Simple egg app boilerplate
    • 3、文件信息全部点确认
    • 4、安装依赖
    • 5、初始目录结构
  • 二、文档执行逻辑
    • 1、基础应用
    • 2、后端渲染
    • 3、从数据库获取数据
  • 三、路由router
    • 1、路由的详细定义说明
      • 1.2、演示示例
      • 1.3 报错:missing csrf token
    • 2、RESTful 风格的 URL 定义
      • 2.1、个人理解
      • 2.2、演示示例
    • 3、获取参数
      • 3.1、获取query查询参数:/user?id=2
      • 3.2、获取params查询参数:/user/2
      • 3.3、获取前端传递的from表单(JSON对象)
  • 四、控制器controller
    • 1、作用
    • 2、controller中每个函数的this
    • 3、获取参数
      • 3.1、获取query查询参数:/user?id=2
      • 3.2、获取params查询参数:/user/2
      • 3.3、获取前端传递的from表单(JSON对象)
      • 3.4、获取上传的文件(\)
  • 五、视图view(模板引擎)-后端渲染?
    • 1、安装(以egg-view-ejs为例)
    • 2、使用前配置
    • 3、创建一个html文件
    • 4、渲染这个文件
  • 六、服务Service
    • 1、使用场景
    • 2、Service中函数this的属性和方法和controller一致
    • 3、使用说明
      • 3.1、定义service
      • 3.2、Service ctx 详解
      • 3.3、使用 Service
    • 4、报错
      • 4.1、报错404
  • 七、修改默认图标
  • 八、发送网络请求(HttpClient)-调用第三方链接
    • 1、通过 app 使用 HttpClient
    • 2、通过 ctx 使用 HttpClient(用这个)
  • 九、框架扩展extend(类似于utils)
    • 1、使用场景
    • 2、使用说明(以Application为例说明)
      • 2.1、定义extend
      • 2.2、获取app场景
      • 2.3、使用extend
  • 十、中间件Middleware(类似于axios 的请求拦截器)
    • 1、定义中间件
    • 2、全局中配置中间件
    • 3、路由中配置中间件
  • 十一、定时任务schedule
    • 1、使用场景
    • 2、使用说明
  • 十二、连接MySQL数据库
    • 1、安装包
    • 2、配置
      • 2.1、开启插件
      • 2.2、单数据源
    • 3、使用数据库组件
      • 3.1、增
      • 3.2、查
      • 3.3、改
      • 3.4、删
      • 3.5、通过`query`直接使用sql语句
  • 理解

一、创建、初始化项目

1、在对应的文件夹下,执行

npm init egg --type=simple

2、选择simple - Simple egg app boilerplate

3、文件信息全部点确认

4、安装依赖

npm i

5、初始目录结构

二、文档执行逻辑

1、基础应用

  • router.js ->

    • utl路径 ->
    • 路径匹配控制器 ->
  • controller文件夹 ->
    • 对应文档 ->
    • 文档中对应的函数 ->
  • 执行渲染

2、后端渲染

  • router.js ->

    • utl路径 ->
    • 路径匹配控制器 ->
  • controller文件夹 ->
    • 对应文档 ->
    • 文档中对应的函数 ->
  • 执行渲染 -> render函数

3、从数据库获取数据

  • router.js ->

    • utl路径 ->
    • 路径匹配控制器 ->
  • controller文件夹 ->
    • 对应文档 ->
    • 文档中对应的函数 ->
    • 调用service里的函数获取数据库数据 ->
    • 将数据作为变量渲染或返回
  • service文件夹 ->
    • 对应函数 ->
    • 写sql语句 ->
    • 返回数据

三、路由router

1、路由的详细定义说明

router.verb('router-name', 'path-match', middleware1, ..., middlewareN, app.controller.action);
  • verb - 用户触发动作,支持 get,post,patch ,put ,delete 等所有 HTTP 方法,
  • router-name 给路由设定一个别名,(可选)
  • path-match - 路由 URL 路径。
  • middleware1 - 中间件。(可选)
  • controller - 指路由对应的执行函数,controller 可以有两种写法:
    • 常用app.controller.user.fetch - 直接指定一个具体的 controller。

      • controller通过app提前解构后,可以写成controller.user.fetch
    • 'user.fetch' - 可以简写为字符串形式

1.2、演示示例

// app/router.js
router.post('/test', controller.home.test);// app/controller/home.js
async test() {const { ctx } = this;ctx.body = '路由测试';
}

1.3 报错:missing csrf token

// config/config.default.js
// 关闭CSRFconfig.security = {csrf: {enable: false,},};

2、RESTful 风格的 URL 定义

2.1、个人理解

RESTful 风格,就是控制器不到单个函数,而是整个文件。
函数名已经内置,用不同的函数名+格式就可以实现增删改查功能。

方法类型 url路径 函数名 函数作用
GET /user index 查询所有数据
GET /user/:id show 查找一条数据
GET /user/:id/edit edit 修改一条数据
POST /user create 新增一条数据
PUT /user/:id update 更新一条数据
DELETE /user/:id destroy 删除一条数据

2.2、演示示例

// app/router.js
router.resources('user', '/user', controller.user);// app/controller/user.js
class UserController extends Controller {async index() {// 查询所有的数据const { ctx } = this;// 获取query查询参数    query:http://127.0.0.1:7001/user?id=2const id = ctx.query.id;ctx.body = 'hi, RESTful风格,返回所有的数据' + id;}async show() {// show查找某一条数据const { ctx } = this;// 获取id参数:params:http://127.0.0.1:7001/user/2 const { id } = ctx.params;ctx.body = 'hi, RESTful风格,从数据库中查询出指定的一条数据,show方法,' + id;}async edit() {const { ctx } = this;const { id } = ctx.params;ctx.body = 'hi, RESTful风格,修改某一条数据,edit方法,' + id;}async create() {const { ctx } = this;// 获取前端传递的from表单(JSON对象)const data = ctx.request.body;// ctx.body = 'hi, RESTful风格,新增某一条数据,create方法,' + data;ctx.body = data;}async update() {const { ctx } = this;const { id } = ctx.params;ctx.body = 'hi, RESTful风格,更新某一条数据,update方法,' + id;}async destroy() {const { ctx } = this;const { id } = ctx.params;ctx.body = 'hi, RESTful风格,删除某一条数据,destroy方法,' + id;}
}

3、获取参数

3.1、获取query查询参数:/user?id=2

// 获取query查询参数    query:http://127.0.0.1:7001/user?id=2
const id = ctx.query.id;

3.2、获取params查询参数:/user/2

// 获取params查询参数:params:http://127.0.0.1:7001/user/2
const { id } = ctx.params;

3.3、获取前端传递的from表单(JSON对象)

// 获取前端传递的from表单(JSON对象)
const data = ctx.request.body;// 获取前端传递的from表单中的某一条数据(JSON对象)
const data = ctx.request.body.from表单的name属性;

四、控制器controller

1、作用

  • 获取用户通过 HTTP 传递过来的请求参数。
  • 校验、组装参数。
  • 调用 Service 进行业务处理,必要时处理转换 Service 的返回结果,让它适应用户的需求。
  • 通过 HTTP 将结果响应给用户

2、controller中每个函数的this

  • this.ctx:当前请求的上下文 Context 对象的实例,通过它我们可以拿到框架封装好的处理当前请求的各种便捷属性和方法。
  • this.app: 当前应用 Application 对象的实例,通过它我们可以拿到框架提供的全局对象和方法。
  • this.service:应用定义的 Service,通过它我们可以访问到抽象出的业务层,等价于 this.ctx.service 。
  • this.config:应用运行时的配置项。
  • this.logger:logger 对象,上面有四个方法(debug,info,warn,error),分别代表打印四个不同级别的日志,使用方法和效果与 context logger 中介绍的一样,但是通过这个 logger 对象记录的日志,在日志前面会加上打印该日志的文件路径,以便快速定位日志打印位置。

3、获取参数

3.1、获取query查询参数:/user?id=2

// 获取query查询参数    query:http://127.0.0.1:7001/user?id=2
const id = ctx.query.id;

3.2、获取params查询参数:/user/2

// 获取params查询参数:params:http://127.0.0.1:7001/user/2
const { id } = ctx.params;

3.3、获取前端传递的from表单(JSON对象)

// 获取前端传递的from表单(JSON对象)
const data = ctx.request.body;// 获取前端传递的from表单中的某一条数据(JSON对象)
const data = ctx.request.body.from表单的name属性;

3.4、获取上传的文件(<form enctype=“multipart/form-data”>)

1)在 config 文件中启用 file 模式:

// config/config.default.js
exports.multipart = {mode: 'file',
};

2)上传 / 接收文件:(单个文件)
你的前端静态页面代码应该看上去如下样子:

<formmethod="POST"action="/upload?_csrf={{ ctx.csrf | safe }}"enctype="multipart/form-data"
>title: <input name="title" /> file: <input name="file" type="file" /><button type="submit">Upload</button>
</form>

对应的后端代码如下:

// app/controller/upload.js
const Controller = require('egg').Controller;
const fs = require('mz/fs');module.exports = class extends Controller {async upload() {const { ctx } = this;const file = ctx.request.files[0];const name = 'egg-multipart-test/' + path.basename(file.filename);let result;try {// 处理文件,比如上传到云端result = await ctx.oss.put(name, file.filepath);} finally {// 需要删除临时文件await fs.unlink(file.filepath);}ctx.body = {url: result.url,// 获取所有的字段值requestBody: ctx.request.body,};}
};

3)上传 / 接收文件:(多个文件)
你的前端静态页面代码应该看上去如下样子:

<formmethod="POST"action="/upload?_csrf={{ ctx.csrf | safe }}"enctype="multipart/form-data"
>title: <input name="title" /> file1: <input name="file1" type="file" /> file2:<input name="file2" type="file" /><button type="submit">Upload</button>
</form>

对应的后端代码如下:

// app/controller/upload.js
const Controller = require('egg').Controller;
const fs = require('mz/fs');module.exports = class extends Controller {async upload() {const { ctx } = this;console.log(ctx.request.body);console.log('got %d files', ctx.request.files.length);for (const file of ctx.request.files) {console.log('field: ' + file.fieldname);console.log('filename: ' + file.filename);console.log('encoding: ' + file.encoding);console.log('mime: ' + file.mime);console.log('tmp filepath: ' + file.filepath);let result;try {// 处理文件,比如上传到云端result = await ctx.oss.put('egg-multipart-test/' + file.filename,file.filepath,);} finally {// 需要删除临时文件await fs.unlink(file.filepath);}console.log(result);}}
};

五、视图view(模板引擎)-后端渲染?

1、安装(以egg-view-ejs为例)

npm i egg-view-ejs --save

2、使用前配置

// {app_root}/config/plugin.js
module.exports = {ejs: {enable: true,package: 'egg-view-ejs',},
};// {app_root}/config/config.default.js
module.exports = appInfo => {config.view = {mapping: {// 让.html文件,按照ejs模板引擎渲染'.html': 'ejs',},};
}// ejs config
exports.ejs = {};

3、创建一个html文件

<!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><link rel="stylesheet" href="/public/css/base.css">
</head><body><!-- 不同模板引擎,对应的语法不同,现查官方文档就行 --><h2>用户---<%= data[1].name %></h2><!-- 静态文件 --><!-- <img src="/public/images/avator.jpg" alt=""> --><ul><% for (let i=0; i<data.length; i++) { %><li><%= data[i].name %></li><% } %></ul>
</body>
</html>

4、渲染这个文件

// app/controller/home.js
class HomeController extends Controller {async index() {const { ctx, service } = this;// 渲染带参数变量的html页面const data = await service.user.getUsers();await ctx.render('user', { data });}
}

六、服务Service

1、使用场景

  • 从数据库获取数据,返回用户显示。
  • 用户上传数据后,更新到数据库。
  • 第三方服务的调用,比如 GitHub 信息获取等。

2、Service中函数this的属性和方法和controller一致

3、使用说明

3.1、定义service

// app/service/user.js
'use strict';
const Service = require('egg').Service;class UserService extends Service {async find(uid) {const user = await this.ctx.db.query('select * from user where uid = ?',uid,);return user;}
}module.exports = UserService;

3.2、Service ctx 详解

  • this.ctx.curl 发起网络调用。
  • this.ctx.service.otherService 调用其他 Service。
  • this.ctx.db 发起数据库调用等, db 可能是其他插件提前挂载到 app 上的模块。

3.3、使用 Service

// app/router.js
module.exports = (app) => {app.router.get('/user/:id', app.controller.user.info);
};// app/controller/user.js
const Controller = require('egg').Controller;
class UserController extends Controller {async info() {const { ctx } = this;const userId = ctx.params.id;const userInfo = await ctx.service.user.find(userId);ctx.body = userInfo;}
}
module.exports = UserController;// app/service/user.js
const Service = require('egg').Service;
class UserService extends Service {// 默认不需要提供构造函数。// constructor(ctx) {//   super(ctx); 如果需要在构造函数做一些处理,一定要有这句话,才能保证后面 `this.ctx`的使用。//   // 就可以直接通过 this.ctx 获取 ctx 了//   // 还可以直接通过 this.app 获取 app 了// }async find(uid) {// 假如 我们拿到用户 id 从数据库获取用户详细信息const user = await this.ctx.db.query('select * from user where uid = ?',uid,);// 假定这里还有一些复杂的计算,然后返回需要的信息。const picture = await this.getPicture(uid);return {name: user.user_name,age: user.age,picture,};}async getPicture(uid) {const result = await this.ctx.curl(`http://photoserver/uid=${uid}`, {dataType: 'json',});return result.data;}
}
module.exports = UserService;// curl http://127.0.0.1:7001/user/1234

4、报错

4.1、报错404

  1. app/controller/user.js文件中调用service,需要在前面加上await
  2. app/service/user.js文件中async 函数中,无论是sql还是请求url,都需要在前面加上await

七、修改默认图标

参考链接:https://sphard.com/修改egg-js项目的默认favicon图标.html

八、发送网络请求(HttpClient)-调用第三方链接

1、通过 app 使用 HttpClient

框架在应用初始化的时候,会自动将 HttpClient 初始化到 app.httpclient。 同时增加了一个 app.curl(url, options) 方法,它等价于 app.httpclient.request(url, options)
这样就可以非常方便地使用 app.curl 方法完成一次 HTTP 请求。

// app.js
module.exports = (app) => {app.beforeStart(async () => {// 示例:启动的时候去读取 https://registry.npmmirror.com/egg/latest 的版本信息const result = await app.curl('https://registry.npmmirror.com/egg/latest', {dataType: 'json',});app.logger.info('Egg latest version: %s', result.data.version);});
};

2、通过 ctx 使用 HttpClient(用这个)

框架在 Context 中同样提供了 ctx.curl(url, options)ctx.httpclient ,保持跟 app 下的使用体验一致。 这样就可以在有 Context 的地方(如在 controller 中)非常方便地使用 ctx.curl() 方法完成一次 HTTP 请求。

简单理解:能获取ctx 的地方都可以用,比如controller 、service等

// app/controller/npm.js
class NpmController extends Controller {async index() {const ctx = this.ctx;// 一般写到service里面了// 示例:发送一个post请求const result = await ctx.curl('https://httpbin.org/post', {// 必须指定 methodmethod: 'POST',// 通过 contentType 告诉 HttpClient 以 JSON 格式发送contentType: 'json',// post请求携带的参数data: {hello: 'world',now: Date.now(),},// 自动解析 JSON responsedataType: 'json',// 3 秒超时timeout: 3000,});ctx.body = {status: result.status,headers: result.headers,package: result.data,};}
}

九、框架扩展extend(类似于utils)

1、使用场景

  • 通过对5个对象进行扩展,来增强框架的功能。比如:时间戳格式化功能等

    • Application(在this.app调用)
    • Context(在this.ctx调用)
    • Request
    • Response
    • Helper
  • 文件名只能是上面五个文件名
    │ └── extend (可选)
    │ │ ├── helper.js (可选)
    │ │ ├── request.js (可选)
    │ │ ├── response.js (可选)
    │ │ ├── context.js (可选)
    │ │ ├── application.js (可选)

2、使用说明(以Application为例说明)

2.1、定义extend

// app/extend/application.js
module.exports = {foo(param) {// this 就是 app 对象,在其中可以调用 app 上的其他方法,或访问属性// 这里写函数的处理逻辑return param},
};

2.2、获取app场景

Controller,Middleware,Helper,Service 中都可以通过 this.app 访问到 Application 对象,例如 this.app.config 访问配置对象。

2.3、使用extend

// app/controller/home.js
class HomeController extends Controller {async index() {// 通过this解构,获取到appconst { ctx, service, app } = this;// 使用app.方法即可console.log(app.foo('extend框架扩展'));const data = await service.user.getUsers();await ctx.render('user', { data });}
}

十、中间件Middleware(类似于axios 的请求拦截器)

1、定义中间件

// app/middleware/aa.js/* eslint-disable strict */
module.exports = options => {return async function(ctx, next) {console.log(111);console.log('接收options:');console.log(options);// 这里写拦截请求后的处理逻辑// ....await next();};
};

2、全局中配置中间件

// config/config.default.js// 将定义的中间件文件添加config.middleware = [ 'aa' ];
// 可以设置传递给中间件的参数config.aa = {name: '中间件参数',};

3、路由中配置中间件

// app/router.jsmodule.exports = app => {const { router, controller } = app;// 添加拦截器const bb = app.middleware.bb('在路由中使用中间件');// 使用拦截器router.get('/', bb, controller.home.index);};

十一、定时任务schedule

1、使用场景

  • 定时上报应用状态。
  • 定时从远程接口更新本地缓存。
  • 定时进行文件切割、临时文件删除。

2、使用说明

// app/schedule/abc.js/* eslint-disable strict */
module.exports = {schedule: {interval: '5s', // 1 分钟间隔type: 'all', // 指定所有的 worker 都需要执行},async task(ctx) {// 这里是真正定时任务执行时被运行的函数// const res = await ctx.curl('http://www.api.com/cache', {//   dataType: 'json',// });// ctx.app.cache = res.data;console.log('定时任务开始了:' + ctx);},
};

十二、连接MySQL数据库

1、安装包

npm i --save egg-mysql

2、配置

2.1、开启插件

// config/plugin.js
module.exports = {// config/plugin.jsmysql: {enable: true,package: 'egg-mysql',},
};

2.2、单数据源

// config/config.default.js
module.exports = appInfo => {// 单数据源config.mysql = {// 单数据库信息配置client: {// hosthost: '127.0.0.1',// 端口号port: '3306',// 用户名,自己mysql的用户名user: 'root',// 密码,自己mysql的密码password: '*******',// 数据库名database: 'test-egg',},// 是否加载到 app 上,默认开启app: true,// 是否加载到 agent 上,默认关闭agent: false,};

3、使用数据库组件

3.1、增

// app/controller/user2.js
'use strict';const Controller = require('egg').Controller;class User2Controller extends Controller {async create() {const { ctx, app } = this;// 正常情况下,这条语句是写在service文件夹下的// 1.获取前端传递的数据// 假设data是// {//   "name":"lisi",//   "age":20,//   "add":"zhongguo",// }const data = ctx.request.body;// 2.将前端传递的参数,进行整理,避免跟数据库的要求格式不符const row = {name: data.name,age: data.age,};// 3.传给数据库const res = await app.mysql.insert('users', row);ctx.body = res;}
}module.exports = User2Controller;

3.2、查

'use strict';const Controller = require('egg').Controller;class User2Controller extends Controller {async index() {const { ctx, app } = this;// 查询所有// const res = await app.mysql.select('users');// 条件查询const res = await app.mysql.select('users', {where: { age: 20 }, // WHERE 条件columns: [ 'id', 'age' ], // 要查询的表字段(要显示的表字段)select id,age from usersorders: [[ 'id', 'desc' ]], // 排序方式limit: 10, // 返回数据量offset: 0, // 数据偏移量  (pageNum-1)*limit});// 查询一条记录// const res = await app.mysql.get('users', { id: 2 });ctx.body = res;}
}module.exports = User2Controller;

3.3、改

'use strict';const Controller = require('egg').Controller;class User2Controller extends Controller {async update() {const { ctx, app } = this;// 1.从前端获取,要修改的数据信息const data = ctx.request.body;// 2.获取要修改的id值const id = ctx.params.id;// 3.将数据信息进行整理const row = {id,name: data.name,age: data.age,};// 4.传给数据库更新数据const res = await app.mysql.update('users', row);ctx.body = res;}
}module.exports = User2Controller;

3.4、删

'use strict';const Controller = require('egg').Controller;class User2Controller extends Controller {async destroy() {const { ctx, app } = this;// 1.获取要删除的id值const id = ctx.params.id;// 2.根据id删除信息const res = await app.mysql.delete('users', { id });// 删除age为19岁的数据// const res = await app.mysql.delete('users', { age:19 });ctx.body = res;}
}module.exports = User2Controller;

3.5、通过query直接使用sql语句

'use strict';const Controller = require('egg').Controller;class User2Controller extends Controller {async index() {const { ctx, app } = this;// 通过sql语句查询// const res = await app.mysql.query('select * from users');// 通过sql语句新建一条数据const data = ctx.request.body;// 单项占位符// const res = await app.mysql.query('INSERT INTO users(name) VALUES(?)', [ data.name ]);// 多个占位符const res = await app.mysql.query('INSERT INTO `users`(`name`, `age`) VALUES(?,?)', [ data.name, data.age ]);ctx.body = res;}}module.exports = User2Controller;

理解

【eggjs的基本使用】相关推荐

  1. eggjs的参数校验模块egg-validate的使用和进一步定制化升级

    简单讲一下这个egg-validate egg-validate是基于parameter的. 安装 npm install --save egg-validate 启用 // config/plugi ...

  2. Eggjs笔记:详解Mongoose的聚合管道以及populate实现关联查询

    基于mongodb的聚合管道 此处忽略之前mongodb在eggjs中需要配置的步骤,前文已有说明,现在开始在controller中调用(应该封装到service中的,仅作为示例) const res ...

  3. Eggjs入门系列-基础全面讲解(完结)

    对上篇文章回顾下,上篇讲到了 服务(Service) 插件 定时任务 框架扩展 启动自定义 应用部署 日志 HttpClient Cookie 与 Session Cookie 通过 ctx.cook ...

  4. Eggjs笔记:egg-mongoose插件的集成,crud操作, 多表关联查询

    Egg 中的 model app/model/** 用于放置领域模型,可选,由领域类相关插件约定. Loader : Egg 在 Koa 的基础上进行增强最重要的就是基于一定的约定 根据功能差异将代码 ...

  5. 一篇文章学会eggjs做后端服务及各种问题处理

    文章目录 一.项目搭建 二.登录鉴权,密码存储 三.swagger生成接口文档 1.安装依赖 2.配置插件 3.路由重定向(非必操项) 4.创建contract目录 5.在controller目录下给 ...

  6. eggjs框架学习心得

    前言: eggjs作为阿里开源的企业级 Node.js 框架,其官网教程https://eggjs.org/zh-cn/tutorials/index.html介绍的很详细,可以帮助初学开发者快速搭建 ...

  7. eggjs mysql_阿里开源eggjs,eggjs+ejs+mysql 初始化项目,简单记录

    基本运行境 node 最低要求 8.x mysql 版本 没具体测试过,理论上都可以 初始化项目 我们推荐直接使用脚手架,只需几条简单指令,即可快速生成项目: npm install egg-init ...

  8. EventSource+eggjs

    最近看了chartGpt的请求,发现了EventSource的事件,之前没用过,所以学习下 前端代码 const evtSource = new EventSource("/test/see ...

  9. web前端学习(四):基于koa的EggJs框架,优雅而又完美的Nodejs框架

    **前言: ** Egg.js为企业级开发应用,而产生的一门Node.js框架 它使用模块化渐进式开发,内置多进程管理(Node是单进程,无法使用多核CPU的能力),具有高度可扩展的插件机制. 基于K ...

  10. eggjs框架源码解读

    文章目录 前言 Egg进程模型 Egg应用程序结构 egg运行启动的内幕 加载插件 扩展内置对象 加载中间件 加载service 加载路由 加载配置 设置应用信息 执行业务逻辑 文件加载机制 结语 前 ...

最新文章

  1. 技术非中立,语言非同质:机器翻译正被用于维护文化障碍
  2. 最新的SqlHelper 类
  3. golang中strings.ToUpper
  4. 如何使用Navicat恢复数据库脚本
  5. DeprecationWarning Mongoose mpromise (mongoose's default promise li
  6. 2018 年都过去了,你还没有掌握用户运营的核心技巧?
  7. HDU 1520 Anniversary party(树形dp)
  8. SAP BRF+ ruleset里维护多条rule,每条rule逐一执行
  9. python知识点总结_20211231
  10. “0”基础让你学会 GridView (一)
  11. C++中引用变量的探究
  12. Python金融数据挖掘 第11章 复习思考题2 (聚类)选取中华人民共和国第六次人口普查的各地区人口数以及男女比例进行K-Means聚类分析。
  13. Tomcat JAAS 身份验证和授权
  14. 中国省份城市数据库表
  15. idea打字光标不跟随解决
  16. PHP遍历数组,分别将内容加入到table表格中
  17. ofo开放平台成立了,mobike该做些什么?
  18. vulnhub靶场,Monitoring
  19. [prometheus]Step7-prometheus使用阿里云企业邮箱告警
  20. STGCN、ASTGCN、STSGCN、STFGNN模型的对比实验操作步骤

热门文章

  1. python 安装 pymssql 库时报错
  2. bootstrap引用glyphicon图标无法显示
  3. 品牌创建百科怎么写?品牌百度百科怎么创建?
  4. 使用Transformer构建自己的机器翻译服务
  5. 【数据结构实验六】图的遍历DFS和BFS
  6. pandas使用to_datetime函数将时间字符串转化为时间对象、其中月份内容为字母而非数字(例如,“January 2, 2022“)
  7. matlab中的isnan函数怎么用,matlab isnan用法
  8. JAVA将十位时间戳格式化为日期Date类型
  9. dcoker常用命令
  10. Sorry, this application cannot run under a Virtual Machine的解决