Android 让你的数据库操作更便捷 --- GreenDao之初体验

你还在为数据库建表时那复杂而冗长的SQL语句烦恼么?

你还在为数据库存储时那频繁的put content values而感到焦躁么?

你还在为在数据库操作中只因为SQL语句中写错了一个字母而找了半天bug
而感到沮丧么?

快用GreenDao吧,解决以上各种疑难杂症,从此告别SQL语句。

回顾SQLiteDatabaseHelper

1.表的创建

如果你的数据库当中有20个数据模型,你要将以下面这段东西写20遍,还不带重样的- -。
If you type a wrong letter,loses the whole game

@Override 
 public void onCreate(SQLiteDatabase db) {      
          StringBuilder sb2 = new StringBuilder();
          sb2.append("CREATE TABLE "+ TABLE_NAME+ "(")
         .append("_id INTEGER PRIMARY KEY AUTOINCREMENT,")
         .append("it TEXT,")
         .append("is TEXT,")
         .append("too TEXT,")
         .append("painful TEXT,")
         .append("do INTEGER,")
         .append("you TEXT,")
         .append("think BIGINT,")
         .append("so INTEGER")
         .append(");");
         db.execSQL(sb2.toString());
  }
2.数据库的存储操作
//以写入模式获取数据存储库
SQLiteDatabase db = mDbHelper.getWritableDatabase();
//创建一个新的值映射,其中列名称是键
values.put(FeedEntry.COLUMN_NAME_TITLE, title);
values.put(FeedEntry.COLUMN_NAME_SUBTITLE, subtitle);
//插入新行,返回新行的主键值
long newRowId = db.insert(FeedEntry.TABLE_NAME, null, values);
3.数据库的查询
SQLiteDatabase db = mDbHelper.getReadableDatabase();
// 指定数据库中的哪些列
String[] projection = {FeedEntry._ID,    FeedEntry.COLUMN_NAME_TITLE,    FeedEntry.COLUMN_NAME_SUBTITLE    };
// 过滤title值为 'My Title'的数据
String selection = FeedEntry.COLUMN_NAME_TITLE + " = ?";
String[] selectionArgs = { "My Title" };
// 制定返回结果的排列顺序
String sortOrder =  FeedEntry.COLUMN_NAME_SUBTITLE + " DESC";
Cursor c = db.query(FeedEntry.TABLE_NAME,                     // 你要查询的表
        projection,                               // 要返回的列
        selection,                                //定义的数据过滤规则
        selectionArgs,                            // 过滤后返回的参数
        null,                                     // 不对行进行分组  
        null,                                     //不按照行分的组过滤数据  
        sortOrder                                 // 定义的排序规则    );
cursor.moveToFirst();
long itemId = cursor.getLong(cursor.getColumnIndexOrThrow(FeedEntry._ID));
4.数据库的删除
// 定义查询位置
String selection = FeedEntry.COLUMN_NAME_TITLE + " LIKE ?";
// 制定要删除的参数(既title = 'MyTitle')
String[] selectionArgs = { "MyTitle" };
// 对应的删除操作
db.delete(FeedEntry.TABLE_NAME, selection, selectionArgs)
5.数据库的更新
SQLiteDatabase db = mDbHelper.getReadableDatabase();
// 定义要更新的值
ContentValues values = new ContentValues();
values.put(FeedEntry.COLUMN_NAME_TITLE, title);
//根据过滤调制定制要更新的列
String selection = FeedEntry.COLUMN_NAME_TITLE + " LIKE ?";
String[] selectionArgs = { "MyTitle" };
int count = db.update(FeedReaderDbHelper.FeedEntry.TABLE_NAME,values, selection,selectionArgs);

当然你也可以直接通过SQL语句进行相关操作

SQLiteDatabase db = mDbHelper.getReadableDatabase();
db.getReadableDatabase().execSQL(your sql?);  //执行增删改查的SQL语句

GreenDao是什么?

一言以蔽之,greenDAO就是一个开源的Android ORM(对象关系映射)框架,使SQLite数据库的开发变得简单,便捷。而且在性能上greenDao也做了很大的优化。该文章主要是介绍如何使用greenDao。(毕竟该发挥拿来主义的时候就要发挥- -)

GreenDao的使用

1.Android Studio中的配置

① app目录下build.grandle的配置

dependencies依赖:

dependencies {  
       compile 'org.greenrobot:greendao:3.1.0'  
 }

在android的根下添加:

android {  
    greendao{     
         schemaVersion 1     //控制数据库版本,若数据库结构发生改变,更改此处版本号
         targetGenDir 'src/main/java' 
   }
}

并在最上方添加对应的plugin
apply plugin: 'org.greenrobot.greendao'

② 工程根目录下目录下build.grandle的配置

buildscript {   
     repositories {     
         jcenter()  
      }  
      dependencies {  
          classpath 'com.android.tools.build:gradle:2.2.0'     
           classpath 'org.greenrobot:greendao-gradle-plugin:3.1.0'      
     }
}

2.创建一张新的表
1.首先你要先创建一个新的类。并未类的属性标上对应的注解
@Entity代表你所要创建表的实体
@Id表示数据库的主键
@Property表示该实体里对应的属性(也就是字段)

@Entity
public class Singer {   
       @Id    
       private Long id;         //主键
       @Property         
       private String name;  
       @Property   
       private String sex;   
       @Property   
       private String country;
}

2.自动生成对应的DaoSession和DaoMater文件

之后双击 Build 一栏下的 Make Moudle app


编译完成后你会发现你的项目结构发生了如下变化:

我们回发现Studio自动帮我们生成了DaoMasterDaoSessionSinger的实体操作类SingerDao

3.GreenDao是如何工作的?
(此处只是简单的介绍一下GreenDao的工作原理,以及粗略的剖析一下源码,没兴趣的哥(姐)们儿直接可直接忽略此小节)

这里先简单的介绍一下这三个东西。

*** - DaoMaster***
greenDAO的入口点。 DaoMaster保存数据库对象(SQLiteDatabase)并管理特定模式的DAO类(而不是对象)。它有静态方法来创建表或删除它们。它的内部类OpenHelper和DevOpenHelper的底层依旧由SQLiteOpenHelper实现,在SQLite数据库中创建数据库,具体可以查看DaoMaster的源码。以下贴出部分源码

/**DaoMaster源码**********************************/
public class DaoMaster extends AbstractDaoMaster {
      //此处为数据库版本号
       public static final int SCHEMA_VERSION = 1;
      //此处也可自己定义一个类去继承OpenHelper
      public static class DevOpenHelper extends OpenHelper {
               public DevOpenHelper(Context context, String name, CursorFactory factory) {
                      super(context, name, factory);
               }
        }

        public static abstract class OpenHelper extends DatabaseOpenHelper {
                  public OpenHelper(Context context, String name, CursorFactory factory) {
                  super(context, name, factory, SCHEMA_VERSION);
        }
      }
}

/*DatabaseOpenHelper 源码***********************************/

public abstract class DatabaseOpenHelper extends SQLiteOpenHelper{
         public DatabaseOpenHelper(Context context, String name, CursorFactory factory, int version) {
                  super(context, name, factory, version);
                  this.context = context;
                  this.name = name;
                  this.version = version;
    }
}

-DaoSession
管理特定模式的所有可用DAO对象,您可以使用其中一个getter方法获取它们。 DaoSession还为实体提供了一些通用的持久性方法,如插入,加载,更新,刷新和删除。以下为DaoSession源码

public class DaoSession extends AbstractDaoSession {

    private final DaoConfig singerDaoConfig;

    private final SingerDao singerDao;

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

        singerDaoConfig = daoConfigMap.get(SingerDao.class).clone();
        singerDaoConfig.initIdentityScope(type);
        //创建对应的DAO对象
        singerDao = new SingerDao(singerDaoConfig, this);
        //将DAO对象与Singer绑定起来
        registerDao(Singer.class, singerDao);
    }

    /**获取对应的DAO对象*/  
    public SingerDao getSingerDao() {
        return singerDao;
    }

}

-SingerDao
这个我想不必过多介绍,相信接触过数据库操作的各位亲们都不会对它陌生,接下来让我们简单的看以它的部分代码

public class SingerDao extends AbstractDao<Singer, Long> {

    public static void createTable(Database db, boolean ifNotExists) {
        String constraint = ifNotExists? "IF NOT EXISTS ": "";
        db.execSQL("CREATE TABLE " + constraint + "\"SINGER\" (" + //
                "\"_id\" INTEGER PRIMARY KEY ," + // 0: id
                "\"NAME\" TEXT," + // 1: name
                "\"SEX\" TEXT," + // 2: sex
                "\"COUNTRY\" TEXT);"); // 3: country
    }
}

我们会发现在这个类已经帮我们把表创建好了,关键是不需要你写一句SQL语句,你要想创建20张表的话只要写上20个数据模型并标上对应的属性值就可以了。这里会被DaoMaster调用。

public class DaoMaster extends AbstractDaoMaster {
    public static void createAllTables(Database db, boolean ifNotExists) {
        //此处调用
        SingerDao.createTable(db, ifNotExists);
    }
}

那他又是如何实现增删改查的呢?我们这里已增加数据为例,其余同理,可查看源码:
从SingerDao的源码我们可以看到它是继承自AbstractDao。我们来粗略的看一下内部进行了怎样实现的。

public abstract class AbstractDao<T, K> {
    public long insert(T entity) {
        return executeInsert(entity, statements.getInsertStatement(), true);
    }
}

