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  
posted @ 2025-04-13 11:15  小郑[努力版]  阅读(39)  评论(0)    收藏  举报