# 如何打开或创建 SQLite 数据库

> 使用 try-with-resources 打开/创建 .db 文件、使用内存数据库并创建表。

Source: https://crossfly.dev/zh/docs/cookbook/data/abrir-banco — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# 如何打开或创建 SQLite 数据库

**目的。** 打开（或在不存在时创建）一个 SQLite 数据库并创建其表。在 CrossFly 中，入口是 `SqliteDb`，一个 `AutoCloseable` 句柄 —— 始终使用 `try (...)` 以确保关闭原生连接。

## 使用的 API
- `SqliteDb.open(String filename)` —— 以读/写模式打开/创建一个**未加密**的数据库（`OPEN_DEFAULT = OPEN_READWRITE | OPEN_CREATE`）。返回一个 `SqliteDb`。
- `SqliteDb.openMemory()` —— 打开一个**内存中**数据库（`:memory:`），易失：关闭时即消失。非常适合测试和临时缓存。
- `SqliteDb.exec(String sql)` —— 运行一条或多条**无结果**的语句（DDL、PRAGMA、批量 DML）。用于 `CREATE TABLE`、`CREATE INDEX`、`PRAGMA ...`。出错时抛出 `SqliteException`。
- `SqliteDb.close()` —— 关闭原生连接。**幂等**（调用两次是安全的）。`try-with-resources` 会自动调用它。
- `SqliteDb.version()` —— 返回 SQLite 库的版本字符串（对诊断很有用）。

> **文件路径。** 传入一个可写的文件路径（视平台而定）。这里不要用 `Gdx.graphics` 做任何事；SQLite 与 UI 无关。关于各平台的文件位置，请参阅存储指南。

## 完整示例（复制、粘贴并运行）

```java
package com.exemplo;

import dev.crossfly.ui.*;                     // Window
import dev.crossfly.ui.layout.*;             // VerticalLayout
import dev.crossfly.sqlite.*;                // SqliteDb, SqliteException

/** 可执行的主界面。将 launcher 指向此类（classname）并运行：gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      // 1) 文件型数据库（不存在则创建）
      try (SqliteDb db = SqliteDb.open("app.db"))
      {
         db.exec(
            "CREATE TABLE IF NOT EXISTS person(" +
            "  id   INTEGER PRIMARY KEY," +
            "  name TEXT NOT NULL," +
            "  age  INTEGER)");
         // ... 在此使用数据库 ...
      }
      // 离开 try 时连接已关闭

      // 2) 内存型数据库（易失）— 适合测试
      try (SqliteDb mem = SqliteDb.openMemory())
      {
         mem.exec("CREATE TABLE t(id INTEGER PRIMARY KEY, v TEXT)");
         // ... 仅在 'mem' 打开期间存在 ...
      }
   }
}
```

> 下面的代码片段仅展示**核心部分**。要运行它，请将其放入上面的 `MainWindow` 骨架中。

## 最小片段
```java
// 已在源码核实：SqliteDb.open / openMemory / exec
import dev.crossfly.sqlite.*;

// 1) 文件型数据库（不存在则创建）
try (SqliteDb db = SqliteDb.open("app.db"))
{
   db.exec(
      "CREATE TABLE IF NOT EXISTS person(" +
      "  id   INTEGER PRIMARY KEY," +
      "  name TEXT NOT NULL," +
      "  age  INTEGER)");
   // ... 在此使用数据库 ...
}
// 离开 try 时连接已关闭

// 2) 内存型数据库（易失）— 适合测试
try (SqliteDb mem = SqliteDb.openMemory())
{
   mem.exec("CREATE TABLE t(id INTEGER PRIMARY KEY, v TEXT)");
   // ... 仅在 'mem' 打开期间存在 ...
}
```

## 深入了解
- [SQLite 存储指南](/docs/data-and-services/storage-sqlite) · 开发指南
- 姊妹配方：[参数化 CRUD](/docs/cookbook/data/crud) · [加密数据库](/docs/cookbook/data/banco-criptografado) · [在 paint 线程之外使用](/docs/cookbook/data/banco-fora-da-paint-thread)
