我的SQLiteOpenHelper的问题

时间:2011-04-11 15:27:57

标签: android

package com.owen.quartergames.dao;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import android.widget.Toast;

import com.owen.quartergames.R;
import com.owen.quartergames.domain.LogEntry;

public class SqlLiteFishLoggerDao extends SQLiteOpenHelper implements
        FishLoggerDao {

    private static final String DB_NAME = "fishingLog";

    private static final String TABLE_NAME = "LogEntries";

    private static final String DELETE_LOG_ENTRY_SQL = "DELETE FROM LogEntries WHERE _id = ?;";

    private static final String FIND_LOG_ENTRY_SQL = "SELECT _id, Longitude, Latitude FROM LogEntries WHERE _id = ?";

    private static final String FIND_ALL_ENTRIES_SQL = "SELECT * FROM LogEntries";

    private static final String[] NO_ARGS = {};

    private Context context;

    private final SQLiteDatabase db = getWritableDatabase();

    public SqlLiteFishLoggerDao(Context context) {
        super(context, DB_NAME, null, 1);
        this.context = context;
    }

    @Override
    public void deleteLogEntry(String id) {
        id = "0";

        db.execSQL(DELETE_LOG_ENTRY_SQL, new Object[] { id });
        // int deleted = db.delete(TABLE_NAME, "_id = ?",
        // new String[] { id.trim() });
        // Log.i("fishlogger", String.format("Delete %d rows", deleted));
        db.close();
    }

    @Override
    public LogEntry findEntry(String id) {
        Cursor cursor = db.rawQuery(FIND_LOG_ENTRY_SQL, new String[] { id });
        if (!cursor.moveToFirst()) {
            return null;
        }

        LogEntry entry = new LogEntry();
        entry.setId(id);
        entry.setLatitude(cursor.getDouble(cursor.getColumnIndex("Latitude")));
        entry
                .setLongitude(cursor.getDouble(cursor
                        .getColumnIndex("Longitude")));
        cursor.close();
        db.close();
        return entry;

    }

    @Override
    public void insertLogEntry(LogEntry entry) {
        ContentValues values = new ContentValues();
        values.put("Latitude", entry.getLatitude());
        values.put("Longitude", entry.getLongitude());
        values.put("PictureURL", entry.getPictureUrl());
        values.put("SizeOrWeight", entry.getSizeOrWeight());
        values.put("CreateDate", entry.getEntryDate());
        values.put("Species", entry.getSpecies());
        db.insertOrThrow("LogEntries", null, values);
        db.close();
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        String s;
        try {
            Toast.makeText(context, "1", 2000).show();
            InputStream in = context.getResources().openRawResource(R.raw.sql);
            DocumentBuilder builder = DocumentBuilderFactory.newInstance()
                    .newDocumentBuilder();
            Document doc = builder.parse(in, null);
            NodeList statements = doc.getElementsByTagName("statement");
            for (int i = 0; i < statements.getLength(); i++) {
                s = statements.item(i).getChildNodes().item(0).getNodeValue();
                db.execSQL(s);
            }
        } catch (Throwable t) {
            Toast.makeText(context, t.toString(), 50000).show();
        }
        Log.e("DB", "DB Created");

    }

    @Override
    public List<LogEntry> findAllEntries() {

        List<LogEntry> entries = new ArrayList<LogEntry>();

        Cursor cursor = db.rawQuery(FIND_ALL_ENTRIES_SQL, NO_ARGS);

        int entryDateCol = cursor.getColumnIndex("CreateDate");
        int speciesCol = cursor.getColumnIndex("Species");
        int sizeCol = cursor.getColumnIndex("SizeOrWeight");
        int latCol = cursor.getColumnIndex("Latitude");

        if (cursor.moveToFirst()) {
            do {
                LogEntry entry = new LogEntry();
                entry.setEntryDate(cursor.getString(entryDateCol));
                entry.setSpecies(cursor.getString(speciesCol));
                entry.setSizeOrWeight(cursor.getString(sizeCol));
                entry.setLatitude(cursor.getDouble(latCol));

                if (entry.getSpecies() == null) {
                    entry.setSpecies("Not Entered");
                }

                if (entry.getSizeOrWeight() == null) {
                    entry.setSizeOrWeight("Not entered");
                }

                entries.add(entry);
            } while (cursor.moveToNext());
        }
        cursor.close();
        db.close();
        return entries;
    }

    @Override
    public void onUpgrade(SQLiteDatabase DB, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
        onCreate(getWritableDatabase());
    }
}

基本上删除不起作用,但我认为问题源于findAllEntries()方法。我说的原因是我在日志猫中发现“泄漏发现”错误,说db已创建但从未关闭。我已经彻底搜索了互联网,并询问了那些代码但没有运气解决问题的朋友。所有我的游标都是关闭的,从我可以看出这是一个sqlliteopenhelper通常应该是什么样子。

感谢您的回复

3 个答案:

答案 0 :(得分:1)

您的getReadableDatabase()打开数据库以供阅读。为避免泄漏,您需要在工作完成后关闭它。

final db = getReadableDatabase();
//do the things
db.close();

getWritableDatabase()相同。

答案 1 :(得分:0)

如上所述in SQLiteOpenHelper.getWritableDatabase javadoc

  

成功打开后,数据库将被缓存,因此您可以在每次需要写入数据库时​​调用此方法。 (确保在不再需要数据库时调用close()。)

答案 2 :(得分:0)

