欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

从零开始学习Node.js系列教程之SQLite3和MongoDB用法分析

程序员文章站 2022-11-14 16:23:17
本文实例讲述了node.js中sqlite3和mongodb的用法。分享给大家供大家参考,具体如下: setup.js:初始化数据库 var util = re...

本文实例讲述了node.js中sqlite3和mongodb的用法。分享给大家供大家参考,具体如下:

setup.js:初始化数据库

var util = require('util');
var async = require('async');  //npm install async
var notesdb = require('./nodesdb-sqlite3');
// var notesdb = require('./notesdb-mongoose');
notesdb.connect(function(error){
  if (error) throw error;
});
notesdb.setup(function(error){
  if (error){
    util.log('error ' + error);
    throw error;
  }
  async.series([  //async.series函数可以控制函数按顺序执行,从而保证最后的函数在所有其他函数完成之后执行
    function(cb){
      notesdb.add("test", "testtest",
      function(error){
        if (error) util.log('error ' + error);
        cb(error);
      });
    }
  ],
    function(error, results){
      if (error) util.log('error ' + error);
      notesdb.disconnect(function(err){});
    }
  );
});

nodesdb-sqlite3.js

sqlite3 是一个轻量级的进程内sql引擎

它是一个无服务器且无需配置的sql数据库引擎,仅仅是作为一个独立的库被链接到应用程序上

npm install sqlite3 安装此模块之前先在系统上安装sqlite3库 下载

//数据库接口库
var util = require('util');
var sqlite3 = require('sqlite3');
sqlite3.verbose();
var db = undefined;
/*
 数据库名是直接硬编码的,所以当调用connect和setup函数时,当前目录中就会生成chap06.sqlite3文件
 */
exports.connect = function(callback){
  db = new sqlite3.database("chap06.sqlite3", sqlite3.open_readwrite | sqlite3.open_create,
    function(err){
      if (err){
        util.log('fail on creating database ' + err);
        callback(err);
      } else {
        callback(null);
      }
    });
}
//此处的disconnect函数是空的
exports.disconnect = function(callback){
  callback(null);
}
exports.setup = function(callback){
  db.run("create table if not exists notes " +
    "(ts datetime, author varchar(255), note text)",
    function(err){
      if (err){
        util.log('fail on creating table ' + err);
        callback(err);
      } else {
        callback(null);
      }
    });
}
exports.emptynote = {"ts": "", author: "", note: ""};
exports.add = function(author, note, callback){
  db.run("insert into notes (ts, author, note) " +
    "values (?, ?, ?);",
    [new date(), author, note],
    function(error){
      if (error){
        util.log('fail on add ' + error);
        callback(error);
      } else {
        callback(null);
      }
    });
}
/*
run函数接受一个字符串参数,其中?表示占位符,占位符的值必须通过一个数组传递进来
调用者提供了一个回调函数,然后通过这个回调函数来声明错误
 */
exports.delete = function(ts, callback){
  db.run("delete from notes where ts = ?;",
    [ts],
    function(err){
      if (err){
        util.log('fail to delete ' + err);
        callback(err);
      } else {
        callback(null);
      }
    });
}
exports.edit = function(ts, author, note, callback){
  db.run("update notes " +
    "set ts = ?, author = ?, note = ? " +
    "where ts = ?",
    [ts, author, note, ts],
    function(err){
      if (err){
        util.log('fail on updating table ' + err);
        callback(err);
      } else {
        callback(null);
      }
    });
}
exports.allnotes = function(callback){
  util.log(' in allnote');
  db.all("select * from notes", callback);
}
exports.forall = function(doeach, done){
  db.each("select * from notes", function(err, row){
    if (err){
      util.log('fail to retrieve row ' + err);
      done(err, null);
    } else {
      doeach(null, row);
    }
  }, done);
}
/*
allnotes和forall函数是操作所有数据的两种方法,allnotes把数据库中所有的数据行收集到一个数组里,
而forall方法可以接受两个回调函数,每当从数据集中拿一行数据,回调函数doeach都会执行一遍,当读完所有数据时,回调函数done就会执行
 */
exports.findnotebyid = function(ts, callback){
  var didone = false;
  db.each("select * from notes where ts = ?",
    [ts],
    function(err, row){
      if (err){
        util.log('fail to retrieve row ' + err);
        callback(err, null);
      } else {
        if (!didone){
          callback(null, row);
          didone = true;  //保证回调函数只被执行一次
        }
      }
    });
}

notesdb-mongoose.js

mongodb是nosql数据库的领头羊之一,"可扩展、高性能、开源、面向文档的数据库",它使用json风格的文档。

