8

通过提供的示例,我完全能够使用 Sugar ORM。

在我的用例中,我从服务器下载了一个 SQLite DB(它的 ETL 负载有数百万条记录,因此必须在服务器端完成)。下载保存到内部存储上的自定义路径。

就我而言,我不需要基于 POCO 的动态数据库创建。

如果所有 POCO 类字段与表结构匹配,是否可以将 Sugar ORM 与预先存在的 SQLite DB 一起使用,指向自定义路径?

4

3 回答 3

4
  1. 首先,我对 Sugar 扩展 app 类的想法不满意。如果我在应用启动前还有其他任务需要执行怎么办?!因此,让我们用我们自己的 AppClass 扩展 SugarApp,然后在清单中注册 appClass 名称。此外,这是我第一次相信初始化 db 的正确位置。

    public class MyAppStartClass extends SugarApp {
    
    @Override
    public final void onCreate() {
        init();
        super.onCreate();
    }
    
    private void init() {
        initDB();
    }
    
    private void initDB() {
        try {
            if (!doesDatabaseExist(this, consts.dbPath)) {
                Context context = getApplicationContext();
                SQLiteDatabase db = context.openOrCreateDatabase(consts.dbName, context.MODE_PRIVATE, null);
                db.close();
                InputStream dbInput = getApplicationContext().getAssets().open(consts.dbName);
                String outFileName = consts.dbPath;
                OutputStream dbOutput = new FileOutputStream(outFileName);
                try {
                    byte[] buffer = new byte[1024];
                    int length;
                    while ((length = dbInput.read(buffer)) > 0) {
                        dbOutput.write(buffer, 0, length);
                    }
                } finally {
                    dbOutput.flush();
                    dbOutput.close();
                    dbInput.close();
                }
            }
        } catch (Exception e) {
            e.toString();
        }
    }
    
    private boolean doesDatabaseExist(ContextWrapper context, String dbName)       {
        File dbFile = context.getDatabasePath(dbName);
        return dbFile.exists();
    }
    }
    
  2. 清单:android:name="com.myPackageName.MyAppStartClass"

  3. 确保首先创建一个空数据库,否则会从 FileOutputStream() 和 dbPath = /data/data/com.myPackageName/databases/myDb.db 收到错误

    SQLiteDatabase db = context.openOrCreateDatabase(consts.dbName, context.MODE_PRIVATE, null);

    db.close();

  4. 确保您现有的数据库架构具有主键列 ID。哦耶!Sugar 仅将 ID 视为检索数据的主键。

  5. 如果您想使用现有表,请不要在扩展 SugarRecord 时指定 T 并且您必须将 Sugar 添加为模块并且您的项目依赖于它!

    public class Book extends SugarRecord {
      String title;
      String edition;
    
      public Book(){
      }
    
      public Book(String title, String edition){
        this.title = title;
        this.edition = edition;
      }
    }
    

6.如果你想使用现有的表。请注意,Sugar 会查找大写的列名,因此如果您现有的表列名是小写的,您将永远无法从中获取任何现有数据!

7.这让我不情愿地得出结论:如果您从头开始启动数据库并使用它为您生成数据库和表,Sugar 非常棒。但当您已经拥有一个包含数据的现有数据库时,情况并非如此。

于 2015-05-24T03:13:13.193 回答
3

我找到的解决方案是将您的 db 文件放在 assets 文件夹中。而不是读取 .csv 文件来创建 .db 文件(当您开始正确的活动时)首先尝试检查 .db 文件是否在 /data/data/file.db 中,如果不是,请从您的资产文件夹到该路径。使用下一个代码,您将能够完成所有操作:

protected void copyDataBase() throws IOException {

        //Open your local db as the input stream
        InputStream myInput = getApplicationContext().getAssets().open("file.db");

        // Path to the just created empty db
        String outFileName = "/data/data/com.yourpackagename/databases/" + "file.db";

        //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();

    }
    protected boolean checkDataBase(){

        SQLiteDatabase checkDB = null;

        try{
            String myPath = "/data/data/com.yourpackage/databases/" + "file.db";
            checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);

        }catch(SQLiteException e){

            //database does't exist yet.

        }

        if(checkDB != null){

            checkDB.close();

        }

        return checkDB != null ? true : false;
    }
于 2015-04-30T16:27:01.820 回答
0

我还没试过。但是,如果您可以将数据库文件复制到 /data/data//db_name.db 位置并在清单中的 Sugar 配置中使用相同的 db_name 和 db 版本,它应该会选择它。

于 2014-06-17T17:47:28.777 回答