在上一章GreenDao3.0學習(二)中,咱們知道了怎麼使用greendao建立數據,這一章主要是介紹greendao的增刪改查java
代碼以下:git
private void insertUser(Long id, String name) { UserBeanDao userDao = GreenDaoManager.getInstance().getSession().getUserBeanDao(); UserBean user = new UserBean(id, name); userDao.insert(user); mNameET.setText(""); mUserList.clear(); mUserList.addAll(userDao.queryBuilder().build().list()); mUserAdapter.notifyDataSetChanged(); }
沒錯,就是這麼簡單:
這裏須要注意的是:insertUser中的id咱們只要傳null
就行,好比insertUser(null, str);
看看效果:
插入成功:github
private void deleteUser(String name) { UserBeanDao userBeanDao = GreenDaoManager.getInstance().getSession().getUserBeanDao(); //刪除 UserBean findUser = userBeanDao.queryBuilder().where(UserBeanDao.Properties.Name.eq(name)).build().unique(); if (findUser != null) { userBeanDao.deleteByKey(findUser.getId()); } // //根據某一個條件批量刪除 // List<UserBean> userList = userBeanDao.queryBuilder().where(UserBeanDao.Properties.Name.eq(name)).build().list(); // for (UserBean user : userList) { // userBeanDao.delete(user); // } mNameET.setText(""); mUserList.clear(); mUserList.addAll(userBeanDao.queryBuilder().build().list()); mUserAdapter.notifyDataSetChanged(); }
根據name刪除單個:
根據name批量刪除:sql
private void updateUser(String prevName, String newName) { UserBeanDao userBeanDao = GreenDaoManager.getInstance().getSession().getUserBeanDao(); //更新單個 UserBean findUser = GreenDaoManager.getInstance().getSession().getUserBeanDao().queryBuilder() .where(UserBeanDao.Properties.Name.eq(prevName)).build().unique(); if (findUser != null) { findUser.setName(newName); GreenDaoManager.getInstance().getSession().getUserBeanDao().update(findUser); Toast.makeText(MyApplication.getContext(), "修改爲功", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(MyApplication.getContext(), "用戶不存在", Toast.LENGTH_SHORT).show(); } //批量更新 // List<UserBean> userList = userBeanDao.queryBuilder().where(UserBeanDao.Properties.Name.eq(prevName)).build().list(); // Log.e("userList", userList + ""); // if (userList.isEmpty()) { // Toast.makeText(MyApplication.getContext(), "用戶不存在", Toast.LENGTH_SHORT).show(); // } else { // for (UserBean user : userList) { // user.setName(newName); // userBeanDao.update(user); // Log.e("修改", "修改爲功"); // } // Toast.makeText(MyApplication.getContext(), "更新成功", Toast.LENGTH_SHORT).show(); // } mNewNameET.setText(""); mNameET.setText(""); mUserList.clear(); mUserList.addAll(userBeanDao.queryBuilder().build().list()); mUserAdapter.notifyDataSetChanged(); }
單個更新
數據庫
批量更新segmentfault
private void initData() { mUserList = GreenDaoManager.getInstance().getSession().getUserBeanDao().queryBuilder().build().list(); mUserAdapter = new UserAdapter(this, mUserList); mUserLV.setAdapter(mUserAdapter); }
沒錯,就是這麼愉快的就搞定了~~~app
等等,好像有一個問題,當咱們升級數據庫版本時,發現,之前保存的數據不見了,啊啊啊~~~咋個搞,,咱們去查看代碼,發如今DaoMaster.java中有這個一段更新代碼ide
/** WARNING: Drops all table on Upgrade! Use only during development. */ public static class DevOpenHelper extends OpenHelper { public DevOpenHelper(Context context, String name) { super(context, name); } public DevOpenHelper(Context context, String name, CursorFactory factory) { super(context, name, factory); } @Override public void onUpgrade(Database db, int oldVersion, int newVersion) { Log.i("greenDAO", "Upgrading schema from version " + oldVersion + " to " + newVersion + " by dropping all tables"); dropAllTables(db, true); onCreate(db); } } }
q其中的註釋WARNING: Drops all table on Upgrade! Use only during development.
翻譯過來就是:
警告:刪除全部升級的表!僅在開發過程當中使用。 學習
這可咋個搞,因而在網上找到了一種解決方案:將之前的表變爲臨時表,而後建立新表,將臨時表中的數據拷貝過來,刪除臨時表。
就是本身從新添加一個新類繼承DaoMaster.OpenHelper,而後本身從新實現onUpgrade方法,
代碼以下:
MySQLiteOpenHelper.javaui
public class MySQLiteOpenHelper extends DaoMaster.OpenHelper { public MySQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory) { super(context, name, factory); } /** * 數據庫升級 * * @param db * @param oldVersion * @param newVersion */ @Override public void onUpgrade(Database db, int oldVersion, int newVersion) { //操做數據庫的更新 MigrationHelper.migrate(db,UserBeanDao.class,UserBean1Dao.class,UserBean3Dao.class,SiteDao.class); } }
MigrationHelper.java
public class MigrationHelper { /** * 調用升級方法 * @param db * @param daoClasses 一系列dao.class */ public static void migrate(Database db, Class<? extends AbstractDao<?, ?>>... daoClasses) { //1 新建臨時表 generateTempTables(db, daoClasses); //2 建立新表 createAllTables(db, false, daoClasses); //3 臨時表數據寫入新表,刪除臨時表 restoreData(db, daoClasses); } /** * 生成臨時表,存儲舊的表數據 * @param db * @param daoClasses */ private static void generateTempTables(Database db, Class<? extends AbstractDao<?, ?>>... daoClasses) { //方法2 for (int i=0;i<daoClasses.length;i++){ DaoConfig daoConfig = new DaoConfig(db,daoClasses[i]); String tableName = daoConfig.tablename; if (!checkTable(db,tableName)) continue; String tempTableName = daoConfig.tablename.concat("_TEMP"); StringBuilder insertTableStringBuilder = new StringBuilder(); insertTableStringBuilder.append("alter table ") .append(tableName) .append(" rename to ") .append(tempTableName) .append(";"); db.execSQL(insertTableStringBuilder.toString()); } } /** * 檢測table是否存在 * @param db * @param tableName */ private static Boolean checkTable(Database db,String tableName){ StringBuilder query = new StringBuilder(); query.append("SELECT count(*) FROM sqlite_master WHERE type='table' AND name='").append(tableName).append("'"); Cursor c = db.rawQuery(query.toString(), null); if (c.moveToNext()){ int count = c.getInt(0); if(count>0){ return true; } return false; } return false; } /** * 刪除全部舊錶 * @param db * @param ifExists * @param daoClasses */ private static void dropAllTables(Database db, boolean ifExists, @NonNull Class<? extends AbstractDao<?, ?>>... daoClasses) { reflectMethod(db, "dropTable", ifExists, daoClasses); } /** * 建立新的表結構 * @param db * @param ifNotExists * @param daoClasses */ private static void createAllTables(Database db, boolean ifNotExists, @NonNull Class<? extends AbstractDao<?, ?>>... daoClasses) { reflectMethod(db, "createTable", ifNotExists, daoClasses); } /** * 建立根刪除都在NoteDao聲明瞭,能夠直接拿過來用 * dao class already define the sql exec method, so just invoke it */ private static void reflectMethod(Database db, String methodName, boolean isExists, @NonNull Class<? extends AbstractDao<?, ?>>... daoClasses) { if (daoClasses.length < 1) { return; } try { for (Class cls : daoClasses) { //根據方法名,找到聲明的方法 Method method = cls.getDeclaredMethod(methodName, Database.class, boolean.class); method.invoke(null, db, isExists); } } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } /** * 臨時表的數據寫入新表 * @param db * @param daoClasses */ private static void restoreData(Database db, Class<? extends AbstractDao<?, ?>>... daoClasses) { for (int i = 0; i < daoClasses.length; i++) { DaoConfig daoConfig = new DaoConfig(db, daoClasses[i]); String tableName = daoConfig.tablename; String tempTableName = daoConfig.tablename.concat("_TEMP"); if (!checkTable(db,tempTableName)) continue; // get all columns from tempTable, take careful to use the columns list List<String> columns = getColumns(db, tempTableName); //新表,臨時表都包含的字段 ArrayList<String> properties = new ArrayList<>(columns.size()); for (int j = 0; j < daoConfig.properties.length; j++) { String columnName = daoConfig.properties[j].columnName; if (columns.contains(columnName)) { properties.add(columnName); } } if (properties.size() > 0) { final String columnSQL = TextUtils.join(",", properties); StringBuilder insertTableStringBuilder = new StringBuilder(); insertTableStringBuilder.append("INSERT INTO ").append(tableName).append(" ("); insertTableStringBuilder.append(columnSQL); insertTableStringBuilder.append(") SELECT "); insertTableStringBuilder.append(columnSQL); insertTableStringBuilder.append(" FROM ").append(tempTableName).append(";"); db.execSQL(insertTableStringBuilder.toString()); } StringBuilder dropTableStringBuilder = new StringBuilder(); dropTableStringBuilder.append("DROP TABLE ").append(tempTableName); db.execSQL(dropTableStringBuilder.toString()); } } private static List<String> getColumns(Database db, String tableName) { List<String> columns = null; Cursor cursor = null; try { cursor = db.rawQuery("SELECT * FROM " + tableName + " limit 0", null); if (null != cursor && cursor.getColumnCount() > 0) { columns = Arrays.asList(cursor.getColumnNames()); } } catch (Exception e) { e.printStackTrace(); } finally { if (cursor != null) cursor.close(); if (null == columns) columns = new ArrayList<>(); } return columns; } }
建立數據庫的方式變動爲:
//建立一個數據庫 MySQLiteOpenHelper helper = new MySQLiteOpenHelper(MyApplication.getContext(), "greendao-db", null); DaoMaster mDaoMaster = new DaoMaster(helper.getWritableDatabase()); mDaoSession = mDaoMaster.newSession();