框架

Android 让你的数据库操作更便捷 --- GreenD

2017-01-21  本文已影响295人  手抓饼烧肉粽

你还在为数据库建表时那复杂而冗长的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部分源码

上一篇下一篇

猜你喜欢

热点阅读