2011年5月3日 星期二

Corona SDK -- sqlite3 SQL資料庫結構

在遊戲設計上,一定常常會需要使用或記錄大量的遊戲參數,例如:金錢、過關數、殺敵數等等。如果都只單純使用一般文字檔來記錄,雖然寫入方法簡單,但是當讀取參數後,該怎麼篩選出你需要的資料,那就頭痛了。因此,建立一個資料庫在處理大量的參數是很必要的。那什麼樣的資料庫適合在遊戲內使用呢?由於遊戲的資料庫只會在單機上使用,不需要在網路上任意上任何人取用,因此不需要一個專屬的資料庫系統,這時嵌入式資料庫 -- SQLite就相當的適合,小巧又簡單上手,而且Corona SDK採用Lua語言,可以直接取用SQLite使用,相當方便。

Corona SDK官方網頁上有介紹如何使用SQLite。不過並沒有針對所有的function作詳細的介紹與使用說明,若希望了解更多的SQLite功能,可參考這個網頁

以下,我將幫助Corona SDK補充一些非常基本、而且非常會用到的語法。

首先,要能使用SQLite,一開始一定要把SQLite包含進來,SQLite不像其他library(如:ui.lua、director.lua等),無需把sqlite.lua納入,只要宣告他即可。
-----------------------------------------
        local sqlite3 = require "sqlite3"
-----------------------------------------
當要建立資料庫時,可以依照你的需求,設計成『建立在Memory上的資料庫』,或者『實體資料庫』。這兩個差別不大,主要就在於這資料庫是否需要儲存提供給下一次遊戲開啟使用,顧名思義,建立在Memory上的自然程式一關掉後資料庫就會清除。
-----------------------------------------
建立在Memory上的資料庫:
        local database = sqlite3.open_memory()
建立實體資料庫:
        local path = system.pathForFile("data.db", system.DocumentsDirectory)
        database = sqlite3.open( path )
-----------------------------------------
這樣的語法相當明顯簡單。
建立好資料庫後,需要了解一下SQLite是怎樣放置資料的?有什麼樣的規則。又要用什麼語法建立你要放置的資料table呢?
SQLite的資料庫結構很簡單,如下:
table: Actor

姓名
性別
年紀
丁力
52
今晚打老虎
28
謝志明
32
郭春嬌
28

以上範例為database(為一資料庫)中的一個資料表(table),這個資料表(table)裡面含有姓名、性別、年紀三個欄位(column),每個欄位裡面有相互對應的資料錄(record)。

因此,就可以依照上述的資料關連性,去找出你要的資料,例如:我要找出上海灘裡面丁力的年紀是多少?那資料庫就會回饋給你答案:52歲。

那怎麼建立這樣的資料庫呢?(不論database是建立在Memory或是實體都一樣語法)
-----------------------------------------
        database:exec[[
                CREATE TABLE Actor (Name, Sex, Age);
                INSERT INTO Actor VALUES ( "丁力"           ,  "男"  , 52);
                INSERT INTO Actor VALUES ( "今晚打老虎"  ,  "男" , 28);
                INSERT INTO Actor VALUES ( "謝志明"        ,  "男" , 32);
                INSERT INTO Actor VALUES ( "郭春嬌"        ,  "女" , 28)
                ]]
-----------------------------------------
(exec指令意義為 執行[[指令]])
這樣資料庫就建立好了。Easy吧 ~~

那怎麼讀取呢?
-----------------------------------------
        for row in database:nrows("SELECT Name FROM Actor") do
                print("姓名 = ".. row.Name)
        end

        for row in database:nrows("SELECT Age FROM Actor") do
                print("Age = ".. row.Age)
        end
-----------------------------------------
Answer :
姓名 = 丁力
姓名 = 今晚打老虎
姓名 = 謝志明
姓名 = 郭春嬌
Age = 52
Age = 28
Age = 32
Age = 28

語法意思是說:
從Actor這個Table裡面選擇Name欄位的資料
從Actor這個Table裡面選擇Age欄位的資料
這樣就把所有年紀的資訊給讀取出來了。

當然也可以在更限定一點,假設我只要讀取丁力的年紀:
-----------------------------------------
        for row in database:nrows("SELECT Age FROM Actor WHERE Name='丁力' ") do
                print("丁力‘s Age = ".. row)
        end
-----------------------------------------
Answer :
丁力‘s Age = 52

那,如何修改參數呢?請使用UPDATE這個語法
例如:我要把丁力的年紀改為80歲
-----------------------------------------
        local tt=[[UPDATE Actor SET Age = 80 WHERE Name='丁力'; ]]
        database:exec(tt)
-----------------------------------------
這樣就可以把丁力的年紀給修正了。

最後,在離開程式的時候,最好把資料庫給close掉。所以最好加入以下程式,當離開程式的event發生的時候,把資料庫關閉。
-----------------------------------------
        local function onSystemEvent (event)
                if event.type == "applicationExit" then
                        database:close()
                end
        end
        Runtime:addEventListener("system", onSystemEvent)
-----------------------------------------
這樣就完成資料庫的建立、修改以及關閉。

以下為完整程式範例:
-----------------------------------------
        local sqlite3 = require "sqlite3"
        local database = sqlite3.open_memory()
        database:exec[[
                CREATE TABLE Actor (Name, Sex, Age);
                INSERT INTO Actor VALUES ("丁力" , "男", 52);
                INSERT INTO Actor VALUES ("今晚打老虎" , "男", 28);
                INSERT INTO Actor VALUES ("謝志明" , "男", 32);
                INSERT INTO Actor VALUES ("郭春嬌" , "女", 28)
                ]]

        for row in database:nrows("SELECT Name FROM Actor") do
                print("姓名 = " .. row.Name)
        end
        for row in database:nrows("SELECT Age FROM Actor") do
                print("Age = " .. row.Age)
        end
        for row in database:nrows("SELECT Age FROM Actor WHERE Name='丁力'") do
                print("丁力‘s Age = ".. row.Age)
        end

        local tt=[[UPDATE Actor SET Age = 80 WHERE Name='丁力'; ]]
        database:exec(tt)
      
        for row in database:nrows("SELECT Age FROM Actor WHERE Name='丁力'") do
                print("丁力‘s Age = ".. row.Age)
        end

        local function onSystemEvent (event)
                if event.type == "applicationExit" then
                        database:close()
                end
        end
        Runtime:addEventListener("system", onSystemEvent)
-----------------------------------------

2 則留言:

  1. 感謝大大的文章 有被拯救的感覺!

    回覆刪除
  2. 請問一下我要怎麼設定我的資料庫檔案要放在哪裡呢??

    回覆刪除