国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Android之 常用數(shù)據(jù)庫框架整理

這篇具有很好參考價值的文章主要介紹了Android之 常用數(shù)據(jù)庫框架整理。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

一 簡介

1.1 上節(jié)說了關(guān)系型數(shù)據(jù)庫有以下幾種:

Oracle、Microsoft SQL Server、Microsoft Access、MySQL、SQLite

1.2 各自的領(lǐng)域也不一樣

java,C#,php等用Oracle,Microsoft SQL Server,MySQL比較多。

移動端Android,IOS等用SQLite比較多

1.3?SQLite是一種輕量型數(shù)據(jù)庫,有以下優(yōu)點:

  • 不需要一個單獨的服務(wù)器進程或操作的系統(tǒng)(無服務(wù)器的)。

  • SQLite 不需要配置,這意味著不需要安裝或管理。

  • 一個完整的 SQLite 數(shù)據(jù)庫是存儲在一個單一的跨平臺的磁盤文件。

  • SQLite 是非常小的,是輕量級的,完全配置時小于 400KiB,省略可選功能配置時小于250KiB。

  • SQLite 是自給自足的,這意味著不需要任何外部的依賴。

  • SQLite 事務(wù)是完全兼容 ACID 的,允許從多個進程或線程安全訪問。

  • SQLite 支持 SQL92(SQL2)標(biāo)準(zhǔn)的大多數(shù)查詢語言的功能。

  • SQLite 使用 ANSI-C 編寫的,并提供了簡單和易于使用的 API。

  • SQLite 可在 UNIX(Linux, Mac OS-X, Android, iOS)和 Windows(Win32, WinCE, WinRT)中運行。

二 Android 本地數(shù)據(jù)庫框架?

2.1 android數(shù)據(jù)庫框架有Room,Relam,GreenDAO,ObjectBox,SQLDelight等等。

2.2 常用的有Room,GreenDAO等,在前兩個沒出現(xiàn)之前主要用的Android官方原生框架SQLiteOpenHelper。

三?SQLiteOpenHelper 框架的使用

3.1?SQLiteOpenHelper是官方api,因此不需要引入其它庫。如下可以看到,SQLiteOpenHelper在android.database.sqlite包下面

android 數(shù)據(jù)庫框架,數(shù)據(jù)庫,sqlite,android

?3.2?SQLiteOpenHelper的使用,自定義DatabaseHelper,繼承SQLiteOpenHelper,來管理數(shù)據(jù)庫的創(chuàng)建和數(shù)據(jù)庫表的創(chuàng)建

public class DatabaseHelper extends SQLiteOpenHelper {

    public static final String DATABASE_NAME = "SMSManager.db";//數(shù)據(jù)庫名字

    private static final int DATABASE_VERSION = 1; // 數(shù)據(jù)庫的版本號

    public static final String CONTACTS_TABLE_NAME = "contacts_table";//聯(lián)系人表名

    //創(chuàng)建聯(lián)系人表SQL語句
    public static final String CREATE_CONTACTS_TABLE =
            "create table " +
            CONTACTS_TABLE_NAME +
            "(" +
            "cid integer primary key autoincrement," +
            "sendPhone varchar(50),name varchar(50) not null," +
            "phone varchar(50) not null" +
            ")";


    /**
     * DatabaseHelper構(gòu)造函數(shù),傳參數(shù)據(jù)庫名,數(shù)據(jù)庫版本,會自動創(chuàng)建數(shù)據(jù)庫
     * @param context
     */
    public DatabaseHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    /**
     * onCreate 回調(diào)SQLiteDatabase對象,自動執(zhí)行創(chuàng)建表語句
     * @param db
     */
    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_CONTACTS_TABLE);
    }

    /**
     * 升級數(shù)據(jù)庫。執(zhí)行表結(jié)構(gòu)變更語句
     * @param db
     * @param oldVersion
     * @param newVersion
     */
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//        if (newVersion > 1) {
//            //Android的ALTER命令不支持一次添加多列,只能分多次添加
//            String alter_sql = "ALTER TABLE " + CONTACTS_TABLE_NAME + " ADD COLUMN " + "phone_new2 VARCHAR;";
//            db.execSQL(alter_sql);
//            alter_sql = "ALTER TABLE " + CONTACTS_TABLE_NAME + " ADD COLUMN " + "phone_new3 VARCHAR;";
//            db.execSQL(alter_sql); // 執(zhí)行完整的SQL語句
//        }
    }
}

3.3 創(chuàng)建聯(lián)系人表的實體類ContactsInfo

public class ContactsInfo implements Serializable{
    int cid;
    String name;
    String phone;
    String sendPhone;
    boolean isChoosed=false;

    public int getCid() {
        return cid;
    }

    public void setCid(int cid) {
        this.cid = cid;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getSendPhone() {
        return sendPhone;
    }

    public void setSendPhone(String sendPhone) {
        this.sendPhone = sendPhone;
    }

    public boolean isChoosed() {
        return isChoosed;
    }

    public void setChoosed(boolean choosed) {
        isChoosed = choosed;
    }
}

3.4 創(chuàng)建聯(lián)系人表的管理類ContactsDatabase,進行表的增刪改查操作

public class ContactsDatabase {
    private final DatabaseHelper dbHelper;

    public ContactsDatabase(Context context) {
        super();
        dbHelper = new DatabaseHelper(context);
    }

    /**
     * 增
     * 
     * @param data
     */
    public void insert(ContactsInfo data) {
        String sql = "insert into " + DatabaseHelper.CONTACTS_TABLE_NAME;

        sql += "(sendPhone, name, phone) values(?,?,?)";

        SQLiteDatabase sqlite = dbHelper.getWritableDatabase();
        sqlite.execSQL(sql, new String[] {data.getSendPhone() + "",data.getName() + "", data.getPhone() + ""});
        sqlite.close();
    }

    /**
     * 刪
     * 
     * @param where
     */
    public void delete(String where) {
        SQLiteDatabase sqlite = dbHelper.getWritableDatabase();
        String sql = "delete from " + DatabaseHelper.CONTACTS_TABLE_NAME + where;
        sqlite.execSQL(sql);
        sqlite.close();
    }

    /**
     * 改
     * 
     * @param data
     */
    public void update(ContactsInfo data) {
        SQLiteDatabase sqlite = dbHelper.getWritableDatabase();
        String sql = ("update " + DatabaseHelper.CONTACTS_TABLE_NAME +" set sendPhone=?,name=?,phone=? where cid=?");
        sqlite.execSQL(sql,
                new String[] { data.getSendPhone() + "", data.getName() + "", data.getPhone()+ "", data.getCid()+ ""});
        sqlite.close();
    }
    /**
     * 查一條數(shù)據(jù)
     *
     * @param where
     * @return
     */
    public ContactsInfo queryContactsInfo(String where) {
        ContactsInfo contactsInfo = null;
        SQLiteDatabase sqlite = dbHelper.getReadableDatabase();
       String sql= "select * from "
                + DatabaseHelper.CONTACTS_TABLE_NAME + where;
        Cursor cursor = sqlite.rawQuery(sql, null);
        for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
            contactsInfo= new ContactsInfo();
            contactsInfo.setCid(cursor.getInt(0));
            contactsInfo.setSendPhone(cursor.getString(1));
            contactsInfo.setName(cursor.getString(2));
            contactsInfo.setPhone(cursor.getString(3));
        }
        if (!cursor.isClosed()) {
            cursor.close();
        }
        sqlite.close();
        return contactsInfo;
    }

    /**
     * 查
     * 
     * @param where
     * @return
     */
    public List<ContactsInfo> query(String where) {
        SQLiteDatabase sqlite = dbHelper.getReadableDatabase();
        ArrayList<ContactsInfo> data = null;
        data = new ArrayList<ContactsInfo>();
        String sql="select * from "
                + DatabaseHelper.CONTACTS_TABLE_NAME + where;
        Cursor cursor = sqlite.rawQuery(sql, null);
        for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
            ContactsInfo contactsInfo = new ContactsInfo();
            contactsInfo.setSendPhone(cursor.getString(1));
            contactsInfo.setName(cursor.getString(2));
            contactsInfo.setPhone(cursor.getString(3));
            data.add(contactsInfo);
        }
        if (!cursor.isClosed()) {
            cursor.close();
        }
        sqlite.close();
        return data;
    }
    /**
     * 查
     *
     * @param where
     * @return
     */
    public int queryCount(String where) {
        SQLiteDatabase sqlite = dbHelper.getReadableDatabase();
        String sql="select count(*) from "
                + DatabaseHelper.CONTACTS_TABLE_NAME+where ;
        Cursor cursor = sqlite.rawQuery(sql, null);
        cursor.moveToFirst();
        int count = cursor.getInt(0);
        sqlite.close();
        return count;
    }

    /**
     * 重置
     * 
     * @param datas
     */
    public void reset(List<ContactsInfo> datas) {
        if (datas != null) {
            SQLiteDatabase sqlite = dbHelper.getWritableDatabase();
            // 刪除全部
            sqlite.execSQL("delete from " + DatabaseHelper.CONTACTS_TABLE_NAME);
            // 重新添加
            for (ContactsInfo data : datas) {
                insert(data);
            }
            sqlite.close();
        }
    }

    public void destroy() {
        dbHelper.close();
    }
}

3.5 總結(jié):

第一步:SQLiteOpenHelper的構(gòu)造函數(shù)創(chuàng)建數(shù)據(jù)庫

public DatabaseHelper(Context context) {
     super(context, DATABASE_NAME, null, 1);
}

第二步:SQLiteOpenHelper的onCreate里面執(zhí)行創(chuàng)建表的sql語句

@Override
public void onCreate(SQLiteDatabase db) {
	db.execSQL(CREATE_CONTACTS_TABLE);
}

第三步:獲取當(dāng)前數(shù)據(jù)庫對象實例,打開數(shù)據(jù)庫,進行增刪改查操作

SQLiteDatabase sqlite = dbHelper.getWritableDatabase();

sqlite .insert(TABLE_NAME, "",entity);

sqlite .delete(TABLE_NAME, entity, null);

sqlite .update(TABLE_NAME, entity, "name=?", new String[]{info.name});

sqlite .rawQuery(sql, null);

第四步:關(guān)閉數(shù)據(jù)庫

if (sqlite != null && sqlite .isOpen()) {
?? ?sqlite .close();
?? ?sqlite = null;
}

四?GreenDAO 框架的使用

4.1?GreenDAO 是一種輕量級快速ORM 框架,可將對象映射到 SQLite 數(shù)據(jù)庫中

4.2?ORM 框架,即 Object-Relational Mapping,它的作用是在關(guān)系型數(shù)據(jù)庫和對象之間作一個映射,這樣,我們在具體操作數(shù)據(jù)庫的時候,就不需要再去和復(fù)雜的 SQL 語句打交道,只是像平時操作對象一樣操作它就可以了

android 數(shù)據(jù)庫框架,數(shù)據(jù)庫,sqlite,android

?4.3?GreenDAO主要類介紹

  • DaoMaster:DaoMaster保存數(shù)據(jù)庫對象(SQLiteDatabase)并管理特定模式的DAO類(而不是對象)。它有靜態(tài)方法來創(chuàng)建表或刪除它們。它的內(nèi)部類OpenHelper和DevOpenHelper是SQLiteOpenHelper實現(xiàn),它們在SQLite數(shù)據(jù)庫中創(chuàng)建模式。
  • DaoSession:管理特定模式的所有可用DAO對象,您可以使用其中一個getter方法獲取該對象。DaoSession還提供了一些通用的持久性方法,如實體的插入,加載,更新,刷新和刪除。
  • DAO:數(shù)據(jù)訪問對象(DAO)持久存在并查詢實體。對于每個實體,greenDAO生成實體XXDAO。它具有比DaoSession更多的持久性方法,例如:count,loadAll和insert等。
  • Entities :可持久化對象。通常, 實體對象代表一個數(shù)據(jù)庫行使用標(biāo)準(zhǔn) Java 屬性(如一個POJO 或 JavaBean )。

