美文网首页框架
Android 让你的数据库操作更便捷 --- GreenD

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

作者: 手抓饼烧肉粽 | 来源:发表于2017-01-21 16:39 被阅读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部分源码

    相关文章

      网友评论

      本文标题:Android 让你的数据库操作更便捷 --- GreenD

      本文链接:https://www.haomeiwen.com/subject/iirrbttx.html