nodejs怎么后台 *** 作mysql

nodejs怎么后台 *** 作mysql,第1张

连接流程代码如下:

var mysql  = require('mysql') //调用MySQL模块//创建一个connectionvar connection = mysql.createConnection({    

host     : '127.0.0.1',       //主机

user     : 'root',            //MySQL认证用户名

password:'12345',

port:   '3306',

database: 'node'})//创建一个connectionconnection.connect(function(err){

if(err){      

console.log('[query] - :'+err)       return

}

console.log('[connection connect]  succeed!')

})

//执行SQL语句connection.query('SELECT 1 + 1 AS solution', function(err, rows, fields) {

if (err) {

console.log('[query] - :'+err)       return

}

console.log('The solution is: ', rows[0].solution)

})

//关闭connectionconnection.end(function(err){

if(err){      

return

}

console.log('[connection end] succeed!')

})12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455

关于Connection Optionos

要想创建一个数据库连接,先就要认识清楚Options

host:主机地址 (默认:localhost)

user:用户名

password:密码

port:端口号 (默认:3306)

database:数据库名

charset:连接字符集(默认:’UTF8_GENERAL_CI’,注意字符集的字母都要大写)

localAddress:此IP用于TCP连接(可选)

socketPath:连接到unix域路径,当使用 host 和 port 时会被忽略

timezone:时区(默认:’local’)

connectTimeout:连接超时(默认:不限制;单位:毫秒)