4.4 GreenDAO的使用

工程目錄build.gradle里面引入greenDao的插件

dependencies {
    classpath "com.android.tools.build:gradle:7.0.0"
	classpath 'org.greenrobot:greendao-gradle-plugin:3.3.0'
}

app的build.gradle里面使用插件,配置數(shù)據(jù)庫,并引入greenDao的依賴庫

plugins {
    id 'com.android.application'
    id 'org.greenrobot.greendao'
}

android {
    compileSdk 32

    defaultConfig {
        applicationId "com.greendao.demo"
        minSdk 21
        targetSdk 32
        versionCode 1
        versionName "1.0"
    }
}

greendao {
    //指定數(shù)據(jù)庫schema版本號,遷移等操作會用到
    schemaVersion 1
    //設(shè)置生成數(shù)據(jù)庫文件的目錄,默認是在build中,可以將生成的文件放到我們的java目錄中
    targetGenDir 'src/main/java'
    //設(shè)置生成的數(shù)據(jù)庫相關(guān)文件的包名,默認為entity所在的包名
    daoPackage 'com.greendao.demo.greendao.database'
}


dependencies {
  implementation 'org.greenrobot:greendao:3.3.0'
}

4.5 封裝數(shù)據(jù)庫管理器DaoManager,用來創(chuàng)建數(shù)據(jù)庫、創(chuàng)建數(shù)據(jù)庫表、包含增刪改查的操作以及數(shù)據(jù)庫的升級

/**
 * 創(chuàng)建數(shù)據(jù)庫、創(chuàng)建數(shù)據(jù)庫表、包含增刪改查的操作以及數(shù)據(jù)庫的升級
 */
public class DaoManager
{
    private static final String TAG = DaoManager.class.getSimpleName();
    private static final String DB_NAME = "diary.db";

    private Context context;

    //多線程中要被共享的使用volatile關(guān)鍵字修飾
    private volatile static DaoManager manager ;
    private static DaoMaster sDaoMaster;
    private static DaoMaster.DevOpenHelper sHelper;
    private static DaoSession sDaoSession;

    /**
     * 單例模式獲得操作數(shù)據(jù)庫對象
     *
     * @return
     */
    public static DaoManager getInstance()
    {
        synchronized (DaoManager.class) {
            if (manager == null) {
                manager = new DaoManager();
            }
        }
        return manager;
    }

    private DaoManager()
    {
        setDebug();
    }

    public void init(Context context)
    {
        this.context = context;
    }

    /**
     * 判斷是否有存在數(shù)據(jù)庫,如果沒有則創(chuàng)建
     *
     * @return
     */
    public DaoMaster getDaoMaster()
    {
        if (sDaoMaster == null)
        {
            sHelper = new DaoMaster.DevOpenHelper(context, DB_NAME, null);
            sDaoMaster = new DaoMaster(sHelper.getWritableDatabase());
        }
        return sDaoMaster;
    }

    /**
     * 完成對數(shù)據(jù)庫的添加、刪除、修改、查詢操作,僅僅是一個接口
     *
     * @return
     */
    public DaoSession getDaoSession()
    {
        if (sDaoSession == null)
        {
            if (sDaoMaster == null)
            {
                sDaoMaster = getDaoMaster();
            }
            sDaoSession = sDaoMaster.newSession();
        }
        return sDaoSession;
    }

    /**
     * 打開輸出日志,默認關(guān)閉
     */
    public void setDebug()
    {
        if (BuildConfig.DEBUG)
        {
            QueryBuilder.LOG_SQL = true;
            QueryBuilder.LOG_VALUES = true;
        }
    }

    /**
     * 關(guān)閉所有的操作,數(shù)據(jù)庫開啟后,使用完畢要關(guān)閉
     */
    public void closeConnection()
    {
        closeHelper();
        closeDaoSession();
    }

    public void closeHelper()
    {
        if (sHelper != null)
        {
            sHelper.close();
            sHelper = null;
        }
    }

    public void closeDaoSession()
    {
        if (sDaoSession != null)
        {
            sDaoSession.clear();
            sDaoSession = null;
        }
    }
}

4.6 在項目Application里面初始化GreenDAO

DaoManager.getInstance().init(this);

4.7 以Uer表為例,創(chuàng)建一個User實體類。實體類開頭必須加 @Entity 注解

@Entity
public class User {
    @Id(autoincrement = true)
    Long id;
    String account;
    String password;
    String name="tom";
    String avatar;
    int gender=0;
    String mobile;
    @Generated(hash = 998056223)
    public User(Long id, String account, String password, String name,
            String avatar, int gender, String mobile) {
        this.id = id;
        this.account = account;
        this.password = password;
        this.name = name;
        this.avatar = avatar;
        this.gender = gender;
        this.mobile = mobile;
    }
}

編譯后User實體類目會自動生成GET,SET方法

