Android数据库-- GreenDao

市面上的一些数据库框架:ORMLite、Afinal、ActiveAndroid、SugarORM、GreenDao、Realm
ORMLite

ActiviteAndroid

SugarORM

GreenDao

Realm

简单的介绍如下:

  1. OrmLite

OrmLite 不是 Android 平台专用的ORM框架,它是Java ORM。支持JDBC连接,Spring以及Android平台。语法中广泛使用了注解(Annotation)。

  1. SugarORM

SugarORM 是 Android 平台专用ORM。提供简单易学的APIs。可以很容易的处理1对1和1对多的关系型数据,并通过3个函数save(), delete() 和 find() (或者 findById()) 来简化CRUD基本操作。

  1. GreenDAO

当性能很重要时(数据访问频繁),GreenDao是一个很快的解决方案,它能够支持数千条记录的CRUD每秒,和OrmLite相比,GreenDAO要快几乎4.5倍。(准确数据请自行benchmark)。
GreenDAO小于100KB,所以对于应用程序APK的大小影响很小。

  1. Active Android

Active Record(活动目录)是Yii、Rails等框架中对ORM实现的典型命名方式。Active Android 帮助你以面向对象的方式来操作SQLite。
在你的项目中包含Active Android,你需要在项目的 /libs 目录下添加一个jar文件。可以从Github中获取源代码并使用Maven进行编辑。

  1. Realm

Realm 是一个将可以使用的Android ORM,基于C++编写,直接运行在你的设备硬件上(不需要被解释),因此运行很快。它同时是开源跨平台的,iOS的代码可以在GitHub找到,你还可以找到Objective C以及Swift编写的Realm使用实例。

 ArrayList<HashMap<String ,String>> list = new ArrayList<HashMap<String, String>>();
39 
40         /**Cursor是结果集游标,使用Cursou.moveToNext()方法可以从当前行移动到下一行**/
41         Cursor cursor = sqLiteDatabase.rawQuery(sql , bindArgs);
42         int clos_len = cursor.getColumnCount();                 //获取数据所有列数
43 
44         Log.i("TAG:","querySQLite()方法中获得总列数clos_len:" + clos_len);
45 
46         boolean isfals = cursor.moveToNext();
47         Log.i("TAG:","isfals值为:" + isfals);
48 
49         while(cursor.moveToNext()) {                            //循环表格中的每一行
50             Log.i("TAG:","进入到while循环中");
51 
52             HashMap<String , String> map = new HashMap<>();
53             for(int i = 0;i<clos_len;i++){                      //循环表格中的每一列
54                 String clos_name = cursor.getColumnName(i);     //从给定的索引i返回列名
55                 String clos_value = cursor.getString(cursor.getColumnIndex(clos_name));//返回指定的名称,没有就返回-1
56                 if(clos_value==null){
57                     clos_value = "";
58                 }
59 
60                 Log.i("TAG:","while循环下面的for循环拿到的数据clos_value为:"
61                         + cursor.getString(cursor.getColumnIndex(clos_name)));
62 
63                 map.put(clos_name , clos_value);
64             }
65             list.add(map);
66         }
67         return list;

特征:底层数据库都是基于开源的SQLite实现,然后在系统层封装成用于应用层的API,虽然直接使用系统的数据库API性能很高,但是这些API接口并不是很方便开发者使用,一不小心就会引入Bugs,而且代码的视觉效果也不好,为了解决这个问题,一系列的对象关系映射(ORM)框架出现

标题Greendao使用

定义:Greendao的本质是为存储在关系数据库Sqlite中的数据提供面向对象的界面,使用过程中,我们只需定义数据模型,而GreenDAO将创建Java数据对象(实体)和DAO(数据访问对象)。

特征:

1.对象/关系映射(ORM Object Relation mapping)

下面是一张对象关系映射图
在这里插入图片描述

2.微小的依赖库

GreenDao关键依赖库大小不超过100kb,So,也不会出现因为引入GreenDao而出现65k问题

3.自动生成代码

使用GreenDao,我们无需关注实体类以及Dao,GreenDao已为我们自动生成了

4.开源

GreenDao 更新日志
从2017年开始greendao这个项目已经没有更新了

使用:
1.配置Gradle

 classpath 'org.greenrobot:greendao-gradle-plugin:3.1.1'//add for greendao

2.添加应用插件

apply plugin: 'org.greenrobot.greendao'//add for greendao

3.添加库文件

implementation "org.greenrobot:greendao:3.1.1"

4.初始化Greendao的配置

greendao {
		        schemaVersion 66 (当前数据库版本)
		        daoPackage '包名.db.generator'(生成的Dao,DaoMaster和DaoSession的包名称)
		        targetGenDir 'src/main/java'(存储的位置,默认为构建目录( build / generated / source / greendao))
   			 }

注意点:当你的数据库在版本升级的时候会自动把表单进行删除,所以当你需要自己管理自己的数据库版本的时候,你需要自己实现DaoMaster.OpenHelper,来进行版本升级管理,有一个开源解决办法MigrationHelper类,可以用这个

5.编写所需要的实体类,然后build下就ok

	@Entity(nameInDb = "article_list")
		public class ArticleItemBean implements Parcelable, Cloneable {

		    @Id(autoincrement = true)
		    private Long id;
		    //去掉唯一键,
		    @Unique
		    public String newsId = "";
		    public double score;
		    public int template;
		    public int commentNum;
		    //下面我省略了一些代码,这是greendao自己生成的就不用管了
		    
   	 }

6.通过DaoSession来操作你写的数据库,举个例子根据newsid来进行查找

