首页 > 解决方案 > 如何通过将列类型从字符串类型更改为日期类型来迁移数据库

问题描述

我正在尝试通过将列的类型从 String 更改为 Date 类型来迁移数据库。这是我所做的,但没有产生预期的结果......

    public static final Migration MIGRATION_1_2 = new Migration(1, 2) {

    SimpleDateFormat mDateFormat = new SimpleDateFormat("dd/MM/yyyy");

    @Override
    public void migrate(@NonNull SupportSQLiteDatabase database) {
        // Create a new table
        database.execSQL("CREATE TABLE newExpense (id INTEGER NOT Null, title TEXT, amount TEXT, date INTEGER" +
                ", PRIMARY KEY(id))");
        // Copy the contents of the old table into this new one
        database.execSQL("INSERT INTO newExpense (id,title,amount,date) SELECT id,title,amount" +
                ", 'mDateFormat.parse(date).getTime()' AS date FROM Expense ");
        // Delete the old table
        database.execSQL("DROP TABLE Expense");
        // Rename the new table to the old table
        database.execSQL("ALTER TABLE newExpense RENAME TO Expense");
    }
};

这是实体之前的样子

    // BEFORE (version 1)
    @Entity
    public class Expense {

       @PrimaryKey(autoGenerate = true)
       private int id;
       private String title;
       private String amount;
       private String date;

       ...

    }

现在

    // NOW (version 2) 
    @Entity
    public class Expense {
    @PrimaryKey(autoGenerate = true)
    private int id;
    private String title;
    private String amount;
    private Date date;

       ...
    }

当我在模拟器设备上模拟更新时,结果显示日期错误。我特别不确定迁移中的这种说法

    database.execSQL("INSERT INTO newExpense (id,title,amount,date) SELECT id,title,amount" +
            ", 'mDateFormat.parse(date).getTime()' AS date FROM Expense ")

特别是'mDateFormat.parse(date).getTime()'。我试图实现的是使用 SimpleDateFormat 解析方法将以前表示为 dd/MM/yyyy 格式的字符串的日期转换为日期对象。这种方法可能有什么问题,或者我还能如何达到目的?

标签: androidsqlandroid-sqlitedatabase-migrationandroid-room

解决方案


这就是我最终做的工作顺利。

    ...

    // Create a Pojo that represents what the Expense looked like in version 1 of database.
    private static class OldExpense {

    private int id;
    private String title;
    private String amount;
    private String date;
    private SimpleDateFormat mSimpleDateFormat = new SimpleDateFormat("dd/MM/yyyy");

    public OldExpense(int id, String title, String amount, String date) {
        this.id = id;
        this.title = title;
        this.amount = amount;
        this.date = date;
    }

    public Expense toExpense()  {
        Date date = null;
        try {
            date = mSimpleDateFormat.parse(this.date);
        } catch (ParseException e) {
            date = new Date();
            e.printStackTrace();
        }
        return new Expense(id, title, amount
                , date);
    }



    public static final Migration MIGRATION_1_2 = new Migration(1, 2) {

      SimpleDateFormat mDateFormat = new SimpleDateFormat("dd/MM/yyyy");

      @Override
      public void migrate(@NonNull SupportSQLiteDatabase database) {
        // Create a new table
        database.execSQL("CREATE TABLE NewExpense (id INTEGER NOT Null, title TEXT, amount TEXT, date INTEGER" +
                ", PRIMARY KEY(id))");


        // Read every thing from the former Expense table
        Cursor cursor = database.query("SELECT * FROM Expense");

        int id;
        String title;
        String amount;
        String date;
        List<OldExpense> expenses = new ArrayList<>();

        while (cursor.moveToNext()) {

            id = cursor.getInt(cursor.getColumnIndex("id"));
            title = cursor.getString(cursor.getColumnIndex("title"));
            amount = cursor.getString(cursor.getColumnIndex("amount"));
            date = cursor.getString(cursor.getColumnIndex("date"));

            expenses.add(new OldExpense(id,title,amount,date));
        }


        // transform the former Expenses into current Expenses
        List<Expense> newExpenses = new ArrayList<>();
        Expense newExpense;
        for(OldExpense oldExpense: expenses) {
            newExpense = oldExpense.toExpense();
            newExpenses.add(newExpense);
        }


        // Insert the current Expenses into current Expense table
        for (Expense expense: newExpenses){
            database.execSQL("INSERT INTO NewExpense (id, title, amount, date) VALUES" +
                    " ('"+expense.getId()+"', '"+expense.getTitle()+"', '"+expense.getAmount()+"', '"+expense.getDate().getTime()+"'  )");
        }


        // Delete the former table
        database.execSQL("DROP TABLE Expense");
        // Rename the current table to the former table name so that all other code continues to work
        database.execSQL("ALTER TABLE NewExpense RENAME TO Expense");



     }
  };

推荐阅读