在SQLite数据库中保存初始内容

时间:2015-07-09 07:07:15

标签: android json sqlite insert

我正在尝试构建一个默认数据库,我的应用程序每次打开时都会使用该数据库。 为此,我做了一个简短的程序来转换我拥有的某个JSON文件中的数据,并将其传递给我创建的空db文件。 解析JSON工作正常,我能够获得它的所有内容。 但是当我尝试将该内容保存到db文件中时,我得到:

E/Database(361): Error inserting password=1234
 E/Database(361): android.database.sqlite.SQLiteException: no such table: passwords: , while compiling: INSERT INTO passwords(password) VALUES(?);

文件本身存在并有一个表。它位于assets文件夹中。 我做完之后: 源码>创建表密码(密码varchar(4)); 并插入了一条记录,我能够在终端上看到它。

在我的应用中,我进行了启动画面活动调用:

jsonToDb.transfer(new WeakReference<Context>(getApplicationContext()));

jsonToDb:

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.ref.WeakReference;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.simple.parser.JSONParser;

import android.content.ContentValues;
import android.content.Context;
import android.content.res.AssetManager;
import android.util.Log;

public class jsonToDb
{
    static void transfer( WeakReference<Context> context )
    {
        DatabaseLoader.init( context );
        String COLUMN_PASSWORD = "password";

        ContentValues cv = new ContentValues();
        JSONParser parser = new JSONParser();

        AssetManager assetManager = context.get().getAssets();
        InputStream inputStream = null;
        String password = "null";
        int successCount ;
        try {

            inputStream = assetManager.open("convertcsv.json");

            BufferedReader streamReader = new BufferedReader(new InputStreamReader(inputStream));


            StringBuilder strBuilder = new StringBuilder();

            String inputStr;
             while ((inputStr = streamReader.readLine()) != null)
                strBuilder.append(inputStr);

            JSONArray jsonArray = new JSONArray( strBuilder.toString() );

//The loop should be up until i=10000 but I've made it 2 just for the sake of the example.
            for (int i=0 ; i<2 ; i++)
            {
                password = (String) jsonArray.getJSONObject(0).get( "Code" );
                cv.put( COLUMN_PASSWORD, password );
                DatabaseLoader.getInstance().transferJson( cv );
            }

        }
        catch (IOException e)
        {
            //
        }
        catch(JSONException e)
        {
            //
        }      
    }
}

DatabaseLoader:

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.util.Map;

import android.content.ContentValues;
import android.content.Context;
import android.content.ContextWrapper;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

class DatabaseLoader 
{
    private static DatabaseLoader instance;
    private DatabaseLoaderHelper dbHelper;
    private static final String ERROR_OPEN_FILE_TAG = "Error Opening File";

    static void init( WeakReference<Context> contextWrapper )
    {
        if( instance == null )
        {
            instance = new DatabaseLoader( contextWrapper );
        }
    }

    protected DatabaseLoader( WeakReference<Context> contextWrapper )
    {
        dbHelper = new DatabaseLoaderHelper( contextWrapper.get() );
    }

    static DatabaseLoader getInstance()
    {
        return instance;
    }

    SQLiteDatabase getDb()
    {
        return dbHelper.getWritableDatabase();
    }


    private static class DatabaseLoaderHelper extends SQLiteOpenHelper
    {
        private static final String DB_NAME = "passwordsdb.sql";
        private static final String DB_PATH = "/data/data/mypackage/databases/";
        private static final int DB_VERSION = 1;

        private DatabaseLoaderHelper( Context context ) 
        {
            super( context, DB_NAME, null, DB_VERSION );
            try
            {
                createDatabase( context );
            }
            catch ( IOException e )
            {
                Log.d( "CAN'T create DB", "cannot create db" );
                e.printStackTrace();
            }
        }

        private void copyDatabase( Context context ) throws IOException{

            //Open your local db as the input stream
            InputStream myInput = context.getAssets().open( DB_NAME );

            // Path to the just created empty db
            String outFileName = DB_PATH + DB_NAME;

            //Open the empty db as the output stream
            OutputStream myOutput = new FileOutputStream( outFileName );

            //transfer bytes from the inputfile to the outputfile
            byte[] buffer = new byte[1024];
            int length;
            while ((length = myInput.read(buffer))>0){
                myOutput.write(buffer, 0, length);
            }

            //Close the streams
            myOutput.flush();
            myOutput.close();
            myInput.close();

        }

        private boolean checkDatabase() 
        { 
            File dbFile = new File( DB_PATH + DB_NAME ); 
            return dbFile.exists(); 
        } 


        public void createDatabase( Context context ) throws IOException 
        { 
          //If database not exists copy it from the assets 

           boolean mDataBaseExist = checkDatabase(); 
           if(!mDataBaseExist) 
           { 
              try  
              { 
                //Copy the database from assests 
                copyDatabase( context ); 
                Log.e("created DBase", "createDatabase database created"); 
              }  
              catch (IOException mIOException)  
              { 
                 throw new Error("ErrorCopyingDataBase"); 
             } 
          } 
        } 



        @Override
        public void onCreate( SQLiteDatabase db )
        {
            // TODO Auto-generated method stub

        }

        @Override
        public void onUpgrade( SQLiteDatabase db, int oldVersion, int newVersion )
        {
            // TODO Auto-generated method stub

        }

    }

    public Map<String,Password> loadDatabase()
    {
        final String TABLE_NAME = "passwords";
        Map<String,Password> passwords = null;  

        try
        {
            SQLiteDatabase db = getDb();
            Cursor result =  db.rawQuery( "select * from " + TABLE_NAME, null );
            result.moveToFirst();

            while( !result.isAfterLast() )
            {
                String password = result.getString( 1 );
                int date = result.getInt( 2 );
                int tried = result.getInt( 3 );
                int successCount = result.getInt( 4 );
                int dbIndex = result.getInt( 5 );
                passwords.put( password , new Password( password, date, tried, successCount, dbIndex ) );
                result.moveToNext();
            }
            result.close();
        }
        catch( SQLiteException errorOpeningDB )
        {
            Log.e( ERROR_OPEN_FILE_TAG, "problem" ,errorOpeningDB );
        }

        return passwords;
    }

    public void transferJson( ContentValues cv )
    {
        String TABLE_PASSWORDS = "passwords";
        try
        {
            SQLiteDatabase db = getDb();
            db.insert( TABLE_PASSWORDS, null, cv );
            db.close();
        }
        catch( SQLiteException errorOpeningDB )
        {
            Log.e( ERROR_OPEN_FILE_TAG, "problem" ,errorOpeningDB );
        }
    }
}

我已经坐了几天,但现在无济于事。

2 个答案:

答案 0 :(得分:1)

如果我没有错,你没有从资产文件夹中复制sqlite数据库。请尝试以下方法。您需要从资产文件夹中复制数据库,如下所示。

/**
     * Copies your database from your local assets-folder to the just created empty database in the
     * system folder, from where it can be accessed and handled.
     * This is done by transfering bytestream.
     * */
    private void copyDataBase() throws IOException{

        //Open your local db as the input stream
        InputStream myInput = myContext.getAssets().open(DB_NAME);

        // Path to the just created empty db
        String outFileName = DB_PATH + DB_NAME;

        //Open the empty db as the output stream
        OutputStream myOutput = new FileOutputStream(outFileName);

        //transfer bytes from the inputfile to the outputfile
        byte[] buffer = new byte[1024];
        int length;
        while ((length = myInput.read(buffer))>0){
            myOutput.write(buffer, 0, length);
        }

        //Close the streams
        myOutput.flush();
        myOutput.close();
        myInput.close();

    }

然后你需要这样做才能检查数据库是否存在

private boolean checkDataBase() 
{ 
    File dbFile = new File(DB_PATH + DB_NAME); 
    return dbFile.exists(); 
} 

最后修改你的创建方法

public void createDataBase() throws IOException 
{ 
  //If database not exists copy it from the assets 

   boolean mDataBaseExist = checkDataBase(); 
   if(!mDataBaseExist) 
   { 
      try  
      { 
        //Copy the database from assests 
        copyDataBase(); 
        Log.e(TAG, "createDatabase database created"); 
      }  
      catch (IOException mIOException)  
      { 
         throw new Error("ErrorCopyingDataBase"); 
     } 
  } 
} 

答案 1 :(得分:0)

在查询之前,必须创建一个表,我无法在SQLiteOpenHelper扩展类中看到表创建查询。

您可以在onCreate()方法中执行创建查询的表:

String CREATE_PASSWORD_TABLE = "CREATE TABLE passwords ( " + "id INTEGER PRIMARY KEY AUTOINCREMENT, " + "password TEXT)";
db.execSQL(CREATE_BOOK_TABLE);