express可以连接各种数据库,进行数据库的操作,目前已mysql为例
1、连接数据库
需要在电脑上安装mysql的服务,这个是最基础的,然后在mysql中建立一个数据库,然后需要开始在项目中引用mysql的依赖包:npm i mysql -s
在环境都已经搭建完毕之后,开始使用express来连接数据库
1 //引用mysql的依赖项 2 const mysql=require('mysql'); 3 4 //定义连接项 5 const cfg =mysql.createConnection({ 6 host: 'localhost',//主机地址 7 user: 'root',//用户名 8 password: '123456',//密码 9 database: 'kaikeba'//数据库 10 })
通过搭建mysql的环境以及引用mysql的依赖项之后,开始进行操作数据
1 //创建数据库的连接 2 conn.connect(); 3 /* 4 对数据库的操作 5 sql 代表的是sql语句的编写, 6 value 代表的是参数的传递,也可以不需要(无参数时) 7 err 错误提示,一般为空,只有报错时才会有值 8 rows 执行sql语句返回的值 9 fields 返回查询字段的属性 10 */ 11 conn.query(sql,value, (err, rows, fields)=> { 12 if (err) throw err 13 console.log(rows); 14 }) 15 //数据库的断开 16 conn.end()
案例1:查询无参数
conn.connect(); conn.query('select * from t_cousesinfo', (err, rows,field)=> { if (err) throw err console.log(rows); console.log(field); }) conn.end()
案例2:查询带参数
1 conn.connect(); 2 //单个参数 3 conn.query('select * from t_cousesinfo where id=?',1, (err, rows,field)=> { 4 if (err) throw err 5 console.log(rows); 6 console.log(field); 7 }) 8 //多个参数则数组进行拼接 9 conn.query('select * from t_cousesinfo where id=? and types=?',[1,"web"], (err, rows,field)=> { 10 if (err) throw err 11 console.log(rows); 12 console.log(field); 13 }) 14 conn.end()
案例3:更新数据/删除数据(新增数据也类同)
1 conn.connect(); 2 //更新数据 3 conn.query('update t_cousesinfo set descriptions=? where id=? ',["测试数据看看",1], (err, rows,field)=> { 4 if (err) throw err 5 console.log(rows); 6 console.log(field); 7 }) 8 //删除数据 9 conn.query('delete from t_cousesinfo where id=?',1, (err, rows,field)=> { 10 if (err) throw err 11 console.log(rows); 12 console.log(field); 13 }) 14 conn.end()
3、数据调用的方法封装(解决回调地狱问题)
通过上述几种写法,如果我们需要一直进行数据的调用,普通的写法我们可能会是这样的
conn.query('select * from t_cousesinfo', (err, rows,field)=> { if (err) throw err conn.query('select * from t_cousesinfo where id=?',rows[0].id, (err, rows,field)=> { if (err) throw err ...//如果需要的请求比较多时,则会写好几个进行回调 }) })
在ES7中,我们可以用async/await 来解决此类情况
//异步方法的调用 async与await两者缺一不可 async function(){ try{ //直接进行查询数据,result就等于查询出来的结果 const result = await query("select * from t_cousesinfo"); } catch(err){ } }
按照上面的写法,我们可以把数据库调用的这一块单独的剥离出来进行封装,直接供其他需要调用数据库的地方去调用
1 // 连接数据库 2 const mysql = require('mysql') 3 const cfg = { 4 host: 'localhost', 5 user: 'kaikeba_admin', 6 password: 'admin', 7 database: 'kkb' 8 } 9 10 module.exports = { 11 query: function (sql, value) { 12 return new Promise((resolve, reject) => { 13 // resolve函数在异步操作成功时执行 14 // reject函数在异步操作失败时执行 15 const conn = mysql.createConnection(cfg); 16 conn.connect(); 17 conn.query(sql, value, (err, results) => { 18 if (err) reject(err); 19 else resolve(results); 20 }) 21 conn.end(); 22 }) 23 } 24 }
在具体的调用时,就可以直接这样写即可
1 //以路由调用为例 2 router.get('/', async (req, res, next) => { 3 try { 4 var firstdata=await query("select * from t_cousesinfo"); 5 var second=await query("select * from t_cousesinfo where id=?",firstdata[0].id); 6 ... 7 } 8 catch(err){ 9 console.log(err); 10 next(err); 11 } 12 })
4、处理数据库的分页
在做后台数据库的操作时,需要用列表进行展示,而在使用列表的时候也会存在的一个问题就是分页,一定会有分页,可以减少数据的一次性请求量,提升体检的速度,避免一次性加载过多带来的界面卡顿等情况。
在进行上述的操作之后,通过知晓在mysql中有一个通过的分页方法,limit 可以通过sql语句直接进行数据的分页。具体的操作为
1 //对t_cousesinfo表进行分页,1代表的是偏移量,10代表的是往后取的条数 2 select * from t_cousesinfo limit 1,10 --第一页的数据 3 select * from t_cousesinfo limit 11,10 --第一页的数据 4 5 //通过对上述两条sql语句得出就是如下情况,currentPage代表的是页码数,pageSize代表的是每页的数据量 6 select * from t_cousesinfo limit (currentPage - 1) * pageSize,pageSize
结合mysql的sql语句对分页的处理,从而也得出在express中使用分页
1 const currentPage = req.query.page || 1;// 获取当前页码,如没有则默认1 2 const pageSize = req.query.pageSize || 1;// 每页条数 3 const offset = (currentPage - 1) * pageSize;// 计算偏移量 4 const sql="SELECT * FROM t_cousesinfo ORDER BY time DESC LIMIT ?,?"; 5 const results = await query(sql, [offset, pageSize]); 6 7 //查询总条数时,会稍微有点改变,因为查询出来的结果是一个数组,而不是一个单独的变量 8 const count=await query("select count(*) as count from t_Open_Course") 9 .then(result=>result[0].count) 10 11 //对于处理分页的计算 12 const total = Math.ceil(count / pagesize);//总页数 13 const firstpage = page != 1;//是否第一页 14 const lastpage = page != total;//是否最后一页 15 const prevet = page > 1;//是否上一页 16 const nextpreve = page < total;//是否下一页
5、连接池的应用
在之前的每次调用数据库时,都需要进行 conn.connect()
和conn.end
,每次这样去连接再释放比较繁琐,故可以使用连接池实现自动连接的插拔。
1 const mysql = require('mysql') 2 const cfg = { 3 host: 'localhost', 4 user: 'kaikeba_admin', 5 password: 'admin', 6 database: 'kkb' 7 } 8 const pool = mysql.createPool(cfg); 9 10 pool.query(sql, value, (err, results) => { 11 12 });