NodeJS_05

 

NodeJS七天课程学习笔记_第5天

课程内容概要:

1. pakcage-lock.json的细节

2. Array的新增方法find内部细节

3. MongoDB的安装、配置和使用

4. CRUD增删改查

5. Promise异步编程

推荐了一个Sublime Text 插件: HTML-CSS-JS Prettify

sublime 通过命令,直接手动设置当前文档的高亮语法种类

Sublime同时选中多行内容等实用操作:
1. ctrl + command + 上下箭头,作用是:上移或下移当前行
2. command + D, 作用是:选中光标所在单词,重复按可同时选中多个相同的单词
3. alt + 左右箭头, 作用是:跳至单词的起始或结束位置
4. ctrl + 左右箭头, 切换屏幕,如全屏的视频 与 编辑器之间切换

NodeJS七天课程主讲老师:李鹏周

JS 奥义: 单线程+事件循环
哪怕setTimeout延迟是0秒,甚至不传第2个延时的参数,
也一定要等主线程运行结束后,才执行定时器中的方法
setTimeout(function(){NSLog(‘keke’)},0)

如图所示:

另一个回调函数的例子:

代码如下:

function add(x,y,callback){
  setTimeout(function(){
    var result = x + y
    callback(result)
  },1000)
}

var x = 6
var y = 7
add(x,y,function(result){
  NSLog(x + ' + ' + y + ' = ' + result)
})

效果如下:

又一个回调函数的例子:

代码如下:

<!DOCTPYE html>  
<html lang="zh">  
<head>  
    <link rel="icon" href="beyond2.jpg" type="image/x-icon"/>
    <meta charset="UTF-8">
    <meta name="author" content="beyond">
    <meta http-equiv="refresh" content="520">
    <meta name="description" content="未闻花名-免费零基础教程-beyond">
    <meta name="viewport" content="width=device-width, 
    initial-scale=1.0, maximum-scale=1.0,minimum-scale=1.0,user-scalable=0" />
    <meta name="keywords" content="HTML,CSS,JAVASCRIPT,JQUERY">
    <title>beyond心中の动漫神作</title>
    <link rel="stylesheet" type="text/css" href="beyondbasestylewhite3.css">
    <script type="text/javascript" src="nslog.js"></script>

    <!--[if lt IE 9]>
        <script src="//apps.bdimg.com/libs/html5shiv/3.7/html5shiv.min.js"></script>


        <script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/1.10.2/jquery.js">
        </script>
    <![endif]-->

    <style type="text/css">
        body{
            font-size: 100%; 
            /*声明margin和padding是个好习惯*/  
            margin: 0;  
            padding: 0; 
            background-image: url("sakura4.png");  
            background-repeat: no-repeat;  
            background-position: center center;  
        }
    </style>
    <!-- 绿色按钮的css效果 -->
    <link rel="stylesheet" type="text/css" href="beyondbuttongreen.css">

    <!-- 引入 jquery 2.1.4 -->
    <!--[if gte IE 9]><!--> 
    <script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.js">
    </script>
    <!--<![endif]-->


    
</head>  
  
<body>  
        <h1 style="color:white;text-shadow:2px 2px 4px #000;letter-spacing:5px;" class="sgcontentcolor sgcenter">  
            未闻花名
        </h1>

        <button id="id_btn" class="class_btn class_btn_green" type="button" style="display:block;margin:auto;margin-top:10px;">点我试试</button>
        <script type="text/javascript">

            // 自己封装一个get请求
            function beyondGet (url,callback) {
                   // 自己实现一个ajax请求
                   // 1. 创建xhr
                   var xmlHttpRequest = new XMLHttpRequest()
                   // 2. 请求url资源
                   xmlHttpRequest.onload = function () {
                      // 5. 核心代码,回调结果
                      callback(xmlHttpRequest.responseText)
                   }
                   // 3.连接资源
                   xmlHttpRequest.open("get",url,true)
                   // 4.发送请求
                   xmlHttpRequest.send()
            }
            $(document).ready(function () {
               $(".class_btn_green").click(function () {
                  // 使用自己封装的ajax请求
                  beyondGet("anohana2.txt",function (responseText) {
                    // body...
                    NSLog('responseText: \n' + responseText)
                  })
                   
               })
            })
        </script>
        <p class="sgcenter">
          <b>注意:</b> 使用自己封装的get函数发送ajax请求
        </p>
        <footer id="copyright">
            <p style="font-size:14px;text-align:center;font-style:italic;">  
            Copyright © <a id="author">2018</a> Powered by <a id="author">beyond</a>  
            </p>        
        </footer>
    
</body>  
</html>  

效果如下:

另一种写法,效果和上面是一样的:

<script type="text/javascript">

            // 自己封装一个get请求
            function beyondGet (url,callback) {
                   // 自己实现一个ajax请求
                   // 1. 创建xhr
                   var xmlHttpRequest = new XMLHttpRequest()
                   // 3.连接资源
                   xmlHttpRequest.open("GET",url,true)

                   // 2. 请求url资源
                   xmlHttpRequest.onreadystatechange = function () {
                      if (xmlHttpRequest.readyState === 4 && xmlHttpRequest.status === 200) {
                          // 5. 核心代码,回调结果
                          callback(xmlHttpRequest.responseText)
                      }
                   }
                   
                   // 4.发送请求
                   xmlHttpRequest.send(null)
            }
            $(document).ready(function () {
               $(".class_btn_green").click(function () {
                  // 使用自己封装的ajax请求
                  beyondGet("anohana2.txt",function (responseText) {
                    // body...
                    NSLog('responseText: \n' + responseText)
                  })
                   
               })
            })
        </script>

注意:凡是需得到一个函数内部异步操作的结果时,必须使用回调函数
如 setTimeout,readFile,writeFile,ajax

打个比方:你想追一部正在播出的动漫,每天都不厌其烦,一天N次去看它有更新了没有,这样非常没有效率
但是,只要你一旦订阅了之后,每当它有更新时,它会主动通知你,这就是在回调

众所周知,JavaScript天生不支持模块化
Node环境,通过CommonJS对JS实现了支持模块化

浏览器中,也可以像Node.js一样模块化编程
只需要使用第3方库:
1. Require.js (俗称AMD,即异步 模块 定义,全称是Asynchromous Module Definition)
官网:requirejs.com

2. Sea.js     (俗称CMD,即公共 模块 定义,全称是Common Module Definition)

3. UMD,即通用 模块 定义,全称是Universal Module Definition)

