本文实例讲述了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库 http://www.sqlite.org/download.html 下载
//数据库接口库 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函数接受一个字符串参数,其中"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 = " + "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下安装部署 :https://www.jb51.net/article/111112.htm
安装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
希望本文所述对大家nodejs程序设计有所帮助。
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!
昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。
这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。
而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?
更新日志
- 好薇2024《兵哥哥》1:124K黄金母盘[WAV+CUE]
- 胡歌.2006-珍惜(EP)【步升大风】【FLAC分轨】
- 洪荣宏.2014-拼乎自己看【华特】【WAV+CUE】
- 伊能静.1999-从脆弱到勇敢1987-1996精选2CD【华纳】【WAV+CUE】
- 刘亮鹭《汽车DJ玩主》[WAV+CUE][1.1G]
- 张杰《最接近天堂的地方》天娱传媒[WAV+CUE][1.1G]
- 群星《2022年度发烧天碟》无损黑胶碟 2CD[WAV+CUE][1.4G]
- 罗文1983-罗文甄妮-射雕英雄传(纯银AMCD)[WAV+CUE]
- 群星《亚洲故事香港纯弦》雨果UPMAGCD2024[低速原抓WAV+CUE]
- 群星《经典咏流传》限量1:1母盘直刻[低速原抓WAV+CUE]
- 庾澄庆1993《老实情歌》福茂唱片[WAV+CUE][1G]
- 许巍《在别处》美卡首版[WAV+CUE][1G]
- 林子祥《单手拍掌》华纳香港版[WAV+CUE][1G]
- 郑秀文.1997-我们的主题曲【华纳】【WAV+CUE】
- 群星.2001-生命因爱动听电影原创音乐AVCD【MEDIA】【WAV+CUE】