Android資料庫相關整理,android資料庫清理
今天對Android中資料庫相關的操作和代碼做了一個整理,便於自己之後的查閱。主要內容有:
1.原生資料庫寫法
2.終端進sqlite的操作
3.第三方庫
4.交易處理
5.許可權和路徑
一、原生資料庫寫法
一般要先繼承自SQLiteOpenHelper寫一個Helper。
public class DatabaseHelper extends SQLiteOpenHelper { private static final String name = "crashier"; //資料庫名稱 private static final int version = 1; //資料庫版本 public DatabaseHelper(Context context) { //第三個參數CursorFactory指定在執行查詢時獲得一個遊標執行個體的工廠類,設定為null,代表使用系統預設的工廠類 super(context, name, null, version); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL("CREATE TABLE IF NOT EXISTS person (personid integer primary key autoincrement, name varchar(20), age INTEGER)"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("ALTER TABLE person ADD phone VARCHAR(12)"); //往表中增加一列 } }
在取到SQLiteDatabase類型的db後,一般操作是直接用其執行String類型的SQL語句。
原生也會支援一些操作的api:insert,update,delete。 參數需要傳入資料內容
ContentValues cv=new ContentValues();cv.put(TABLE_NUM,1);cv.put(TABLE_DATA,"測試資料庫資料");db.insert(Test,null,cv);
二、終端進sqlite操作1.裝置連結
通過Open Module Settings,或者File→Project Structure,都可以看到SDK的位置。然後從終端進到SDK的此目錄下
$cd /Users/dsx/Library/Android/sdk/platform-tools
Android的模擬器或是pos真機,可以使用usb連結或者wifi訪問。如果是usb串連,可以直接存取。如果是wiki連結需要使用adb指令串連IP
$./adb devices $./adb disconnect XXX.XXX.194.238$./adb connect XXX.XXX.194.238
註:這裡需要注意的一點是,部分網路環境下可能無法使用wifi,需要使用網線串連。最好關閉模擬器,讓devices列表中只存在一個裝置。
2.sqlite3操作
使用下列操作時,資料庫列表只能有一個裝置,否則會報錯。 pos機的斷開可以使用disconnect指令,模擬器的斷開就是直接關閉。
然後使用下列操作開啟並進入資料庫
$./adb shell$cd sdcard/path/subdir$sqlite3 dsxniubility.db
終端內進入資料庫一般操作也就是 查和刪,這邊介紹這兩種情況。
$.table //查看錶的列表$.dump 某個表 //查看錶內資料$.schema 某個表 //查看錶的結構$rm 某個表 // 刪除
使用select語句展示時,預設的樣式不清晰,建議設定成清晰明了的樣式。 具體各種樣式就不廢話了,直接給個最優樣式。
$.nullvalue null //空欄位用null佔位$.mode column //隔得比較開的一種樣式$.headers on //顯示表頭$.width 5,5 //表寬度減短獲得更大空間$.show //查看現在的設定情況
在退出的時候有個小坑,這三種退出指令要在合適的情境下敲
$.exit; //在一個語句中退出$.exit //從資料表中退出$exit //從資料庫操作中退出
三、第三方庫
關於第三方庫,安卓常用的也就是ORMLite和GreenDao了,前者的使用較為簡單是使用反射原理寫的,效能不如後者。
greendao官網有一個非常明顯效能對比圖,所以往下就唯寫greendao了。
GREENDAO 是一個基於Android的第三方資料庫管理工具,其設計的主要特點
一個精簡的庫
效能最大化
記憶體開銷最小化
便於使用的 APIs
對 Android 進行高度最佳化
1.greenDao配置
項目從零開始如何配置
①.build.gradle
compile 'org.greenrobot:greendao:2.2.1'
②.建立Module,名字類似與DaoGenerator
File→New→NewModule→java Library
③.給建立的Module的build.gradle配置
apply plugin: 'java' task(run, dependsOn: 'classes', type: JavaExec) { main = 'com.example.MainGen' classpath = sourceSets.main.runtimeClasspath systemProperty 'user.dir', project.rootDir} dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'org.greenrobot:greendao-generator:2.2.0' targetCompatibility = '1.7' sourceCompatibility = '1.7'}
④.上面說的MainGen需要自己建立一個類
裡面實現一個main函數,裡面做一些配置
public static void main(String[] args) throws Exception{ // 擷取一些標識,設定scheme String relativePath = System.getProperty("user.dir"); int DB_VERSION = 201666; System.out.print("dbVersion is:" + DB_VERSION); Schema schema = new Schema(DB_VERSION,"com.dsx.a201666"); schema.enableActiveEntitiesByDefault(); schema.enableKeepSectionsByDefault(); // 這裡可能會有很多建立建立資料表的方法 createMenuItem(schema); // 代碼產生路徑的指定和執行 String daoPath = relativePath + "/app/src/main/java"; File daoDir = new File(daoPath); if (!daoDir.isDirectory()){ //noinspection ResultOfMethodCallIgnored daoDir.mkdirs(); } new DaoGenerator().generateAll(schema,daoPath); }
上面有兩個特殊屬性解釋一下
enableActiveEntitiesByDefault 如果開啟 則支援實體類之間update,refresh,delete等操作。 所以這屬性一般情境都是不開啟的。
enableKeepSectionsByDefault 如果開啟 則支援使用者給模型自訂資料,會產生下列代碼,在這代碼之間寫的屬性,可以用但不會往資料庫存。
// KEEP INCLUDES - put your custom includes here// KEEP INCLUDES END // KEEP FIELDS - put your custom fields here// KEEP FIELDS END // KEEP METHODS - put your custom methods here// KEEP METHODS END
⑤.右鍵執行一下main函數,產生各種檔案(DaoMaster,DaoSession,模型類的entity 和Dao)
也可以在build.gradle中設定preBuild.dependsOn讓他在程式編譯時間就自動執行
2.greenDao使用
首先在greenDao的入口,MainGen檔案中用greenDao的api建立資料庫
private static void createCategoryTable(Schema schema){ Entity entity = schema.addEntity("SnackCategory"); entity.implementsSerializable(); entity.addIntProperty("id").primaryKey().autoincrement(); entity.addIntProperty("no"); Property orderProperty = entity.addLongProperty("orderId").getProperty(); entity.addToOne(orderBase, orderProperty); entity.addStringProperty("name");}
main函數中調用後會自動產生SnackCategory 和 SnackCategoryDao 檔案,前者相當於實體類,後者是操作層,利用Dao尾碼檔案進行read,load,insert等操作。
serializable和parcelable區別, 前者用於儲存到本地檔案資料庫中,網路流傳輸。 後者常用於記憶體中的傳輸,效能更好。
greenDao內部提供了幾乎所有功能的api可以自行去標頭檔裡看,下面列出基本操作
//刪session.getSnackCategoryDao().deleteAll();//存session.getSnackCategoryDao().insert(cate);session.getSnackCategoryDao().insertInTx(cateList);//取List<SnackCategory> categoryList = session.getSnackCategoryDao().loadAll();
按照一定的要求取資料:
取出所有種類為涼菜的item 然後按照價格排序
List<SnackFood> nicefoods = session.getSnackFoodDao().queryBuilder().where(SnackFoodDao.Properties.Categoryid.eq("主食")).orderAsc(SnackFoodDao.Properties.Price).list();//董鉑然部落格園
取出所有種類為涼菜,並且價格小於10元的菜品
QueryBuilder qb = session.getSnackFoodDao().queryBuilder();qb.where(SnackFoodDao.Properties.Categoryid.eq("主食"),SnackFoodDao.Properties.Price.le(10.0));List goodfoods = qb.list();
四、交易處理
對於重要且耗時操作需要加入到事務中,避免極端情況所產生的問題
SQLiteDatabase database = session.getDatabase();database.beginTransaction();try { session.getSnackCategoryDao().deleteAll(); session.getSnackFoodDao().deleteAll(); session.getSnackCategoryDao().insertInTx(cateList); session.getSnackFoodDao().insertInTx(snackList); database.setTransactionSuccessful();} catch (Exception e) { e.printStackTrace();} finally { database.endTransaction();}
五、sd卡許可權、路徑1.許可權擷取
這個SD卡的許可權擷取和其他Android6.0的運行時許可權擷取差不多,大致分為三個操作:查詢是否有許可權,請求擷取許可權,使用者選擇後的回調方法
查詢許可權
private boolean lackPermission() { return ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED; //董鉑然部落格園}
請求擷取許可權
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_PHONE_STATE}, WRITE_EXTERNAL_STORAGE_REQUEST_CODE);
請求後點擊的回調方法
@Overridepublic void onRequestPermissionsResult(int requestCode,String permissions[], int[] grantResults) { if(requestCode == mRequestCode(12)){ if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // 授權通過 } else { // 授權失敗 } } }}
2.儲存路徑判斷SDK有許可權放到sd卡裡 ,無許可權就放到根目錄
public DaoMaster.OpenHelper provideOpenHelper() { File path = new File(Environment.getExternalStorageDirectory(), "path/subdir/" + DATABASE_NAME); path.getParentFile().mkdirs(); if (path.getParentFile().exists()) { return new DaoOpenHelper(BaseApplication.application(), path.getAbsolutePath(), null); } else { return new DaoOpenHelper(BaseApplication.application(), DATABASE_NAME, null); }}