4. ECMAScript6 中官方的 Modules 规范(后面的Vue课程中会讲编译工具)

(前面课程已经教过)Less 编译–> CSS
ES6  编译–> ES5

在npm5以前,是没有package-lock.json这个文件

npm5以后,才增加了package-lock.json  (关键字:锁定版本+提高下载速度)
1. 当你安装第3方包的时候,都会生成或更新这个package-lock.json文件
2. 新版本中,不用写 –save,也能够将第3方包的安装记录,自动添加到包描述文件package.json里的dependences属性里
3. package-lock.json中记录了node_modules中所有包的 版本 以及 下载地址
4. 从package-lock.json文件名来看,有一个lock,作用就是(在不小心删除node_modules目录时,重新npm install时)锁定住特定的版本号的功能,防止自动升级到新版本

// 在不升级Node的情况下,npm自己升级自己
npm install –global npm

// 下载安装时,指定版本@1.11.1
npm install jquery@1.11.1

// package.json中jquery的^1.11.1中的^符号表示,可以安装该版本之上的版本

自己为数组实现一个find函数,参数是一个匿名函数,
find函数内部遍历数组,并让每个元素作为参数传递给参数里的匿名函数,
如果条件成立,则返回 当前的元素
Array.prototype.myFind = function(conditionFunction){
for(var i = 0; i < this.length; i++){
if(conditionFunction(this[i],i)){
return this[i]
}
}
// 如果没有找到符合条件的元素,则undefine
}

// 使用方法
var girlArr = [‘面码’,’mathilda’,’逢坂大河’]
var menma = girlArr.myFind(function(item,index){
return item === ‘面码’
})
NSLog(menma)

运行效果,如图所示

express 默认情况下,提示Can’t get xxx
如何自定义一个漂亮的404页面?

只需要要在自己的路由之后,增加一个
appServer.use(function(request,response){
// 这样所有的未处理的请求,都会跑到这儿来
// 在这儿,定制404页面即可
})

补充了一下,数组所有的与遍历相关的方法
forEach
find,findIndex
every
some
map
includes

reduce 强大

MongoDB

关系型数据库 与 非关系型数据库

NoSQL

关系型数据库:
1. 表就是关系,表与表之间存在关系
2. 所有关系型数据库都通过sql语言进行操作数据库
3. 所有的关系型数据库最初都要设计表结构(包括约束:唯一,主键,非空,默认值)

非关系型数据库:
1. 非常得灵活
2. 有的仅仅就是key – value键值对
3. MongoDB是长得最像关系型数据库的非关系型数据库
3.1 MongoDB里面,也有数据库
3.2 MongoDB里面,表 就叫做 集合/数据
3.3 MongoDB里面,记录 就叫做 文档对象
3.4 MongoDB里面,不需要设计 表结构 ,你可以往里面任意地存入数据,没有结构这么一个概念

MongoDB官网:mongodb.org,

点击download,然后选择社区版Community Server

https://fastdl.mongodb.org/osx/mongodb-osx-ssl-x86_64-3.6.3.tgz

mongodb-osx-ssl-x86_64-3.6.3.tgz  大小 87.7M

32位的下载地址: mongodb.org/dl/win32/i386

安装过程:

1.  解压缩

2. 将文件夹mongodb-osx-x86_64-3.6.3 重命名为 mongodb

3. 将mongodb目录整个移动到 /usr/local目录

4. 将mongodb目录下的bin目录的路径永久添加到path环境变量中

4.1 打开 open -t ~/.bash_profile

4.2 在文档的最后面追加下面两行

MONGODB=/usr/local/mongodb/bin
export PATH=$PATH:$MONGODB

注意: 下面这个如果是在命令行中,那么仅仅是临时添加到环境变量中

export PATH=/usr/local/mongodb/bin:$PATH

5. 核心步骤:在系统根目录下创建/data/db  (若缺少这一步,服务无法启动)

MongoDB的数据存储在磁盘根目录下的data目录的db目录下,但是这个目录在安装过程不会自动创建,所以你需要手动创建data目录,并在data目录中创建db目录。
sudo mkdir -p /data/db
注意:/data/db 是 MongoDB 默认的启动的数据库路径(--dbpath)。

也可以使用下面的命令来 修改默认的存储目录

mongod --dbpath=数据存储目录

6. 打开终端,输入mongod –version 查看版本

7. sudo mongod 启动数据库服务,如图所示: (必须加sudo)

8. 下面使用mongo命令,连接本机的数据库

再打开一个终端, cd /usr/local/mongodb/bin/ ,  再执行  ./mongo

(因为加入了 环境变量,直接敲 mongo 也是可以的)

可以看到连接信息,如图所示:

此时前面一个终端就会收到连接信息,如下所示:

2018-04-13T19:54:02.196+0800 I NETWORK  [initandlisten] waiting for connections on port 27017
2018-04-13T19:58:16.181+0800 I NETWORK  [listener] connection accepted from 127.0.0.1:64944 #1 (1 connection now open)
2018-04-13T19:58:16.183+0800 I NETWORK  [conn1] received client metadata from 127.0.0.1:64944 conn: 
{ application: { name: "MongoDB Shell" }, driver: { name: "MongoDB Internal Client", version: "3.6.3" }, os: { type: "Darwin", name: "Mac OS X", architecture: "x86_64", version: "16.6.0" } }

9. 如果要退出连接, 输入 exit 即可

如果要关闭服务, 只要关闭终端即可,或者 Ctrl + C 取消

注意: windows系统下面,也要找到安装目录下的bin目录,将它添加到环境变量中

如windows下的 c:\Program Files\MongoDB\Server\3.4\bin

之后,再打开终端: 输入命令 mongod –version

MongodDB数据库的表现形式如下:

1. 可以有多个数据库

2. 一个库,可以有多个表(集合)

3. 一个表(集合),可以有多个记录(文档)

4. 一个记录(文档),就是一个对象,由键值对构成

由此可见: 文档结构相当滴灵活,木有任何限制;

不需要像关系型数据库,事先设计库、表、约束等

{
  db2:{
    girls:[
      {
        "girlName" : "面码",
        "girlAge" : 15,
        "girlAnime" : "未闻花名"
      },
      {
        "girlName" : "mathilda",
        "girlAge" : 12,
        "girlAnime" : "这个杀手不太冷"
      },
      {
        "girlName" : "逢坂大河",
        "girlAge" : 16,
        "girlAnime" : "龙与虎"
      }
    ],
  // 另外两张表(集合)  
  animes:[{},{},{}],
  songs: [{},{},{}]
  },
// 另外的一个数据库,以此类推
db2:{...}
}