mongoose是用于访问mongodb的模块之一,它是一个对象建模工具,意味着你的程序负责定义模式对象来描述数据,

而mongoose负责数据到mongodb的存储。

mongoose对于node和mongodb而言是一个非常强大的对象建模工具,使用嵌入式文档,是一个类型灵活的系统,

适用于字段输入、字段验证、虚拟字段等。

mongodb在windows下安装部署 :

安装mongoose模块

npm install mongoose

mongoose不是唯一一个在node中使用mongodb的工具。

var util = require('util');
var mongoose = require('mongoose');
var schema = mongoose.schema;
var dburl = 'mongodb://localhost/chap06'; //dburl用于连接已运行的mongodb
exports.connect = function(callback){
  mongoose.connect(dburl);
}
exports.disconnect = function(callback){
  mongoose.disconnect(callback);
}
exports.setup = function(callback){callback(null);}
//定义模式
var noteschema = new schema({
  ts: {type: date, default: date.now}, //默认值
  author: string,
  note: string
});
//将noteschema作为mongoose的模型注册进去
mongoose.model('note', noteschema);
var note = mongoose.model('note');
exports.emptynote = {"_id": "", author: "", note: ""};
exports.add = function(author, note, callback){
  var newnote = new note();
  newnote.author = author;
  newnote.note = note;
  newnote.save(function(err){
    if (err){
      util.log('fatal ' + err);
      callback(err);
    } else {
      callback(null);
    }
  });
}
exports.delete = function(id, callback){
  exports.findnotebyid(id, function(err, doc){
    if (err){
      callback(err);
    } else {
      util.log(util.inspect(doc));
      doc.remove();
      callback(null);
    }
  });
}
exports.edit = function(id, author, note, callback){
  exports.findnotebyid(id, function(err, doc){
    if (err){
      callback(err);
    } else {
      doc.ts = new date();
      doc.author = author;
      doc.note = note;
      doc.save(function(err){
        if (err){
          util.log('fatal ' + err);
          callback(err);
        } else {
          callback(null);
        }
      });
    }
  });
}
exports.allnotes = function(callback){
  note.find({}, callback);
}
exports.forall = function(doeach, done){
  note.find({}, function(err, docs){
    if (err){
      util.log('fatal ' + err);
      done(err, null);
    }
    docs.foreach(function(doc){
      doeach(null, doc);
    });
    done(null);
  });
}
/*
_id字段是mongodb提供的全局唯一的id,用于标识存储的文档
 */
var findnotebyid = exports.findnotebyid = function(id, callback){
  note.findone({_id: id}, function(err, doc){
    if (err){
      util.log('fatal ' + err);
      callback(err, null);
    }
    callback(null, doc);
  });
}

app.js

//在数据库需要放置在一台计算机上时,应该考虑使用sqlite3
//控制器,在nodesdb-sqlite3.js和notesdb-mongoose.js模块之间切换
var util = require('util');
var url = require('url');
var express = require('express');
var nmdbengine = 'sqlite3'; //用于命名数据库引擎、选择合适的notesdb实现和选择合适的views目录
//var nmdbengine = 'mongoose';
var notesdb = require('./nodesdb-' + nmdbengine);
var app = express();
app.use(express.logger());
app.use(express.cookieparser()); //添加cookieparser中间件
app.use(express.bodyparser());
app.engine('.html', require('ejs').__express);  //3.x
//app.register('.html', require('ejs'));  //2.x
app.set('views', __dirname + '/views-' + nmdbengine);
app.set('view engine', 'ejs');
//是一个路由中间件函数,用于在一些路由器函数中解析url查询参数
var parseurlparams = function(req, res, next){
  req.urlp = url.parse(req.url, true);
  next();
}
//检查用户是否被允许访问,这里只检查cookie是否等于aok,这个单词通常意味着一切都没问题
/*
 很多应用都需要用户登录,然后用户才能进行一些特权操作。由于http是一个无状态的协议,
 验证用户的唯一方式就是发送一个cookie到浏览器上,然后验证标识符。cookie包含了应用中用于验证用户的数据。
 cookieparser中间件在这里做了很多工作,查找cookie,解析cookie,然后将解析出来的值让到req对象中。
 当存在cookie时,它的值会被放入req.cookies中。
 */
