Skip to content

数据存储读取方法

1. 打开或创建字典 (QDictionary.open)

说明: 打开或创建一个QDictionary字典对象,用于存储键值对数据

函数: QDictionary.open(name)

参数:

参数名类型说明
name字符串字典的名称,对应磁盘上的文件名

返回值:

返回值类型说明
QDictionary对象成功时返回QDictionary对象
nil创建失败时返回nil

示例:

lua
-- 示例1: 打开一个字典
local dict = QDictionary.open("user_settings")
if dict then
    print("字典打开成功")
else
    print("字典打开失败")
end

-- 示例2: 存储和读取数据
local appConfig = QDictionary.open("app_config")

-- 存储不同类型的数据
appConfig:put("username", "张三")
appConfig:put("age", 25)
appConfig:put("score", 95.5)
appConfig:put("is_vip", true)

-- 读取数据
local name = appConfig:getString("username")
local age = appConfig:getInt("age")
local score = appConfig:getDouble("score")
local isVip = appConfig:getBool("is_vip")

print("用户名:", name)
print("年龄:", age)
print("分数:", score)
print("VIP:", isVip)

-- 保存到文件
appConfig:commit()

2. 存储键值对 (QDictionary.put)

说明: 在字典中存储键值对数据,支持字符串、数字、布尔值等多种类型

函数: dict:put(key, value)

参数:

参数名类型说明
key字符串键名
value任意类型支持字符串、数字、布尔值等

返回值:

返回值类型说明
booleantrue表示成功,false表示失败

示例:

lua
local dict = QDictionary.open("test_dict")

-- 存储字符串
dict:put("name", "李四")
dict:put("email", "lisi@example.com")

-- 存储数字
dict:put("count", 100)
dict:put("price", 19.99)

-- 存储布尔值
dict:put("enabled", true)
dict:put("verified", false)

-- 存储nil值(会被转换为空字符串)
dict:put("notes", nil)

print("数据存储完成")

3. 获取值 (QDictionary.get)

说明: 根据键名获取字典中存储的值,自动识别数据类型

函数: dict:get(key)

参数:

参数名类型说明
key字符串键名

返回值:

返回值类型说明
任意类型根据存储的数据类型返回相应的值
nil如果键不存在返回nil

示例:

lua
local dict = QDictionary.open("data_dict")

-- 存储测试数据
dict:put("product", "手机")
dict:put("quantity", 5)
dict:put("price", 2999.99)
dict:put("available", true)

-- 获取值(自动识别类型)
local product = dict:get("product")
local quantity = dict:get("quantity")
local price = dict:get("price")
local available = dict:get("available")
local notExist = dict:get("not_exist_key")

print("产品:", product, type(product))
print("数量:", quantity, type(quantity))
print("价格:", price, type(price))
print("可用:", available, type(available))
print("不存在的键:", notExist)

4. 删除键值对 (QDictionary.remove)

说明: 从字典中删除指定的键值对

函数: dict:remove(key)

参数:

参数名类型说明
key字符串键名

返回值:

返回值类型说明
booleantrue表示删除成功,false表示键不存在

示例:

lua
local dict = QDictionary.open("remove_test")

-- 添加测试数据
dict:put("temp_data1", "value1")
dict:put("temp_data2", "value2")
dict:put("important_data", "不要删除")

print("删除前大小:", dict:size())

-- 删除键值对
local result1 = dict:remove("temp_data1")
local result2 = dict:remove("temp_data2")
local result3 = dict:remove("not_exist_key")

print("删除temp_data1:", result1)
print("删除temp_data2:", result2)
print("删除不存在的键:", result3)
print("删除后大小:", dict:size())

-- 验证删除结果
print("temp_data1是否存在:", dict:contains("temp_data1"))
print("important_data是否存在:", dict:contains("important_data"))

5. 获取字典大小 (QDictionary.size)

说明: 获取字典中键值对的数量

函数: dict:size()

参数: 无

返回值:

返回值类型说明
整数表示字典中键值对的数量

示例:

lua
local dict = QDictionary.open("size_test")

print("初始大小:", dict:size())

-- 添加数据
dict:put("key1", "value1")
dict:put("key2", "value2")
dict:put("key3", "value3")

print("添加后大小:", dict:size())

-- 删除一个键
dict:remove("key2")

print("删除后大小:", dict:size())

-- 清空字典
dict:clear()

print("清空后大小:", dict:size())

6. 清空字典 (QDictionary.clear)

说明: 清空字典中的所有键值对

函数: dict:clear()

参数: 无

返回值:

返回值类型说明
booleantrue表示清空成功

示例:

lua
local dict = QDictionary.open("clear_test")

-- 添加大量数据
for i = 1, 10 do
    dict:put("key_" .. i, "value_" .. i)
end

print("清空前:")
print("大小:", dict:size())
print("包含key_5:", dict:contains("key_5"))

-- 清空字典
local result = dict:clear()

print("清空结果:", result)
print("清空后大小:", dict:size())
print("包含key_5:", dict:contains("key_5"))

-- 清空后可以重新使用
dict:put("new_key", "new_value")
print("重新使用后大小:", dict:size())

7. 保存字典到文件 (QDictionary.commit)

说明: 将字典中的数据保存到磁盘文件

函数: dict:commit()

参数: 无

返回值:

返回值类型说明
booleantrue表示保存成功,false表示保存失败

示例:

lua
local dict = QDictionary.open("persistent_data")

-- 添加一些重要数据
dict:put("last_login", os.date())
dict:put("user_preferences", "dark_mode,large_font")
dict:put("session_count", 15)

print("保存前数据已修改")

-- 显式保存到文件
local saveResult = dict:commit()

if saveResult then
    print("数据保存成功")
else
    print("数据保存失败")
end

-- 重新打开字典验证数据持久化
local newDict = QDictionary.open("persistent_data")
print("重新打开后:")
print("最后登录:", newDict:getString("last_login"))
print("会话次数:", newDict:getInt("session_count"))

8. 获取值类型 (QDictionary.getType)

说明: 获取指定键对应的值的类型

函数: dict:getType(key)

参数:

参数名类型说明
key字符串键名

返回值:

返回值类型说明
字符串表示值的类型,可能的值有:"string", "int", "double", "bool", "null", "unknown"

示例:

lua
local dict = QDictionary.open("type_test")

-- 存储不同类型的数据
dict:put("string_val", "hello")
dict:put("int_val", 100)
dict:put("double_val", 3.14)
dict:put("bool_val", true)
dict:put("null_val", nil)

-- 获取每个值的类型
local types = {
    "string_val",
    "int_val", 
    "double_val",
    "bool_val",
    "null_val",
    "not_exist"
}

print("值类型检查:")
for _, key in ipairs(types) do
    local valueType = dict:getType(key)
    print(string.format("  %s: %s", key, valueType))
end

-- 根据类型进行不同的处理
local key = "int_val"
local valueType = dict:getType(key)

if valueType == "string" then
    local value = dict:getString(key)
    print("字符串值:", value)
elseif valueType == "int" or valueType == "double" then
    local value = dict:getDouble(key)
    print("数字值:", value)
elseif valueType == "bool" then
    local value = dict:getBool(key)
    print("布尔值:", value)
else
    print("未知或空值")
end

9. 打印字典内容 (QDictionary.print)

说明: 打印字典中的所有键值对内容

函数: dict:print()

参数: 无

返回值:

返回值类型说明
booleantrue表示打印成功

示例:

lua
local dict = QDictionary.open("print_demo")

-- 添加各种类型的数据
dict:put("app_name", "我的应用")
dict:put("version", 1.2)
dict:put("user_count", 1500)
dict:put("price", 9.99)
dict:put("is_active", true)
dict:put("features", "a,b,c")

print("字典内容:")
dict:print()

-- 实际应用:调试信息
function debugDictionary(dict, title)
    print("=== " .. (title or "字典调试信息") .. " ===")
    dict:print()
    print("=== 结束 ===")
end

