Mas qual o motivo desse erro? Onde está no código, não estou localizando.
Ninguém pra ajudar?
seria parecido com isso:
db = new DbAdapter(this);
dao = new TipoVeiculoDAO(this); // isso?
Não estou identificando onde fazer isso. Seria na classe TipoVeiculos?
wellington.nogueira
O que eu posso tirar o que está sobrando no código?
Alguém me ajuda, não estou conseguindo. Será que colocar os métodos de abertura e fechamento do banco no DAO resolve o problema? Deixar no DBAdapter somente a criação do banco?
Por favor, alguém poderia me dar uma luz?
Ninguém? Estou parado nisso, preciso de ajuda.
Alguém??
Bom, tenho acompanhado de perto esse tópico, e relato minha experiência, talvez ajude:
Após muito quebrar a cabeça pra ver como poderia organizar meu código, já que tb tenho várias tabelas, cheguei a uma das mais simples soluções:
- Criei uma classe extendendo SQLiteOpneHelper, no qual eu crio todo o banco e tabelas;
- E no mais, criei várias classes “dao”, onde cada uma extende à classe mencionada acima, e nas quais tenho os métodos implementados referente a cada entidade;
Ainda não é a melhor maneira, uma vez o crud é similar a inúmeras classes, portanto, poderia criar métodos abstratos… mas enfim … dessa forma já temos uma boa organização e separação dos códigos …
espero ter ajudado …
abraços …
Eu faço exatamente como Frital falou acima e funciona, vou postar exemplo:
public class DBHelper extends SQLiteOpenHelper {
public static final String NOME_DO_BANCO = "banco";
public static final int DATABASE_VERSION = 1;
private final String SCRIPT_TABELA_CLIENTE = " CREATE TABLE IF NOT EXISTS CLIENTE ( " +
" CODIGO INTEGER AUTO_INCREMENT NOT NULL PRIMARY KEY, " +
" NOME VARCHAR(60) NOT NULL " +
" );";
private final String SCRIPT_TABELA_FORNECEDOR = " CREATE TABLE IF NOT EXISTS CLIENTE ( " +
" CODIGO INTEGER AUTO_INCREMENT NOT NULL PRIMARY KEY, " +
" NOME VARCHAR(60) NOT NULL " +
" );";
public DBHelper(Context ctx) {
super(ctx, NOME_DO_BANCO, null, DATABASE_VERSION);
}
public void onCreate(SQLiteDatabase db) {
db.execSQL(SCRIPT_TABELA_CLIENTE);
db.execSQL(SCRIPT_TABELA_FORNECEDOR);
}
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
Uma classe por tabela, chamo de repositório, mas é o DAO rs
public class RepositorioCliente {
private SQLiteDatabase db;
private static RepositorioCliente instance = new RepositorioCliente();
// para não abrir o banco toda vez
public static RepositorioCliente getInstance(Context ctx) {
if (instance.db == null || instance.db.isOpen()) {
instance.db = new DBHelper(ctx).getWritableDatabase();
}
return instance;
}
public boolean insert(Cliente cliente) {
boolean resultado = false;
db.beginTransaction();
try {
ContentValues contentValues = new ContentValues();
contentValues.put("CODIGO", cliente.getCodigo());
contentValues.put("NOME", cliente.getNome());
if (db.insert("CLIENTE", null, contentValues) > -1) {
db.setTransactionSuccessful();
resultado = true;
}
} finally {
db.endTransaction();
}
return resultado;
}
// outras funções (alterar, excluir, consulta)
}
Chamando na activity
Não sei se é a maneira mais correta, mas funciona rs.
Valerio Bezerra,
No caso, vc teria um outro Repositório chamado RepositorioFornecedor. Faria isso pra cada tabela que tenha no banco?
Obrigado pelo retorno Valério !
=)
Exatamente fbrigatt. Assim vc tem uma classe para cada tabela, e seu código fica extremamente organizado.
Aproveitando, estou querendo montar uns layout´s dividindo a tela de um tablet, e só tenho material impresso pra smartphone, que não aborda “fragments” …
devo estudar é isso mesmo né ? fragments ? pra poder dividir a tela né ?
=)
abraços galera …
Frital,
Posta aqui um exemplo de como vc utiliza, tem como?
Sim ! segue código exemplo:
Primeiro a classe que gera o banco (chamada DbAdapter):
public class DbAdapter extends SQLiteOpenHelper {
private static final String NOME_BANCO = "agenda";
private static final int VERSAO=1;
public DbAdapter(Context context) {
super(context, NOME_BANCO, null, VERSAO);
}
@Override
public void onCreate(SQLiteDatabase db) {
String tabela_materia = "CREATE TABLE IF NOT EXISTS 'materia' ('id' INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT , " +
"'descricao' VARCHAR(45) NULL , 'professor' VARCHAR(45) NULL , 'nota' FLOAT NULL , 'faltas' INT NULL , " +
"'status' VARCHAR(45) NULL); ";
String tabela_atividade = "CREATE TABLE IF NOT EXISTS 'atividade' ('id' INTEGER NOT NULL PRIMARY" +
" KEY AUTOINCREMENT , 'titulo' VARCHAR(45) NULL , 'descricao' VARCHAR(255) NULL ," +
" 'pontos' FLOAT NULL , 'data' DATETIME NULL , 'status' VARCHAR(45) NULL);";
db.execSQL(tabela_materia);
db.execSQL(tabela_atividade);
}
Agora, uma classe dao no caso, chamada materia:
[code]
public class MateriaDao extends DbAdapter {
private static final String NOME_TABELA = "materia";
public MateriaDao(Context context) {
super(context);
}
public List listarMaterias(){
List materias = new ArrayList();
Cursor c = getWritableDatabase().query(NOME_TABELA,Materia.colunasMateria,null,null,null,null,null);
while (c.moveToNext()){
Materia materia = new Materia();
materia.setId(c.getLong(0));
materia.setDescricao(c.getString(1));
materia.setProfessor(c.getString(2));
materia.setNota(c.getFloat(3));
materia.setFaltas(c.getLong(4));
materia.setStatus(c.getString(5));
materias.add(materia);
}
c.close();
return materias;
}
}
}[/code]
e por último, a classe main(mas poderia se qualquer outra, que chama uma classe dao …
[code]
public class Main extends Activity {
List<Materia> materias = new ArrayList<Materia>();
List<Dia> dias = new ArrayList<Dia>();
Button btn_atividades, btn_horario, btn_notas, btn_faltas, btn_materias;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
verificaMaterias();
}
private void verificaMaterias() {
MateriaDao materiaDao = new MateriaDao(this);
materias = materiaDao.listarMaterias();
materiaDao.close();
}
}[/code]
tranquilo né ?
=)
Sim, Frital, depois dessa aula, sim. Uma dúvida que tenho é quanto ao relacionamento entre tabelas, como fazer.
Eu faço assim:
// CRIA A TABELA CARROS
private static final String DATABASE_CREATE_CARROS = "create table " + DATABASE_TABLE_CARROS + " ("
+ KEY_ID_CARRO + " integer primary key autoincrement, "
+ KEY_IDCLIENTE_CARRO + " integer, "
+ KEY_IDTIPO_CARRO + " integer, "
+ KEY_MODELO + " text, "
+ KEY_PLACA + " text, FOREIGN KEY ( " + KEY_IDCLIENTE_CARRO
+ " ) REFERENCES " + DATABASE_TABLE_CLIENTES + " (" + KEY_ID_CLI
+ " ) ON DELETE RESTRICT ON UPDATE CASCADE , FOREIGN KEY ( "
+ KEY_IDTIPO_CARRO + " ) REFERENCES " + DATABASE_TABLE_TIPO_VEICULO + " ("
+ KEY_IDTIPO_CARRO + " ) ON DELETE RESTRICT ON UPDATE CASCADE);";
Teria um outro jeito mais fácil de fazer?
Sim, vc foi bastante minuncioso na estruturação de seu código …
por um acaso, pegou de algum exemplo ? ou fez vc mesmo ?
pois se fez vc mesmo, não entendo pq está com dúvida …
=)
quando vc cria tabelas relacionadas, com chaves estrangeiras, só não pode acontecer é de vc criar uma tabela que contém chave estrangeira que referencia uma chave (geralmente primária) de uma tabela que ainda não foi criada …
Foi eu quem fiz, rs, gostaria de saber se tem um jeito mais fácil de fazer, pq assim é meio complicado, rs. Eu fiz isso nesses programas de modelagem e que gera o script depois.
fbrigatt, teria sim um RepositorioFornecedor
ah sim … perfeito …
=)
eu sempre faço a modelagem, e depois gero o script …
pode ver que meu código está bem mais simples que o seu …
a vantagem do seu código é a facilidade visual de localizar os campos, e se vc mudar um nome de um campo, vc muda só na constante inicial, no inicio do código …
a vantagem do meu, é que não preciso fazer “nada” … hihi … e quando vou mudar um campo, vou no script e altero … tb naum tem nenhuma dificuldade …
=)
abraço …
=)
Como vc faz? Posta um exemplo aqui com relacionamento.