stringifyObjects:是否序列化对象(默认:’false’ ;与安全相关https://github.com/felixge/node-mysql/issues/501)

typeCast:是否将列值转化为本地JavaScript类型值 (默认:true)

queryFormat:自定义query语句格式化方法 https://github.com/felixge/node-mysql#custom-format

supportBigNumbers:数据库支持bigint或decimal类型列时,需要设此option为true (默认:false)

bigNumberStrings:supportBigNumbers和bigNumberStrings启用 强制bigint或decimal列以JavaScript字符串类型返回(默认:false)

dateStrings:强制timestamp,datetime,data类型以字符串类型返回,而不是JavaScript Date类型(默认:false)

debug:开启调试(默认:false)

multipleStatements:是否许一个query中有多个MySQL语句 (默认:false)

flags:用于修改连接标志,更多详情:https://github.com/felixge/node-mysql#connection-flags

ssl:使用ssl参数(与crypto.createCredenitals参数格式一至)或一个包含ssl配置文件名称的字符串,目前只捆绑Amazon RDS的配置文件

其它:

可以使用URL形式的加接字符串,不多介绍了,不太喜欢那种格式,觉得可读性差,也易出错,想了解的可以去主页上看。

MYSQL CURD *** 作

增加

var mysql = require('mysql')var DATABASE = "seckill"var TABLE="seckill"var connection = mysql.createConnection({

host:'127.0.0.1',

user:'root',

password:'12345',

port:'3306',

database: DATABASE

})

connection.connect()var addVip = 'insert into seckill(name,number) values(?,?)'var param = ['100元秒杀家教机',100]

connection.query(addVip, param, function(error, result){

if(error)

{

console.log(error.message)

}else{

console.log('insert id: '+result.insertId)

}

})

connection.end()12345678910111213141516171819202122232425

删除

var mysql = require('mysql')var DATABASE = "node"var TABLE="seckill"var connection = mysql.createConnection({

host:'127.0.0.1',

user:'root',

password:'12345',

port:'3306',

database: DATABASE

})

connection.connect()var addVip = 'delete from seckill where seckill_id = 1005'

connection.query(addVip, function(error, result){

if(error)

{

console.log(error.message)

}else{

console.log('affectedRows: '+result.affectedRows)

}

})

connection.end()123456789101112131415161718192021222324

查找

var mysql = require("mysql")var DATABASE = "node"var TABLE="seckill"var connection = mysql.createConnection({

host:'127.0.0.1',

user:'root',

password:'12345',

port:'3306',

})

connection.connect()

connection.query('use '+DATABASE)

connection.query('select * from '+TABLE, function(error, results, fields){

if (error) {        throw error

}    if (results) {        for(var i = 0i <results.lengthi++)

{

console.log('%s\t%s',results[i].name,results[i].end_time)

}

}

})

connection.end()12345678910111213141516171819202122232425

修改

var mysql = require('mysql')var DATABASE = "seckill"var connection = mysql.createConnection({

host:'127.0.0.1',

user:'root',

password:'12345',

port:'3306',

database: DATABASE

})

connection.connect()var userSql = "update seckill set number = number-1 where seckill_id = ?"var param = [1000, 2]

connection.query(userSql, param, function (error, result) {

if(error)

{

console.log(error.message)

}else{

console.log('affectedRows: '+result.affectedRows)

}

})

connection.end()123456789101112131415161718192021

结束连接其实有两种方法end(),destory();

end() 

end()方法在queries都结束后执行,end()方法接收一个回调函数,queries执行出错,仍然后结束连接,错误会返回给回调函数err参数,可以在回调函数中处理!

destory() 

比较暴力,没有回调函数,即刻执行,不管queries是否完成!

使用连接池

在数据库中执行如下代码创建一个存储过程

DROP PROCEDURE IF EXISTS `P_SeckillInfo`DELIMITER CREATE DEFINER=`root`@`localhost` PROCEDURE `P_SeckillInfo`(IN ExtName VARCHAR(120),IN ExtNumber INT(11),OUT ExtReturnVal INT)

TOP: BEGIN

   DECLARE EXIT HANDLER FOR SQLEXCEPTION    BEGIN

   ROLLBACK

   SET ExtReturnVal = 0 -- Failed

   END

   START TRANSACTION

   INSERT INTO seckill(name, number) VALUES(ExtName,ExtNumber)

   SET ExtReturnVal = 1

   SELECT ExtReturnVal

   COMMITEND

DELIMITER 12345678910111213141516171819202122232425262728293031323334

调用示例:

var mysql = require("mysql")var pool = mysql.createPool({

   host: '127.0.0.1',    

   user: 'root',

   password:'12345',

   port:'3306',

   database:'node'})//监听connection事件pool.on('connection', function(connection) {

   connection.query('select * from seckill', function(error, results, fields){

       if (error) {            throw error

       }        if (results) {            for(var i = 0i <results.lengthi++)

           {

               console.log('%s\t%s',results[i].name,results[i].end_time)

           }

       }

   })

})//连接池可以直接使用,也可以共享一个连接或管理多个连接(引用官方示例)//直接使用pool.query('SELECT 1 + 1 AS solution', function(err, rows, fields) {

   if (err) throw err

   console.log('The solution is: ', rows[0].solution)

})//共享连接function myQuery(sql){

   pool.getConnection(function(err, connection) {

       connection.query(sql, function(err, result) {  

           console.log(result)           //释放连接

           connection.release()

       })       //Error: Connection already released,应该每次到连接池中再次获取

       // connection.query( 'SELECT * FROM seckill', function(err, result) {

       //  console.log(result)

       //  connection.release()

       // })

   })

}

myQuery('SELECT * FROM seckill')

myQuery('SELECT * FROM seckill')123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172

1.连接池的创建,使用createPool方法,options和createConntion一致; 

2.其它连接池配置选项 

waitForConnections

当连接池没有连接或超出最大限制时,设置为true且会把连接放入队列,设置为false会返回error

connectionLimit 

连接数限制,默认:10

queueLimit 

最大连接请求队列限制,设置为0表示不限制,默认:0

断开重连

示例代码:

var mysql = require('mysql')var db_config = {

   host: '127.0.0.1',    

   user: 'root',

   password:'12345',

   port:'3306',

   database:'node'}var connectionfunction handleDisconnect() {

   connection = mysql.createConnection(db_config)                                             

   connection.connect(function(err) {            

       if(err) {                                    

           console.log('进行断线重连:' + new Date())

           setTimeout(handleDisconnect, 2000)  //2秒重连一次

           return

       }        

       console.log('连接成功')

   })                                                                         

   connection.on('error', function(err) {

       console.log('db error', err)       if(err.code === 'PROTOCOL_CONNECTION_LOST') {

           handleDisconnect()                       

       } else {                                    

           throw err                               

       }

   })

}