debugDictionary(dict, "应用配置")

10. QDictionary 综合示例

说明: QDictionary字典的综合应用示例,展示配置管理的完整流程

示例:

lua
-- 综合示例:应用配置管理
local config = QDictionary.open("app_config")

-- 1. 初始化默认配置
if config:size() == 0 then
    print("初始化默认配置...")
    config:put("app_name", "我的应用")
    config:put("version", "1.0.0")
    config:put("max_users", 1000)
    config:put("default_theme", "dark")
    config:put("enable_logging", true)
    config:put("log_level", 2)
    config:put("timeout", 30.5)
    config:commit()
end

-- 2. 读取配置
print("=== 应用配置 ===")
print("应用名称:", config:getString("app_name"))
print("版本:", config:getString("version"))
print("最大用户数:", config:getInt("max_users"))
print("默认主题:", config:getString("default_theme"))
print("启用日志:", config:getBool("enable_logging"))
print("日志级别:", config:getInt("log_level"))
print("超时时间:", config:getDouble("timeout"))

-- 3. 更新配置
config:put("last_launch", os.date())
config:put("launch_count", (config:getInt("launch_count", 0) + 1))

-- 4. 配置验证和修复
if not config:contains("default_language") then
    config:put("default_language", "zh-CN")
    print("添加缺失的默认语言配置")
end

-- 5. 批量操作演示
print("\n=== 配置统计 ===")
print("配置项数量:", config:size())

-- 找出所有字符串类型的配置
local stringKeys = {}
local allKeys = {"app_name", "version", "default_theme", "default_language", "last_launch"}
for _, key in ipairs(allKeys) do
    if config:getType(key) == "string" then
        table.insert(stringKeys, key)
    end
end

print("字符串配置项:", table.concat(stringKeys, ", "))

-- 6. 保存配置
if config:commit() then
    print("配置保存成功")
else
    print("配置保存失败")
end

-- 7. 配置备份
local backupConfig = QDictionary.open("app_config_backup")
backupConfig:clear()

-- 复制所有配置
for _, key in ipairs(allKeys) do
    if config:contains(key) then
        local valueType = config:getType(key)
        if valueType == "string" then
            backupConfig:put(key, config:getString(key))
        elseif valueType == "int" then
            backupConfig:put(key, config:getInt(key))
        elseif valueType == "double" then
            backupConfig:put(key, config:getDouble(key))
        elseif valueType == "bool" then
            backupConfig:put(key, config:getBool(key))
        end
    end
end

backupConfig:commit()
print("配置备份完成,备份项数量:", backupConfig:size())

11. 打开或创建SQLite数据库 (SQlite3.open)

说明: 打开或创建一个SQLite数据库文件

函数: SQlite3.open(path)

参数:

参数名类型说明
path字符串数据库文件路径

返回值:

返回值类型说明
SQlite3对象成功时返回SQlite3对象
nil打开失败时返回nil
字符串打开失败时返回错误信息

示例:

lua
-- 示例1: 打开或创建数据库
local dbPath = getWorkPath() .. "/test.db"
local db, err = SQlite3.open(dbPath)

if db then
    print("数据库打开成功:", dbPath)
else
    print("数据库打开失败:", err)
end

-- 示例2: 创建表
if db then
    local sql = [[
        CREATE TABLE IF NOT EXISTS users (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            name TEXT NOT NULL,
            age INTEGER,
            email TEXT UNIQUE,
            created_at DATETIME DEFAULT CURRENT_TIMESTAMP
        )
    ]]
    
    local success = db:execute(sql)
    if success then
        print("用户表创建成功")
    else
        print("用户表创建失败")
    end
end

12. 执行SQL语句 (SQlite3.execute)

说明: 执行SQL语句,包括创建表、插入、更新、删除等操作

函数: db:execute(sql)

参数:

参数名类型说明
sql字符串要执行的SQL语句

返回值:

返回值类型说明
booleantrue表示执行成功,false表示执行失败

示例:

lua
-- 示例1: 插入数据
local db = SQlite3.open(getWorkPath() .. "/app.db")

