Android數據庫相關整理

今天對Android中數據庫相關的操做和代碼作了一個整理,便於本身以後的查閱。主要內容有:java

1.原生數據庫寫法sql

2.終端進sqlite的操做shell

3.第三方庫數據庫

4.事務處理api

5.權限和路徑網絡

 

1、原生數據庫寫法

通常要先繼承自SQLiteOpenHelper寫一個Helper。session

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語句。app

原生也會支持一些操做的api:insert,update,delete。 參數須要傳入數據內容ide

ContentValues cv=new ContentValues();
cv.put(TABLE_NUM,1);
cv.put(TABLE_DATA,"測試數據庫數據");
db.insert(Test,null,cv); 

 

2、終端進sqlite操做

1.設備連接

經過Open Module Settings,或者File→Project Structure,均可以看到SDK的位置。而後從終端進到SDK的此目錄下函數

$cd /Users/dsx/Library/Android/sdk/platform-tools

Android的模擬器或是pos真機,可使用usb連接或者wifi訪問。若是是usb鏈接,能夠直接訪問。若是是wifi連接須要使用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       //從數據庫操做中退出

 

3、第三方庫

 關於第三方庫,安卓經常使用的也就是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();

 

4、事務處理

對於重要且耗時操做須要加入到事務中,避免極端狀況所產生的問題

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();
}

 

5、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);  

請求後點擊的回調方法

@Override
public 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);
    }
}
相關文章
相關標籤/搜索