handleDisconnect()12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455

首先关闭mysql服务,然后执行程序,会一直打印断线重连,当再次开启mysql服务后,打印连接成功。

防止SQL注入

可以使用pool.escape()和connect.escape(),示例代码:

var mysql = require('mysql')var pool = mysql.createPool({

   host: '127.0.0.1',    

   user: 'root',

   password:'12345',

   port:'3306',

   database:'node'})function myQuery(sql){

   pool.getConnection(function(err,connection){

       connection.query(sql,function(err,result){

           //console.log(err)

           console.log(result)

           connection.release()

       })       // connection.query('SELECT * FROM userinfo WHERE id = ' + pool.escape('5 OR ID = 6') ,function(err,result){

       // //console.log(err)

       // console.log(result)

       // connection.release()

       // })

   })

}

myQuery('SELECT * FROM seckill WHERE seckill_id = ' + '1006 OR seckill_id = 1007')

myQuery('SELECT * FROM seckill WHERE seckill_id = ' + pool.escape('1006 OR seckill_id = 1007'))123456789101112131415161718192021222324252627282930313233343536373839404142434445464748

 

结果可以看出,第1个query拼接条件可以被执行,而通过escape方法转义后的忽略了后面的拼接的部分!

遇到的问题

编码导致的问题 

1366 (HY000): Incorrect string value: ‘\xC3\xEB\xC9\xB1’ for column ‘ExtName’ at row 1 

字符编码没有统一的问题,查看数据库的编码方式命令为: 

mysql>show variables like ‘character%’ 

从以上信息可知数据库的编码为latin1,需要修改为gbk或者是utf8;