常用命令和操作:

1.  显示所有的数据库

> show dbs

效果如下:

2.  使用指定数据库(如果没有会创建)

> use db2

3.  显示当前在哪一个数据库

> db

4.  尝试在db2这个数据库的girl表(这儿叫集合),插入一条记录(这儿叫文档 )

> db.girl.inserOne({

“girlName” : “面码”,

“girlAge” : 15

})

上面的语句在插入一条记录(文档)的同时,也新建了一个girl表(集合)

5.  显示当前的db2数据库下面,所有的表(集合)

> show collections

6.  查询当前的db2数据库下面girl表(集合)里面的所有记录(文档)

> db.girl.find()

7.  更新一条记录(文档)

> 有点复杂,emmmm….

8.  删除一条记录(文档),条件是: girlAge = 15

>db.girl.remove({“girlAge”:15})

删除所有的记录(文档)

>db.girl.remove({})

9.  删除girl表(集合)

> db.girl.drop()

在Node中如何操作MongoDB数据库,

1.  使用MongoDB官方提供的包进行操作

https://github.com/mongodb/node-mongodb-native

2.  推荐使用第3方包 mongoose 进行操作,mongoose在MongoDB官方的包上面再进行了一层封装,使用起来更加方便

http://mongoosejs.com/

第1步:  安装第3方包

npm install mongoose --save

第2步:  按照官方的demo,向db2数据库中的girl表(集合)中插入一条记录(文档)

node_34_add.js代码如下:

function NSLog(loli,needLogo=true) {console.log(loli);if(needLogo){console.log('\nCopyright © 2018 Powered by beyond')};}  


// 导入框架
const mongoose = require('mongoose')
// 向db2这个数据库插入记录(没有则会创建)
const dbUrl = 'mongodb://localhost/db2'
mongoose.connect(dbUrl)

// 向girl表(集合)插入记录(文档)
// 定义girl表(集合)的规范
var girlSchema = mongoose.Schema({
	girlName: {
		type:String,
		// 非空字段
		required: true
	},
	girlAge: Number,
	girlAnime: String
	// isLoli: Boolean
	// pubTime: Date
	// messages:[{title:String,content:String,pubTime:Date}]
	// lover:{name:String,age:Number}
})
// 通过schema转成一个构造函数
// 参数1必须是: 首字母大写
// mongoose会自动将它转成小写并变成复数,作为表(集合)名
// 例如这儿的Girl,会自动变成girls表(集合)
// model方法的返回值是: 构造函数
const Girl = mongoose.model('Girl',girlSchema)
// typeof Girl: function 构造函数
NSLog('typeof Girl: ' + typeof(Girl))
// 使用 构造函数,创建一个记录(文档)对象,用于插入
const tiger = new Girl({
	girlName: "面码",
	girlAge: 15,
	girlAnime: "未闻花名"
})

// 插入一个对象
tiger.save().then(
	() => NSLog('插入成功')
)

效果如下: (插入成功后,再通过mongo命令连接数据库,查看是否真的有添加成功)

查询所有的记录(文档)node_35_find.js代码如下:

find方法

// 查找所有,第1个参数不写,就是查找所有
Girl.find(function (error,girls) {
	if (error) {
		return NSLog('查询出错: ' + error)
	}
	NSLog('查询结果: ' + girls)
})

效果如下:

按条件,查询指定的记录(文档)node_35_find.js代码如下:

find方法

// ----------------条件查询------------------

// 条件查询,第1个参数就是查询条件之一
var condition = {girlName:"面码"}
Girl.find(condition,function (error,girls) {
	if (error) {
		return NSLog('查询出错: ' + error)
	}
	NSLog('条件查询: ' + girls)
})

条件查询,效果如下:

另一个按条件查询,年龄大于12岁,node_35_find.js代码如下:

find方法

// ----------------条件查询------------------
// 条件查询,第1个参数就是查询条件之一
// 姓名为 面码, 并且 年龄 大于(great than) 12
var condition = {
				  girlName:"面码",
				  girlAge: {$gt: 12}
				}
Girl.find(condition,function (error,girls) {
	if (error) {
		return NSLog('查询出错: ' + error)
	}
	NSLog('条件查询: ' + girls)
})

效果如下:

根据id查找,并更新记录node_35_update.js代码如下:

findByIdAndUpdate

// ----------------根据Id查找并更新记录(文档)------------------
var idString = '5ad1732aa33423ed19e7ae2e'
var newObj = {girlAge: 13}
Girl.findByIdAndUpdate(idString,newObj,function (error) {
	if (error) {
		NSLog('更新失败: ' + error)	
	}
	NSLog('更新成功')
})

效果如下:

根据指定条件,更新一个:
Model.findOneAndUpdate([conditions],[updateObj],[options],[callback])

// ------------把girlName为'面码'更新为'menma'--------
var newObj = {girlName: 'menma'}
// 参数1: conditions不写 就是更新所有
var conditions = {girlName: '面码'}
// 参数3: 写不写好像都可以...emmmm
var options = {strict: true}
Girl.findOneAndUpdate(conditions,newObj,options,function (error) {
	if (error) {
		NSLog('更新失败: ' + error)	
	}
	NSLog('更新成功')
})

根据条件更新所有:

Model.updateMany(conditions,newDoc,[options],[callback])

还有一个只更新一个的方法是: Model.update(conditions,newDoc,[options],[callback])

// ------------把所有的girl年龄更新为13岁---------
var newObj = {girlAge: 13}
// 参数1: conditions不写 就是更新所有
var conditions = {}
// 参数3: 写不写好像都可以...emmmm
var options = {strict: false}
Girl.updateMany(conditions,newObj,options,function (error) {
	if (error) {
		NSLog('更新失败: ' + error)	
	}
	NSLog('更新成功')
})

条件删除node_35_remove.js代码如下:

remove方法

// ----------------条件删除------------------
Girl.remove({girlAge: 15},function (error) {
	if (error) {
		return NSLog('删除失败: ' + error)
	}
	NSLog('success: 条件删除')
})

删除全部node_35_remove.js代码如下:

remove方法

// ----------------删除所有------------------
Girl.remove({},function (error) {
	if (error) {
		return NSLog('删除失败: ' + error)
	}
	NSLog('success: 删除全部')
})

