我是GreenDAO的新人。我在GitHub提供的项目中实现了一些代码。在github中有默认的db称为"注",我试图在其中创建一个新的列插入图像。这是在启动器活动中插入数据的代码。
Note note = new Note(null, noteText, comment, new Date() , ih.getBitmapAsByteArray(R.drawable.ic_launcher));
noteDao.insert(note);
和这个Note.java类
private byte[] img;
public Note(Long id, String text, String comment, java.util.Date date , byte[] img) {
this.id = id;
this.text = text;
this.comment = comment;
this.date = date;
this.img = img;
}
// Setter and getter for other field and as well as for image
public byte[] getImg(){
return img;
}
public void setimg(byte[] img_v){
this.img = img_v;
}
和这个在NoteDAO.java类
public static class Properties {
public final static Property Id = new Property(0, Long.class, "id", true, "_id");
public final static Property Text = new Property(1, String.class, "text", false, "TEXT");
public final static Property Comment = new Property(2, String.class, "comment", false, "COMMENT");
public final static Property Date = new Property(3, java.util.Date.class, "date", false, "DATE");
public final static Property Image = new Property(4, Blob.class, "image", false, "IMAGE");
};
/** Creates the underlying database table. */
public static void createTable(SQLiteDatabase db, boolean ifNotExists) {
String constraint = ifNotExists? "IF NOT EXISTS ": "";
db.execSQL("CREATE TABLE " + constraint + "'NOTE' (" + //
"'_id' INTEGER PRIMARY KEY ," + // 0: id
"'TEXT' TEXT NOT NULL ," + // 1: text
"'COMMENT' TEXT," + // 2: comment
"'DATE' INTEGER"+
"'IMAGE' TEXT);"); // 3: date
}
/** Drops the underlying database table. */
public static void dropTable(SQLiteDatabase db, boolean ifExists) {
String sql = "DROP TABLE " + (ifExists ? "IF EXISTS " : "") + "'NOTE'";
db.execSQL(sql);
}
/** @inheritdoc */
@Override
protected void bindValues(SQLiteStatement stmt, Note entity) {
stmt.clearBindings();
Long id = entity.getId();
if (id != null) {
stmt.bindLong(1, id);
}
stmt.bindString(2, entity.getText());
String comment = entity.getComment();
if (comment != null) {
stmt.bindString(3, comment);
}
java.util.Date date = entity.getDate();
if (date != null) {
stmt.bindLong(4, date.getTime());
}
byte[] img_byte = entity.getImg();
if (img_byte != null) {
stmt.bindBlob(5,img_byte );
}
}
/** @inheritdoc */
@Override
public Long readKey(Cursor cursor, int offset) {
return cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0);
}
/** @inheritdoc */
@Override
public Note readEntity(Cursor cursor, int offset) {
Note entity = new Note(
cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0), // id
cursor.getString(offset + 1), // text
cursor.isNull(offset + 2) ? null : cursor.getString(offset + 2), // comment
cursor.isNull(offset + 3) ? null : new java.util.Date(cursor.getLong(offset + 3)) // date
, cursor.getBlob(offset + 4)
);
return entity;
}
/** @inheritdoc */
@Override
public void readEntity(Cursor cursor, Note entity, int offset) {
entity.setId(cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0));
entity.setText(cursor.getString(offset + 1));
entity.setComment(cursor.isNull(offset + 2) ? null : cursor.getString(offset + 2));
entity.setDate(cursor.isNull(offset + 3) ? null : new java.util.Date(cursor.getLong(offset + 3)));
entity.setimg(cursor.getBlob(offset +4));
}
但是对于上面所有的代码,我得到一个异常,为什么我没有得到?
05-26 11:24:30.265: E/AndroidRuntime(3864): java.lang.RuntimeException: Unable
to start activity ComponentInfo{com.example.test/com.example.test.NoteActivity}:
android.database.sqlite.SQLiteException: no such column: IMAGE: , while
compiling: SELECT _id, TEXT, COMMENT, DATE, IMAGE FROM NOTE ORDER BY TEXT
COLLATE LOCALIZED ASC
任何帮助都是非常感激的。提前感谢大家。
可能您之前已经在您的设备上创建了数据库,并且没有注意到数据库的模式更新。
您必须增加模式版本,并处理从旧模式到实际模式的更新。
对于开发,最简单的解决方案是使用DaoMaster.DevOpenHelper-class
。它将简单地删除并重新创建所有表。
但是我认为在开发过程中实现服装升级处理程序是一个很好的实践。这样,当你的数据模型增长/更新时,你的升级机制就会在开发过程中"自动"进行测试。
我个人使用这样的代码:
public class MyOpenHelper extends OpenHelper {
public MyOpenHelper(Context context, String path, SQLiteDatabase.CursorFactory factory) {
super(context, path, factory);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.i(TAG, "Update DB-Schema: "+Integer.toString(oldVersion)+"->"+Integer.toString(newVersion));
switch (oldVersion) {
case 1:
db.execSQL(SQL_1_2);
case 2:
db.execSQL(SQL_2_3);
case 3:
db.execSQL(SQL_3_4);
}
}
}
请注意,break语句是故意遗漏的。这将导致我的方法将模式从旧版本更新到跨多个版本的新版本,即通过依次执行语句sql__2、SQL_2_3、SQL_3_4,从版本1更新到版本4。
通过比较旧生成的dao类的表创建语句和新生成的dao类中的表创建语句,可以获得版本更新所需的sql语句。
在你的方法createTable中,你有这样一行:
"'IMAGE' TEXT);"); // 3: date
你应该为BLOB更改"TEXT",因为你正在处理一个字节数组