原文地址:http://blog.gdfengshuo.com/2017/07/29/20

前言

Express 是基于 Node.js 平台的 web 应用开发框架,在学习了 Node.js 的基础知识后,可以使用 Express 框架来搭建一个 web 应用,实现对数据库的增删查改。

数据库选择 MongoDB,它是一个基于分布式文件存储的开源数据库系统,Mongoose 是 MongoDB 的对象模型工具,可以在异步环境里工作。

接下来就使用 Express + Mongoose 来实现简单的增删查改,在实现的过程中来学习 Express 和 Mongoose 的基础知识。

原文作者:林鑫,作者博客:http://blog.gdfengshuo.com/

准备

既然是基于 Node.js 的框架,那么肯定需要装 node.js,还有 MongoDB,网上有很多安装教程。然后使用 express-generator 来快速生成一个 Express 项目。那么先安装一下 express-generator

  1. npm install -g express-generator

然后初始化一个名为 express-demo 的项目

  1. express express-demo

目前 Express 已经发布到了 4.x 版本,接下来也是基于这个版本来实现的。

  1. cd express-demo
  2. npm install
  3. npm start

浏览器打开 http://localhost:3000 ,就可以看到已经可以访问了。

目录

  1. ├─bin/ // 启动文件
  2. ├─public/ // 资源文件
  3. ├─routes/ // 路由
  4. ├─views/ // 视图
  5. ├─app.js
  6. └─package.json

初始化的项目目录简单明了,接下来我们来看看 app.js 里是写了什么。

  1. // view engine setup
  2. app.set('views', path.join(__dirname, 'views'));
  3. app.set('view engine', 'jade');

这是设置模板引擎,使用了 jade 模板引擎,views/ 目录下都是 .jade 格式文件,这种写法我并不熟悉,那么来改一下,改成 ejs 引擎,.html 格式的视图文件。(需要 npm 安装 ejs 模块)

  1. var ejs = require('ejs');
  2. // view engine setup
  3. app.set('views', path.join(__dirname, 'views'));
  4. app.engine('html', ejs.__express);
  5. app.set('view engine', 'html');

实现

以上准备都好了之后,我们就来看看如何实现用户信息的增删查改。这里我们先把视图和路由搭建起来,能访问页面之后再来实现数据库操作的功能。

用户列表

在 view/ 视图目录下创建以下文件: UserList.html

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>用户列表页面</title>
  5. </head>
  6. <body>
  7. <table>
  8. <tr>
  9. <th>用户名</th>
  10. <th>邮箱</th>
  11. <th>操作</th>
  12. </tr>
  13. <% for(var i in user){ %>
  14. <tr>
  15. <td><%= user[i].username %></td>
  16. <td><%= user[i].email %></td>
  17. <td>
  18. <div>
  19. <a href="/users/detail/<%= user[i]._id %>"> 查看 </a>
  20. <a href="/users/edit/<%= user[i]._id %>"> 编辑 </a>
  21. <a href="#" class="del" data-id="<%= user[i]._id %>"> 删除 </a>
  22. </div>
  23. </td>
  24. </tr>
  25. <% } %>
  26. </table>
  27. </body>
  28. </html>

<% %> 就是 ejs 模板引擎的语法,user 是在路由渲染页面的时候传过来的,它是如何传的,待会再看。

接下来实现上面视图对应的路由,项目中默认已经给我们生成了两个路由。在 routes/ 路由目录下已经有了两个路由文件:index.js 和 users.js。

app.js 中,已经帮我们设置好了这两个路由:

  1. var index = require('./routes/index');
  2. var users = require('./routes/users');
  3. app.use('/', index);
  4. app.use('/users', users);

只要浏览器访问 http://localhost:3000/users ,就能访问到 users 对应的页面了。我们来看看路由里 users.js 是如何写的。

  1. var express = require('express');
  2. var router = express.Router();
  3. router.get('/', function(req, res, next) {
  4. res.send('respond with a resource');
  5. });
  6. module.exports = router;