一、写在前面人人都想成为全栈码农,作为一个web前端开发人员,通往全栈的简洁之路,貌似就是node/dist/v0.6.1/node-v0.6.1.msi 下载电脑适配的安装包(这个是windows的,买不起mac啊),然后根据引导安装就可以了,默认安装在C:\Program Files\nodejs文件下,并将该目录添加进PATH环境变量。具体做法,右击”我的电脑“-”属性“-“系统高级”-”高级“-”环境变量“-选择“变量名:PATH”;“改变量值:在最后面添加【C:\Program Files\nodejs】(根据自己的安装目录而定)”。打开cmd直接运行命令: node -v 可以输出当前版本号。node文件里已经集成了npm,之后使用npm install XXX 来安装需要的插件或者模块。 三、使用express框架忙活了一阵,终于可用npm命令进行初始化、安装express框架,然后写个hello world 爽一下了。为什么要选择express框架了,当然有它的特别之处,对新手来说最怕的就是麻烦还容易出错。express当然为我们考虑到了,所以提供了快速生成器:express-generator 1、通过命令:npm install express-generator -g 安装到全局 2、在用express 命令生成项目结构express myapp 其中的myapp是你的项目名称 3、通过cd myapp 进入项目文件中通过npm install 初始化依赖模块通过set DEBUG=myapp &npm start 启动web服务器 4、在浏览器中打开 localhost:3000/ 网址就可以看到这个应用了。 默认情况下用的模版引擎是jade,项目里也已经配置好了这个模版。 四、介绍express 生成器的项目 1、myapp项目的机构如下: 2、package.json 这个可以说是模块管理包,项目信息和模块的版本号,其实你会发现在项目模块初始化的时候就是由这里的配置去查找生成的。 3、app.js 是项目的启动文件,可以说是项目的核心。主要写一些公共的功能。 4、bin 文件下有个无后缀的www文件,这是项目的入口文件,配置web服务端口和一些监听事件。 5、node_modules是项目的依赖的的文件模块,之后导入的包也会被放在其中,比如连接数据库的mongoose模块,后面会详细讲。 6、public 是项目的静态资源文件集,很容易看出图片、css文件、js文件都放在这里。 7、routes 是项目的路由模块,其中已经默认了index.js和user.js文件。在这里其实也包括一般后台语言中的控制器内容,当然在大的项目上是可以分离开来的。 8、views是项目的模版文件,是jade模版引擎,这个模版很简洁,但是坑也比较多,比如对空格的要求都非常严格,多一个少一个空格都会报错的,曾经踩过很多坑,其实它的性能也不是很高还不如用ejs呢。 五、安装mongoDB 1、同样在官网(/downloads)上直接下载msi文件 2、简单的下一步进行安装,有默认的就让其默认,有选择的就全选了 3、然后配置环境变量,和node的一样不再累述,不过可以放中图,哈哈哈…… 4、接下来是启动mongoDB服务 5、通过命令:mongod --dbpath f:\MongoDB\data 其中 f:\MongoDB\data是文件存放路径,看到如下信息说明成功了 6、MongoDB监听的是27017端口,同时打开浏览器输入127.0.0.1:27017,则会看到如下提示: It looks like you are trying to access MongoDB over HTTP on the native driver port. 7、然后,再打开一个cmd,输入mongo命令链接数据库,出现如下提示: 2015-05-02T17:10:19.467+0800 I CONTROL Hotfix KB2731284 or later update is not installed, will zero-out data files MongoDB shell version: 3.0.2 connecting to: test 8、这样windows环境下的monogDB就安装成功了。 补充: 9、如果你嫌每次用命令打开服务麻烦的话,可以写成批处理文件,就是新建一个后缀.bat的文件,写上如下代码: start mongod --dbpath F:\MongoDB\data 10、当然了,你也可以将MongoDB以服务的方式启动,不过我觉得在学习的过程中用处不大,小伙伴们可以自己尝试一下,如果有需要的话,我在后面会补上。 11、要是觉得命令行不好用,推荐一个带图形化界面的软件:MongoVUE,就和navicat差不多,它有免费版的,就是功能少点,但学习过程中完全足够了 六、在node项目中使用monogDB 1、导入monogDB连接模块,express 官方介绍的是mongoskin模块,这个我就不说了,这里介绍通过mongoose安装 2、在myapp项目下执行命令 npm install mongoose -save 安装保存到node_modules,也可以在package.json中配置"mongoose": "^4.4.12",然后命令npm install 安装。 3、在app.js文件中  a、导入mongoose模块: var mongoose = require('mongoose')b、创建数据库连接 mongoose.connect('mongodb://localhost/myDB') //连接本地数据库 4、在项目根目录下新建文件夹schemas,这个是数据集模块,在模块下新建users.js文件 var mongoose = require('mongoose') //申明一个mongoons对象 var UsersSchema = new mongoose.Schema({ name: String, paw: String, meta: { createAt: { type: Date, default: Date.now()},updateAt: { type: Date, default: Date.now()} } })//每次执行都会调用,时间更新 *** 作 UsersSchema.pre('save', function(next) { if(this.isNew) {this.meta.createAt = this.meta.updateAt = Date.now() }else {this.meta.updateAt = Date.now() } next() })//查询的静态方法 UsersSchema.statics = { fetch: function(cb) { //查询所有数据return this .find() .sort('meta.updateAt') //排序 .exec(cb) //回调 }, findById: function(id, cb) { //根据id查询单条数据return this .findOne({_id: id}).exec(cb) } }//暴露出去的方法 module.exports = UsersSchema 5、在根目录新增modules文件,这个是数据模型模块,在模块下新增users.js文件 var mongoose = require('mongoose') var UsersSchema = require('../schemas/users') //拿到导出的数据集模块 var Users = mongoose.model('Users', UsersSchema) // 编译生成Movie 模型 module.exports = Users 6、在routes文件中的users.js文件中添加路由控制器代码 var express = require('express') var mongoose = require('mongoose')//导入mongoose模块var Users = require('../models/users')//导入模型数据模块var router = express.Router() /* GET users listing. */ router.get('/', function(req, res, next) { res.send('respond with a resource') }) //查询所有用户数据 router.get('/users', function(req, res, next) { Users.fetch(function(err, users) {if(err) { console.log(err) } res.render('users',{title: '用户列表', users: users}) //这里也可以json的格式直接返回数据res.json({data: users}) }) }) module.exports = router 7、在views文件下新增users.jade extends layoutblock content h1= title //jade取值方式 ul each user in users //jade模版的遍历方式lih4 #{user.name} span #{user.paw} 8、最后在浏览器中打开网址:localhost:3000/users/users,查看效果。到这里一个从数据库到前端展现的项目就完成了。 以上就是本文的全部内容,希望对大家的学习有所帮助。

