OpenResty中使用mysql
使用MySQL
默认安装OpenResty时已经自带了mysql模块
我们编写一个案例,操作mysql数据库,编辑test.lua
---定义关闭mysql的连接
local function close_db(db)
if not db then
return
end
db:close()
end
local mysql = require("resty.mysql") ---引入mysql模块
--创建实例
local db, err = mysql:new()
if not db then
ngx.say("new mysql error : ", err)
return
end
--设置超时时间(毫秒)
db:set_timeout(1000)
---连接属性定义
local props = {
host = "127.0.0.1",
port = 3306,
database = "testdb",
user = "root",
password = "root",
charset = "utf8"
}
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
ngx.say("===========删除表user========", "<br/>")
--我们对数据库进行crud,统一的操作方法 query
--不同于其他语言 insert update delete select
--删除表
local drop_table_sql = "drop table if exists user"
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
ngx.say("===========创建表user========", "<br/>")
--创建表
local create_table_sql = "create table user(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
ngx.say("===========插入数据user========", "<br/>")
--插入
local insert_sql = "insert into user (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/>")
ngx.say("===========更新表user========", "<br/>")
--更新
local update_sql = "update user 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/>")
ngx.say("===========查询user========", "<br/>")
--查询
local select_sql = "select id, ch from user"
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
----查询成功后,res为表类型,结构类型如下
----{{id=1,name="n1"},{id=2,name="n2"}}
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/>")
ngx.say("===========查询user=根据ch参数=======", "<br/>")
--防止sql注入
local ch_param = ngx.req.get_uri_args()["ch"] or ''
--使用ngx.quote_sql_str防止sql注入
local query_sql = "select id, ch from user 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
ngx.say("===========删除user========", "<br/>")
--删除
local delete_sql = "delete from user"
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/>")
ngx.say("===========关闭db========", "<br/>")
close_db(db)
注意点:
客户端目前还没有提供预编译SQL支持(即占位符替换位置变量),
这样在入参时记得使用ngx.quote_sql_str
进行字符串转义,防止sql注入;
操作返回格式
对于新增/修改/删除会返回如下格式的响应:
{
insert_id = 0, ----insert_id是在使用自增序列时产生的id。
server_status = 2,
warning_count = 1,
affected_rows = 32, ----affected_rows表示操作影响的行数
message = nil
}
对于查询会返回如下格式的响应:
{
{ id= 1, ch= "hello"},
{ id= 2, ch= "hello2"}
}
null将返回ngx.null
。
连接池
连接池和之前Redis客户端完全一样。
ocal function close_db(db)
if not db then
return
end
--释放连接(连接池实现)
local pool_max_idle_time = 10000 --毫秒
local pool_size = 100 --连接池大小
local ok, err = db:set_keepalive(pool_max_idle_time, pool_size)
if not ok then
ngx.say("set keepalive error : ", err)
end
end