@Entity
public class User {
    @Id(autoincrement = true)
    Long id;
    String account;
    String password;
    String name="tom";
    String avatar;
    int gender=0;
    String mobile;
    @Generated(hash = 998056223)
    public User(Long id, String account, String password, String name,
            String avatar, int gender, String mobile) {
        this.id = id;
        this.account = account;
        this.password = password;
        this.name = name;
        this.avatar = avatar;
        this.gender = gender;
        this.mobile = mobile;
    }
    @Generated(hash = 586692638)
    public User() {
    }
    public Long getId() {
        return this.id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getAccount() {
        return this.account;
    }
    public void setAccount(String account) {
        this.account = account;
    }
    public String getPassword() {
        return this.password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public String getName() {
        return this.name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getAvatar() {
        return this.avatar;
    }
    public void setAvatar(String avatar) {
        this.avatar = avatar;
    }
    public int getGender() {
        return this.gender;
    }
    public void setGender(int gender) {
        this.gender = gender;
    }
    public String getMobile() {
        return this.mobile;
    }
    public void setMobile(String mobile) {
        this.mobile = mobile;
    }

}

同時編譯后還會在 build 目錄下生成XXXDao實體類,通過DAO實體就能操作數(shù)據(jù)庫了

android 數(shù)據(jù)庫框架,數(shù)據(jù)庫,sqlite,android

?4.7 可以封裝一個通用的增刪改查工具類,這樣像正常操作對象那樣就可以了

/**
 * 通用greendao工具
 * @param <T>
 */
public class CommonDaoUtils<T> {

    private static final String TAG = CommonDaoUtils.class.getSimpleName();

    private DaoSession daoSession;
    private Class<T> entityClass;
    private AbstractDao<T, Long> entityDao;

    public CommonDaoUtils(Class<T> pEntityClass, AbstractDao<T, Long> pEntityDao)
    {
        DaoManager mManager = DaoManager.getInstance();
        daoSession = mManager.getDaoSession();
        entityClass = pEntityClass;
        entityDao = pEntityDao;
    }

    public DaoSession getDaoSession() {
        return daoSession;
    }

    /**
     * 插入記錄,如果表未創(chuàng)建,先創(chuàng)建表
     *
     * @param pEntity
     * @return
     */
    public boolean insert(T pEntity)
    {
        boolean flag = entityDao.insert(pEntity) == -1 ? false : true;
        return flag;
    }

    /**
     * 插入記錄數(shù)據(jù)存在則替換,數(shù)據(jù)不存在則插入
     *
     * @param pEntity
     * @return
     */
    public boolean insertOrReplace(T pEntity)
    {
        boolean flag = entityDao.insertOrReplace(pEntity) == -1 ? false : true;
        return flag;
    }


    /**
     * 插入多條數(shù)據(jù),在子線程操作
     *
     * @param pEntityList
     * @return
     */
    public boolean insertMulti(final List<T> pEntityList)
    {
        try
        {
            daoSession.runInTx(new Runnable()
            {
                @Override
                public void run()
                {
                    for (T meizi : pEntityList)
                    {
                        daoSession.insertOrReplace(meizi);
                    }
                }
            });
            return true;
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 修改一條數(shù)據(jù)
     *
     * @param pEntity
     * @return
     */
    public boolean update(T pEntity)
    {
        try
        {
            daoSession.update(pEntity);
            return true;
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 刪除單條記錄
     *
     * @param pEntity
     * @return
     */
    public boolean delete(T pEntity)
    {
        try
        {
            //按照id刪除
            daoSession.delete(pEntity);
            return true;
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 刪除所有記錄
     *
     * @return
     */
    public boolean deleteAll()
    {
        try
        {
            //按照id刪除
            daoSession.deleteAll(entityClass);
            return true;
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 查詢所有記錄
     *
     * @return
     */
    public List<T> queryAll()
    {
        return daoSession.loadAll(entityClass);
    }

    /**
     * 根據(jù)主鍵id查詢記錄
     *
     * @param key
     * @return
     */
    public T queryById(long key)
    {
        return daoSession.load(entityClass, key);
    }

    /**
     * 使用native sql進行查詢操作
     */
    public List<T> queryByNativeSql(String sql, String[] conditions)
    {
        return daoSession.queryRaw(entityClass, sql, conditions);
    }


    /**
     * 使用queryBuilder進行查詢
     *
     * @return
     */
    public List<T> queryByQueryBuilder(WhereCondition cond, WhereCondition... condMore)
    {
        QueryBuilder<T> queryBuilder = daoSession.queryBuilder(entityClass);
        return queryBuilder.where(cond, condMore).list();
    }
    /**
     * 使用queryBuilder進行查詢
     *
     * @return
     */
    public List<T> queryByBuilder(WhereCondition cond)
    {
        QueryBuilder<T> queryBuilder = daoSession.queryBuilder(entityClass);
        return queryBuilder.where(cond).list();
    }

}

4.8 再定義具體的Dao操作類,實現(xiàn)單獨管理

public class DaoUserUtils
{
    private volatile static DaoUserUtils instance;

    public CommonDaoUtils<User> userCommonDaoUtils;


    public static DaoUserUtils getInstance()
    {
        synchronized (DaoUserUtils.class) {
            if(instance==null){
                instance = new DaoUserUtils();
            }
        }

        return instance;
    }

    private DaoUserUtils()
    {
        DaoManager mManager = DaoManager.getInstance();

        userCommonDaoUtils = new CommonDaoUtils(User.class,mManager.getDaoSession().getUserDao());

    }


    //新建用戶
    public void daoInsertDefaultUser(){
        String account="boss1";
        String password="123456";
        if(daoQueryAllUser().size()==0){
            User user= new User();
            user.setAccount(account);
            user.setPassword(password);
            userCommonDaoUtils.insert(user);
        }
    }

    //查詢用戶
    public List<User> daoQueryAllUser(){
        return userCommonDaoUtils.queryAll();
    }

    //查詢用戶
    public User daoQueryUser(long id){
        return userCommonDaoUtils.queryById(id);
    }


    //刪除用戶
    public boolean deleteAllUser(){
        return userCommonDaoUtils.deleteAll();
    }

    //更新用戶
    public boolean updateUser(User user){
        return userCommonDaoUtils.update(user);
    }
}

4.9 GreenDao提供有豐富的操作數(shù)據(jù)庫接口,比如查詢常用的三種方式:

  • load(entityClass, dataKey); 主鍵查詢單條數(shù)據(jù)
  • loadAll():查詢所有數(shù)據(jù)。
  • queryRaw():根據(jù)條件查詢。
  • queryBuilder() : 方便查詢的創(chuàng)建,后面詳細講解。

而且queryBuilder功能非常強大,比如下面常見的方法:

  • where(WhereCondition cond, WhereCondition... condMore): 查詢條件,參數(shù)為查詢的條件!
  • or(WhereCondition cond1, WhereCondition cond2, WhereCondition... condMore): 嵌套條件或者,用法同or。
  • and(WhereCondition cond1, WhereCondition cond2, WhereCondition... condMore): 嵌套條件且,用法同and。
  • join(Property sourceProperty, Class<J> destinationEntityClass):多表查詢,后面會講。
    輸出結(jié)果有四種方式,選擇其中一種最適合的即可,list()返回值是List,而其他三種返回值均實現(xiàn)Closeable,需要注意的不使用數(shù)據(jù)時游標(biāo)的關(guān)閉操作:
  • list ()所有實體都加載到內(nèi)存中。結(jié)果通常是一個沒有魔法的 ArrayList。最容易使用。
  • listLazy ()實體按需加載到內(nèi)存中。首次訪問列表中的元素后,將加載并緩存該元素以供將來使用。必須關(guān)閉。
  • listLazyUncached ()實體的“虛擬”列表:對列表元素的任何訪問都會導(dǎo)致從數(shù)據(jù)庫加載其數(shù)據(jù)。必須關(guān)閉。
  • listIterator ()讓我們通過按需加載數(shù)據(jù)(懶惰)來迭代結(jié)果。數(shù)據(jù)未緩存。必須關(guān)閉。
  • orderAsc() 按某個屬性升序排;
  • orderDesc() 按某個屬性降序排;

以及Property中豐富的查詢函數(shù):

  • eq():"equal ('=?')" 等于;
  • notEq() :"not equal ('<>?')" 不等于;
  • like():" LIKE ?" 值等于;
  • between():" BETWEEN ? AND ?" 取中間范圍;
  • in():" IN (" in命令;
  • notIn():" NOT IN (" not in 命令;
  • gt():">?" 大于;
  • lt():"<? " 小于;
  • ge():">=?" 大于等于;
  • le():"<=? " 小于等于;
  • isNull():" IS NULL" 為空;
  • isNotNull():" IS NOT NULL" 不為空;

4.10 queryRaw()原始sql語句查詢

  /**
     * @param sql 查詢語句
     * @param conditions 位字段賦值
     * @return
     */
    public List<T> queryByNativeSql(String sql, String[] conditions)
    {
        DaoMaster.DevOpenHelper sHelper= new DaoMaster.DevOpenHelper(context, DB_NAME, null);
        DaoSession daoSession = new DaoMaster(sHelper.getWritableDatabase());
      
        return daoSession.queryRaw(entityClass, sql, conditions);
    }

比如:

queryByNativeSql("where columnName=?", new String[]{coverId});

4.11?queryBuilder()純api查詢,不用寫任何sql語句

/**
 * @param cond 一個條件
 * @param condMore 多個條件
 * @return
 */
public List<T> queryByQueryBuilder(WhereCondition cond, WhereCondition... condMore)
{
   DaoMaster.DevOpenHelper sHelper= new DaoMaster.DevOpenHelper(context, DB_NAME, null);
   DaoSession daoSession = new DaoMaster(sHelper.getWritableDatabase());

	QueryBuilder<T> queryBuilder = daoSession.queryBuilder(entityClass);
	return queryBuilder.where(cond, condMore).list();
}

比如:

queryByQueryBuilder(DiaryDao.Properties.Time.ge(startTime),DiaryDao.Properties.Time.le(endTime));

4.12 常用注解

表名字段注解,實體類注解,必須加在類前才起用

@Entity注解

只有在實體類中使用了@Entity注解GreenDao才會創(chuàng)建對應(yīng)的表

@Entity配置:

  • schema:如果你有多個架構(gòu),你可以告訴GreenDao當(dāng)前屬于哪個架構(gòu)。
  • active:標(biāo)記一個實體處于活躍狀態(tài),活動實體有更新、刪除和刷新方法。
  • nameInDb:在數(shù)據(jù)中使用的別名,默認使用的是實體的類名。
  • indexes:標(biāo)記如果DAO應(yīng)該創(chuàng)建數(shù)據(jù)庫表(默認為true),如果您有多個實體映射到一個表,或者表的創(chuàng)建是在greenDAO之外進行的,那么將其設(shè)置為false。
  • createInDb:標(biāo)記創(chuàng)建數(shù)據(jù)庫表。
  • generateGettersSetters:如果缺少,是否應(yīng)生成屬性的getter和setter方法。
@Entity(
        schema = "myschema",
        active = true,
        nameInDb = "AWESOME_USERS",
        indexes = {
                @Index(value = "message DESC", unique = true)
        },
        createInDb = false,
        generateConstructors = true,
        generateGettersSetters = true
)
public class User{   

}

基礎(chǔ)屬性注解

@Id
@Id注解選擇 long / Long屬性作為實體ID。在數(shù)據(jù)庫方面,它是主鍵。參數(shù)autoincrement = true 表示自增,id不給賦值或者為賦值為null即可(這里需要注意,如果要實現(xiàn)自增,id必須是Long)

@Entity
public class User{
    @Id(autoincrement = true)
    Long uid;
}

@Property
允許您定義屬性映射到的非默認列名。如果不存在,GreenDAO將使用字段名稱。會生成大寫列名,如 name將成為 NAME

@Entity
public class User{
    @Id(autoincrement = true)
    Long id;

    //設(shè)置了,數(shù)據(jù)庫中的表格屬性名為"name",如果不設(shè)置,數(shù)據(jù)庫中表格屬性名為"NAME"
    @Property (nameInDb="name") 
    String name;
}

@NotNull

設(shè)置數(shù)據(jù)庫表當(dāng)前列不能為空

@Entity
public class User{
    @NotNull
    String password;
}

@Transient?

添加次標(biāo)記之后不會生成數(shù)據(jù)庫表的列。標(biāo)記要從持久性中排除的屬性。將它們用于臨時狀態(tài)等?;蛘?,您也可以使用Java中的transient關(guān)鍵字

@Entity
public class User{
    @Transient
    boolean isChecked;
}

索引注解

@Index

創(chuàng)建一個索引,通過name設(shè)置索引別名,也可以通過unique給索引添加約束。

@Unique

向索引添加UNIQUE約束,強制所有值都是唯一的。

@Entity
public class User{
    @Id(autoincrement = true)
    Long id;

    @Index(unique = true)
    String account;
}

關(guān)系注解

@ToOne:

定義與另一個實體(一個實體對象)的關(guān)系

創(chuàng)建用戶表和身份證表,一個人對應(yīng)一個身份證

@Entity
public class Student {
    @Id(autoincrement = true)
    Long uid;

    String name;

    Long cardId;

    @ToOne(joinProperty = "cardId")
    Card card;
}
@Entity
public class Card {
    @Id(autoincrement = true)
    Long cardId;

    String carNo;
}

@ToMany:

定義與多個實體對象的關(guān)系

創(chuàng)建用戶表和銀行卡表,一個人對應(yīng)多張銀行卡

@Entity
public class Student {
    @Id(autoincrement = true)
    Long uid;

    @Property (nameInDb="name")
    String newm;

   //這個 uid是對應(yīng)在 BankCard 中的 uid
    @ToMany(referencedJoinProperty = "uid")
    List<BankCard> bankCardList;
}
@Entity
public class BanKCard {
    @Id(autoincrement = true)
    Long cardId;
    String carNo;

    Long uid;
}

五 Jetpack Room框架使用

5.1?Jetpack是google官方一套MVVM架構(gòu)的解決方案框架,里面包含以下分類

UI 庫 : Animation , Transitions , Emoji , Layout , Palette …
架構(gòu)庫 : Data Binding , ViewModel , Lifecycles , LiveData , Navigation , Padding , Room …
行為庫 : Download Manager , Permissions , Notifications , Sharing …
基礎(chǔ)庫 : AppCompat , Android KTX , Multidex , Test …

5.2 Room使用跟greenDao非常相似,才采用大量注解生成表字段結(jié)構(gòu)。比如@Entity,@PrimaryKey,@NonNull,@Ignore等

如下用戶表示例:

@Entity
public class User {
    @PrimaryKey(autoGenerate = true)
    Long uid;
    @ColumnInfo(name = "account")
    String account;
    @ColumnInfo(name = "password")
    String password;
    @ColumnInfo(name = "name")
    String name;
    @Ignore
    String avatar;

    @NonNull
    boolean isChecked;

    public Long getUid() {
        return uid;
    }

    public void setUid(Long uid) {
        this.uid = uid;
    }

    public String getAccount() {
        return account;
    }

    public void setAccount(String account) {
        this.account = account;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAvatar() {
        return avatar;
    }

    public void setAvatar(String avatar) {
        this.avatar = avatar;
    }

    public boolean isChecked() {
        return isChecked;
    }

    public void setChecked(boolean checked) {
        isChecked = checked;
    }
}

5.3 使用Room,可以配合LiveData使用,也可以配合Rxjava使用。下面配合Rxjava示例:

添加Room依賴庫,和Rxjava依賴庫

ependencies {
    implementation "androidx.room:room-runtime:2.5.0"
    annotationProcessor "androidx.room:room-compiler:2.5.0"
    implementation "androidx.room:room-rxjava2:2.4.2"
    implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
}

5.4??定一個Dao管理類AppDatabase,繼承自RoomDatabase

@Database(entities = {User.class , Asset.class , Bill.class , Community.class , Ping.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
    public abstract UserDao userDao();
    public abstract AssetDao assetDao();
    public abstract BillDao billDao();
    public abstract CommunityDao communityDao();
    public abstract PingDao pingDao();
}

5.5 封裝Room數(shù)據(jù)庫管理工具類DBHelper,管理AppDatabase

public class DBHelper {
    private static AppDatabase appDatabase;

    //初始化數(shù)據(jù)庫
    public static AppDatabase initDB() {
        if (appDatabase == null) {
            appDatabase = Room.databaseBuilder(App.getInstance(),
                    AppDatabase.class, "finance.db").build();
        }
        return appDatabase;
    }

    //獲取表管理類AppDatabase
    public static AppDatabase getDB() {
        if(appDatabase==null){
            initDB();
        }
        return appDatabase;
    }


    //關(guān)閉數(shù)據(jù)庫
    public static void closeDB() {
        if (appDatabase != null && appDatabase.isOpen()) {
            appDatabase.close();
        }
    }

}

5.5 在Application里面初始化Room數(shù)據(jù)庫

public class App extends Application {
    private static App app;

    @Override
    public void onCreate() {
        super.onCreate();
        if (app == null) {
            app = this;
        }

        //初始化Room數(shù)據(jù)庫
        DBHelper.initDB();
    }

    public static App getInstance() {
        return app;
    }
}

5.6 上面已經(jīng)建了一個用戶表User,可以再建一個UserDao來管理用戶表的增刪改查操作

以查詢?nèi)坑脩魹槔皇褂胷xjava的寫法

@Dao
public interface UserDao {
  //查詢?nèi)坑脩?  @Query("SELECT * FROM user")
  List<User> getAll();
}

配合rxjava的寫法?,這個Single是rxjava里面的一個監(jiān)聽回調(diào)方法

@Dao
public interface UserDao {
    //查詢?nèi)繑?shù)據(jù)
    @Query("SELECT * FROM user")
    Single<List<User>> getAll();
}

5.7? 完整的增刪改查Rxjava寫法,跟平時用Retrofit+Rxjava差不多?

@Dao
public interface UserDao {

    //插入一條或多條用戶數(shù)據(jù)
    @Insert
    Single<List<Long>> insert(User... users);

    //刪除一條數(shù)據(jù)
    @Delete
    Single<Integer> delete(User user);

    //查詢?nèi)繑?shù)據(jù)
    @Query("SELECT * FROM user")
    Single<List<User>> getAll();

    //查詢指定賬戶數(shù)據(jù)
    @Query("SELECT * FROM user where account=:account")
    Single<List<User>> getOnUser(String account);

    //查詢指定id數(shù)據(jù)
    @Query("SELECT * FROM user where uid=:uid")
    Single<User> getOnUserById(long uid);
}

異步插入一條數(shù)據(jù)?

private void daoInsertUser(String account , String password){
	User user=new User();
	user.setAccount(account);
	user.setPassword(password);
	DBHelper.getDB().userDao().insert(user)
			.compose(DBHelper.singleSchedulers())
			.subscribe(new ObserverListener<List<Long>>() {
				@Override
				public void success(List<Long> longs) {

				}

				@Override
				public void onError(String msg) {

				}
			});

}

異步獲取全部用戶

 private void daoGetUser(){
	DBHelper.getDB().userDao().getAll()
			.compose(DBHelper.singleSchedulers())
			.subscribe(new ObserverListener<List<User>>() {
				@Override
				public void success(List<User> users) {
				   if(users.size()<=0){
					   daoInsertUser("admin","123456");
				   }
				}

				@Override
				public void onError(String msg) {
					ToastHelp.showToast(msg);
				}
			});
}

里面的compose(DBHelper.singleSchedulers())是rxjava的一個線程調(diào)度,執(zhí)行任務(wù)在子線程,返回結(jié)果更新UI在主線程

public class DBHelper {
    public static <T> ObservableTransformer<T, T> schedulers() {
        return new ObservableTransformer<T, T>() {
            @Override
            public ObservableSource<T> apply(Observable<T> upstream) {
                return upstream.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
            }
        };
    }

    public static <T> SingleTransformer<T, T> singleSchedulers() {
        return new SingleTransformer<T, T>() {
            @Override
            public SingleSource<T> apply(Single<T> upstream) {
                return upstream.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
            }
        };
    }
}

5.8 使用注意:

第一次使用可能報以下錯誤:

Schema export directory is not provided to the annotation processor so we cannot export the schema. You can either provide room.schemaLocation annotation processor argument OR set exportSchema to false.

原因:

在編譯時,Room 會將數(shù)據(jù)庫的架構(gòu)信息導(dǎo)出為 JSON 文件(默認exportSchema = true導(dǎo)出架構(gòu))。要導(dǎo)出架構(gòu),請在 build.gradle 文件中設(shè)置 room.schemaLocation 注釋處理器屬性(設(shè)置將json存放的位置)。

解決方法:

方法一:在app的build.gradle中添加如下javaCompileOptions?配置

android {
    namespace 'com.dinghe.financeapp'
    compileSdk 33

    defaultConfig {
        applicationId "com.dinghe.financeapp"
        minSdk 21
        targetSdk 33
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"


        javaCompileOptions {
            annotationProcessorOptions {
                arguments = ["room.schemaLocation" : "$projectDir/schemas".toString()]
            }
        }
    }

?方法二:在數(shù)據(jù)庫注解中添加exportSchema = false

@Database(entities = {User.class},version = 1,exportSchema = false)
public abstract class AppDatabase extends RoomDatabase {
    public abstract UserDao userDao();

}

六 總結(jié)

6.1?SQLiteOpenHelper原生api相對較少,需要自己寫大量sql語句,開發(fā)維護成本較大。而且執(zhí)行效率速度上沒其它框架快,所有新項目還是以其它框架用的多,SQLiteOpenHelper小項目可以用。

6.2 GreenDao和Room的比較

  • GreenDao和Room用法上很類似,都是用了大量注解,比如@Entity,@ID等
  • GreenDao提供的api比Room多,GreenDao可以不寫sql完成數(shù)據(jù)庫的造作,但Room的查詢還是通過寫sql語句操作的
  • GreenDao編譯后自動生成Dao,Room通過注解@Dao定義Dao
  • GreenDao會自動生成Set,Get方法,Room需要手動生成
  • GreenDao的增刪改查通過api,Room的增刪改查通過注解就可以,比如@Insert,@Update,@Delete
  • GreenDao支持Rxjava,不支持LiveData,Room由于Jetpack家族的強大同時支持Rxjava和liveData

6.3??GreenDao和Room架構(gòu)圖示對比

GreenDao:

android 數(shù)據(jù)庫框架,數(shù)據(jù)庫,sqlite,android

?

Room:

android 數(shù)據(jù)庫框架,數(shù)據(jù)庫,sqlite,android文章來源地址http://www.zghlxwxcb.cn/news/detail-625490.html

到了這里,關(guān)于Android之 常用數(shù)據(jù)庫框架整理的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • [Android Studio]Android 數(shù)據(jù)存儲--SQLite數(shù)據(jù)庫存儲

    [Android Studio]Android 數(shù)據(jù)存儲--SQLite數(shù)據(jù)庫存儲

    ??????????? Android Debug ?????????? Topic ? 發(fā)布安卓學(xué)習(xí)過程中遇到問題解決過程,希望我的解決方案可以對小伙伴們有幫助。 ??實戰(zhàn)演練--基于SQLite數(shù)據(jù)庫的通訊錄實現(xiàn)數(shù)據(jù)的增刪改查 1,創(chuàng)建程序 2,放置界面控件 3,編寫界面交互代碼 4, 核心方法講解 5,數(shù)據(jù)庫

    2024年02月08日
    瀏覽(24)
  • Android+阿里云數(shù)據(jù)庫,實現(xiàn)安卓云數(shù)據(jù)庫

    Android+阿里云數(shù)據(jù)庫,實現(xiàn)安卓云數(shù)據(jù)庫

    目錄 阿里云部分 Adnroid配置部分 Android代碼部分 效果 在阿里云中查看已保存的數(shù)據(jù) 進入阿里云首頁,這里選擇的是 云數(shù)據(jù)庫RDS?MySQL版 。 購買完成后,點擊 控制臺 。 點擊 “云數(shù)據(jù)庫RDS版” 點擊 實例列表 點擊 實例ID 接下來是 設(shè)置白名單 。 測試的話,設(shè)置為 0.0.0.0/0 就可

    2024年02月05日
    瀏覽(24)
  • Android數(shù)據(jù)庫查詢

    1.查詢圖片 2.查詢視頻 3.查詢音頻 4.根據(jù)文件路徑返回Uri (1) (2)備注代碼里返回的視頻的Uri,要返回音頻或者圖片的Uri要在查詢和獲取Uri里改為相應(yīng)的URI查詢。 5.查詢特定后綴名的文件(\\\"pdf\\\", \\\"txt\\\", \\\"doc\\\", \\\"docx\\\", \\\"xlsx\\\", \\\"xls\\\", \\\"ppt\\\", \\\"pptx\\\", \\\"epub\\\") (1)根據(jù)后綴名來查詢(存在的

    2024年02月16日
    瀏覽(17)
  • Android studio 連接SQLite數(shù)據(jù)庫 +創(chuàng)建數(shù)據(jù)庫+創(chuàng)建數(shù)據(jù)庫表

    Android studio 連接SQLite數(shù)據(jù)庫 +創(chuàng)建數(shù)據(jù)庫+創(chuàng)建數(shù)據(jù)庫表

    Android studio 之?dāng)?shù)據(jù)庫的使用 連接創(chuàng)建SQLite 大家好,歡迎來到寒依。 相信看啦我的教程 當(dāng)老師問你在學(xué)習(xí)Android studio 數(shù)據(jù)庫使用過程中遇到什么困難,分享一下你的感悟和解決方法 的時候,你可以直接大膽的說出來: “老師我沒有遇到問題,看啦寒依的教程 暢行無阻” 我

    2024年02月02日
    瀏覽(35)
  • Android studio引入外部SQLite數(shù)據(jù)庫,獲取數(shù)據(jù)庫列表數(shù)據(jù)

    Android studio引入外部SQLite數(shù)據(jù)庫,獲取數(shù)據(jù)庫列表數(shù)據(jù)

    準(zhǔn)備好Android studio和一個創(chuàng)建管理數(shù)據(jù)庫的軟件,推薦SQLite Expert Professional或者Navicat Premium。這里以SQLite Expert Professional為例。 1.穿件sqlite數(shù)據(jù)庫,按照自己的項目要求定義數(shù)據(jù)庫和相應(yīng)的數(shù)據(jù)表 1.在main目錄下創(chuàng)建assets文件,將準(zhǔn)備好的sqlite數(shù)據(jù)庫文件放入這個目錄下 解釋:

    2024年02月08日
    瀏覽(21)
  • Android 數(shù)據(jù)庫增刪改查

    Android 數(shù)據(jù)庫增刪改查

    1、activity_main.xml 頁面布局 代碼 2、MainActivity.java 通過點擊不同的按鈕,進行不同的增刪改查操作 3、UserDao.java 包含對數(shù)據(jù)庫的增刪改查方法 4、User.java 實體類對應(yīng)著user表中的字段 5、SQLiteOpenHelper.java 創(chuàng)建表,更新表方法

    2023年04月08日
    瀏覽(17)
  • Android 數(shù)據(jù)庫之GreenDAO

    Android 數(shù)據(jù)庫之GreenDAO

    GreenDAO 是一款開源的面向 Android 的輕便、快捷的 ORM 框架,將 Java 對象映射到 SQLite 數(shù)據(jù)庫中,我們操作數(shù)據(jù)庫的時候,不再需要編寫復(fù)雜的 SQL語句, 在性能方面,greenDAO 針對 Android 進行了高度優(yōu)化,最小的內(nèi)存開銷 、依賴體積小 同時還是支持 數(shù)據(jù)庫加密。 greenDAO 官網(wǎng)地址

    2024年02月13日
    瀏覽(15)
  • python常用庫之?dāng)?shù)據(jù)庫orm框架之SQLAlchemy

    python常用庫之?dāng)?shù)據(jù)庫orm框架之SQLAlchemy

    官網(wǎng):https://www.sqlalchemy.org/ SQLAlchemy是一個基于Python實現(xiàn)的SQL工具包和ORM框架,提供了高層抽象來管理數(shù)據(jù)庫交互。 SQLAlchemy功能強大,可以省去很多手動管理數(shù)據(jù)庫連接、資源、事務(wù)等重復(fù)工作,讓開發(fā)者更加高效地使用數(shù)據(jù)庫。許多大型Python項目都選擇使用SQLAlchemy作為ORM框架

    2024年02月07日
    瀏覽(52)
  • 【Android】Room數(shù)據(jù)庫的使用

    Room 是在 SQLite 的基礎(chǔ)上推出的 Android 庫,它是 Google 官方對數(shù)據(jù)庫操作的推薦方式。使用 Room 可以更方便、高效地操作 SQLite 數(shù)據(jù)庫。 添加依賴 在使用 Room 之前,需要在項目中添加 Room 相關(guān)的依賴。在 build.gradle 文件中添加以下依賴: 在上面的依賴中,我們添加了 room-runti

    2024年02月09日
    瀏覽(25)
  • Android之SQLite數(shù)據(jù)庫使用

    Android之SQLite數(shù)據(jù)庫使用

    SQLite是Android系統(tǒng)集成的一個輕量級的數(shù)據(jù)庫。 Android提供了 SQLiteDatabase代表一個數(shù)據(jù)庫 (底層就是一個數(shù)據(jù)庫文件),一旦應(yīng)用程序獲得了代表指定數(shù)據(jù)庫的SQLiteDatabase對象,接下來可通過SQLiteDatabase對象來管理、操作數(shù)據(jù)庫了。 Android為了讓我們能夠更加方便地管理數(shù)據(jù)庫,

    2024年02月16日
    瀏覽(31)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包