删除数据:
Model.findOneAndRemove(conditions,[options],[callback])

// ----------------条件删除------------------
Girl.findOneAndRemove({girlAge: 13},function (error) {
	if (error) {
		return NSLog('删除失败: ' + error)
	}
	NSLog('success: 条件删除')
})

根据id删除一个
Model.findByIdAndRemove(id,[options],[callback])

// ----------------条件删除------------------
Girl.findOneAndRemove('5ad40f38d1a2972dfb3fcf94',function (error) {
	if (error) {
		return NSLog('删除失败: ' + error)
	}
	NSLog('success: 条件删除')
})

下面开始把前面的使用文件作为数据库的CRUD项目Node_32_index.js,改造成使用mongodb

这是原来项目的结构:

使用mongod作为数据库,  新的项目node_36_index.js结构如下:

运行效果如下:

3个完整js代码如下:

首页app入口: node_36_index.js代码如下:

function NSLog(loli,needLogo=true) {console.log(loli);if(needLogo){console.log('\nCopyright © 2018 Powered by beyond')};}  


// 导入框架
var express = require('express')
// 创建服务器对象
var appServer = express()
// 监听端口,并启动服务
appServer.listen(5267,function (error) {
	if (error) {
		return NSLog('启动失败: ' + error)
	}
	NSLog('服务启动成功')
})
// -----------------------------------

// 静态资源请求时的 staticFileUrlPrefix
var staticFileUrlPrefix = '/public/'
// var staticFileUrlPrefix = '/public'

// 访问也只能使用 localhost:5267/public/img/beyond.jpg
// 磁盘上的静态资源目录
var staticFilePath = './public/'   
// var staticFilePath = 'public' 

var callbackFunction = express.static(staticFilePath)
appServer.use(staticFileUrlPrefix,callbackFunction)

// -----------------------------------

// 指明:对于 所有后缀为html 的模板文件 使用模板引擎
var templateFileSuffix = 'html'
appServer.engine(templateFileSuffix,require('express-art-template'))
// 下面这一句参数配置,可有可无
appServer.set('view options',{
	debug: process.env.NODE_ENV !== 'production'
})
// 注意:如果不想把模板文件放在默认的views目录下,则可以通过下面代码更改设置
// appServer.set('views','其他目录')

// -----------------------------------
// 使用middleware中间件body-parser进行post请求体中数据解析
var bodyParser = require('body-parser')
// 设置解析 application/x-www-form-urlencoded
appServer.use(bodyParser.urlencoded({extended: false}))        
// 设置解析 application/json
appServer.use(bodyParser.json())
// -----------------------------------
// 自定义路由设计的目的是:
// 1.让主入口程序的职责更加单一,代码更加简洁
//     1.1 创建服务
//     1.2 做一些服务相关的配置,比如:
//           1.2.1 静态资源配置
//           1.2.2 模板引擎配置
//           1.2.3 body-parse 解析表单
//           1.2.4 挂载自定义路由
//           1.2.5 监听端口,启动服务
// 使用自定义的路由模块 必须使用./
// 注意: 配置模板引擎和body-parser, 一定要在挂载路由之前
var beyondRouter = require('./node_36_router')
appServer.use(beyondRouter)

路由模块node_36_router.js代码如下:

function NSLog(loli) {console.log(loli);return 'Copyright © 2018 Powered by beyond';};  
/*
	自定义路由模块的职责是:
		专门处理所有的路由
		根据不同的请求方式和路径,采取相应的处理方法
*/ 
// express 专门提供了路由的处理方法
var express = require('express')
// 1.使用express专门提供的路由器处理路由
var router = express.Router()

// ----------------引入dao模块-------------------
// 先对dao初始化
var GirlDaoFunction = require('./node_36_dao')
// 时间格式化
var BeyondDateFormatFunction = require('./BeyondDateFormat')

// ----------------首页-------------------
router.get('/',function (request,response) {
	// 至于请求参数可以这样:
	// var queryObj = request.query

	// ----------------查找所有------------------
	// 查找所有,第1个参数不写,就是查找所有
	GirlDaoFunction.find(function (error,girls) {
	if (error) {
		return NSLog('查询出错: ' + error)
	}

	// 使用模板引擎渲染
		// 注意: 模板文件默认是放在views目录下
		// 为此,我们在views目录下  分别为不同的业务模块创建了不同的文件夹
		// 如 login登录 admin后台管理 index前台首页 article文章 comment评论
		response.render('index/node_36_index.html',{girlArr:girls})

	})

})

// ----------------添加的表单页面-------------------
router.get('/add',function (request,response) {
	response.render('index/node_36_add.html')
})


// ----------------增加一条记录-------------------
router.post('/insert',function (request,response) {
	// 1.body-parser得到obj
	var girlObj = request.body
	// NSLog(girlObj)
	// 1.调用girlDao写到文件数据库
	girlObj.pubTime = BeyondDateFormatFunction(new Date(),'yyyy-MM-dd')
	var newGirl = new GirlDaoFunction(girlObj)
	// 2.保存到数据库
	newGirl.save(function (error) {
		if (error) {
			// 有错误
			return response.status(500).send(error)
		}
		// 没有错误,跳转到首页	
		response.redirect('/')
	})
})

