Eu estou com algumas duvidas com relação à estrutura da utilização do SQLiteOpenHelper junto com o SQLitedatabase.
Li este tutorial e ainda não consegui entender muito bem a função dessa classe.
Pelo que vi deve-se extender a classe SQLiteOpenHelper e implementar onCreate e onUpgrade. Vamos supor que esta se chame DBHelper como vi no tutorial.
Depois, uma outra classe qualquer deve ter uma instancia de DBHelper e uma do SQLitedatabase. Suponhamos da mesma maneira que esta se chama DBAdapter.
É a partir daí que eu não entendo, porque o DBHelper é usado apenas uma vez, no construtor de DBAdapter. Mas em que momento e em que classe do app eu devo instanciar a classe DBAdapter? E o onCreate é chamado quando eu faço essa instanciação ou quando eu tento executar a primeira operação no banco?
O DBHelper é usado apenas no construtor mesmo? Ele não é usado em mais NADA?
E por ultimo, onde eu devo usar metodos como o getWritableDatabase() e close() e quais trechos de codigo eu devo circundar com try catch?
Eu sei que é muita duvida mas por favor me ajudem porque eu já estou tentado entender isso corretamente ha dias.
O SQLiteOpenHelper também gerencia versões do banco de dados.
Caso voce mude algo na estrutura de alguma tabela, você indica nele que o DB_VERSION mudou, e o método onUpgrade(int oldVersion, int newVersion) vai ser invocado com os novos valores para voce ter a possibilidade de dar um ALTER_TABLE na tabela. Normalmente você cai nesse caso na atualização de aplicativos.
Continuo na mesma. Você é um grande filósofo, amigão.
Foi mal heheh
É o seguinte, quando voce desenvolve o sistema e lança com certa estrutura no banco de dados, voce vai ter implementado o Helper como o seguinte:
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DBSupport extends SQLiteOpenHelper {
private static final String DB_NAME = "library.db";
private static final int DB_VERSION = 1;
public DBSupport(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(LibraryDAO.createLibraryStatement);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
Depois de lançado, imagine que voce precise em uma atualização adicionar um novo campo na tabela, você irá mudar o DB_VERSION e fazer as alterações de versoes antigas, como o seguinte:
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DBSupport extends SQLiteOpenHelper {
private static final String DB_NAME = "library.db";
private static final int DB_VERSION = 2;
public DBSupport(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(LibraryDAO.createLibraryStatement);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("ALTER TABLE LIBRARY ADD COLUMN createdAt TEXT");
db.execSQL("ALTER TABLE LIBRARY ADD COLUMN openedAt INTEGER");
db.execSQL("ALTER TABLE LIBRARY ADD COLUMN lastPage TEXT");
db.execSQL("ALTER TABLE LIBRARY ADD COLUMN " + LibraryDAO.LibraryMetadata.CONTENT_ID.fieldAndType());
db.execSQL("update LIBRARY set openedAt = 0");
if(oldVersion == 1)
return;
}
}
Você não entendeu. Não estou com duvidas na criação, gerenciamento, exclusao, alteração e etc do banco de dados. Eu não sei é como vai funcionar o query, o insert, e operações basicas. Não consegui assimilar a relação entre o SQLiteOpenHelper e o SQLitedatabase nas operações cotidianas.
O Ricardo Lecheta no livro dele explicou primeiro como se faz para importar um sqlite para o emulador e só depois em cima disso explicou como criar o banco atraves da API ao inves de fazer a importação. Ou seja, ele explicou como alterar um aplicativo que usava importação para agora criar via API, mas não explicou como criar da API desde o começo.
Le com atenção a minha primeira pergunta que vc entende.
Olha só a diferença do primeiro tutorial que eu postei la em cima e este. Cada um faz de um jeito, o de todo mundo funciona. O meu não.
Olá
A sequência é a seguinte:
DBHelper dbHelper = new DBHelper(contexto);
SQLiteDatabase db = dbHelper.getWritableDatabase(); // ou Readable -> aqui vai criar do db na primeira vez
// usa o db.insert, db.update, db.delete, db.query…
// para fechar
dbHelper.close();
Normalmente você coloca isso numa classe DBAdapter
A classe DBHelper não pode extender SQLiteOpenHelper e ter em si uma instancia de SQLitedatabase para fazer as operações? E eu ainda tenho as dúvidas que eu escrevi na primeira postagem.
DBHelper extends a SQLiteOpenHelper.
É apenas uma classe utilitária para facilitar a manutenção do SQLite.
Pode usar direto do SQLIte.
A diferença entre os dois tutoriais é que o primeiro separou em duas classes e o segundo deixou tudo numa mesma classe.
PS: Note que nenhum dos dois tutoriais estão completos e perfeitos. Não vi se tem o projeto completo para dowload.
incrivel como a galera consegue responder, responder, responder e responder, e não responder o que eu perguntei.
Quem sabe se você tentar perguntar de outra maneira, porque quem não está entendendo agora sou eu.
Qual é a dúvida?
A classe SQLiteOpenHelper você estende e implementa alguns métodos.
Nela tem o método que te retorna uma instancia do db
Você usa a instancia retornada para realizar leitura/inserts/updates/queries/etc no db
Pergunto de novo onde está a dúvida?
public static final String COLUNA_MARCA = "marca";
public static final String COLUNA_MODELO = "modelo";
public static final String COLUNA_ANO = "ano";
public static final String COLUNA_PLACA = "placa";
public void onCreate(SQLiteDatabase db) {
String SQL_CREATE = "CREATE TABLE " + TABLE + "( " + COLUNA_MARCA
+ " TEXT NOT NULL ," + COLUNA_MODELO + " TEXT NOT NULL ,"
+ COLUNA_ANO + "TEXT NOT NULL, " + COLUNA_PLACA
+ " TEXT PRIMARY KEY)";
db.execSQL(SQL_CREATE);
Log.i(tag, "BANCO CRIADO");
}
public void salvar(Carro carro) {
SQLiteDatabase db = this.getWritableDatabase();
db.insert(TABLE, null, carro.getContentValues());
Toast.makeText(context, carro.modelo + " adicionado.",
Toast.LENGTH_SHORT).show();
db.close();
}
public ContentValues getContentValues() {
ContentValues cv = new ContentValues();
cv.put(Database.COLUNA_MARCA, this.marca);
cv.put(Database.COLUNA_MODELO, this.modelo);
cv.put(Database.COLUNA_ANO, this.ano);
cv.put(Database.COLUNA_PLACA, this.placa);
return cv;
}
E o problema da vez é…
[color=red]06-08 10:43:18.985: E/SQLiteDatabase(543): Error inserting placa=PLACA ano=2000 marca=Marca modelo=Modelo
06-08 10:43:18.985: E/SQLiteDatabase(543): android.database.sqlite.SQLiteException: table CARROS has no column named ano: , while compiling: INSERT INTO CARROS(placa,ano,marca,modelo) VALUES (?,?,?,?)
[/color]
[color=#444444]Existe explicação? [/color]
Pode ter criado a tabela sem essa coluna?
Incrementa um na versão do db e tenta recriar usando o onUpgrade para deletar e recriar a tabela
ps: onUpgrade
Faltou um espaço na linha seguinte, "TEXT… deve ser " TEXT…
Já implementei um botão na activity que faz isso. Se eu acabo de de recriar o banco e clico em salvar denovo, ele da o mesmo erro.
[quote=A H Gusukuma]Faltou um espaço na linha seguinte, "TEXT… deve ser " TEXT…
A madrugada inteira por causa de UM espaço…
Te amo cara…
Em breve eu posto os próximos erros, o banco de dados não vai me deixar ser feliz tão cedo, mas um dia eu venço.
Uma duvida rápida sobre o close().
Qual a hora certa que eu devo usa-lo? Ele deve ser usado dentro do meu helper (SQLiteDatabase.close()) dentro de cada operação tipo:
public void salvar(Carro carro) {
SQLiteDatabase db = this.getWritableDatabase();
db.insert(TABLE, null, carro.getContentValues());
Toast.makeText(context, carro.modelo + " adicionado.",
Toast.LENGTH_SHORT).show();
db.close();
}
Ou deve ser usado na Activity sobre a instancia desssa classe? (SQLiteOpenHelper.close())
DBHelper helper = new DBHelper(context);
...
helper.close();
Atualizando: é impressão minha ou eu não consigo mais usar o cursor se der close()?