Android數據庫設計——1,面向對象(ORM)建庫、建表

創建數據庫

創建一個數據庫工廠類,用於創建數據庫操作對象和表的Dao對象

//數據庫工廠類
public class BaseDaoFactory {
    //該對象是單例的
    private static final BaseDaoFactory instance = new BaseDaoFactory();

    //數據庫對象
    private SQLiteDatabase sqLiteDatabase;

    //定義建數據庫的路徑
    //路徑可以寫在data/data下,優點是數據保密;缺點是app卸載數據丟失
    //寫在sd卡中,優點是app卸載數據不會丟失;缺點是數據缺乏保密性
    private String sqliteDatabasePath;
	
    //單例
    public static BaseDaoFactory getInstance() {
        return instance;
    }
	//構造方法
    public BaseDaoFactory() {
        //新建數據庫
//        Environment.getExternalStorageDirectory()+ File.separator;
        //寫在data/data路徑下
        sqliteDatabasePath = "data/data/com.xxx.greendao/test_1.db";
        //創建數據庫操作對象
        sqLiteDatabase = SQLiteDatabase.openOrCreateDatabase(sqliteDatabasePath, null);
    }

創建表

定義一個創建和操作的Dao的接口(面向接口編程)

public interface IBaseDao<T> {
    //插入
    long insert(T entity);

    //更新
    long update(T entity,T where);

    //刪除
    int delete(T where);

    //查詢全部
    List<T> queryAll();

    //條件查詢
    List<T> queryByWhere(T where);

    //條件查詢,排序,分頁
    List<T> queryByWhere(T where,String orderBy,int startIndex,int limit);
}

實現Dao接口

//每一張表都有與之對應的Dao類,而所有的具體對象的Dao都要繼承該BaseDao
public class BaseDao<T> implements IBaseDao<T> {

    //數據庫對象
    private SQLiteDatabase sqLiteDatabase;

    //表名,當前dao所對應的表
    private String tableName;

    //持有操作數據庫所對應的javaBean類型
    private Class<T> entityClass;

    //是否已經初始化
    private boolean isInit;

    //架構內部的邏輯不要提供構造方法給調用層使用,表名靠反射來獲得
    public void init(SQLiteDatabase sqLiteDatabase, Class<T> entityClass) {
        //保存對象
        this.sqLiteDatabase = sqLiteDatabase;
        this.entityClass = entityClass;
        //是否已經初始化,防止同一個表的Dao對象多次實例化
        if (!isInit) {
            //自動建表
            //通過反射和註解獲得表名,如果沒有添加註解,則通過反射去拿表名
            DbTable dbTable = entityClass.getAnnotation(DbTable.class);
            if (dbTable != null) {
                //註解拿表名
                this.tableName = dbTable.value();
            } else {
                //反射拿表名
                this.tableName = entityClass.getSimpleName();
            }
            //創建表的sql語句
            String createTableSql = getCreateTableSql();
            //執行sql
            this.sqLiteDatabase.execSQL(createTableSql);
            isInit = true;
        }
    }
}

getCreateTableSql()

public class BaseDao<T> implements IBaseDao<T> {
    //...其他代碼
    
	//創建表的sql
	private String getCreateTableSql() {
	    StringBuilder stringBuilder = new StringBuilder();
        //拼接創建表的sql語句
	    stringBuilder.append("create table if not exists ");
	    stringBuilder.append(tableName).append("(");
	    //反射得到所有的成員變量
	    Field[] fields = entityClass.getDeclaredFields();
	    for (Field field : fields) {
            //拿到成員的類型
	        Class type = field.getType();
	        //拿到成員的值
            String fieldName;
	        if (field.getAnnotation(DbField.class) != null) {
	            //有註解
	            fieldName = field.getAnnotation(DbField.class).value();
	        } else {
	            //通過反射
	            fieldName = field.getName();
	        }
            //拼接類型對應的sql
	        if (type == String.class) {
	            stringBuilder.append(fieldName).append(" varchat,");
	        } else if (type == Integer.class) {
	            stringBuilder.append(fieldName).append(" INTEGER,");
	        } else if (type == Long.class) {
	            stringBuilder.append(fieldName).append(" BIGINT,");
	        } else if (type == Double.class) {
	            stringBuilder.append(fieldName).append(" DOUBLE,");
	        } else if (type == Float.class) {
	            stringBuilder.append(fieldName).append(" FLOAT,");
	        } else if (type == byte[].class) {
	            stringBuilder.append(fieldName).append(" BLOB,");
	        }
	    }
	    //去掉結尾的,號
	    if (stringBuilder.charAt(stringBuilder.length() - 1) == ',') {
	        stringBuilder.deleteCharAt(stringBuilder.length() - 1);
	    }
        //sql拼接結束
	    stringBuilder.append(")");
	    //返回創建表的sql語句
        return stringBuilder.toString();
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章