-- 创建表
db:execute([[
    CREATE TABLE IF NOT EXISTS products (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        name TEXT NOT NULL,
        price REAL,
        stock INTEGER DEFAULT 0
    )
]])

-- 插入单条数据
local insertSQL = "INSERT INTO products (name, price, stock) VALUES ('手机', 1999.99, 50)"
local success = db:execute(insertSQL)
if success then
    print("数据插入成功")
else
    print("数据插入失败")
end

-- 示例2: 批量插入数据
local products = {
    {"笔记本电脑", 5999.99, 20},
    {"平板电脑", 2999.99, 30},
    {"智能手表", 999.99, 100}
}

for _, product in ipairs(products) do
    local sql = string.format("INSERT INTO products (name, price, stock) VALUES ('%s', %f, %d)",
        product[1], product[2], product[3])
    db:execute(sql)
end

-- 示例3: 更新数据
local updateSQL = "UPDATE products SET stock = stock - 1 WHERE name = '手机'"
db:execute(updateSQL)

-- 示例4: 删除数据
local deleteSQL = "DELETE FROM products WHERE stock = 0"
db:execute(deleteSQL)

print("数据操作完成")

13. 执行查询语句 (SQlite3.query)

说明: 执行查询SQL语句,返回JSON格式的查询结果

函数: db:query(sql)

参数:

参数名类型说明
sql字符串要执行的查询SQL语句

返回值:

返回值类型说明
字符串JSON格式的查询结果字符串
字符串包含错误信息时会返回错误JSON

示例:

lua
-- 示例1: 基本查询
local db = SQlite3.open(getWorkPath() .. "/data.db")

-- 创建测试数据
db:execute([[
    CREATE TABLE IF NOT EXISTS employees (
        id INTEGER PRIMARY KEY,
        name TEXT,
        department TEXT,
        salary REAL
    )
]])

-- 插入测试数据
db:execute("INSERT OR IGNORE INTO employees VALUES (1, '张三', '技术部', 15000)")
db:execute("INSERT OR IGNORE INTO employees VALUES (2, '李四', '销售部', 12000)")
db:execute("INSERT OR IGNORE INTO employees VALUES (3, '王五', '技术部', 18000)")

-- 查询所有员工
local result = db:query("SELECT * FROM employees")
print("查询结果:", result)

-- 解析JSON结果
local data = jsonLib.decode(result)

if data.error then
    print("查询错误:", data.error)