// 创建数据
        DaoMaster.DevOpenHelper devOpenHelper = new DaoMaster.DevOpenHelper(context, "article-db", null);
        DaoMaster daoMaster = new DaoMaster(devOpenHelper.getWritableDatabase());
        DaoSession daoSession = daoMaster.newSession();
        ArticleItemBeanDao dao = daoSession.getArticleItemBeanDao();
        //查找
          dao.queryBuilder().where(ArticleItemBeanDao.Properties.NewsId.eq(newsId)).unique();
        
        
        DaoMaster:保存数据库的对象并管理特定模式的Dao类,它具有静态方法来创建表或者将他们删除,一个DaoMaster就代表着一个数据库的连接
        
        DaoSession:管理特定模式的所有可用的Dao类,有一些方法,插入加载更新删除等操作,DaoSession可以创建多个,每一个都是属于同一个数据库的连接
        
        Dao层:数据访问对象持续存在并查询实体

7.注解,红色标记一般是常用的

在这里插入图片描述

源码分析:
1.创建数据库

DaoMaster.OpenHelper openHelper = new DaoMaster.OpenHelper(){...}
daoMaster = new DaoMaster(openHelper.getWritableDb());

主要看openHelper.getWritableDb()

进入到这个方法如下
public abstract class DatabaseOpenHelper extends SQLiteOpenHelper {
/**
     * Like {@link #getWritableDatabase()}, but returns a greenDAO abstraction of the database.
     * The backing DB is an standard {@link SQLiteDatabase}.
     */
    public Database getWritableDb() {
        return wrap(getWritableDatabase());
    }
}

在往下看getWritableDatabase()

public abstract class SQLiteOpenHelper{
public SQLiteDatabase getWritableDatabase() {
        synchronized (this) {
            return getDatabaseLocked(true);
        }
    }

private SQLiteDatabase getDatabaseLocked(boolean writable) {
        ///这是一系列异常判断可以直接忽略
                if (version > 0 && version < mMinimumSupportedVersion) {
                    File databaseFile = new File(db.getPath());
                    onBeforeDelete(db);
                    db.close();
                    if (SQLiteDatabase.deleteDatabase(databaseFile)) {
                        mIsInitializing = false;
                        return getDatabaseLocked(writable);
                    } else {
                        throw new IllegalStateException("Unable to delete obsolete database "
                                + mName + " with version " + version);
                    }
                } else {
                    db.beginTransaction();
                    try {
                        if (version == 0) {
                        //这里就是关键的地方创建表单了
                            onCreate(db);
                        } else {
                            if (version > mNewVersion) {
                                onDowngrade(db, version, mNewVersion);
                            } else {
                            //进行升级操作,自己在本地实现
                                onUpgrade(db, version, mNewVersion);
                            }
                        }
                        db.setVersion(mNewVersion);
                        db.setTransactionSuccessful();
                    } finally {
                        db.endTransaction();
                    }
                }
            }

            onOpen(db);

            if (db.isReadOnly()) {
                Log.w(TAG, "Opened " + mName + " in read-only mode");
            }

            mDatabase = db;
            return db;
        } finally {
            mIsInitializing = false;
            if (db != null && db != mDatabase) {
                db.close();
            }
        }
    }
}

在往下看
public class DaoMaster extends AbstractDaoMaster {
    public static final int SCHEMA_VERSION = 66;

    /** Creates underlying database table using DAOs. */
    public static void createAllTables(Database db, boolean ifNotExists) {
    //创建了一个个的表
        AppListBeanDao.createTable(db, ifNotExists);
    }
到此为止是把数据库中的表全部创建完全

然后将数据库的表与实体类进行关联
还是回到
daoMaster = new DaoMaster(openHelper.getWritableDb());

进入到DaoMaster的构造方法中
public DaoMaster(Database db) {
        super(db, SCHEMA_VERSION);
        registerDaoClass(AppListBeanDao.class);
    }

进入到registerDaoClass方法里
public abstract class AbstractDaoMaster {
    protected final Database db;
    protected final int schemaVersion;
    protected final Map<Class<? extends AbstractDao<?, ?>>, DaoConfig> daoConfigMap;

    public AbstractDaoMaster(Database db, int schemaVersion) {
        this.db = db;
        this.schemaVersion = schemaVersion;

        daoConfigMap = new HashMap<Class<? extends AbstractDao<?, ?>>, DaoConfig>();
    }

    protected void registerDaoClass(Class<? extends AbstractDao<?, ?>> daoClass) {
    //这个DaoConfig就是将数据库和实体类进行了关联
        DaoConfig daoConfig = new DaoConfig(db, daoClass);
        daoConfigMap.put(daoClass, daoConfig);
    }

2.DaoSeesion

DaoSession对象是通过master.newSession();创建的。DaoSession对象是连接GreenDao框架到SQLite数据库的纽带,通过该对象我们可以得到一个与数据库某个表相关的操作对象xxxDao

daoSession = getDaoMaster().newSession();

进入到newSession()这个方法里去
public class DaoMaster extends AbstractDaoMaster{
 public DaoSession newSession() {
        return new DaoSession(db, IdentityScopeType.Session, daoConfigMap);
    }
}
在往下看

public DaoSession(Database db, IdentityScopeType type, Map<Class<? extends AbstractDao<?, ?>>, DaoConfig>
            daoConfigMap) {
        super(db);

        appListBeanDaoConfig = daoConfigMap.get(AppListBeanDao.class).clone();
        appListBeanDaoConfig.initIdentityScope(type);
}

这个daoConfigMap保存了数据库db与实体类之间的联系,当我们用XXXDao类进行增删查改的时候对应的数据库也会进行对应的操作

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值