本页面由葡萄牙语机器翻译,可能存在错误。葡萄牙语版本为准。
如何在 SQLite 中进行参数化 CRUD
目的。 使用位置参数(?)执行 INSERT/UPDATE/DELETE 和 SELECT,避免字符串拼接(它会导致 SQL 注入和引号错误)。请注意 CrossFly 的两种索引约定。
⚠️ 索引。 在绑定参数时,索引从 1 开始(
?第 1、2、… 个)。在从 cursor 读取列时,索引从 0 开始(getString(0)= 第一列)。这是有意为之,并且与 SQLite 的原生 API 一致。
使用的 API
SqliteDb.execute(String sql, Object... params)—— 准备语句、执行bindAll(params)(bind 从 1 开始)、执行单个 INSERT/UPDATE/DELETE,并返回受影响的行数(int)。类型会被推断:Integer/Long/Short/Byte→整数,Float/Double→实数,Boolean→0/1,byte[]→BLOB,null→NULL,否则toString()→TEXT。SqliteDb.query(String sql, Object... params)—— 返回一个已打开的SqliteCursor(bind 从 1 开始)。调用方必须关闭(使用try-with-resources)。SqliteCursor.next()—— 前进到下一行;如果有行则返回true。SqliteCursor.getInt(col)/getLong/getDouble/getString/getBlob/isNull(col)—— 类型化的 getter,列从 0 开始。SqliteDb.queryLong(sql, defaultValue, params)—— 快捷方式:第一行第一列作为long,若无行则返回defaultValue。SqliteDb.queryString(sql, params)—— 快捷方式:第一行第一列作为String,若无行则返回null。SqliteDb.lastInsertRowid()—— 最后一次 INSERT 的 rowid(long)。SqliteDb.changes()—— 最后一条语句更改的行数。
完整示例(复制、粘贴并运行)
package com.exemplo;
import dev.crossfly.ui.*; // Window
import dev.crossfly.ui.layout.*; // VerticalLayout
import dev.crossfly.sqlite.*; // SqliteDb, SqliteCursor
/** 可执行的主界面。将 launcher 指向此类(classname)并运行:gradlew :lwjgl3:run */
public class MainWindow extends Window
{
@Override
public void onShow() throws Exception
{
super.onShow();
setLayout(new VerticalLayout());
try (SqliteDb db = SqliteDb.open("app.db"))
{
db.exec("CREATE TABLE IF NOT EXISTS person(id INTEGER PRIMARY KEY, name TEXT, age INTEGER)");
// CREATE — 位置参数(? 第 1 = name,? 第 2 = age)
int inserted = db.execute("INSERT INTO person(name, age) VALUES(?, ?)", "Alice", 30);
long id = db.lastInsertRowid(); // 生成的 rowid
System.out.println(inserted + " linha(s), id=" + id);
// READ — cursor:列从 0 开始
try (SqliteCursor c = db.query("SELECT name, age FROM person WHERE age > ?", 18))
{
while (c.next())
System.out.println(c.getString(0) + " = " + c.getInt(1)); // col 0 = name,col 1 = age
}
// READ 标量 — 快捷方式
long total = db.queryLong("SELECT count(*) FROM person", 0);
String nome = db.queryString("SELECT name FROM person WHERE id = ?", id);
// UPDATE — 返回受影响的行数
int updated = db.execute("UPDATE person SET age = ? WHERE id = ?", 31, id);
// DELETE
int deleted = db.execute("DELETE FROM person WHERE id = ?", id);
}
}
}
下面的代码片段仅展示核心部分。要运行它,请将其放入上面的
MainWindow骨架中。
最小片段
// 已在源码验证:execute(bind 从 1 开始)、query + cursor(getters 从 0 开始)、queryLong/queryString
import dev.crossfly.sqlite.*;
try (SqliteDb db = SqliteDb.open("app.db"))
{
db.exec("CREATE TABLE IF NOT EXISTS person(id INTEGER PRIMARY KEY, name TEXT, age INTEGER)");
// CREATE — 位置参数(? 第 1 = name,? 第 2 = age)
int inserted = db.execute("INSERT INTO person(name, age) VALUES(?, ?)", "Alice", 30);
long id = db.lastInsertRowid(); // 生成的 rowid
System.out.println(inserted + " linha(s), id=" + id);
// READ — cursor:列从 0 开始
try (SqliteCursor c = db.query("SELECT name, age FROM person WHERE age > ?", 18))
{
while (c.next())
System.out.println(c.getString(0) + " = " + c.getInt(1)); // col 0 = name,col 1 = age
}
// READ 标量 — 快捷方式
long total = db.queryLong("SELECT count(*) FROM person", 0);
String nome = db.queryString("SELECT name FROM person WHERE id = ?", id);
// UPDATE — 返回受影响的行数
int updated = db.execute("UPDATE person SET age = ? WHERE id = ?", 31, id);
// DELETE
int deleted = db.execute("DELETE FROM person WHERE id = ?", id);
}
深入了解
- SQLite 存储指南 · 开发指南
- 姊妹配方:打开/创建数据库 · 事务与批量写入 · 在 paint 线程之外使用
这个页面有帮助吗?感谢你的反馈!