else
    print("查询到", #data, "条记录")
    for i, employee in ipairs(data) do
        print(string.format("员工%d: %s - %s - ¥%.2f", 
            employee.id, employee.name, employee.department, employee.salary))
    end
end

-- 示例2: 条件查询
local techResult = db:query("SELECT * FROM employees WHERE department = '技术部'")
local techData = jsonLib.decode(techResult)

print("技术部员工:")
for i, emp in ipairs(techData) do
    print("  " .. emp.name .. " - ¥" .. emp.salary)
end

-- 示例3: 聚合查询
local statsResult = db:query([[
    SELECT 
        department,
        COUNT(*) as count,
        AVG(salary) as avg_salary,
        MAX(salary) as max_salary
    FROM employees 
    GROUP BY department
]])

local statsData = jsonLib.decode(statsResult)
print("部门统计:")
for i, stat in ipairs(statsData) do
    print(string.format("  %s: %d人, 平均工资¥%.2f, 最高工资¥%.2f",
        stat.department, stat.count, stat.avg_salary, stat.max_salary))
end

14. 获取最后插入的ID (SQlite3.last_insert_id)

说明: 获取最后插入行的自增ID值

函数: db:last_insert_id()

参数: 无

返回值:

返回值类型说明
整数表示最后插入行的ID

示例:

lua
local db = SQlite3.open(getWorkPath() .. "/test.db")

-- 创建带自增主键的表
db:execute([[
    CREATE TABLE IF NOT EXISTS orders (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        product_name TEXT,
        quantity INTEGER,
        order_date DATETIME DEFAULT CURRENT_TIMESTAMP
    )
]])

-- 插入多条记录并获取ID
local products = {"iPhone", "iPad", "MacBook"}

for i, product in ipairs(products) do
    local sql = string.format("INSERT INTO orders (product_name, quantity) VALUES ('%s', %d)",
        product, i * 2)
    db:execute(sql)
    
    local lastId = db:last_insert_id()
    print("插入记录ID:", lastId, "产品:", product)
end

-- 批量插入并获取最后一个ID
db:execute("INSERT INTO orders (product_name, quantity) VALUES ('AirPods', 10)")
db:execute("INSERT INTO orders (product_name, quantity) VALUES ('Watch', 5)")

local finalId = db:last_insert_id()
print("最后插入的ID:", finalId)

-- 验证最后插入的记录
local lastRecord = db:query("SELECT * FROM orders WHERE id = " .. finalId)
print("最后插入的记录:", lastRecord)

15. 开始事务 (SQlite3.begin_transaction)

说明: 开始一个数据库事务,用于保证多个操作的原子性

函数: db:begin_transaction()

参数: 无

返回值:

返回值类型说明
booleantrue表示开始事务成功,false表示失败

示例:

lua
local db = SQlite3.open(getWorkPath() .. "/inventory.db")

-- 创建库存表
db:execute([[
    CREATE TABLE IF NOT EXISTS inventory (
        product_id INTEGER PRIMARY KEY,
        product_name TEXT,
        quantity INTEGER,
        price REAL
    )
]])

-- 开始事务
local transactionStarted = db:begin_transaction()
if not transactionStarted then
    print("开始事务失败")
    return
end

print("事务开始成功")

-- Lua中正确的错误处理方式
local success, errorMessage = pcall(function()
    -- 在事务中执行多个操作
    local success1 = db:execute("INSERT INTO inventory VALUES (1, '商品A', 100, 29.99)")
    if not success1 then
        error("插入商品A失败")
    end
    
    local success2 = db:execute("INSERT INTO inventory VALUES (2, '商品B', 50, 49.99)")
    if not success2 then
        error("插入商品B失败")
    end
    
    local success3 = db:execute("UPDATE inventory SET quantity = quantity - 10 WHERE product_id = 1")
    if not success3 then
        error("更新库存失败")
    end
    
    -- 模拟一个可能失败的操作
    local shouldFail = false
    if shouldFail then
        error("模拟操作失败")
    end
    
    return true
end)

if success then
    -- 所有操作成功,提交事务
    local commitSuccess = db:commit()
    if commitSuccess then
        print("事务提交成功")
    else
        print("事务提交失败")
        -- 提交失败也需要回滚
        db:rollback()
    end
else
    -- 发生错误时回滚事务
    print("操作失败,回滚事务:", errorMessage)
    db:rollback()
end

16. 提交事务 (SQlite3.commit)

说明: 提交当前事务,将所有操作永久保存到数据库

函数: db:commit()

参数: 无

返回值:

返回值类型说明
booleantrue表示提交成功,false表示提交失败

示例:

lua
-- 示例:银行转账事务(使用正确的Lua错误处理)
local db = SQlite3.open(getWorkPath() .. "/bank.db")

-- 创建账户表
db:execute([[
    CREATE TABLE IF NOT EXISTS accounts (
        account_id INTEGER PRIMARY KEY,
        account_name TEXT,
        balance REAL
    )
]])

-- 初始化账户数据
db:execute("INSERT OR IGNORE INTO accounts VALUES (1, '张三', 1000.00)")
db:execute("INSERT OR IGNORE INTO accounts VALUES (2, '李四', 500.00)")

-- 执行转账事务
function transferMoney(fromAccount, toAccount, amount)
    -- 开始事务
    if not db:begin_transaction() then
        return false, "开始事务失败"
    end
    
    -- 使用pcall进行错误处理
    local success, err = pcall(function()
        -- 检查转出账户余额
        local fromBalance = getAccountBalance(fromAccount)
		if amount >= fromBalance  then
			error("余额不足")
		end
        
        -- 执行转账操作
        local success1 = db:execute(string.format(
            "UPDATE accounts SET balance = balance - %f WHERE account_id = %d",
            amount, fromAccount))
            
        if not success1 then
            error("扣款操作失败")
        end
        
        local success2 = db:execute(string.format(
            "UPDATE accounts SET balance = balance + %f WHERE account_id = %d", 
            amount, toAccount))
        
        if not success2 then
            error("收款操作失败")
        end
        
        return true
    end)
    
    if success then
        -- 提交事务
        if db:commit() then
            return true, "转账成功"
        else
            db:rollback()
            return false, "提交失败"
        end
    else
        -- 回滚事务
        db:rollback()
        return false, err
    end
end

-- 执行转账
local result, msg = transferMoney(1, 2, 100)
if result then
    print(msg)
else
    print("转账失败:", msg)
end

17. 回滚事务 (SQlite3.rollback)

说明: 回滚当前事务,撤销事务中的所有操作

函数: db:rollback()

参数: 无

返回值:

返回值类型说明
booleantrue表示回滚成功,false表示回滚失败

示例:

lua
local db = SQlite3.open(getWorkPath() .. "/test.db")

-- 创建测试表
db:execute([[
    CREATE TABLE IF NOT EXISTS test_table (
        id INTEGER PRIMARY KEY,
        value TEXT
    )
]])

-- 开始事务
db:begin_transaction()

-- 插入数据
db:execute("INSERT INTO test_table VALUES (1, 'value1')")
db:execute("INSERT INTO test_table VALUES (2, 'value2')")

-- 查询插入的数据
local result1 = db:query("SELECT * FROM test_table")
print("回滚前:", result1)

-- 回滚事务
db:rollback()

-- 查询回滚后的数据
local result2 = db:query("SELECT * FROM test_table")
print("回滚后:", result2)

-- 示例2:错误时自动回滚
db:begin_transaction()

local success, err = pcall(function()
    db:execute("INSERT INTO test_table VALUES (3, 'value3')")
    
    -- 模拟错误
    if true then
        error("操作失败")
    end
    
    db:execute("INSERT INTO test_table VALUES (4, 'value4')")
end)

if not success then
    print("发生错误,回滚事务:", err)
    db:rollback()
end

-- 验证数据是否被回滚
local result3 = db:query("SELECT * FROM test_table")
print("错误处理后:", result3)

18. 关闭数据库 (SQlite3.close)

说明: 关闭数据库连接,释放资源

函数: db:close()

参数: 无

返回值:

返回值类型说明
booleantrue表示关闭成功,false表示关闭失败

示例:

lua
local db = SQlite3.open(getWorkPath() .. "/test.db")

-- 执行数据库操作
db:execute([[
    CREATE TABLE IF NOT EXISTS users (
        id INTEGER PRIMARY KEY,
        name TEXT,
        email TEXT
    )
]])

db:execute("INSERT INTO users VALUES (1, '张三', 'zhangsan@example.com')")
db:execute("INSERT INTO users VALUES (2, '李四', 'lisi@example.com')")

-- 查询数据
local result = db:query("SELECT * FROM users")
print("查询结果:", result)

-- 关闭数据库
local closeResult = db:close()
if closeResult then
    print("数据库关闭成功")
else
    print("数据库关闭失败")
end

-- 示例2:使用pcall确保数据库正确关闭
local function safeDatabaseOperation()
    local db = SQlite3.open(getWorkPath() .. "/safe.db")
    
    local success, err = pcall(function()
        -- 执行数据库操作
        db:execute("CREATE TABLE IF NOT EXISTS test (id INTEGER, value TEXT)")
        db:execute("INSERT INTO test VALUES (1, 'test')")
        
        -- 模拟可能的错误
        if false then
            error("操作失败")
        end
        
        return true
    end)
    
    -- 无论成功失败,都关闭数据库
    db:close()
    
    if not success then
        print("操作失败:", err)
        return false
    end
    
    return true
end

safeDatabaseOperation()