只是想跟进。我感谢大家的帮助。 最后似乎有一些问题。你们给我的东西你们很可能已经把它想象出来了,我花了很长时间才把它想出来。
无论如何继承人我做错了加上更新的代码:

  1. 我没有为每一个打开和关闭数据库 方法(泄漏发现错误)

  2. 找不到食物 _id字段进入对象。所以当我的列表视图填充并且你 说删除,它会使用 迭代器id而不是真实的 数据库_id的条目。

  3. 我需要在我的身份上打电话给.trim 字段

  4. (但是2和3都没有在logcat中产生错误。它永远不会删除。它插入正常,选择*精细,但删除时没有发生)


    package com.owen.quartergames.dao;
    
    import java.io.InputStream;
    import java.util.ArrayList;
    import java.util.List;
    
    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;
    
    import org.w3c.dom.Document;
    import org.w3c.dom.NodeList;
    
    import android.content.ContentValues;
    import android.content.Context;
    import android.database.Cursor;
    import android.database.sqlite.SQLiteDatabase;
    import android.database.sqlite.SQLiteOpenHelper;
    import android.util.Log;
    
    import com.owen.quartergames.R;
    import com.owen.quartergames.domain.LogEntry;
    
    public class SqlLiteFishLoggerDao extends SQLiteOpenHelper implements
            FishLoggerDao {
    
        private static final String DB_NAME = "fishingLog";
    
        private static final String TABLE_NAME = "LogEntries";
    
        private static final String DELETE_LOG_ENTRY_SQL = "DELETE FROM LogEntries WHERE _id = ?;";
    
        private static final String FIND_LOG_ENTRY_SQL = "SELECT _id, Longitude, Latitude FROM LogEntries WHERE _id = ?";
    
        private static final String FIND_ALL_ENTRIES_SQL = "SELECT * FROM LogEntries";
    
        private static final String[] NO_ARGS = {};
    
        private Context context;
    
        private SQLiteDatabase DB;
    
        public SqlLiteFishLoggerDao(Context context) {
            super(context, DB_NAME, null, 1);
            this.context = context;
        }
    
        @Override
        public void deleteLogEntry(String id) {
            DB = getWritableDatabase();
            DB.execSQL(DELETE_LOG_ENTRY_SQL, new Object[] { id });
            DB.close();
        }
    
        @Override
        public LogEntry findEntry(String id) {
            DB = getReadableDatabase();
            Cursor cursor = DB.rawQuery(FIND_LOG_ENTRY_SQL,
                    new String[] { id });
            if (!cursor.moveToFirst()) {
                return null;
            }
    
            LogEntry entry = new LogEntry();
            entry.setId(id);
            entry.setLatitude(cursor.getDouble(cursor.getColumnIndex("Latitude")));
            entry
                    .setLongitude(cursor.getDouble(cursor
                            .getColumnIndex("Longitude")));
            cursor.close();
            DB.close();
            return entry;
    
        }
    
        @Override
        public void insertLogEntry(LogEntry entry) {
            DB = getWritableDatabase();
            ContentValues values = new ContentValues();
            values.put("Latitude", entry.getLatitude());
            values.put("Longitude", entry.getLongitude());
            values.put("PictureURL", entry.getPictureUrl());
            values.put("SizeOrWeight", entry.getSizeOrWeight());
            values.put("CreateDate", entry.getEntryDate());
            values.put("Species", entry.getSpecies());
            DB.insertOrThrow("LogEntries", null, values);
            DB.close();
        }
    
        @Override
        public void onCreate(SQLiteDatabase db) {
            String s;
            try {
                InputStream in = context.getResources().openRawResource(R.raw.sql);
                DocumentBuilder builder = DocumentBuilderFactory.newInstance()
                        .newDocumentBuilder();
                Document doc = builder.parse(in, null);
                NodeList statements = doc.getElementsByTagName("statement");
                for (int i = 0; i < statements.getLength(); i++) {
                    s = statements.item(i).getChildNodes().item(0).getNodeValue();
                    db.execSQL(s);
                }
                Log.e("DB", "DB Created Successfully");
            } catch (Throwable t) {
                Log.e("DB error: ",t.toString());
            }
        }
    
        @Override
        public List<LogEntry> findAllEntries() {
            DB = getReadableDatabase();
    
            List<LogEntry> entries = new ArrayList<LogEntry>();
    
            Cursor cursor = DB.rawQuery(FIND_ALL_ENTRIES_SQL,
                    NO_ARGS);
    
            int entryID = cursor.getColumnIndex("_id");
            int entryDateCol = cursor.getColumnIndex("CreateDate");
            int speciesCol = cursor.getColumnIndex("Species");
            int sizeCol = cursor.getColumnIndex("SizeOrWeight");
            int latCol = cursor.getColumnIndex("Latitude");
    
            if (cursor.moveToFirst()) {
                do {
                    LogEntry entry = new LogEntry();
                    entry.setId(cursor.getString(entryID));
                    entry.setEntryDate(cursor.getString(entryDateCol));
                    entry.setSpecies(cursor.getString(speciesCol));
                    entry.setSizeOrWeight(cursor.getString(sizeCol));
                    entry.setLatitude(cursor.getDouble(latCol));
    
                    if (entry.getSpecies() == null) {
                        entry.setSpecies("Not Entered");
                    }
    
                    if (entry.getSizeOrWeight() == null) {
                        entry.setSizeOrWeight("Not entered");
                    }
    
                    entries.add(entry);
                } while (cursor.moveToNext());
            }
            cursor.close();
            DB.close();
            return entries;
        }
    
        @Override
        public void onUpgrade(SQLiteDatabase DB, int oldVersion, int newVersion) {
            DB = getWritableDatabase();
            DB.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
            onCreate(getWritableDatabase());
            DB.close();
        }
    }