使用mysql模块

Mysql客户端

在我们应用中最长打交道的就是数据库了,尤其mysql数据库,那openresty lua如何操作mysql呢? 默认安装OpenResty时已经自带了该模块。

我们编写个案例,操作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 = "192.168.31.247",
    port = 3306,
    database = "test",
    user = "root",
    password = "123456",
    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)

对于新增/修改/删除会返回如下格式的响应:

对于查询会返回如下格式的响应:

null将返回ngx.null。

访问请求http://127.0.0.1/lua?ch=hello

输出结果

注意点:

客户端目前还没有提供预编译SQL支持(即占位符替换位置变量),

这样在入参时记得使用ngx.quote_sql_str进行字符串转义,防止sql注入;

连接池和之前Redis客户端完全一样。

更多资料 https://github.com/openresty/lua-resty-mysql

sqlstate: https://blog.csdn.net/tercel99/article/details/1520094

Last updated

Was this helpful?