准备工作:
- 利用第三方模块 mongoose 连接数据库,代码如下:
// 首先在命令行中使用 npm install mongoose 命令下载 mongoose 模块
// 引入mongoose模块
const mongoose = require('mongoose');
// 连接数据库
mongoose.connect('mongodb://localhost/test01', { useNewUrlParser: true, useUnifiedTopology: true })
.then(() => console.log('数据库连接成功'))
.catch(err => console.log(err, '数据库连接失败'));
- 利用第三方模块mongoose创建集合规则,代码如下:
// 引入mongoose模块
const mongoose = require('mongoose');
// 创建集合规则
const userSchema = new mongoose.Schema({
name: {
type: String,
required: [true, '请输入姓名'],
minlength: 2,
maxlength: 25
},
age: {
type: Number,
min: 18,
max: 80
},
password: String,
email: String,
hobbies: [String]
});
- 利用上边创建好的集合规则创建具体的集合:
// 利用集合规则创建集合
const user = mongoose.model('User', userSchema);
// 为了保证开发模块化,将创建集合规则和创建集合放到了model文件夹下的user.js文件中,而user集合会在其他的模块中用到,所以用mu
module.exports = user;
- 搭建服务器,并监听端口:3000;命令行输入node ./app.js启动服务器
案例实现的功能
- 从网页表单添加用户信息到数据库
- 展示MongoDB数据库中所存储的用户信息:用户名、年龄、爱好、邮箱
- 对每一条用户信息可以进行删除
- 对每一条用户信息可以进行修改
代码如下:
// 引入http模块用于搭建服务器
const http = require('http');
// 引入url模块实现路由选择
const url = require('url');
// 引入第三方模块querystring模块用于将接收到的表单信息转换成对象
const querystring = require('querystring');
// 引入index.js链接数据库
require('./model/index');
// 引入user.js创建集合
const user = require('./model/user');
// 创建服务器
const app = http.createServer();
// req请求体,res服务器响应
app.on('request', async(req, res) => {
// 得到请求方式
const method = req.method;
// 得到请求地址
const pathName = url.parse(req.url).pathname;
// 得到请求地址后边带的参数,url.parse得到的query默认是字符串,
// 当第二个参数为true时,得到的就是对象
const query = url.parse(req.url, true).query;
// 进行路由选择判断
if (method == 'GET') {
// 根据请求地址呈现页面
// ----- 展示所有用户信息 start -----
if (pathName == '/list') {
// 用find()查询数据库中所有的用户数据
let userinfo = await user.find();
let list = `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>用户信息增删改查</title>
<style>
* {
margin: 0;
padding: 0;
}
button {
border: none;
}
a {
text-decoration: none;
}
.box {
width: 1300px;
margin: 100px auto;
/* border: 1px solid red; */
}
#addUser {
display: block;
width: 85px;
height: 35px;
line-height: 35px;
margin-left: 100px;
text-align: center;
border-radius: 5px;
background-color: #7c9ec1;
color: #fff;
font-size: 14px;
}
.userInfo {
margin: 30px auto;
/* 合并单元格之间的空隙 */
border-collapse: collapse;
text-align: center;
}
td {
width: 220px;
height: 40px;
border: 1px solid #ccc;
}
#delBtn,
#updataBtn {
display: inline-block;
width: 50px;
height: 25px;
line-height: 25px;
font-size: 12px;
color: #fff;
border-radius: 5px;
}
#delBtn {
background-color: #8e89a3;
}
#updataBtn {
background-color: #333;
}
tbody tr:nth-child(odd) {
background-color: #f4f4f4;
}
</style>
</head>
<body>
<div class="box">
<a href="/add" id="addUser">添加用户</a>
<table class="userInfo">
<thead>
<tr>
<td>用户名</td>
<td>年龄</td>
<td>爱好</td>
<td>邮箱</td>
<td>操作</td>
</tr>
</thead>
<tbody>`;
// 循环遍历集合中的对象
userinfo.forEach(ele => {
list += `<tr>
<td>${ele.name}</td>
<td>${ele.age}</td>
<td>`;
// 循环遍历每一条文档中的爱好数组
ele.hobbies.forEach(item => {
list += `<span>${item}</span>`;
});
// 给修改按钮加modify路由通过ele._id获取到当前点击了修改按钮的一组数据
list += `
</td>
<td>${ele.email}</td>
<td>
<a href="/remove?id=${ele._id}" id="delBtn">删除</a>
<a href="/modify?id=${ele._id}" id="updataBtn">修改</a>
</td>
</tr>`;
});
list += `
</tbody>
</table>
</div>
</body>
</html>`;
res.end(list);
} // ----- 展示所有用户信息 end -----
// ----- 展示添加用户信息页面 start -----
else if (pathName == '/add') {
let add = `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>页面添加用户</title>
<style>
* {
margin: 0;
padding: 0;
}
ul {
text-decoration: none;
list-style: none;
}
.box {
width: 400px;
margin: 100px auto;
}
ul li {
margin-top: 15px;
}
label {
display: block;
height: 30px;
}
.inp {
display: inline-block;
width: 300px;
height: 30px;
padding-left: 10px;
color: #333;
border-radius: 5px;
border: 1px solid #ccc;
/* 改变input触发时 边框颜色 */
outline-color: skyblue;
}
li:nth-child(5) input {
margin-left: 15px;
margin-right: 5px;
}
li:nth-child(5) div {
height: 50px;
}
.checkbox-inline {
float: left;
}
button {
display: block;
width: 85px;
height: 35px;
background-color: #7c9ec1;
color: #fff;
border: none;
border-radius: 10px;
outline: none;
cursor: pointer;
}
</style>
</head>
<body>
<div class="box">
<h2>添加用户</h2>
<form method="POST" action="/add">
<ul>
<li>
<label for="name">用户名</label>
<input type="text" name="name" class="inp" />
</li>
<li>
<label for="password">密码</label>
<input type="password" name="password" class="inp" />
</li>
<li>
<label for="age">年龄</label>
<input type="number" name="age" class="inp" />
</li>
<li>
<label for="email">邮箱</label>
<input type="email" name="email" class="inp" />
</li>
<li>
<label>请选择爱好</label>
<div>
<label class="checkbox-inline">
<input type="checkbox" value="足球" name="hobbies"/>足球
</label>
<label class="checkbox-inline">
<input type="checkbox" value="篮球" name="hobbies" />篮球
</label>
<label class="checkbox-inline">
<input type="checkbox" value="羽毛球" name="hobbies" />羽毛球
</label>
<label class="checkbox-inline">
<input type="checkbox" value="读书" name="hobbies" />读书
</label>
</div>
</li>
<li><button>添加用户</button></li>
</ul>
</form>
</div>
</body>
</html>`;
res.end(add);
} // ----- 展示添加用户信息页面 end -----
// ----- 修改用户信息页面 start -----
else if (pathName == '/modify') {
// 根据url地址中的id参数,用findOne方法在数据库中查询到相应的用户信息
let modifyUser = await user.findOne({ _id: query.id });
// 定义一个数组用于存放所有爱好
let hobAry = ['足球', '篮球', '羽毛球', '读书'];
// 根据查到的用户信息来显示页面
let modify = `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>修改用户信息页面</title>
<style>
* {
margin: 0;
padding: 0;
}
ul {
text-decoration: none;
list-style: none;
}
.box {
width: 400px;
margin: 100px auto;
}
ul li {
margin-top: 15px;
}
label {
display: block;
height: 30px;
}
.inp {
display: inline-block;
width: 300px;
height: 30px;
padding-left: 10px;
color: #333;
border-radius: 5px;
border: 1px solid #ccc;
/* 改变input触发时 边框颜色 */
outline-color: skyblue;
}
li:nth-child(5) input {
margin-left: 15px;
margin-right: 5px;
}
li:nth-child(5) div {
height: 50px;
}
.checkbox-inline {
float: left;
}
button {
display: block;
width: 85px;
height: 35px;
background-color: #7c9ec1;
color: #fff;
border: none;
border-radius: 10px;
outline: none;
cursor: pointer;
}
</style>
</head>
<body>
<div class="box">
<h2>修改用户信息</h2>
<form method="POST" action="/modify?id=${query.id}">
<ul>
<li>
<label for="name">用户名</label>
<input type="text" value="${modifyUser.name}" name="name" class="inp" />
</li>
<li>
<label for="password">密码</label>
<input type="password" value="${modifyUser.passwored}" name="password" class="inp" />
</li>
<li>
<label for="age">年龄</label>
<input type="number" value="${modifyUser.age}" name="age" class="inp" />
</li>
<li>
<label for="email">邮箱</label>
<input type="email" value="${modifyUser.email}" name="email" class="inp" />
</li>
<li>
<label>请选择爱好</label>
<div>
`;
// 循环遍历hobAry数组
hobAry.forEach(ele => {
let have = modifyUser.hobbies.includes(ele);
if (have) {
modify += `
<label class="checkbox-inline">
<input type="checkbox" value="${ele}" name="hobbies" checked/>${ele}
</label>`;
} else {
modify += `
<label class="checkbox-inline">
<input type="checkbox" value="${ele}" name="hobbies"/>${ele}
</label>
`;
}
});
modify += `
</div>
</li>
<li><button>确认修改</button></li>
</ul>
</form>
</div>
</body>
</html>`;
res.end(modify);
} // ----- 修改用户信息 end -----
// ----- 删除用户信息 start -----
else if (pathName == '/remove') {
await user.findOneAndDelete({ _id: query.id });
res.writeHead(301, {
'Location': '/list'
});
res.end();
} // ----- 删除用户信息 end
} else if (method == 'POST') {
// ----- 从添加用户信息页面添加用户到数据库 start -----
if (pathName == '/add') {
// 接收用户填写的表单信息
// post并不是一次性接收所有的信息,所以定义一个变量用于拼接post接收的信息
let info = '';
// 传递参数时触发data事件
req.on('data', param => {
info += param;
});
// 参数传递结束触发end事件
req.on('end', async() => { // 因await只能在异步函数中使用,所以给函数加上async
// 用querystring.parse()方法将接收到的参数转换成对象方便处理
let uInfo = querystring.parse(info);
/* 将处理后的数据存入数据库,create接收的参数是一个对象,
而经过parse处理的数据也是一个对象,所以可以直接给creat()传参。
对数据库的操作都是异步操作,所以给其加关键字await变成同步
*/
await user.create(uInfo);
// 用301重定向跳转回/list页面
res.writeHead(301, { 'Location': '/list' });
// 最后不要忘记结束响应
res.end();
});
} // ----- 从添加用户信息页面添加用户到数据库 end -----
// ----- 用户点击了确认修改按钮 start -----
else if (pathName == '/modify') {
// 接收用户填写的表单信息
// post并不是一次性接收所有的信息,所以定义一个变量用于拼接post接收的信息
let info = '';
// 传递参数时触发data事件
req.on('data', param => {
// 拼接接收到的post请求
info += param;
});
// 参数传递结束触发end事件
req.on('end', async() => {
// 用querystring.parse()方法将接收到的参数转换成对象方便处理
let userInfo = querystring.parse(info);
await user.updateOne({ _id: query.id }, userInfo)
});
// 用301重定向跳转回/list页面
res.writeHead(301, {
'Location': '/list'
});
res.end();
} // ----- 用户点击了确认修改按钮 end -----
}
});
// 监听端口
app.listen(3000);
具体操作:
- 在浏览器地址栏输入localhost:3000/list 可以访问展示所有用户信息的页面list
- 在浏览器地址栏输入localhost:3000/add 可以访问添加用户信息的页面add
- 点击 /add 页面的添加用户按钮会将该条用户信息添加到数据库并重定向至 /list 页面
- 点击 /list 页面的添加用户按钮会跳转到 /add
- 点击每一条展示用户信息最后操作栏里边的删除按钮会从数据库删除该条用户信息
- 点击每一条展示用户信息最后操作栏里边的修改按钮会跳转至修改用户信息页面 /modify
- 点击 /modify 页面的确认修改按钮会将修改的信息提交数据库修改,然后重定向到 /list 页面
备注:从地址栏输入地址的是get请求;点击按钮或是提交表单等操作是post请求
运行结果:
- 添加用户:
- 展示数据库中所有用户信息:
- 修改用户信息:
- 删除用户003: