gist

2012年1月22日日曜日

「SQLが不味いですって?それでも食わねばならぬ!」ORMLiteでonUpgradeする

ORMLiteにはデータベーススキーマを更新するため素敵な機能にonUpgradeメソッドがあります。このメソッド内でマイグレーションを実装します。SQLで。

前回のエントリーで実装したコードを修正していきます。

Account.java

package com.luckyandhappy.models;

import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.table.DatabaseTable;

@DatabaseTable(tableName = "accounts")
public class Account {

 @DatabaseField(generatedId = true)
 private Integer id;
 @DatabaseField
 private String name;
 @DatabaseField(canBeNull = true)
 private String mail;
 // 年齢フィールドを追加
 @DatabaseField(canBeNull = true)
 private Integer age;
 
 public Account() {}
 public Account(String name) { 
  this.name = name; 
 }
 public Account(String name, String mail) {
  this.name = name; this.mail = mail;
 }
 public Integer getId() { return this.id; }
 public String getName() { return this.name; }
 public void setName(String name) { this.name = name; }
 public String getMail() { return this.mail; }
 public void setMail(String mail) { this.mail = mail; }
 public Integer getAge() { return this.age; }
 public void setAge(Integer age) { this.age = age; }
}

DatabaseHelper.javaをデータベースのバージョンを修正し、onUpgradeメソッドを実装します。

DatabaseHelper.java

package com.luckyandhappy.models;

import java.sql.SQLException;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.os.Environment;
import android.util.Log;

import com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper;
import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.support.ConnectionSource;
import com.j256.ormlite.table.TableUtils;

public class DatabaseHelper extends OrmLiteSqliteOpenHelper {

 private static final String DATABASE_NAME = Environment.getExternalStorageDirectory() + "/Sample.db";
 // データベースのバージョンを上げる
 private static final int DATABASE_VERSION = 2;

 public DatabaseHelper(Context context) {
  super(context, DATABASE_NAME, null, DATABASE_VERSION);
 }

 @Override
 public void onCreate(SQLiteDatabase arg0, ConnectionSource arg1) {
  try {
   TableUtils.createTable(arg1, Account.class);
  } catch (SQLException e) {
   Log.e(DatabaseHelper.class.getName(), "データベースを作成できませんでした", e);
  }
 }

 @Override
 public void onUpgrade(SQLiteDatabase db, ConnectionSource source, int oldVersion,
   int newVersion) {
  // ここを追加
  try {
   while(++oldVersion <= newVersion) {
    switch (oldVersion) {
    // バージョンが2なら年齢フィールドを追加
    case 2:
     Dao<Account,Integer> dao = getDao(Account.class);
     dao.executeRaw("ALTER TABLE `accounts` ADD COLUMN `age` INTEGER;");
     break;
    default:
     break;
    }
   }
  }catch(SQLException e) {
   Log.e(DatabaseHelper.class.getName(), "Accountを変更できませんでした", e);
  }
 }
}

起動してデータベースの中身を確認します。

データベースはきちんと更新されているようです。

しかし!この方法ですと、Accountクラスにフィールドを追加したら「手動で」データベースのバージョンを変更し、マイグレーションのクエリを記述する必要があります(当たり前か)。でも間違えそうですし、チームでの作業にも影響しそうです。なんとか省力化する方法を考えよう。

0 件のコメント: