簡單的數(shù)據(jù)操作,我們用文件就可以處理。但是,某些時候文件操作存在性能、擴(kuò)展性等問題。這時候,我們就需要使用數(shù)據(jù)庫。LuaSQL 是一個提供數(shù)據(jù)庫操作的庫,它支持多種 SQL 數(shù)據(jù)庫的操作。包括:
在本教程中,我們會講解用 Lua 語言對 MySQL 數(shù)據(jù)庫與 SQLite 數(shù)據(jù)庫進(jìn)行操作。這些操作具有一般性,它們也可以移植到其它類型 SQL 數(shù)據(jù)庫中。首先讓我們看一下如何操作 MySQL 數(shù)據(jù)庫。
為了下面的例子可以正確演示,我們需要首先初始化數(shù)據(jù)庫設(shè)置。我們假設(shè)你已經(jīng)完成了如下的工作:
假設(shè)你已經(jīng)安裝配置正確了,那么我們可以使用 require 語句導(dǎo)入 sqlite 庫。安裝過程中會產(chǎn)生一個存儲數(shù)據(jù)相關(guān)文件的目錄 libsql。
mysql = require "luasql.mysql"
我們可以通過 mysql 變量訪問 luasql.mysql 中的 mysql 表,該表中存存儲數(shù)據(jù)庫操作相關(guān)的函數(shù)。
先初始化 MySQL 的環(huán)境,再建立一個連接。如下所示:
local env = mysql.mysql()
local conn = env:connect('test','root','123456')
上面的程序會與已存在的 MySQL 數(shù)據(jù)庫 test 建立連接。
LuaSQL 庫中有一個 execute 函數(shù),此函數(shù)可以完成所有數(shù)據(jù)加操作,包括創(chuàng)建、插入、更新等操作。其語法如下所示:
conn:execute([[ 'MySQLSTATEMENT' ]])
執(zhí)行上面的語句這前,我們需要保證與 MySQL 數(shù)據(jù)庫的連接 conn 是打開的,同時將 MySQLSTATEMENT 更改為合法的 SQL 語句。
下面的示例演示如何創(chuàng)建一個數(shù)據(jù)庫表。例子中為表創(chuàng)建了兩個屬性分別為 id 和 name,其類型分別為整數(shù)和 vchar。
mysql = require "luasql.mysql"
local env = mysql.mysql()
local conn = env:connect('test','root','123456')
print(env,conn)
status,errorString = conn:execute([[CREATE TABLE sample2 (id INTEGER, name TEXT);]])
print(status,errorString )
運(yùn)行上面的程序后,數(shù)據(jù)庫中創(chuàng)建了一個表 sample,該表有兩列,屬性名分別為 id 和 name。
MySQL environment (004BB178) MySQL connection (004BE3C8)
0 nil
如果發(fā)生錯誤,則函數(shù)將返回一個錯誤消息,成功執(zhí)行則返回 nil。下面是錯誤消息的一個例子:
LuaSQL: Error executing query. MySQL: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '"id INTEGER, name TEXT)' at line 1
MySQL 插入語句的示例如下所示:
conn:execute([[INSERT INTO sample values('11','Raj')]])
MySQL 更新語句的示例如下所示:
conn:execute([[UPDATE sample3 SET name='John' where id ='12']])
MySQL 刪除語句的示例如下所示:
conn:execute([[DELETE from sample3 where id ='12']])
成功查找返回后,我們需要循環(huán)遍歷返回的所有行以取得我們需要的數(shù)據(jù)。查找語句的示例如下:
cursor,errorString = conn:execute([[select * from sample]])
row = cursor:fetch ({}, "a")
while row do
print(string.format("Id: %s, Name: %s", row.id, row.name))
-- reusing the table of results
row = cursor:fetch (row, "a")
end
上面的代碼中,我們先打開了一個 MySQL 連接。通過 execute 函數(shù)返回的游標(biāo)(cursor),我們可以使用游標(biāo)遍歷返回的表,取得我們查找的數(shù)據(jù)。
下面這個例子用到了所有上面提到的數(shù)據(jù)的操作函數(shù),請看下面這個完整的例子:
mysql = require "luasql.mysql"
local env = mysql.mysql()
local conn = env:connect('test','root','123456')
print(env,conn)
status,errorString = conn:execute([[CREATE TABLE sample3 (id INTEGER, name TEXT)]])
print(status,errorString )
status,errorString = conn:execute([[INSERT INTO sample3 values('12','Raj')]])
print(status,errorString )
cursor,errorString = conn:execute([[select * from sample3]])
print(cursor,errorString)
row = cursor:fetch ({}, "a")
while row do
print(string.format("Id: %s, Name: %s", row.id, row.name))
row = cursor:fetch (row, "a")
end
-- close everything
cursor:close()
conn:close()
運(yùn)行上面的程序,我們可以得到如下的輸出結(jié)果:
MySQL environment (0037B178) MySQL connection (0037EBA8)
0 nil
1 nil
MySQL cursor (003778A8) nil
Id: 12, Name: Raj
事務(wù)是數(shù)據(jù)庫中保證數(shù)據(jù)一致性的一種機(jī)制。事務(wù)有以下四個性質(zhì):
事務(wù)以 START_TRANSACTION 開始,以 提交(commit)或 回滾(rollback)語句結(jié)束。
為了初始化一個事務(wù),我們需要先打開一個 MySQL 連接,再執(zhí)行如下的語句:
conn:execute([[START TRANSACTION;]])
當(dāng)需要取消事務(wù)執(zhí)行時,我們需要執(zhí)行如下的語句回滾至更改前的狀態(tài)。
conn:execute([[ROLLBACK;]])
開始執(zhí)行事務(wù)后,我們需要使用 commit 語句提交完成的修改內(nèi)容。
conn:execute([[COMMIT;]])
前面我們已經(jīng)了解了 MySQL 的基本知識。接下來,我們將解釋一下基本的 SQL 操作。請記住事務(wù)的概念,雖然我們在 SQLite3 中我們不在解釋它,但是它的概念在 SQLite3 中同樣適用。
假設(shè)你已經(jīng)安裝配置正確了,那么就可以使用 require 語句導(dǎo)入 sqlite 庫。安裝過程中會產(chǎn)生一個存儲數(shù)據(jù)相關(guān)文件的目錄 libsql。
sqlite3 = require "luasql.sqlite3"
通過 sqlite3 變量可以訪問提供的所有數(shù)據(jù)庫操作相關(guān)函數(shù)。
我們先初始化 sqlite 環(huán)境,然后為該環(huán)境創(chuàng)建一個連接。語法如下:
local env = sqlite3.sqlite3()
local conn = env:connect('mydb.sqlite')
上面的代碼會與一個 sqlite 文件建立連接,如果文件不存在則創(chuàng)建新的 sqlite 文件并與該新文件建立連接。
LuaSQL 庫中有一個 execute 函數(shù),此函數(shù)可以完成所有數(shù)據(jù)加操作,包括創(chuàng)建、插入、更新等操作。其語法如下所示:
conn:execute([[ 'SQLite3STATEMENT' ]])
執(zhí)行上面的語句這前,我們需要保證與 MySQL 數(shù)據(jù)庫的連接 conn 是打開的,同時將 SQLite3STATEMENT 更改為合法的 SQL 語句。
下面的示例演示如何創(chuàng)建一個數(shù)據(jù)庫表。例子中為表創(chuàng)建了兩個屬性分別為 id 和 name,其類型分別為整數(shù)和 vchar。
sqlite3 = require "luasql.sqlite3"
local env = sqlite3.sqlite3()
local conn = env:connect('mydb.sqlite')
print(env,conn)
status,errorString = conn:execute([[CREATE TABLE sample ('id' INTEGER, 'name' TEXT)]])
print(status,errorString )
運(yùn)行上面的程序后,數(shù)據(jù)庫中創(chuàng)建了一個表 sample,該表有兩列,屬性名分別為 id 和 name。
SQLite3 environment (003EC918) SQLite3 connection (00421F08)
0 nil
如果發(fā)生錯誤,則函數(shù)將而一個錯誤消息;若成功執(zhí)行則返回 nil。下面是錯誤消息的一個例子:
LuaSQL: unrecognized token: ""'id' INTEGER, 'name' TEXT)"
插入語句的示例如下所示:
conn:execute([[INSERT INTO sample values('11','Raj')]])
查找返回后,我們需要循環(huán)遍歷每行以取得我們需要的數(shù)據(jù)。查找語句的示例如下:
cursor,errorString = conn:execute([[select * from sample]])
row = cursor:fetch ({}, "a")
while row do
print(string.format("Id: %s, Name: %s", row.id, row.name))
-- reusing the table of results
row = cursor:fetch (row, "a")
end
上面的代碼中,我們先打開了一個 sqlite3 連接。通過 execute 函數(shù)返回的游標(biāo)(cursor),我們可以遍歷返回的表,以取得我們查找的數(shù)據(jù)。
下面這個例子用到了所有上面提到的數(shù)據(jù)的操作函數(shù),請看下面這個完整的例子:
sqlite3 = require "luasql.sqlite3"
local env = sqlite3.sqlite3()
local conn = env:connect('mydb.sqlite')
print(env,conn)
status,errorString = conn:execute([[CREATE TABLE sample ('id' INTEGER, 'name' TEXT)]])
print(status,errorString )
status,errorString = conn:execute([[INSERT INTO sample values('1','Raj')]])
print(status,errorString )
cursor,errorString = conn:execute([[select * from sample]])
print(cursor,errorString)
row = cursor:fetch ({}, "a")
while row do
print(string.format("Id: %s, Name: %s", row.id, row.name))
row = cursor:fetch (row, "a")
end
-- close everything
cursor:close()
conn:close()
env:close()
運(yùn)行上面的程序,我們可以得到如下的輸出結(jié)果:
SQLite3 environment (005EC918) SQLite3 connection (005E77B0)
0 nil
1 nil
SQLite3 cursor (005E9200) nil
Id: 1, Name: Raj
使用 libsql 庫我們可以執(zhí)行所有的數(shù)據(jù)庫操作。所以,看完這些例子后,請自己多做一些練習(xí)。