最近用SugarOrm创建了数据表userInfo,用contentProvider暴露数据,后来userInfo中增加了两个字段,升级数据库时遇到了找不到字段的异常。
下面记录了解决的方法
原来的数据表:
public class UserInfo extends SugarRecord { private int userId; private String userName; private String sex; private String userImg; private String birthday; private float height; private float weight; private String phone; @Ignore private boolean isSelect;//是否选中 public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getUserImg() { return userImg; } public void setUserImg(String userImg) { this.userImg = userImg; } public String getBirthday() { return birthday; } public void setBirthday(String birthday) { this.birthday = birthday; } public float getHeight() { return height; } public void setHeight(float height) { this.height = height; } public float getWeight() { return weight; } public void setWeight(float weight) { this.weight = weight; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public int getUserId() { return userId; } public void setUserId(int userId) { this.userId = userId; } }
1. 新的userInfo表:
public class UserInfo extends SugarRecord { private int userId; private String userName; private String sex; private String userImg; private String birthday; private float height; private float weight; private String tags; private String phone; private String faceId; private boolean isMain;//是否是主帐号 private String mainPhone;//关联主帐号 private String facePosition;//脸部位置 private String facepath;//人脸图片路径 private String mac;//冰箱mac private String tagIds; private String isLogin;//1:登录;0:未登录 private String isDefault;//1:是默认帐户;0:不是默认账户 @Ignore private boolean isSelect;//是否选中 public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getUserImg() { return userImg; } public void setUserImg(String userImg) { this.userImg = userImg; } public String getBirthday() { return birthday; } public void setBirthday(String birthday) { this.birthday = birthday; } public float getHeight() { return height; } public void setHeight(float height) { this.height = height; } public float getWeight() { return weight; } public void setWeight(float weight) { this.weight = weight; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public int getUserId() { return userId; } public void setUserId(int userId) { this.userId = userId; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public boolean isSelect() { return isSelect; } public void setSelect(boolean select) { isSelect = select; } public String getIsLogin() { return isLogin; } public void setIsLogin(String isLogin) { this.isLogin = isLogin; } public String getIsDefault() { return isDefault; } public void setIsDefault(String isDefault) { this.isDefault = isDefault; } }
2. sugar数据库升级:
在src/main目录下,新建accests/sugar_upgrades目录,创建文件2.sql,将要添加的字段写进2.sql,
alter table USER_INFO add IS_LOGIN VARCHAR; alter table USER_INFO add IS_DEFAULT VARCHAR;
3. ContentProvier文件:
public class FamilyProvider extends ContentProvider { //这里的AUTHORITY就是我们在AndroidManifest.xml中配置的authorities,这里的authorities可以随便写 private static final String AUTHORITY = "com.privider.Family"; //匹配成功后的匹配码 private static final int MATCH_ALL_CODE = 200; // private static final String MATCH_ONE_CODE = "101"; private static UriMatcher uriMatcher; private Cursor cursor = null; private static final Uri FAMILY_URI = Uri.parse("content://"+AUTHORITY+"/USER_INFO"); private SQLiteFamilyUtil sqLiteFamilyUtil; private SQLiteDatabase db; //在静态代码块中添加要匹配的 Uri static { //匹配不成功返回NO_MATCH(-1) uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); uriMatcher.addURI(AUTHORITY,"USER_INFO",MATCH_ALL_CODE); } @Override public boolean onCreate() { sqLiteFamilyUtil = new SQLiteFamilyUtil(getContext()); db = sqLiteFamilyUtil.getReadableDatabase(); return false; } @Nullable @Override public Cursor query(@NonNull Uri uri, @Nullable String[] strings, @Nullable String s, @Nullable String[] strings1, @Nullable String s1) { Cursor cursor = null; switch (uriMatcher.match(uri)){ case MATCH_ALL_CODE: cursor = db.query("USER_INFO",null,null,null,null,null,null); Log.e("wangchm","cursor.getCount()="+cursor.getCount()); break; } return cursor; } @Nullable @Override public String getType(@NonNull Uri uri) { return null; } @Nullable @Override public Uri insert(@NonNull Uri uri, @Nullable ContentValues contentValues) { return null; } @Override public int delete(@NonNull Uri uri, @Nullable String s, @Nullable String[] strings) { return 0; } @Override public int update(@NonNull Uri uri, @Nullable ContentValues contentValues, @Nullable String s, @Nullable String[] strings) { return 0; } }
SQLiteFamilyUtil.java文件:
public class SQLiteFamilyUtil extends SQLiteOpenHelper{ private static final int VERSION = 2; // 版本号 public static final String DB_NAME ="/data/data/com.unilife.fridge.haierbase.tft/databases/user.db"; public SQLiteFamilyUtil(Context context, String name, CursorFactory factory, int version) { super(context, name, factory, version); } @Override public void onCreate(SQLiteDatabase sqLiteDatabase) { //创建数据库和表 String family="create table if not exists USER_INFO(ID INTEGER PRIMARY KEY AUTOINCREMENT,USER_ID Integer,USER_NAME varchar(100),"+ "SEX varchar(10),USER_IMG varchar(100),BIRTHDAY varchar(100),HEIGHT Float," + "WEIGHT Float,TAGS varchar(100),PHONE varchar(100),"+ ",IS_LOGIN varchar(100)"+ ",IS_DEFAULT varchar(100)"+ ")"; sqLiteDatabase.execSQL(family); } @Override public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) { Log.e("wangchm","onUpgrade "+i+",i1="+i1); //OnUpgrade() 方法中的 switch 语句是没有 break 的,会一直执行到语句结束。为什么要这么写想想就明白了。 // 比如用户手上的版本是 1,新版 App 的版本是 5,那么就会有 4 个版本的数据库升级,switch() 自然不能中途 break, // 必须执行这 4 个版本的数据库升级语句。 switch (i){ case 1: sqLiteDatabase.execSQL("alter table USER_INFO add IS_LOGIN VARCHAR;"); // 增加字段 sqLiteDatabase.execSQL("alter table USER_INFO add IS_DEFAULT VARCHAR;"); // 增加字段 default: break; } // sqLiteDatabase.execSQL("drop table if exists USER_INFO;"); // onCreate(sqLiteDatabase); } public SQLiteFamilyUtil(Context context, String name, int version) { this(context, name, null, version); } public SQLiteFamilyUtil(Context context, String name) { this(context, name, VERSION); } public SQLiteFamilyUtil(Context context){ super(context, DB_NAME, null, VERSION); } }
将第一行的版本号改为2;并在onUpgrade中利用旧版本号做判断。
4. 在AndroidManifest.xml中,把版本号改为2