nodejs中我们使用net模块来创建tcp服务器,tcp客户端,实现服务器与客户端之前的数据通信

创建tcp服务器

var server=net.createServer([optations],[connectionListener])

optations:{allowHalfOpen:boolean}

allowHalfOpen:false 当服务器接受到客户端发送的一个FIN包时候,会回发一个FIN包,当为true时服务器不会回FIN包,使得tcp服务器可以继续发送数据到客户端,但是不会接受客户端发送的数据,开发者必须调动end方法来关闭socket,默认是false

connectionListener:当客户端与服务器连接上了,可以触发的回调函数。

function(socket){

//.......

}

我们也可以不用回调函数来写连接上做什么处理,连接上会触发connection事件

var server=net.createServer()返回创建的tcp服务器

我们可以server.on('connection',function(socket){

})

在创建完tcp服务器我们通知服务器要监听客户端连接

server.listen(port,[host],[backlog],[callback])

port:监听的端口,为0时候tcp服务器分配一个随机的端口

host:监听的ip和主机名,省略该参数,服务器监听任何ipv4地址的客户端连接

backlog:指定等待队列中最大的客户端连接最大数量 默认511

当指定端口、ip这个时候服务器开始监听这个ip这个端口的客户端了,这个时候触发listening事件,可以指定callback参数来处理触发listening具体要做什么

我们也可以

server.on('lisening',function(){

//.......

})

创建一个tcp服务器后可以用server.address()查看tcp服务器监听的信息

var address=server.address()

addres是一个对象

prot :监听的端口

address:监听的ip

family:ipv4还是ipv6

我们可以使用getConnections()查看与服务器连接的客户端的数量

server.getConnections(callback)

callback:function(err,count){

}

err:错误信息

count:为连接服务器的数量

我们也可以设置最大的连接数,超过这个数字,服务器不允许连接

server.maxConnections=2

服务器关闭

server.close([callback])

这个 方法让tcp服务器拒绝新的客户端连接,原有已经连上的客户端是不关闭的,当所有的连接服务器的客户端关闭时候,服务器默认自动关闭,触发服务器的close事件

下面我们写一个tcp服务器

var net=require("net")

opations={allowHalfOpne:false}

var server=net.createServer(opations)

server.on('connection',function(socket){

server.maxConnections=2

console.log("服务器最大连接数为%s",server.maxConnections)

server.getConnections(function(err,count){

console.log("已经有%s个客户端连接",count)

})

console.log("%s客户端与服务器建立连接",server.address().address)

})

server.on('error',function(err){

throw err

})

server.on('listening',function(){

console.log("服务器开始监听%j",server.address())

console.log("服务器开始监听")

})

server.listen(9966,'192.168.0.3')

setTimeout(function(){

server.close(function(){

console.log("tcp服务器关闭11111")

})

console.log("tcp服务器关闭")

},20000)

注意连接成功的时候触发的connection事件,执行的方法,参数是一个socket端口对象,这个就是服务器所监听的端口对象,所以我们socket.address().address返回给我们的是监听ip

socket端口对象

port:端口

address:ip

family:ipv4 ipv6

socket端口对象,可以读取客户端发送的流数据,每次接收到客户端发送的数据触发data事件。

接受客户端发送的消息(在连接成功的触发函数中 让server监听data事件做相应的处理)

server.on('connection',function(socket){

socket.on('data',function(data){

socket.setEncoding("utf-8")

console.log(data)

//console.log(data.toString())

})

})

bytesRead为socket端口对象监听客户端发送的数据字节数

console.log(socket.bytesRead)

当客户端关闭时候,触发socket端口对象的end事件

我们把客户端连接发送的数据保存到一个文件下

var net=require("net")

var fs=require("fs")

var server =net.createServer()

var op={

flags:"a",

encoding:"utf-8"

}

var file=fs.createWriteStream('./socket.txt',op)

server.on('connection',function(socket){

socket.on('data',function(data){

file.write(data)

})

})

server.on('listening',function(){

console.log("监听开始")

})

server.listen('1111','192.168.0.3')

以管道形式发送数据到文件

var net=require("net")

var fs=require("fs")

var server =net.createServer()

var op={

flags:"a",

encoding:"utf-8"

}

var file=fs.createWriteStream('./socket.txt',op)

server.on('connection',function(socket){

//socket.on('data',function(data){

// file.write(data)

//})

socket.pipe(file,{end:false})

socket.on("end",function(){

file.end("wanbi")

})

})

server.on('listening',function(){

console.log("监听开始")

})

server.listen('1111','192.168.0.3')

tcp客户端

创建tcp客户端

var client =new net.socket([opations])

optation:fd 一个现有的socket端口对象文件描述

type :ipv4 、ipv6

allowHalfOpne:true、false

连接服务器

client.connect(prot,[host],[callback])

host不指定默认为本地ip

回调函数表示连接上了做什么

若没有可以socket端口对象触发connect事件

client.on("connect",function(){

})

当我们连接成功后客户端服务器端的socket端口对象有下面的属性

remoteAddress、remotePort、localAddress、localPort

socket端口对象可以写入服务器、客户端流数据

socket.write(data,[encodeing],[callback])

写入数据少时候我们直接写入缓存区,数据很多时候,缓存区满了,我们要把数据写入缓存队列中,这个时候write(data) 返回false,触发drain

我们可以用bufferSize看缓存队列中有多少个字节

socket.on("error",function(err){

})

当遇到error时候这个socket端口对象应该销毁

socket.destory()

socket.end([data],[encoding])

这个方法表示我们要关闭socket端口对象,这个不是关闭服务器的close方法,后者是关闭服务器,实现的效果是不能让客户端连接了,前者是关闭连接(socket端口对象)

当我们使用服务器的socket端口对象(连接客户端得)的end(data,encoding)方法时候,会触发客户端socket端口对象end事件

服务器:

socket.end('88')

客户端会执行下面的代码:

client.on("end",function(){

//......

})

服务器端不会退出应用程序,即使所有的客户端都断开了,这个时候我们要server.unref(),退出程序,可以用server.ref()阻止程序退出.

当socket端口对象彻底关闭时候会触发close事件,我们可以指定当端口对象关闭时候做的处理

socket.on(''close',faction(had_error){

if(had_error){}

else{}

})

socket.writtenBytes表示写了多少个字节

我们tcp服务器与客户端连接了,但是突然间有一个断电了,来不及向另一端发送关闭连接的FIN包,这样另一边这个socket端口永远处于连接状态,我们用socket.setKeepAlive([enable],[inteval])定时向另一端发送监测包,

我们实现一个服务器读一个文件的信息,当有客户单连接上,吧这个信息传给客户端,输出在控制台

服务器代码

var net=require("net")

var fs=require("fs")

var server =net.createServer()

var op={

flags:"r",

encoding:"utf-8"

}

var file=fs.createReadStream('./socket.txt',op)

server.on('connection',function(socket){

file.on('data',function(data){

socket.write(data)

})

socket.on("end",function(){

file.end("wanbi")

})

})

server.on('listening',function(){

console.log("监听开始")

})

server.listen('1111','192.168.0.3')

客户端代码

var net=require("net")

var client=new net.Socket()

client.connect(1111,'192.168.0.3')

client.on('connect',function(){

console.log("ok")

})

client.on("data",function(data){

console.log(data.toString())

})


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/sjk/6768795.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-03-28
下一篇2023-03-28

发表评论

登录后才能评论

评论列表(0条)

    保存