Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

[Exercício 12 - Persistência com SQLite] - Propósito e resposta correta

Eu fiz o exercício mas não entendi o propósito e não sei se fiz certo pois não há o gabarito. Alguém consegue me explicar porque foi solicitada essa mudança no DAO e qual seria a resposta correta do exercício?

Exercício 12 - Persistência com SQLite:

(opcional - difícil) Se possuirmos mais de um DAO em nossa aplicação não poderemos usar a estratégia de fazer todos herdarem de SQLiteOpenHelper e depois usar mais de um DAO na mesma Activity. Nesse caso precisaremos utilizar composição no lugar de herança. Antecipe-se e altere seu DAO para TER-UM (ter um atributo do tipo) e não SER-UM (extends) SQLiteOpenHelper.

Minha resposta foi:

package br.com.caelum.cadastro.dao;

import java.util.ArrayList;
import java.util.List;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import br.com.caelum.cadastro.modelo.Aluno;

public class AlunoDAO {

    private static final String DATABASE = "CadastroCaelum";
    private static final int VERSAO = 1;

    private SQLiteOpenHelper sqlHelper; 

    public AlunoDAO(Context context) {

        this.sqlHelper = new SQLiteOpenHelper(context, DATABASE, null, VERSAO) {

            @Override
            public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
                String ddl = "DROP TABLE IF EXISTS Alunos";
                db.execSQL(ddl);                
                this.onCreate(db);                
            }

            @Override
            public void onCreate(SQLiteDatabase db) {
                String ddl = "CREATE TABLE Alunos (id PRIMARY KEY, "+
                        " nome TEXT UNIQUE NOT NULL, telefone TEXT,"+
                        " endereco TEXT, site TEXT, foto TEXT, nota REAL);";
                db.execSQL(ddl);                
            }
        };
    }    

    public void salva(Aluno aluno) {    
        sqlHelper.getWritableDatabase().insert("Alunos", null, toValues(aluno));
    }

    private ContentValues toValues(Aluno aluno) {

        ContentValues values = new ContentValues();

        values.put("id", aluno.getId());
        values.put("nome", aluno.getNome());
        values.put("telefone", aluno.getTelefone());
        values.put("endereco", aluno.getEndereco());
        values.put("site", aluno.getSite());
        values.put("foto", aluno.getFoto());
        values.put("nota", aluno.getNota());

        return values;
    }

    public List<Aluno> getLista() {
        String[] colunas = {"id","nome","telefone","endereco","site","foto","nota"};

        Cursor cursor = sqlHelper.getWritableDatabase().query("Alunos", colunas, null, null, null, null, null);

        ArrayList<Aluno> alunos = new ArrayList<Aluno>();

        while (cursor.moveToNext()) {

            Aluno aluno = new Aluno();

            aluno.setId(cursor.getLong(0));
            aluno.setNome(cursor.getString(1));
            aluno.setTelefone(cursor.getString(2));
            aluno.setEndereco(cursor.getString(3));
            aluno.setSite(cursor.getString(4));
            aluno.setFoto(cursor.getString(5));
            aluno.setNota(cursor.getDouble(6));

            alunos.add(aluno);
        }     

        return alunos;
    }

    public void close() {
        this.sqlHelper.close();
    }

}
2 respostas

Creio q não deu muito certo, pois a classe SQLiteOpenHelper é abstrata e não pode ser instanciada. Uma das possiveis soluções pode ser criar um DataBaseHelper e generalizar os métodos. Na classe AlunoDao, instanciamos um objeto DataBaseHelper e através dele chamamos as ações do banco.

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;

public class DatabaseHelper extends SQLiteOpenHelper {

    private String queryCreate;
    private String queryUpdate;
    private String name;
    private CursorFactory factory;
    private int version;

    DatabaseHelper(Context context, String name, CursorFactory factory, int version, String queryCreate, String queryUpdate) {
      super(context,name,factory,version);
      this.queryCreate = queryCreate;
      this.queryUpdate = queryUpdate;
      this.name = name;
      this.factory = factory;
      this.version= version;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(this.queryCreate);

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL(this.queryUpdate);
        this.onCreate(db);

    }

    public void salvar(ContentValues values){
        getWritableDatabase().insert(name, null, values);

    }

    public Cursor listar(String[] colunas){
        Cursor cursor = getWritableDatabase().query(name, colunas, null,null, null, null, null);
        return cursor;
    }



}
solução!

Oi Vanessa, a ideia é essa que a Tathiana sugeriu!

A ideia é criar uma classe que estende de SQLiteOpenHelper (como o DatabaseHelper que ela fez) e utilizar esse DatabaseHelper dentro dos seus daos. Assim, você concentra as estratégias de criação/atualização do schema do banco de dados em uma classe (caso contrário ficaria complicado administrar isso em vários daos que herdassem de SQLiteOpenHelper).

Sacou a ideia?