Pular para o conteúdo
CrossFly é 100% open sourceSiga no GitHub
CrossFlyCrossFly
Começar

Como fazer CRUD parametrizado no SQLite

Propósito. Executar INSERT/UPDATE/DELETE e SELECT com parâmetros posicionais (?), evitando concatenação de strings (que causa SQL injection e erros de aspas). Atenção às duas convenções de índice do CrossFly.

⚠️ Índices. Ao bindar parâmetros, os índices são 1-based (? nº 1, 2, …). Ao ler colunas do cursor, os índices são 0-based (getString(0) = primeira coluna). Isso é intencional e espelha a API nativa do SQLite.

APIs usadas

  • SqliteDb.execute(String sql, Object... params) — prepara, faz bindAll(params) (bind 1-based), executa um único INSERT/UPDATE/DELETE e retorna o nº de linhas afetadas (int). Os tipos são inferidos: Integer/Long/Short/Byte→inteiro, Float/Double→real, Boolean→0/1, byte[]→BLOB, null→NULL, senão toString()→TEXT.
  • SqliteDb.query(String sql, Object... params) — retorna um SqliteCursor aberto (bind 1-based). O chamador deve fechar (use try-with-resources).
  • SqliteCursor.next() — avança para a próxima linha; retorna true se houver linha.
  • SqliteCursor.getInt(col)/getLong/getDouble/getString/getBlob/isNull(col) — getters tipados, coluna 0-based.
  • SqliteDb.queryLong(sql, defaultValue, params) — atalho: 1ª coluna da 1ª linha como long, ou defaultValue se não houver linhas.
  • SqliteDb.queryString(sql, params) — atalho: 1ª coluna da 1ª linha como String, ou null se não houver linhas.
  • SqliteDb.lastInsertRowid() — rowid do último INSERT (long). SqliteDb.changes() — linhas alteradas pela última instrução.

Exemplo completo (copiar, colar e rodar)

package com.exemplo;

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

/** Tela principal executável. Aponte o launcher (classname) e rode: 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 — parâmetros posicionais (? nº 1 = name, ? nº 2 = age)
         int inserted = db.execute("INSERT INTO person(name, age) VALUES(?, ?)", "Alice", 30);
         long id = db.lastInsertRowid();            // rowid gerado
         System.out.println(inserted + " linha(s), id=" + id);

         // READ — cursor: colunas 0-based
         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 escalar — atalhos
         long total = db.queryLong("SELECT count(*) FROM person", 0);
         String nome = db.queryString("SELECT name FROM person WHERE id = ?", id);

         // UPDATE — retorna nº de linhas afetadas
         int updated = db.execute("UPDATE person SET age = ? WHERE id = ?", 31, id);

         // DELETE
         int deleted = db.execute("DELETE FROM person WHERE id = ?", id);
      }
   }
}

O trecho abaixo mostra só o miolo. Para rodar, coloque-o no esqueleto MainWindow acima.

Trecho mínimo

// verificado na fonte: execute (bind 1-based), query + cursor (getters 0-based), 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 — parâmetros posicionais (? nº 1 = name, ? nº 2 = age)
   int inserted = db.execute("INSERT INTO person(name, age) VALUES(?, ?)", "Alice", 30);
   long id = db.lastInsertRowid();            // rowid gerado
   System.out.println(inserted + " linha(s), id=" + id);

   // READ — cursor: colunas 0-based
   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 escalar — atalhos
   long total = db.queryLong("SELECT count(*) FROM person", 0);
   String nome = db.queryString("SELECT name FROM person WHERE id = ?", id);

   // UPDATE — retorna nº de linhas afetadas
   int updated = db.execute("UPDATE person SET age = ? WHERE id = ?", 31, id);

   // DELETE
   int deleted = db.execute("DELETE FROM person WHERE id = ?", id);
}

Aprofunde-se

Esta página foi útil?