// ----------------修改页面------------------- 
router.get('/edit',function (request,response) {
	// 查询的girlID 不知怎么滴,首尾有引号
	//  "5ad42675f917fa32e250a58a"
	// 使用正则,把引号去掉, 如果不使用g的话,仅仅只是去掉第1个引号
	var pureId = request.query._id.replace(/"/g,"")
	// NSLog('query: ' + pureId)
	GirlDaoFunction.findById(pureId,function (error,girl) {
		if (error) {
			return response.status(500),send(error)
		}
		response.render('index/node_36_edit.html',{'girl': girl})
	})
})
// ----------------更新数据库------------------- 
router.post('/update',function (request,response) {
	// 1.请求体 id号 (前后多了两个引号,要手动去掉)
	var girlID = request.body._id
	var girlIDWithoutQuote = girlID.replace(/"/g,'')
	// 2.重新设置回去
	request.body._id = girlIDWithoutQuote
	// 3.根据id查询和更新
	GirlDaoFunction.findByIdAndUpdate(girlIDWithoutQuote,request.body,function (error) {
		if(error){
			// 如果保存出错了
			return response.status(500).send(error)
		}
		// 如果保存成功,回首页
		response.redirect('/')
	})
})

// ----------------删除一条记录------------------- 
router.get('/delete',function (request,response) {
	// 1.获取query对象中的_id
	var girlID = request.query._id
	var girlIDWithoutQuote = girlID.replace(/"/g,'')
	// 2.调用dao从数据库中删除一个对象
	GirlDaoFunction.findByIdAndRemove(girlIDWithoutQuote,function (error) {
		if (error) {
			// 有错误
			return response.status(500).send(error)
		}
		// 如果没有错误,跳转到首页
		return response.redirect('/')
	})
})


// 3.在模块文件最后,导出router
module.exports = router

使用了MongodDB的数据库操作模块node_36_dao.js代码如下:

function NSLog(loli) {console.log(loli);return 'Copyright © 2018 Powered by beyond';};  

// ----------------初始化------------------- 
var mongoose = require('mongoose')
// 连接数据库 db2,默认端口是: 27017
mongoose.connect('mongodb://localhost/db2')
var Schema = mongoose.Schema
// 仿着 文件数据库 node_32.db 设计表结构
var girlSchema = new Schema({
	girlName: {
		type: String,
		required: true
	},
	girlAge: {
		type: Number,
		enum: [8,9,10,11,12,13,14,15,16], // 好像没有什么效果
		default: 13
	},
	girlDescription: {
		type: String,
		required: true,
		default: ''

	},
	pubTime: {
		type: String,
		required: true,
		// 默认值 只是一个函数名,但不调用,即不加括号,因为一旦调用,会立刻执行
		default: ''
	},

})


// 核心代码: 直接导出 模型构造函数
// 参数1: Girl 首字母必须大写,且必须是单数; 
// 这样就能自动生成girls表(集合)
module.exports = mongoose.model('Girl',girlSchema)

3个html模板代码如下:

首页模板node_36_index.html代码如下:

<!DOCTPYE html>  
<html lang="zh">  
<head>  
    <link rel="icon" href="/public/img/beyond2.jpg" type="image/x-icon"/>
    <meta charset="UTF-8">
    <meta name="author" content="beyond">
    <meta http-equiv="refresh" content="520">
    <meta name="description" content="未闻花名-免费零基础教程-beyond">
    <meta name="viewport" content="width=device-width, 
    initial-scale=1.0, maximum-scale=1.0,minimum-scale=1.0,user-scalable=0" />
    <meta name="keywords" content="HTML,CSS,JAVASCRIPT,JQUERY,XML,JSON,C,C++,C#,OC,PHP,JAVA,JSP,PYTHON,RUBY,PERL,LUA,SQL,LINUX,SHELL,汇编,日语,英语,泰语,韩语,俄语,粤语,阿语,魔方,乐理,动漫,PR,PS,AI,AE">
    <title>beyond心中の动漫神作</title>
    <link rel="stylesheet" type="text/css" href="/public/css/beyondbasestylewhite5.css">
    <script type="text/javascript" src="/public/js/nslog.js"></script>

    <!--[if lt IE 9]>
        <script src="//apps.bdimg.com/libs/html5shiv/3.7/html5shiv.min.js"></script>


        <script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/1.10.2/jquery.js">
        </script>
    <![endif]-->

    <style type="text/css">
        body{
            font-size: 100%; 
            /*声明margin和padding是个好习惯*/  
            margin: 0;  
            padding: 0; 
            background-image: url("/public/img/sakura4.png");  
            background-repeat: no-repeat;  
            background-position: center center;  
        }
    </style>
    <!-- 绿色按钮的css效果 -->
    <link rel="stylesheet" type="text/css" href="/public/css/beyondbuttongreen.css">

    <!-- 引入 jquery 2.1.4 -->
    <!--[if gte IE 9]><!--> 
    <script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.js">
    </script>
    <!--<![endif]-->


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


    <!-- 分隔线 -->

    <!-- Bootstrap core CSS -->
    <link href="/public/lib/node30_337_bootstrap.css" rel="stylesheet">

    <!-- Custom styles for this template -->
    <link href="/public/css/node30dashboard.css" rel="stylesheet">

    

    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!--[if lt IE 9]>
      <script src="https://cdn.bootcss.com/html5shiv/3.7.3/html5shiv.min.js"></script>
      <script src="https://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->

</head>  
  
<body>

    <nav class="navbar navbar-inverse navbar-fixed-top">
      <div class="container-fluid">
        <div class="navbar-header">
          <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>
          <a class="navbar-brand" href="#" style="color:white;">beyond</a>
        </div>
        <div id="navbar" class="navbar-collapse collapse">
          <ul class="nav navbar-nav navbar-right">
            <li><a href="#">Dashboard</a></li>
            <li><a href="#">Settings</a></li>
            <li><a href="#">Profile</a></li>
            <li><a href="#">Help</a></li>
          </ul>
          <form class="navbar-form navbar-right">
            <input type="text" class="form-control" placeholder="Search...">
          </form>
        </div>
      </div>
    </nav>

    <div class="container-fluid">
      <div class="row">
        <div class="col-sm-3 col-md-2 sidebar">
          <ul class="nav nav-sidebar">
            <li class="active"><a href="#">Overview <span class="sr-only">(current)</span></a></li>
            <li><a href="#">Reports</a></li>
            <li><a href="#">Analytics</a></li>
            <li><a href="#">Export</a></li>
          </ul>
          <ul class="nav nav-sidebar">
            <li><a href="">Nav item</a></li>
            <li><a href="">Nav item again</a></li>
            <li><a href="">One more nav</a></li>
            <li><a href="">Another nav item</a></li>
            <li><a href="">More navigation</a></li>
          </ul>
          <ul class="nav nav-sidebar">
            <li><a href="">Nav item again</a></li>
            <li><a href="">One more nav</a></li>
            <li><a href="">Another nav item</a></li>
          </ul>
        </div>
        <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
          <h1 class="page-header" style="color:white;text-shadow:2px 2px 4px #000;letter-spacing:5px;" class="sgcontentcolor sgcenter">未闻花名<small style="color:#ddd;"><a href="/add" style="color:white">添加记录</a>(Node+Express+MongoDB版)</small></h1>

          <!-- <div class="row placeholders">
            <div class="col-xs-6 col-sm-3 placeholder">
              <img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail">
              <h4>Label</h4>
              <span class="text-muted">Something else</span>
            </div>
            <div class="col-xs-6 col-sm-3 placeholder">
              <img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail">
              <h4>Label</h4>
              <span class="text-muted">Something else</span>
            </div>
            <div class="col-xs-6 col-sm-3 placeholder">
              <img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail">
              <h4>Label</h4>
              <span class="text-muted">Something else</span>
            </div>
            <div class="col-xs-6 col-sm-3 placeholder">
              <img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail">
              <h4>Label</h4>
              <span class="text-muted">Something else</span>
            </div>
          </div> -->

          <!-- <h2 class="sub-header">动漫神作列表 </h2> -->
          
          <div class="table-responsive" >
            <table class="table table-striped">
              <thead>
                <tr>
                  <th>id</th>
                  <th>芳名</th>
                  <th>年龄</th>
                  <th>动漫</th>
                  <th>日期</th>
                  <th>操作</th>
                </tr>
              </thead>
              <tbody>
              {{ each girlArr }}
                <tr>
                  <td style="vertical-align:middle;">{{ $index + 1 }}</td>
                  <td style="vertical-align:middle;">{{ $value.girlName }}</td>
                  <td style="vertical-align:middle;">{{ $value.girlAge }}</td>
                  <td style="vertical-align:middle;">{{ $value.girlDescription }}</td>
                  <td style="vertical-align:middle;">{{ $value.pubTime }}</td>
                  <td>
                    <button class="btn btn-success"><a href="/edit?_id={{ $value._id }}" style="color:white;">修改</a></button>
                    <button class="btn btn-danger"><a href="/delete?_id={{ $value._id }}" style="color:white;">删除</a></button>
                  </td>
                </tr>
            {{ /each }}
                
              </tbody>
            </table>
          </div>
        </div>
      </div>
    </div>

    <footer id="copyright">
            <p style="font-size:14px;text-align:center;font-style:italic;">  
            Copyright © <a id="author">2018</a> Powered by <a id="author">beyond</a>  
            </p>        
        </footer>
  </body>
</html>

添加girl的模板node_36_add.html代码如下:

<!DOCTPYE html>  
<html lang="zh">  
<head>  
  <link rel="icon" href="/public/img/beyond2.jpg" type="image/x-icon"/>
  <meta charset="UTF-8">
  <meta name="author" content="beyond">
  <meta http-equiv="refresh" content="520">
  <meta name="description" content="未闻花名-免费零基础教程-beyond">
  <meta name="viewport" content="width=device-width, 
  initial-scale=1.0, maximum-scale=1.0,minimum-scale=1.0,user-scalable=0" />
  <meta name="keywords" content="HTML,CSS,JAVASCRIPT,JQUERY,XML,JSON,C,C++,C#,OC,PHP,JAVA,JSP,PYTHON,RUBY,PERL,LUA,SQL,LINUX,SHELL,汇编,日语,英语,泰语,韩语,俄语,粤语,阿语,魔方,乐理,动漫,PR,PS,AI,AE">
  <title>beyond心中の动漫神作</title>
  <link rel="stylesheet" type="text/css" href="/public/css/beyondbasestylewhite5.css">
  <script type="text/javascript" src="/public/js/nslog.js"></script>

    <!--[if lt IE 9]>
        <script src="//apps.bdimg.com/libs/html5shiv/3.7/html5shiv.min.js"></script>


        <script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/1.10.2/jquery.js">
        </script>
        <![endif]-->

        <style type="text/css">
          body{
            font-size: 100%; 
            /*声明margin和padding是个好习惯*/  
            margin: 0;  
            padding: 0; 
            background-image: url("/public/img/sakura4.png");  
            background-repeat: no-repeat;  
            background-position: center center;  
          }
        </style>
        <!-- 绿色按钮的css效果 -->
        <link rel="stylesheet" type="text/css" href="/public/css/beyondbuttongreen.css">

        <!-- 引入 jquery 2.1.4 -->
        <!--[if gte IE 9]><!--> 
        <script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.js">
        </script>
        <!--<![endif]-->


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


        <!-- 分隔线 -->

        <!-- Bootstrap core CSS -->
        <link href="/public/lib/node30_337_bootstrap.css" rel="stylesheet">

        <!-- Custom styles for this template -->
        <link href="/public/css/node30dashboard.css" rel="stylesheet">



        <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!--[if lt IE 9]>
      <script src="https://cdn.bootcss.com/html5shiv/3.7.3/html5shiv.min.js"></script>
      <script src="https://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
      <![endif]-->

    </head>  

    <body>

      <nav class="navbar navbar-inverse navbar-fixed-top">
        <div class="container-fluid">
          <div class="navbar-header">
            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
              <span class="sr-only">Toggle navigation</span>
              <span class="icon-bar"></span>
              <span class="icon-bar"></span>
              <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="#" style="color:white;">beyond</a>
          </div>
          <div id="navbar" class="navbar-collapse collapse">
            <ul class="nav navbar-nav navbar-right">
              <li><a href="#">Dashboard</a></li>
              <li><a href="#">Settings</a></li>
              <li><a href="#">Profile</a></li>
              <li><a href="#">Help</a></li>
            </ul>
            <form class="navbar-form navbar-right">
              <input type="text" class="form-control" placeholder="Search...">
            </form>
          </div>
        </div>
      </nav>

      <div class="container-fluid">
        <div class="row">
          <div class="col-sm-3 col-md-2 sidebar">
            <ul class="nav nav-sidebar">
              <li class="active"><a href="#">Overview <span class="sr-only">(current)</span></a></li>
              <li><a href="#">Reports</a></li>
              <li><a href="#">Analytics</a></li>
              <li><a href="#">Export</a></li>
            </ul>
            <ul class="nav nav-sidebar">
              <li><a href="">Nav item</a></li>
              <li><a href="">Nav item again</a></li>
              <li><a href="">One more nav</a></li>
              <li><a href="">Another nav item</a></li>
              <li><a href="">More navigation</a></li>
            </ul>
            <ul class="nav nav-sidebar">
              <li><a href="">Nav item again</a></li>
              <li><a href="">One more nav</a></li>
              <li><a href="">Another nav item</a></li>
            </ul>
          </div>
          <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
            <h1 class="page-header" style="color:white;text-shadow:2px 2px 4px #000;letter-spacing:5px;" class="sgcontentcolor sgcenter">未闻花名<small><a href="/" style="color:white;">回到首页</a></small></h1>

            <div class="row placeholders">
              <!-- <div class="col-xs-6 col-sm-3 placeholder">
                <img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail">
                <h4>Label</h4>
                <span class="text-muted">Something else</span>
              </div>
              <div class="col-xs-6 col-sm-3 placeholder">
                <img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail">
                <h4>Label</h4>
                <span class="text-muted">Something else</span>
              </div>
              <div class="col-xs-6 col-sm-3 placeholder">
                <img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail">
                <h4>Label</h4>
                <span class="text-muted">Something else</span>
              </div>
              <div class="col-xs-6 col-sm-3 placeholder">
                <img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail">
                <h4>Label</h4>
                <span class="text-muted">Something else</span>
              </div> -->
            </div>

            <!-- <h2 class="sub-header">动漫神作列表 </h2> -->



            <form action="/insert" method="post">
              <div class="form-group">
                <label for="in_input_name">芳名</label>
                <input type="text" class="form-control" id="in_input_name" placeholder="请输入妳的名字" name="girlName">
              </div>
              <div class="form-group">
                <label for="id_input_age">年龄</label>
                <input type="text" class="form-control" id="id_input_age" placeholder="请输入妳的芳龄" name="girlAge">
              </div>

              <div class="form-group">
                <label for="id_input_anime">动漫推荐</label>
                <input type="text" class="form-control" id="id_input_anime" placeholder="请输入妳主演过的动漫" name="girlDescription">
              </div>
              <button type="submit" class="btn btn-default">Submit</button>
            </form>
          </div>
        </div>
        <footer id="copyright">
          <p style="font-size:14px;text-align:center;font-style:italic;">  
            Copyright © <a id="author">2018</a> Powered by <a id="author">beyond</a>  
          </p>        
        </footer>
      </body>
      </html>

修改girl的模板node_36_edit.html代码如下:

<!DOCTPYE html>  
<html lang="zh">  
<head>  
  <link rel="icon" href="/public/img/beyond2.jpg" type="image/x-icon"/>
  <meta charset="UTF-8">
  <meta name="author" content="beyond">
  <meta http-equiv="refresh" content="520">
  <meta name="description" content="未闻花名-免费零基础教程-beyond">
  <meta name="viewport" content="width=device-width, 
  initial-scale=1.0, maximum-scale=1.0,minimum-scale=1.0,user-scalable=0" />
  <meta name="keywords" content="HTML,CSS,JAVASCRIPT,JQUERY,XML,JSON,C,C++,C#,OC,PHP,JAVA,JSP,PYTHON,RUBY,PERL,LUA,SQL,LINUX,SHELL,汇编,日语,英语,泰语,韩语,俄语,粤语,阿语,魔方,乐理,动漫,PR,PS,AI,AE">
  <title>beyond心中の动漫神作</title>
  <link rel="stylesheet" type="text/css" href="/public/css/beyondbasestylewhite5.css">
  <script type="text/javascript" src="/public/js/nslog.js"></script>

    <!--[if lt IE 9]>
        <script src="//apps.bdimg.com/libs/html5shiv/3.7/html5shiv.min.js"></script>


        <script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/1.10.2/jquery.js">
        </script>
        <![endif]-->

        <style type="text/css">
          body{
            font-size: 100%; 
            /*声明margin和padding是个好习惯*/  
            margin: 0;  
            padding: 0; 
            background-image: url("/public/img/sakura4.png");  
            background-repeat: no-repeat;  
            background-position: center center;  
          }
        </style>
        <!-- 绿色按钮的css效果 -->
        <link rel="stylesheet" type="text/css" href="/public/css/beyondbuttongreen.css">

        <!-- 引入 jquery 2.1.4 -->
        <!--[if gte IE 9]><!--> 
        <script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.js">
        </script>
        <!--<![endif]-->


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


        <!-- 分隔线 -->

        <!-- Bootstrap core CSS -->
        <link href="/public/lib/node30_337_bootstrap.css" rel="stylesheet">

        <!-- Custom styles for this template -->
        <link href="/public/css/node30dashboard.css" rel="stylesheet">



        <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!--[if lt IE 9]>
      <script src="https://cdn.bootcss.com/html5shiv/3.7.3/html5shiv.min.js"></script>
      <script src="https://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
      <![endif]-->

    </head>  

    <body>

      <nav class="navbar navbar-inverse navbar-fixed-top">
        <div class="container-fluid">
          <div class="navbar-header">
            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
              <span class="sr-only">Toggle navigation</span>
              <span class="icon-bar"></span>
              <span class="icon-bar"></span>
              <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="#" style="color:white;">beyond</a>
          </div>
          <div id="navbar" class="navbar-collapse collapse">
            <ul class="nav navbar-nav navbar-right">
              <li><a href="#">Dashboard</a></li>
              <li><a href="#">Settings</a></li>
              <li><a href="#">Profile</a></li>
              <li><a href="#">Help</a></li>
            </ul>
            <form class="navbar-form navbar-right">
              <input type="text" class="form-control" placeholder="Search...">
            </form>
          </div>
        </div>
      </nav>

      <div class="container-fluid">
        <div class="row">
          <div class="col-sm-3 col-md-2 sidebar">
            <ul class="nav nav-sidebar">
              <li class="active"><a href="#">Overview <span class="sr-only">(current)</span></a></li>
              <li><a href="#">Reports</a></li>
              <li><a href="#">Analytics</a></li>
              <li><a href="#">Export</a></li>
            </ul>
            <ul class="nav nav-sidebar">
              <li><a href="">Nav item</a></li>
              <li><a href="">Nav item again</a></li>
              <li><a href="">One more nav</a></li>
              <li><a href="">Another nav item</a></li>
              <li><a href="">More navigation</a></li>
            </ul>
            <ul class="nav nav-sidebar">
              <li><a href="">Nav item again</a></li>
              <li><a href="">One more nav</a></li>
              <li><a href="">Another nav item</a></li>
            </ul>
          </div>
          <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
            <h1 class="page-header" style="color:white;text-shadow:2px 2px 4px #000;letter-spacing:5px;" class="sgcontentcolor sgcenter">未闻花名<small><a href="/" style="color:white;">回到首页</a></small></h1>

            <div class="row placeholders">
              <!-- <div class="col-xs-6 col-sm-3 placeholder">
                <img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail">
                <h4>Label</h4>
                <span class="text-muted">Something else</span>
              </div>
              <div class="col-xs-6 col-sm-3 placeholder">
                <img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail">
                <h4>Label</h4>
                <span class="text-muted">Something else</span>
              </div>
              <div class="col-xs-6 col-sm-3 placeholder">
                <img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail">
                <h4>Label</h4>
                <span class="text-muted">Something else</span>
              </div>
              <div class="col-xs-6 col-sm-3 placeholder">
                <img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail">
                <h4>Label</h4>
                <span class="text-muted">Something else</span>
              </div> -->
            </div>

            <!-- <h2 class="sub-header">动漫神作列表 </h2> -->



            <form action="/update" method="post">
              <div class="form-group">
                <label for="in_input_name">芳名</label>
                <input type="text" class="form-control" id="in_input_name" placeholder="请输入妳的名字" name="girlName" value="{{ girl.girlName }}">
              </div>
              <div class="form-group">
                <label for="id_input_age">年龄</label>
                <input type="text" class="form-control" id="id_input_age" placeholder="请输入妳的芳龄" name="girlAge"  value="{{ girl.girlAge }}">
              </div>
              <!-- 隐藏表单 -->
              <input type="hidden" name="_id" value="{{ girl._id }}" />

              <div class="form-group">
                <label for="id_input_anime">动漫推荐</label>
                <input type="text" class="form-control" id="id_input_anime" placeholder="请输入妳主演过的动漫" name="girlDescription"  value="{{ girl.girlDescription }}">
              </div>
              <button type="submit" class="btn btn-default">Submit</button>
            </form>
          </div>
        </div>
        <footer id="copyright">
          <p style="font-size:14px;text-align:center;font-style:italic;">  
            Copyright © <a id="author">2018</a> Powered by <a id="author">beyond</a>  
          </p>        
        </footer>
      </body>
      </html>

# Node.js 第5天课堂笔记

## 知识点

- Express
- MongoDB
- 项目
  + 一天半的时间

## 反馈

-  新版sublime 怎么格式化 怎么一起选中长度不等的内容 怎么改颜色 有的写对了也没颜色 仍然是白色
  +  HTML-CSS-JS Prettify
-  callback是不是相当于函数自调用?
  +  很简单,函数也是一种数据类型,既可以当作参数进行传递,也可以当作方法的返回值
- 我们现在用的模块化是CMD吧 老师能不能给我们扩展一下AMD
  + PHP 中为什么就可以直接 `require`、`include` 因为 PHP 当初在设计的时候就加入了这个功能
  + PHP 这门语言天生就支持
  + 模块作用域
  + 可以使用 API 来进行文件与文件之间的依赖加载
  + 在 Node 这个环境中对 JavaScript 进行了特殊的模块化支持 CommonJS
  + JavaScript 天生不支持模块化
    * require
    * exports
    * Node.js 才有的
  + 在浏览器中也可以像在 Node 中的模块一样来进行编程
    * `<script>` 标签来引用加载,而且你还必须考虑加载的顺序问题
    * require.js 第三方库 AMD
    * sea.js     第三方库 CMD
  + 无论是 CommonJS、AMD、CMD、UMD、EcmaScript 6 Modules 官方规范
    * 都是为了解决 JavaScript 的模块化问题
    * CommonJS、AMD、CMD 都是民间搞出来的
    * EcmaScript 是官方规范定义
    * 官方看民间都在乱搞,开发人员为了在不同的环境使用不同的 JavaScript 模块化解决方案
    * 所以 EcmaScript 在 2015 年发布了 EcmaScript 2016 官方标准
    * 其中就包含了官方对 JavaScript 模块化的支持
    * 也就是说语言天生就支持了
    * 但是虽然标准已经发布了,但是很多 JavaScript 运行换将还不支持
    * Node 也是只在 8.5 版本之后才对 EcmaScript 6 module 进行了支持
    * 后面学 Vue 的时候会去学习
    * less 编译器 > css
    * EcmaScript 6 -> 编译器 -> EcmaScript 5
    * 目前的前端情况都是使用很多新技术,然后利用编译器工具打包可以在低版本浏览器运行。
    * 使用新技术的目的就是为了提高效率,增加可维护性
  +  本着达芬奇画鸡蛋的精神
  +  《使徒行者》三哥
  +  《反黑》陈小春
    *  卧底 8年卧底
    *  文职工作
    *  报了电脑版
    *  吃饭都在看书
    *  学习 -》吃饭也是看书
    *  边角余料
  + 这里涉及到一个中间件的概念
  + app.use 不仅仅是用来处理静态资源的
  + 还可以做很多工作
  + 配置 body-parse 也是通过 app.use 来配置的
  + 这叫中间件,其中有一套规则
- npm init --yes 生成一个package.json 文件 npm --save 文件名 又生成一个package-lock.json文件,又生成的文件和初始化生成的文件有区别吗?
  + 当你安装包的时候,新版的 npm 还会自动生成一个文件:package-lock.json
  + 中间件
  + EcmaScript 6 的 find 方法
- 在express框架中怎么判断访问页面不存在的情况?

## 复习

- 文件路径中的 `/` 和模块标识中的 `/`
- Express 中配置使用 art-template 模板引擎
- Express 中配置使用 body-parser
- Express 中配置处理静态资源
- CRUD 案例中单独提取路由模块

## 上午总结

- 回调函数
  + 异步编程
  + 如果需要得到一个函数内部异步操作的结果,这是时候必须通过回调函数来获取
  + 在调用的位置传递一个函数进来
  + 在封装的函数内部调用传递进来的函数
- find、findIndex、forEach
  + 数组的遍历方法,都是对函数作为参数一种运用
    + every
  + some
  + includes
  + map
  + reduce
- package-lock.json 文件的作用
  + 下载速度快了
  + 锁定版本
- JavaScript 模块化
  + Node 中的 CommonJS
  + 浏览器中的
    * AMD require.js
    * CMD sea.js
  + EcmaScript 官方在 EcmaScript 6 中增加了官方支持
  + EcmaScript 6
  + 后面我们会学,编译工具
- MongoDB 数据库
  + MongoDB 的数据存储结构
    * 数据库
    * 集合(表)
    * 文档(表记录)
- MongoDB 官方有一个 mongodb 的包可以用来操作 MongoDB 数据库
  + 这个确实和强大,但是比较原始,麻烦,所以咱们不使用它
- mongoose
  + 真正在公司进行开发,使用的是 mongoose 这个第三方包
  + 它是基于 MongoDB 官方的 mongodb 包进一步做了封装
  + 可以提高开发效率
  + 让你操作 MongoDB 数据库更方便
- 掌握使用 mongoose 对数据集合进行基本的 CRUD
- 把之前的 crud 案例改为了 MongoDB 数据库版本
- 使用 Node 操作 mysql 数据库

## 下午总结

## 目标

未完待续,下一章节,つづく