var checkaccess = function(req, res, next){
  if (!req.cookies || !req.cookies.notesaccess || req.cookies.notesaccess !== "aok"){
    res.redirect('/login');
  } else {
    next();
  }
}
notesdb.connect(function(error){
  if (error) throw error;
})
app.on('close', function(error){
  notesdb.disconnect(function(err){});
});
app.get('/', function(req, res) {res.redirect('/view');});
app.get('/view', checkaccess, function(req, res){ //可以在每个路由上加checkaccess检查
  notesdb.allnotes(function(err, notes){
    if (err){
      util.log('error ' + err);
      throw err;
    } else {
      res.render('viewnotes.html', {title: "notes ("+ nmdbengine +")", notes: notes});
    }
  });
});
/*
当用户点击add按钮时app.get('/add', ...)内的函数就会被调用,浏览器会发出一个发往/add的http get请求。
这个函数使用addedit.html模板来创建一个表单,让用于通过这个表单输入标签,然后通过单击submit按钮提交,
当用户提交表单,浏览器就会发出一个http post请求,app.post('/add', ...)内的函数就会被调用,
用户输入的数据会被存放在请求主体中,而请求主体会被bodyparser(app.use(express.bodyparser()))中间件处理并存放在req.body中
 */
app.get('/add', function(req, res){
  res.render('addedit.html', {title: "notes ("+ nmdbengine +")", postpath: '/add', note: notesdb.emptynote});
});
app.post('/add', function(req, res){
  notesdb.add(req.body.author, req.body.note,
    function(error){
      if (error) throw error;
      res.redirect('/view');
    });
});
app.get('/del', parseurlparams, function(req, res){
  notesdb.delete(req.urlp.query.id,
    function(error){
      if (error) throw error;
      res.redirect('/view');
    });
});
app.get('/edit', parseurlparams, function(req, res){
  notesdb.findnotebyid(req.urlp.query.id,
    function(error, note){
      if (error) throw error;
      res.render('addedit.html',
        {title: "notes ("+ nmdbengine +")", postpath: '/edit', note: note});
    });
});
app.post('/edit', function(req, res){
  notesdb.edit(req.body.id, req.body.author, req.body.note,
    function(error){
      if (error) throw error;
      res.redirect('/view');
    });
});
app.get('/login', function(req, res){
  res.render('login.html', {title: "notes login ("+ nmdbengine +")"});
});
app.post('/login', function(req, res){
  //此处可以添加检查用户信息的逻辑
  //...
  res.cookie('notesaccess', 'aok');
  res.redirect('/view');
});
app.listen(3000);

show.js

//控制台显示
var util = require('util');
var notesdb = require('./notesdb-sqlite3');
// var notesdb = require('./notesdb-mongoose');
notesdb.connect(function(error){
  if (error) throw error;
});
notesdb.forall(function(error, row){
  util.log('row: ' + util.inspect(row));
}, function(error){
  if (error) throw error;
  util.log('all done');
  notesdb.disconnect(function(err){});
});

前台页面在views-sqlite3目录下

layout.html

<!doctype html>
<html>
<head>
  <title><%= title%></title>
</head>
<body>
  <h1><%= title%></h1>
  <p><a href='/view'>view</a> | <a href='/add'>add</a></p>
</body>
</html>

viewnotes.html

<% include layout.html %>
<table><% notes.foreach(function(note){ %>
  <tr>
    <td>
      <p><%=new date(note.ts).tostring()%>: by <b><%=note.author%></b></p>
      <p><%=note.note%></p>
    </td>
    <td>
      <form method="get" action="/del">
        <input type="submit" value="delete" />
        <input type="hidden" name="id" value="<%=note.ts%>" />
      </form>
      <br/>
      <form method="get" action="/edit">
        <input type="submit" value="edit" />
        <input type="hidden" name="id" value="<%=note.ts%>" />
      </form>
    </td>
  </tr>
  <% }); %>
</table>

addedit.html

<% include layout.html %>
<form method="post" action="<%=postpath%>">
  <% if (note){ %>
  <input type="hidden" name="id" value="<%=note.ts%>" />
  <% } %>
  <input type="text" name="author" value="<%=note.author%>" />
  <br/>
  <textarea rows="5" cols="40" name="note">
    <%=note.note%>
  </textarea>
  <br/>
  <input type="submit" value="submit" />
</form>

login.html

<% include layout.html %>
<form method="post" action="/login">
  <p>click the <i>login</i> to log in.</p>
  <input type="submit" value="login" />
</form>

node setup.js

node app.js

从零开始学习Node.js系列教程之SQLite3和MongoDB用法分析

从零开始学习Node.js系列教程之SQLite3和MongoDB用法分析

从零开始学习Node.js系列教程之SQLite3和MongoDB用法分析

从零开始学习Node.js系列教程之SQLite3和MongoDB用法分析

希望本文所述对大家nodejs程序设计有所帮助。