public class TableStatements {
    public DatabaseStatement getInsertStatement() {
        if (insertStatement == null) {
            //sql语句的拼接
            String sql = SqlUtils.createSqlInsert("INSERT INTO ", tablename, allColumns);
            DatabaseStatement newInsertStatement = db.compileStatement(sql);
            synchronized (this) {
                if (insertStatement == null) {
                    insertStatement = newInsertStatement;
                }
            }
            if (insertStatement != newInsertStatement) {
                newInsertStatement.close();
            }
        }
        return insertStatement;
    }
}

public class SqlUtils {
    public static String createSqlInsert(String insertInto, String tablename, String[] columns) {
        StringBuilder builder = new StringBuilder(insertInto);
        builder.append('"').append(tablename).append('"').append(" (");
        appendColumns(builder, columns);
        builder.append(") VALUES (");
        appendPlaceholders(builder, columns.length);
        builder.append(')');
        return builder.toString();
    }
}

我们会发现,到最后,他还是将所有的参数拼成了一句添加的sql。GreenDao的内部都已经帮你实现好了。而我们在外部只需要简单的调用一句即可。
singerDao.insert(new Singer(null, "周杰伦", "男", "中国"));

4.GreenDao的简单操作

①在Application中的配置

public class MyApplication extends Application {

    public static final String TAG = MyApplication.class.getSimpleName();
    private static Context mContext;
    public SQLiteDatabase db;
    public DaoSession daoSession;
    public DaoMaster.DevOpenHelper helper;
    public DaoMaster daoMaster;

    @Override
    public void onCreate() {
        super.onCreate();
        mContext = getApplicationContext();
        setupDatabase();
    }

    /**数据库的配置*/
    private void setupDatabase() {
        //此处的Helper可自定义
        helper = new DaoMaster.DevOpenHelper(this, "green_dao_demo.db", null);
        db = helper.getWritableDatabase();
        // 注意:该数据库连接属于 DaoMaster,所以多个 Session 指的是相同的数据库连接。
        daoMaster = new DaoMaster(db);
        daoSession = daoMaster.newSession();
    }

    public static Context getContext() {
        return mContext;
    }

    public DaoSession getDaoSession() {
        return daoSession;
    }

    public SQLiteDatabase getDb() {
        return db;
    }
}

②获取Dao对象

    SingerDao singerDao = ((MyApplication) getActivity()
                    .getApplicationContext())
                    .getDaoSession()
                    .getSingerDao();

-添加数据

           Singer singer = new Singer(null, name, age, country);
            singerDao.insert(singer);

-查询数据

    public List<Singer> getSingerList(String country) {
        if (!TextUtils.isEmpty(country)) {
            List<Singer> singers = getSingerDao()       
                    .queryBuilder()
                    .where(SingerDao.Properties.Country.eq(country))  //判断条件
                    .orderDesc()                                     //排序顺序
                    .build()
                    .list();                                     //生成对应的list
            return singers;
        }
        return null;
      }

-更新数据

        //通过主键更新数据
        singerDao.update(new Singer(Loing.valueOf(id),name, sex, country));
        //常规更新
        singer.setName(name);
        singer.setSex(sex);
        singer.setCountry(country);
        singerDao.update(singer);

-删除数据

   //通过主键删除
  singerDao.deleteByKey(Long.valueOf(singer.getId()));
   //常规删除
  singerDao.delete(singer);

-批量操作

  singerDao.insertInTx(singers); // 批量添加
 singerDao.updateInTx(singers); // 批量更新
singerDao.deleteInTx(singers); //批量删除

项目示例地址

https://github.com/HandGrab/GreenDaoDemo

参考:
GreenDao官网:http://greenrobot.org/greendao/
GreenDao部分源码

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,319评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,801评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,567评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,156评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,019评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,090评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,500评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,192评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,474评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,566评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,338评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,212评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,572评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,890评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,169评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,478评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,661评论 2 335

推荐阅读更多精彩内容

  • 一、关于greenDAO greenDAO应该算是当前最火的数据库开源框架了,它是一个将对象映射到SQLite数据...
    当幸福来敲门58阅读 13,834评论 3 19
  • (一)GreenDao简介 GreenDao是一个对象关系映射(ORM)的开源框架,目前最主流的安卓数据库操作框架...
    miss2008阅读 5,213评论 4 18
  • GreenDao 介绍:greenDAO是一个对象关系映射(ORM)的框架,能够提供一个接口通过操作对象的方式去操...
    小董666阅读 715评论 0 1
  • 前言 最近的项目需要使用到数据库,本来想用Sqlite数据来做的,但是听同事说使用Greendao数据库是真的好用...
    Smile__EveryDay阅读 3,599评论 2 7
  • iOS开发中应用的横竖屏在项目中就可以设置App支持的旋转方向,这是全局控制的一种方法,代码的实现是以下三个方法:...
    轻云_阅读 3,367评论 1 4