Как добавить новые поля в существующий объект в Android с помощью ormLite?

СТАРЫЙ ОБЪЕКТ: у меня был объект, но я забыл добавить аннотацию @DatabaseField к некоторым полям.

@DatabaseTable
public class Card {
    @DatabaseField(generatedId = true)
    private int id;
    @DatabaseField(unique = true)
    private String cardNumber;
    @DatabaseField
    private String nameOnCard;
    private String ccv;
    private String validFrom;
    private String validTill;
    private String pin;
    //Required by ormLite
    public Card() {
    }
//skipped the getter setters below
}

У меня есть класс, который пишет конфигурацию, вот код.

package net.udevs.db;
import com.j256.ormlite.android.apptools.OrmLiteConfigUtil;
import net.udevs.entity.Card;

public class OrmLiteSqlLiteConfigGenerator extends OrmLiteConfigUtil {
    private final static Class<?>[] entityClasses=new Class[]{EmailAccount.class, Card.class};
    public static void main(String... args) throws Exception{
        writeConfigFile("ormlite_config.txt",entityClasses);
    }
}

Созданный файл конфигурации приведен ниже, и, посмотрев на него, я знаю, что поля в базе данных не обновляются.

#
# generated on 2016/01/14 01:13:56
#
# --table-start--
dataClass=net.udevs.entity.Card
tableName=card
# --table-fields-start--
# --field-start--
fieldName=id
generatedId=true
# --field-end--
# --field-start--
fieldName=cardNumber
unique=true
# --field-end--
# --field-start--
fieldName=nameOnCard
# --field-end--
# --table-fields-end--
# --table-end--
#################################

НОВАЯ СУЩНОСТЬ: теперь я добавил отсутствующую аннотацию @DatabaseField.

public class Card {
    @DatabaseField(generatedId = true)
    private int id;
    @DatabaseField(unique = true)
    private String cardNumber;
    @DatabaseField
    private String nameOnCard;
    @DatabaseField
    private String ccv;
    @DatabaseField
    private String validFrom;
    @DatabaseField
    private String validTill;
    @DatabaseField
    private String pin;

    public Card() {
    }

    public Card(int id, String cardNumber, String nameOnCard, String ccv, String validFrom, String validTill, String pin) {

        this.id = id;
        this.cardNumber = cardNumber;
        this.nameOnCard = nameOnCard;
        this.ccv = ccv;
        this.validFrom = validFrom;
        this.validTill = validTill;
        this.pin = pin;
    }
//skipped the getter setters below
}

и затем я снова запустил класс OrmLiteConfigUtil, но файл конфигурации не изменился.


person Sujal Mandal    schedule 14.01.2016    source источник


Ответы (2)


Вы можете добавить аннотацию @DatabaseField к отсутствующим полям и увеличить версию базы данных, а затем в методе onUpgrade сделать это

@Override
    public void onUpgrade(SQLiteDatabase db, ConnectionSource connectionSource, int oldVersion, int newVersion) {
        if(oldVersion == 1) {
            try {
                Dao dao = getCardDao();
                dao.executeRaw("ALTER TABLE `Card` ADD COLUMN ccv STRING;");
                dao.executeRaw("ALTER TABLE `Card` ADD COLUMN validFrom STRING;");
            } catch (SQLException e) {
                Log.e(DatabaseHelper.class.getName(), "Error ", e);
            }
        }
    }

Наконец, запустите OrmLiteConfigUtil, и текстовый файл конфигурации должен измениться.

Таким образом, вам не нужно стирать базу данных и терять данные.

person AfroChase    schedule 20.01.2016
comment
в этом случае мне нужно каждый раз вручную писать код sql в executeRaw() для новых столбцов? И спасибо, это, безусловно, поможет :) - person Sujal Mandal; 21.01.2016
comment
Только раз. Представьте, что у вас есть таблица Card со столбцами A и B, а версия базы данных равна 1. Если вы хотите добавить столбец C, вам нужно увеличить версию базы данных и написать пример кода для метода onUpgrade. Таким образом, executeRaw вызывается только один раз, и ваша база данных в версии 2 будет содержать столбец C в таблице Card. - person AfroChase; 21.01.2016

Вы можете сделать следующее для добавления нового столбца:

  1. Сначала обновите версию вашей базы данных, то есть с 1 на 2.

  2. В методе onUpgrade() вы можете удалить предыдущие таблицы:

    public void onUpgrade(SQLiteDatabase database, ConnectionSource connectionSource, int oldVersion, int newVersion)
    {
        try
        {
            TableUtils.dropTable(connectionSource, ABC.class, true);
            TableUtils.dropTable(connectionSource, XYZ.class, true);
        }
        catch (SQLException e)
        {
            e.printStackTrace();
        }
        onCreate(database, connectionSource);
    }
    
  3. В OnCreate() снова создайте таблицу:

    @Override
    public void onCreate(SQLiteDatabase database, ConnectionSource connectionSource) {
        try
        {
            TableUtils.createTable(connectionSource, ABC.class);
            TableUtils.createTable(connectionSource, XYZ.class);
        }
        catch (SQLException ex)
        {
            ex.printStackTrace();
        }
    }
    
  4. В вашей таблице ABC вы можете добавить еще один столбец:

    @DatabaseField(columnName = AppConstants.TABLE_COLUMN_IS_SHOW_AUTOGRAPH, defaultValue = "false")
    private boolean mShowAutoGraph;
    
  5. Примечание. Обязательно отредактируйте файл ormlite_config.txt со следующими значениями:

    fieldName=mShowAutoGraph // field name used in table
    columnName=show_autograph // key used in AppConstants.TABLE_COLUMN_IS_SHOW_AUTOGRAPH
    defaultValue=false
    # --field-end--
    # --table-fields-end--
    # --table-end--
    

    Здесь убедитесь, что вы заканчиваете таблицу тегом --end--. Удалить тег конца из предыдущей записи этой таблицы. Если вы этого не сделаете, вы никогда не сможете увидеть свою колонку.

person Kirti    schedule 02.08.2018
comment
drop table не является подходящим решением для приложения в производстве. - person Warwicky; 17.03.2019