express.Router 类创建模块化、可挂载的路由句柄。我们修改上面代码来创建用户列表的路由 users/list

  1. var express = require('express');
  2. var router = express.Router();
  3. router.get('/', function(req, res, next) {
  4. res.send('respond with a resource');
  5. });
  6. router.get('/list', function(req, res, next) {
  7. var list = [{_id: 1, username: 'linxin', email: '123123@qq.com'}];
  8. res.render('UserList',{
  9. user: list
  10. })
  11. });
  12. module.exports = router;

还记得在 UserList.html 视图中的 user 变量吗,这里用到了 res.render() 响应方法,功能就是渲染视图模板,第一个参数为视图文件名,第二个参数为对象,用于向模板中传递数据,user 就是在这里传过去的。更改完路由之后重启服务器,访问 http://localhost:3000/users/list 就可以看到用户列表页面了。

但是这用户信息是写死的,要怎么从数据库中读取呢?

连接数据库

我们这里用到了 Mongoose,需要先安装 npm install mongoose -S 。安装之后在项目中引入并连接到数据库 userdb

  1. var mongoose = require('mongoose');
  2. mongoose.Promise = global.Promise;
  3. mongoose.connect('mongodb://localhost:27017/userdb', {useMongoClient: true});

连接成功之后,定义一个 Schema,它一种以文件形式存储的数据库模型骨架,不具备数据库的操作能力。

  1. var userSchema = new mongoose.Schema({
  2. username: String,
  3. email: String
  4. })

这里的 userSchema 还不能对数据库进行操作,只是定义了数据模型属性 username, email 为字符串类型。需要将该 Schema 发布为 Model,Model 是由 Schema 发布生成的模型,具有抽象属性和行为的数据库操作对。

  1. var model = mongoose.model('user', userSchema);

最后 model 就可以对数据库进行操作了,把上面的代码封装成 userModel.js 到根目录下新建一个 models/ 目录下面,用 module.exports = model; 将 model 暴露出来供其他文件使用。

在 user.js 路由文件里,我们来引入 userModel.js 进行数据库操作。

  1. var userModel = require('../models/userModel.js');
  2. router.get('/list', function(req, res, next) {
  3. userModel.find(function(err, data){
  4. if(err){ return console.log(err) }
  5. res.render('UserList',{
  6. user: data
  7. })
  8. })
  9. });

这里使用 userModel.find() 查询到所有用户。但是现在数据库里还是空的,我们来新增一个添加用户页面向数据库里插入数据。

添加用户

在 views/ 目录下新建 UserAdd.html 添加用户视图

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>用户编辑页面</title>
  5. </head>
  6. <body>
  7. <form action="/users/add" method="post">
  8. <input type="text" name="username" value="">
  9. <input type="email" name="email" value="">
  10. <button type="submit">submit</button>
  11. </form>
  12. </body>
  13. </html>

在 user.js 路由文件里来添加对应视图的路由

  1. router.get('/add', function(req, res, next) {
  2. res.render('UserAdd');
  3. });

这是渲染视图页面的路由,我们需要添加一个 post 方法的路由,在点击提交按钮的时候,把数据存进数据库里。

  1. router.post('/add', function(req, res, next) {
  2. var newUser = new userModel({
  3. username: req.body.username,
  4. email: req.body.email
  5. })
  6. newUser.save(function(err, data){
  7. if(err){ return console.log(err) }
  8. res.redirect('/users/list');
  9. })
  10. });

这里使用 new userModel() 创建了一个 Entity,它是由 Model 创建的实体,它的操作也会影响数据库。newUser 调用 save() 方法将数据保存到数据库中。然后 res.redirect() 将页面重定向到用户列表页面,这时就可以看到我们新增的用户显示在列表中了。接下来我们看看如何来编辑用户信息。

编辑用户

依然是创建相应的用户编辑视图:UserEdit.html

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>用户编辑页面</title>
  5. </head>
  6. <body>
  7. <form action="/users/update" method="post">
  8. <input type="hidden" name="id" value="<%= user._id %>">
  9. <input type="text" name="username" value="<%= user.username %>">
  10. <input type="email" name="email" value="<%= user.email %>">
  11. <button type="submit">update</button>
  12. </form>
  13. </body>
  14. </html>

添加对应的路由:/users/edit/:id 来渲染视图,/users/update 来修改数据库数据

  1. router.get('/edit/:id', function (req, res, next) {
  2. var id = req.params.id;
  3. userModel.findOne({_id: id}, function (err, data) {
  4. res.render('UserEdit', {
  5. user: data
  6. })
  7. })
  8. });
  9. router.post('/update', function (req, res, next) {
  10. var id = req.body.id;
  11. userModel.findById(id, function (err, data) {
  12. if(err){ return console.log(err); }
  13. data.username = req.body.username;
  14. data.email = req.body.email;
  15. data.save(function(err){
  16. res.redirect('/users/list');
  17. })
  18. })
  19. });

userModel.findOne() 会根据查询条件 {_id: id} 查询到对应的一条数据,那么同理,查看用户详情的实现也是如此,只是渲染你到另外一个模板而已,这里就不重复写了;userModel.findById() 查询到 data 对象,该对象也属于 Entity,有 save() 操作。req.body.username 就可以获取到我们修改后的 username,修改 data 对象之后调用 save() 方法保存到数据库中。接下来看看如何删除用户吧。

删除用户

在用户列表中,点击删除按钮,就把该用户从数据库中给删除了,不需要视图,那直接写路由吧。

  1. router.delete('/del', function (req, res) {
  2. var id = req.query.id;
  3. userModel.remove({_id: id}, function (err, data) {
  4. if(err){ return console.log(err); }
  5. res.json({code: 200, msg: '删除成功'});
  6. })
  7. })

点击按钮,发送删除的请求,那我们可以使用 ajax 来实现。在用户列表页面引入 jquery,方便我们操作。然后添加 ajax 请求

  1. $('.del').on('click',function(){
  2. var id = $(this).data('id');
  3. $.ajax({
  4. url: '/users/del?id='+id,
  5. type: 'delete',
  6. success: function (res) { console.log(res); }
  7. })
  8. })

重启服务器,进入 users/list,点击删除按钮,如果看到控制台中已经打印了 {code: 200, msg: '删除成功'} ,表示已经成功删除了,这时我们刷新页面,看看列表中确实已经不存在该用户了。

代码地址: express-demo

总结

通过对用户的增删查改,学习如何写路由已经如何操作数据库。我们来总结一下:

  1. 定义 Schema,由 Schema 发布 Model 来操作数据库。
  2. Model 创建的实体 Entity,可以调用 save() 方法将数据保存到数据库中。
  3. Model.find() 方法查询到该 Schema 下的所有数据,findOne() 根据条件查询数据,findById() 根据 id 查询数据。
  4. Model.remove() 删除数据。

更多文章:lin-xin/blog

