高并发 Nginx+Lua OpenResty系列(6)——Lua开发库Mysql
2023-09-14 09:00:02 时间
Mysql客户端
lua-resty-mysql是为基于cosocket API的ngx_lua提供的Lua Mysql客户端,通过它可以完成Mysql的操作。默认安装OpenResty时已经自带了该模块,使用文档可参考https://github.com/openresty/lua-resty-mysql。
1. 编辑mysql/test_mysql.lua
local function close_db( db )
if not db then
return
end
db:close()
end
local mysql = require("resty.mysql")
-- 创建实例
local db, err = mysql:new()
if not db then
ngx.say("new mysql error:", err)
return
end
-- 设置超时时间(毫秒)
db:set_timeout(5000)
local props = {
host = "172.19.237.44",
port = 3306,
database = "fuhuitest",
user = "root",
password = "wsy@123456"
}
local res, err, errno, sqlstate = db:connect(props)
if not res then
ngx.say("connect to mysql error : ", err, " , errno : ", errno, " , sqlstate : ", sqlstate)
return close_db(db)
end
-- 删除表
local drop_table_sql = "drop table if exists test"
res, err, errno, sqlstate = db:query(drop_table_sql)
if not res then
ngx.say("drop table error : ", err, " , errno : ", errno, " , sqlstate : ", sqlstate)
return close_db(db)
end
-- 创建表
local create_table_sql = "create table test(id int primary key auto_increment, ch varchar(100))"
res, err, errno, sqlstate = db:query(create_table_sql)
if not res then
ngx.say("create table error : ", err, " , errno : ", errno, " , sqlstate : ", sqlstate)
return close_db(db)
end
-- 插入
local insert_sql = "insert into test (ch) values('hello')"
res, err, errno, sqlstate = db:query(insert_sql)
if not res then
ngx.say("insert error : ", err, " , errno : ", errno, " , sqlstate : ", sqlstate)
return close_db(db)
end
res, err, errno, sqlstate = db:query(insert_sql)
ngx.say("insert rows : ", res.affected_rows, " , id : ", res.insert_id, "<br/>")
-- 更新
local update_sql = "update test set ch = 'hello2' where id =" .. res.insert_id
res, err, errno, sqlstate = db:query(update_sql)
if not res then
ngx.say("update error : ", err, " , errno : ", errno, " , sqlstate : ", sqlstate)
return close_db(db)
end
ngx.say("update rows : ", res.affected_rows, "<br/>")
-- 查询
local select_sql = "select id, ch from test"
res, err, errno, sqlstate = db:query(select_sql)
if not res then
ngx.say("select error : ", err, " , errno : ", errno, " , sqlstate : ", sqlstate)
return close_db(db)
end
for i, row in ipairs(res) do
for name, value in pairs(row) do
ngx.say("select row ", i, " : ", name, " = ", value, "<br/>")
end
end
ngx.say("<br/>")
--防止sql注入
local ch_param = ngx.req.get_uri_args()["ch"] or ''
--使用ngx.quote_sql_str防止sql注入
local query_sql = "select id, ch from test where ch = " .. ngx.quote_sql_str(ch_param)
res, err, errno, sqlstate = db:query(query_sql)
if not res then
ngx.say("select error : ", err, " , errno : ", errno, " , sqlstate : ", sqlstate)
return close_db(db)
end
for i, row in ipairs(res) do
for name, value in pairs(row) do
ngx.say("select row ", i, " : ", name, " = ", value, "<br/>")
end
end
-- 删除
local delete_sql = "delete from test"
res, err, errno, sqlstate = db:query(delete_sql)
if not res then
ngx.say("delete error : ", err, " , errno : ", errno, " , sqlstate : ", sqlstate)
return close_db(db)
end
ngx.say("delete rows : ", res.affected_rows, "<br/>")
close_db(db)
对于新增/修改/删除会返回如下格式的响应:
{
insert_id = 0,
server_status = 2,
warning_count = 1,
affected_rows = 32,
message = nil
}
affected_rows表示操作影响的行数,insert_id是在使用自增序列时产生的id。
对于查询会返回如下格式的响应:
{
{ id= 1, ch= "hello"},
{ id= 2, ch= "hello2"}
}
null将返回ngx.null。
2. openResty.conf配置文件
location /lua_mysql {
default_type 'text/html';
lua_code_cache on;
content_by_lua_file /usr/openResty/lua/mysql/test_mysql.lua;
}
3. 访问如http://127.0.0.1/lua_mysql?ch=hello进行测试,得到如下结果
insert rows : 1 , id : 2
update rows : 1
select row 1 : ch = hello
select row 1 : id = 1
select row 2 : ch = hello2
select row 2 : id = 2
select row 1 : ch = hello
select row 1 : id = 1
delete rows : 2
客户端目前还没有提供预编译SQL支持(即占位符替换位置变量),这样在入参时记得使用ngx.quote_sql_str进行字符串转义,防止sql注入;连接池和之前Redis客户端完全一样就不介绍了。
对于Mysql客户端的介绍基本够用了,更多请参考https://github.com/openresty/lua-resty-mysql。
相关文章
- MySQL实现的高效并发队列机制(mysql并发队列)
- 解决MySQL中重复数据的查询策略(mysql查询重复的数据)
- MySQL单表多并发写入实践指南(mysql单表多并发写入)
- MySQL:调整最大并发数量的方法(mysql最大并发数)
- 解决MySQL并发访问问题(mysql并发问题吗)
- MySQL远程连接慢:解决措施(mysql远程连接慢)
- Mysql并发控制和事务管理的研究返回索引(mysql并发事务)
- MySQL中插入表数据的步骤指南(mysql插入表数据)
- 性能优化MySQL高并发环境下的性能优化策略(高并发mysql)
- 深入解析MySQL并发优化技巧,让你的数据库性能大幅提升!(mysql并发优化)
- MySQL队列并发:解密数据库处理高并发问题(mysql队列并发)
- MySQL:支持并发性吗?(mysql支持并发吗)
- 比较:MSSQL和MySQL哪个更适合您的业务?(mssql与mysql)
- 「如何优化MySQL性能?调整缓冲区大小来提升数据库效率吧!」(mysql缓冲区大小)
- 授权MySQL 正版授权让企业获得放心(mysql 正版)
- MySQL并发查询优化技巧(mysql 查询并发)
- MySQL数据库的优点及优势简述(mysql的优势)
- MySQL中的意向锁:实现更好的并发性(意向锁mysql)
- 从 Qt 中编译到 MySQL 的进程(qt mysql 编译)
- 数据库中的MySQL 理解Mysql数据库的重要性(MySql中mysql)
- 使用CMD命令掌控MySQL数据库(cmd命令管理mysql)
- 1w并发MySQL架构优化实践(1w并发 mysql架构)
- 如何在MYSQL中删除分区(mysql中分区怎么删)
- 掌握MySQL三要素,让你轻松应对数据库问题(mysql三大核心知识)
- MySQL有文件上传限制吗(mysql上传文件限制吗)
- 将MySQL数据上传至hive的方法详解(MySQL上传hive)
- 如何避免 MySQL 数据库中显示空值(mysql 不显示空值)