http://www.jianshu.com/p/b268264bf305
http://www.jianshu.com/p/b268264bf305
http://www.jianshu.com/p/b268264bf305
greenDao
http://www.cnblogs.com/libertycode/p/6256000.html
http://www.jianshu.com/p/b268264bf305
http://blog.csdn.net/u010151514/article/details/72865861
以前开发用到数据库时,基本上都是用android原生的sql语句,写那些语句时稍有不慎,就给你抛出一个exception。现在网上有很多的数据库ORM框架,今天写篇文章来记录一下比较好用的框架:greendao的使用。关于greendao的介绍,网上已经有很多了,可以自行查阅。
准备工作
- 1、新建一个android工程,在main目录下新建一个文件夹java-gen,如下图:
- 2、在同一个project下,再新建一个java module,并新创建一个类,如下图:
3、在android module中的build.gradle文件中加上以下代码:
0){ fos.write(buffer,0,length); } fos.close(); inputStream.close(); } catch (Exception e) { e.printStackTrace(); } } @Override public SQLiteDatabase openOrCreateDatabase(String name, int mode, SQLiteDatabase.CursorFactory factory) { Log.d("GreenDao","openOrCreateDatabase"); SQLiteDatabase result= SQLiteDatabase.openOrCreateDatabase(getDatabasePath(name),factory); return result; } @Override public SQLiteDatabase openOrCreateDatabase(String name, int mode, SQLiteDatabase.CursorFactory factory, DatabaseErrorHandler errorHandler) { Log.d("GreenDao","openOrCreateDatabase"); SQLiteDatabase result= SQLiteDatabase.openOrCreateDatabase(getDatabasePath(name),factory); return result; }}" data-snippet-id="ext.02002a61fd295b53c17554d8876c3582" data-snippet-saved="false" data-codota-status="done" style="margin-top: 0px; margin-bottom: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: "Courier New" !important;"> Log.d("GreenDao","buildDatabase");
InputStream inputStream=mContext.getResources().openRawResource(R.raw.accurmedicine);
FileOutputStream fos= null;
try {
fos = new FileOutputStream(filePath);
byte[] buffer=new byte[1024];
int length;
while ((length=inputStream.read(buffer))>0){
fos.write(buffer,0,length);
}
fos.close();
inputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public SQLiteDatabase openOrCreateDatabase(String name, int mode, SQLiteDatabase.CursorFactory factory) {
Log.d("GreenDao","openOrCreateDatabase");
SQLiteDatabase result= SQLiteDatabase.openOrCreateDatabase(getDatabasePath(name),factory);
return result;
}
@Override
public SQLiteDatabase openOrCreateDatabase(String name, int mode, SQLiteDatabase.CursorFactory factory, DatabaseErrorHandler errorHandler) {
Log.d("GreenDao","openOrCreateDatabase");
SQLiteDatabase result= SQLiteDatabase.openOrCreateDatabase(getDatabasePath(name),factory);
return result;
}
}这里提一下:ContextWrapper是一个Context包装类,需要包含一个真正的Context,详细介绍看:
http://www.jianshu.com/p/94e0f9ab3f1d
3)在创建DevOpenHelper的时候使用GreenDaoContextWrapper
String DBName="xxx"; DaoMaster.DevOpenHelper helper=new DaoMaster.DevOpenHelper(new GreenDaoContextWrapper(context),DBName,null);这样就大功告成了!
二、数据库版本升级
这个办法是从网上看到的,还不错,就搬过来了。
public class MigrationHelper { private static MigrationHelper instance; public static MigrationHelper getInstance() { if (instance==null){ instance=new MigrationHelper(); } return instance; } /** * 创建临时表->删除旧表->创建新表->导入数据 * @param database * @param daoClasses */ public void migrate(SQLiteDatabase database, Class<? extends AbstractDao<?,?>>...daoClasses){ generateTempTables(database,daoClasses); DaoMaster.dropAllTables(database,true); DaoMaster.createAllTables(database,false); restoreData(database,daoClasses); } /** * 临时表生产 * @param database * @param daoClasses */ private void generateTempTables(SQLiteDatabase database,Class<? extends AbstractDao<?,?>>...daoClasses){ for (int i=0;i<daoClasses.length;i++){ DaoConfig config=new DaoConfig(database,daoClasses[i]); String divider=""; String tableName=config.tablename; String tmpTableName=config.tablename.concat("_TEMP"); ArrayList<String > properties=new ArrayList<>(); StringBuilder createTableStringBuilder=new StringBuilder(); createTableStringBuilder.append("CREATE TABLE ").append(tmpTableName).append(" ("); List<String> columns = getColumns(database, tableName); for (int j=0;j<config.properties.length;j++){ String columnName=config.properties[j].columnName; if (columns.contains(columnName)){ properties.add(columnName); String type=null; try { type=getTypeByClass(config.properties[j].type); } catch (Exception e) { e.printStackTrace(); } createTableStringBuilder.append(divider).append(columnName).append(" ").append(type); if (config.properties[j].primaryKey){ createTableStringBuilder.append(" PRIMARY KEY"); } divider=","; } } createTableStringBuilder.append(");"); Log.d("xxxxx","sql="+createTableStringBuilder.toString()); database.execSQL(createTableStringBuilder.toString()); StringBuilder insertTableString=new StringBuilder(); insertTableString.append("insert into ").append(tmpTableName).append(" ("); insertTableString.append(TextUtils.join(",",properties)); insertTableString.append(") select "); insertTableString.append(TextUtils.join(",",properties)); insertTableString.append(" from ").append(tableName).append(";"); Log.d("xxxxx","sql="+insertTableString.toString()); database.execSQL(insertTableString.toString()); } } /** * 数据字段与Java数据类型匹配 * @param type * @return * @throws Exception */ private String getTypeByClass(Class<?> type) throws Exception { if (type.equals(String.class)){ return "TEXT"; } if (type.equals(Long.class)||type.equals(Integer.class)){ return "INTEGER"; } if (type.equals(Boolean.class)){ return "BOOLEAN"; } String strException="数据表数据类型匹配错误"; Exception exception=new Exception(strException.concat("- Class").concat(type.toString())); throw exception; } /** * 获取当前数据表字段列表 * @param database * @param tableName * @return */ private static List<String > getColumns(SQLiteDatabase database,String tableName){ List<String > columns=new ArrayList<>(); Cursor cursor=null; /** * 通过查询数据表 */ cursor=database.rawQuery("select * from "+tableName+" limit 1",null); try { if (cursor!=null){ String[] columnNames = cursor.getColumnNames(); for (String name:columnNames){ columns.add(name.toUpperCase()); } // columns=new ArrayList<>(Arrays.asList(cursor.getColumnNames())); } }catch (Exception e){ e.printStackTrace(); }finally { if (cursor!=null){ cursor.close(); } } return columns; } /** * 数据恢复->删除临时表 * @param database * @param daoClasses */ private void restoreData(SQLiteDatabase database,Class<? extends AbstractDao<?,?>>...daoClasses){ for (int i=0;i<daoClasses.length;i++){ DaoConfig config=new DaoConfig(database,daoClasses[i]); String tableName=config.tablename; String tmpTableName=config.tablename.concat("_TEMP"); ArrayList<String > properties=new ArrayList<>(); for (int j=0;j<config.properties.length;j++){ String columnName = config.properties[j].columnName; if(getColumns(database, tmpTableName).contains(columnName)) { properties.add(columnName); } } StringBuilder insertTableStringBuilder = new StringBuilder(); insertTableStringBuilder.append("INSERT INTO ").append(tableName).append(" ("); insertTableStringBuilder.append(TextUtils.join(",", properties)); insertTableStringBuilder.append(") SELECT "); insertTableStringBuilder.append(TextUtils.join(",", properties)); insertTableStringBuilder.append(" FROM ").append(tmpTableName).append(";"); StringBuilder dropTableStringBuilder = new StringBuilder(); dropTableStringBuilder.append("DROP TABLE ").append(tmpTableName); database.execSQL(insertTableStringBuilder.toString()); database.execSQL(dropTableStringBuilder.toString()); } } }
然后在需要数据库版本设计的时候修改DaoMaster中的SCHEMA_VERSION
public static final int SCHEMA_VERSION = 1;这个变量就是用于在创建OpenHelper时指定数据库版本号。
紧接着修改DevOpenHelper的onUpgrade代码:
@Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { Log.i("greenDAO", "Upgrading schema from version " + oldVersion + " to " + newVersion + " by dropping all tables"); // dropAllTables(db, true); // onCreate(db); MigrationHelper.getInstance() .migrate(db, paramsDao.class, ); }最后大功告成!
顺带需要补充一下,查看SQLite数据库版本可以执行以下这句语句:
PRAGMA user_version
设置SQLite数据库版本的语句:
PRAGMA user_version =<你的版本号>以上的这两句话其实可以在SQLiteDatabase以及SQLiteOpenHelper的源码中看到:
在android-24的SQLiteOpenHelper源码中可以看到:
/** * Gets the database version. * * @return the database version */ public int getVersion() { return ((Long) DatabaseUtils.longForQuery(this, "PRAGMA user_version;", null)).intValue(); } /** * Sets the database version. * * @param version the new database version */ public void setVersion(int version) { execSQL("PRAGMA user_version = " + version); }而SQLiteOpenHelper设置和获取数据库版本就是通过调用这两句话来实现的,具体源码可以查看SQLiteOpenHelper的getDatabaseLocked函数,这里不再赘述。
greendao的使用
最新推荐文章于 2020-08-03 17:03:45 发布