Node.js 入门:Express + Mongoose 基础使用的更多相关文章

  1. Node.js、express、mongodb 入门(基于easyui datagrid增删改查)

    前言 从在本机(win8.1)环境安装相关环境到做完这个demo大概不到两周时间,刚开始只是在本机安装环境并没有敲个Demo,从周末开始断断续续的想写一个,按照惯性思维就写一个增删改查吧,一方面是体验 ...

  2. [js高手之路]Node.js+jade+express+mongodb+mongoose+promise实现todolist

    promise主要是用来解决异步回调问题,其实还有好几种比promise更好的方案,后面再说,这节,我们先用promise来改造下,我以前写的一篇文章[js高手之路]javascript腾讯面试题学习 ...

  3. Node.js、express、mongodb 实现分页查询、条件搜索

    前言 在上一篇Node.js.express.mongodb 入门(基于easyui datagrid增删改查) 的基础上实现了分页查询.带条件搜索. 实现效果 1.列表第一页. 2.列表第二页 3. ...

  4. Node.js 入门手册:那些最流行的 Web 开发框架

    这篇文章与大家分享最流行的 Node.js Web 开发框架.Node 是一个服务器端 JavaScript 解释器,它将改变服务器应该如何工作的概念.它的目标是帮助程序员构建高度可伸缩的应用程序,编 ...

  5. Node.js 入门到干活,10 个优质项目就够了!

    Node.js 在很多大公司都有不错的实践,比如:淘宝.天猫 Web 版,很多页面都是在 Node 服务器上渲染的.还有各种脚手架.前端打包发布工具.构建生态的小工具,也基本都是 Node.js 编写 ...

  6. Node.js基于Express框架搭建一个简单的注册登录Web功能

    这个小应用使用到了node.js  bootstrap  express  以及数据库的操作 :使用mongoose对象模型来操作 mongodb 如果没了解过的可以先去基本了解一下相关概念~ 首先注 ...

  7. 【特别推荐】Node.js 入门教程和学习资源汇总

    这篇文章与大家分享一批很有用的 Node.js 入门教程和学习资源.Node 是一个服务器端的 JavaScript 解释器,它将改变服务器应该如何工作的概念.它的目标是帮助程序员构建高度可伸缩的应用 ...

  8. Node.js 入门教程和学习资源汇总

    这篇文章与大家分享一批很有用的 Node.js 入门教程和学习资源.Node 是一个服务器端的 JavaScript 解释器,它将改变服务器应该如何工作的概念.它的目标是帮助程序员构建高度可伸缩的应用 ...

  9. node.js使用express框架进行文件上传

    关于node.js使用express框架进行文件上传,主要来自于最近对Settings-Sync插件做的研究.目前的研究算是取得的比较好的进展.Settings-Sync中通过快捷键上传文件,其实主要 ...

  10. node.js之express框架

    之前学习过node.js接触过express框架,最近为了编写一个mock server正好用到了express.下面正好就跟大家介绍一下关于express.今天的内容主要围绕这么几个方面? expr ...

随机推荐

  1. Java NIO学习笔记 NIO选择器

    Java NIO选择器 A Selector是一个Java NIO组件,可以检查一个或多个NIO通道,并确定哪些通道已准备就绪,例如读取或写入.这样一个线程可以管理多个通道,从而管理多个网络连接. 为 ...

  2. 【Python3之面向对象进阶】

    一.isinstance和issubclass 1.isinstance(obj,cls)检查是否obj是否是类 cls 的对象 class Foo(object): pass obj=Foo() p ...

  3. 闭包中this指向window的原因

    var t={ b:1, w:function a(){ var b=2; alert(this.b); //弹出t对象的b属性 alert(b); //弹出a函数的b变量 return functi ...

  4. Swift 路由机制设计

    设计模式 APP设计模式多种多样,从最初的MVC到MVVM,再到MVP,VIPER等.越来越多的设计模式被开发出来并得以应用,但不论我们用到哪种设计模式,只需要记住高内聚.低耦合那边是好的设计模式.在 ...

  5. touchmover 手机端拖动方法

    function drag(obj, parentNode) { var obj = document.getElementById(obj); if (arguments.length == 1) ...

  6. Python 操作 MYSQL

    本文介绍了 Python 操作 MYSQL.执行 SQL 语句.获取结果集.遍历结果集.取得某个字 段.获取表字段名.将图片插入数据库.执行事务等各种代码实例和详细介绍,代码居多, 是一桌丰盛唯美的代 ...

  7. EF查询百万级数据的性能测试--多表连接复杂查询

    相关文章:EF查询百万级数据的性能测试--单表查询 一.起因  上次做的是EF百万级数据的单表查询,总结了一下,在200w以下的数据量的情况(Sql Server 2012),EF是可以使用,但是由于 ...

  8. JavaWeb 后端 <四> 之 Cookie HttpSession 学习笔记

    一.会话管理概述 1.什么是会话? 好比一次通话.打开浏览器,点击多次链接(发出多次请求和收到多次的响应),关闭浏览器,这个过程就是一次会话. 有功能 可以  文件 新建会话 2.解决的问题是什么? ...

  9. poj3276

    Face The Right Way Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 5121   Accepted: 237 ...

  10. Spring3中@Value注解的使用

    Spring可以通过@Value注解来直接获取properties文件里面配置的值. 1. 首先要在spring的配置文件中指明properties文件的位置: <context:propert ...