迁移学习_引入Android迁移

迁移学习

迁移学习

您曾经与Rails的迁移一起工作吗? 他们使数据库更改变得轻而易举,不是吗? 尽管每个软件发行版不一定都涉及迁移,但是当某个软件发行版确实恰好可以利用它时,我总是对事情的进展很满意。 无论是添加新数据还是更改现有数据结构,Rails迁移都使开发数据存储库(无论是RDMBS还是像MongoDB这样的NoSQL数据存储库)变得轻松自如。

android_platform

最近,当我发现自己为自己的一个Android应用程序更改了SQLite数据库的数据结构时,我发现自己希望有一些与Rails中类似的Android迁移机制。 las,我不能罚款,所以我做了其他开发人员会做的事情:我写了一个

Droid Migrate是一个简单的命令行框架,可为使用SQLite的Android应用程序生成并运行数据库迁移。 迁移由包含updown方法的DBVersion类封装。 调用up方法进行升级,调用down进行回滚。 这些方法的工作完全取决于您。

此外,Droid Migrate生成一个DatabaseHelper类,通过该类您可以获取与SQLite实例的基础连接–无论如何,这是在Android应用中 与SQLite进行 交互的规范方法,但是使用Droid Migrate,您将获得一个经过特殊增强的DatabaseHelper ,该DatabaseHelper可以确定哪个版本目标数据库实例的版本是最新的,并运行适当的迁移以将数据库升级到该版本。

因此,使用新创建的DatabaseHelper类,您仍然可以像通常一样与应用程序的数据库进行交互,但是,通过使用此类,可以为您处理所有迁移。 请允许我示范。

我已经创建了一个简单的应用程序,该应用程序目前不与任何数据库交互–它只是创建了一个ListView ,该ListView旨在保存记录列表以供查看。 如果您想继续,可以在Github上找到此应用。 尽管如此,该应用程序的主要活动如下所示。

没有任何SQLite逻辑的简单Android应用
package com.b50.db.ex;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends Activity {

  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    TextView textView = (TextView) findViewById(R.id.textView1);
    textView.setText("This would be a list from a DB if there was a DB");
  }
}

我想做的就是添加与SQLite数据库进行交互的功能; 另外,我希望能够在后续版本中发展数据模型。 这是Droid Migrate闪耀的地方。

安装Droid Migrate(只需克隆或下载代码,进行构建,然后将其放入PATH并创建名为DROID_MIGRATE_HOME新环境变量)之后,我可以通过在根目录中打开一个终端来初始化我的应用程序以使用Droid Migrate我的应用程序并输入:

初始化Droid迁移
$> droid-migrate init -d a_catalog

-d标志指定所需数据库的名称。 如果希望将新生成的类与主应用程序放在单独的包中,则可以通过-p标志提供包名。

如果您查看应用程序的代码,则应该注意到许多新事物。 首先,您将看到两个新类和一个新的jar文件。 这些类是前面提到的DatabaseHelper和一个名为DBVersion1的类。 应用程序的libs文件夹中新添加的jar文件包含一些与Droid Migrate的运行时依赖项相对应的类-此jar非常紧凑,只有4KB。

DatabaseHelper类非常简单:

DatabaseHelper再简单不过了
package com.b50.db.ex;

import com.b50.db.ex.R;
import android.content.Context;
import com.b50.migrations.MigrationsDatabaseHelper;

public class DatabaseHelper extends MigrationsDatabaseHelper {

  public DatabaseHelper(Context context) {
    super(context, context.getString(R.string.database_name), null,
      context.getResources().getInteger(R.integer.database_version),
      context.getString(R.string.package_name));
  }
}

该类扩展了Droid Migrate的MigrationsDatabaseHelper ,最终扩展了Android的SQLiteOpenHelper因此,正如我前面提到的,您已经拥有通过DatabaseHelper与SQLite交互所需的一切。 如果仔细观察,您会发现该类利用了专用的XML文件(最终会生成到R类中)。

res/values文件夹中查看并打开新创建的migrations.xml文件。 它看起来应该像这样:

migrations.xml包含数据库版本,程序包名称和数据库名称
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <integer name="database_version">1</integer>
    <string name="database_name">a_catalog</string>
    <string name="package_name">com.b50.db.ex</string>
</resources>

注意database_version的值-为1。这对应于生成的DBVersion1类。 看一看该课程:

DBVersion1是您的初始迁移类
package com.b50.db.ex;

import com.b50.migrations.AbstractMigration;

public class DBVersion1 extends AbstractMigration {

  public void up() {
      //execSQL("some sql create stmts");
  }

  public void down() {
      //execSQL("some delete sql stmts");
  }
}

在此类中,您可以实现初始迁移,这将创建各种表并填充它们。 使用execSQL方法传递有效SQL String 。 例如,我将创建一个初始迁移,如下所示:

现在已实现DBVersion1
package com.b50.db.ex;

import com.b50.migrations.AbstractMigration;

public class DBVersion1 extends AbstractMigration {

  public void up() {
      String create = "CREATE TABLE hops (_id integer  PRIMARY KEY AUTOINCREMENT DEFAULT NULL, name TEXT, description TEXT, substitutions TEXT DEFAULT '', alpha_acid TEXT DEFAULT '', beer_styles TEXT DEFAULT '', type TEXT DEFAULT '', user_notes TEXT DEFAULT '');";
      execSQL(create);
      String oneThing = "INSERT INTO 'hops' VALUES(1,'Amarillo','Spicy hop with mild bitterness and a noble aroma.  Good all around hop.','Cascade, Centennial','7 to 10','Ale, IPA','Aroma', '');";
      execSQL(oneThing);
  }

  public void down() {
      execSQL("DROP TABLE hops;");
  }

}

如您所见,我的up方法创建一个表并插入一条记录。 我的down方法回滚down一切,在这种情况下,这意味着删除创建的表。

现在,我要做的就是利用我应用程序的DatabaseHelper实例,Droid Migrate将确保正确初始化所有内容。 因此,我将更新原始活动以显示数据库中的内容的列表,根据我的初始迁移,我只知道这是一条记录。

更新了活动以与SQLite进行交互
package com.b50.db.ex;

import android.app.Activity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;

public class MainActivity extends Activity {

  protected SQLiteDatabase db;

  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    this.db = (new DatabaseHelper(this)).getWritableDatabase();
    ListView list = (ListView) findViewById(R.id.list);

    ListAdapter adapter = getAdaptorForQuery("SELECT _id, name, description FROM hops ORDER BY name ASC", null);
    list.setAdapter(adapter);
  }

  private ListAdapter getAdaptorForQuery(String queryString, String[] parameters) {
    Cursor cursor = this.db.rawQuery(queryString, parameters);
    return new SimpleCursorAdapter(this, R.layout.list_item, cursor,
              new String[] { "name", "description" }, new int[] { R.id.hopName, R.id.description }, 0);
  }
}

从上面的代码中可以看到,该应用程序现在对基础SQLite实例进行查询,并根据查询的结果集构建ListView

关键是如何获取SQLiteDatabase实例: this.db = (new DatabaseHelper(this)).getWritableDatabase(); –这就是所有魔术发生的地方。 Droid Migrate将版本号传递给Android平台,如果有更改,Android平台将调用一系列生命周期方法,Droid Migrate与您的迁移相关联。

例如,让我们想象该应用程序的后续发行版将更多数据添加到hops表中。 因此,我将生成一个新的迁移。 这是通过在项目的根目录中键入以下命令来完成的,如下所示:

产生新的迁移
$> droid-migrate generate up

up标志表示数据库版本(即版本++)增加,而down标志表示回滚(即版本–)。 如果查看应用程序的代码,您会注意到一个新类: DBVersion2并且您的migrations.xml文件已更新: database_version值现在为2。

我将像这样实现DBVersion2类:

实现DBVersion2以添加另一行数据
package com.b50.db.ex;

import com.b50.migrations.AbstractMigration;

public class DBVersion2 extends AbstractMigration {

  public void up() {
      execSQL("INSERT INTO 'hops' VALUES(100,'Zythos','New IPA style hop blend created to optimize and exceed the aroma characteristics of the traditional, and sometimes hard to get, IPA hops.','Amarillo, Columbus, Cascade','9.5 to 12','IPAs','Bittering and Aroma', '');");
  }

  public void down() {
      execSQL("DELETE from 'hops' where _id = 100");
  }
}

现在,如果我启动我的应用程序,则ListView中将包含2个项目!

migration_2

如果需要回滚怎么办? 就这么简单。 想象一下,添加第二行数据是一个巨大的错误,相反,我实际上只想要一行(即,我只想要最初在DBVersion1创建的数据)。 我要做的就是在项目的根目录下键入:

Droid Migrate中的回滚同样简单
$> droid-migrate generate down

键入上面的命令后,您应该看到以下输出:

回滚到版本1!
Generating a rollback migration...
Rolling back your migrations.xml file to indicate database version 1
Done!

项目中唯一会更改的是migrations.xml文件– database_version值将回滚到1(或1减去当前版本的值)。

重新启动应用程序,然后DBVersion2 :因为执行了DBVersion2down方法,所以显示一个值!

Droid Migrate使升级和回滚到基础SQLite数据库变得轻而易举。 而且,它不仅可以处理一个版本,还可以处理升级或回滚。 也就是说,如果应用程序实例从版本2升级到版本6,则每个迁移将按顺序(3、4、5和6)运行。 回滚也是如此。

如果您在Android应用程序中使用SQLite,强烈建议您看一下Droid Migrate

参考: The Disco Blog博客中的JCG合作伙伴Andrew Glover介绍了Android迁移

翻译自: https://www.javacodegeeks.com/2013/07/introducing-android-migrations.html

迁移学习

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值