美文网首页
greendao 的使用

greendao 的使用

作者: sunjiandev | 来源:发表于2019-11-07 20:32 被阅读0次

    greendao 的使用

    参考文章一篇技术好文之Android数据库 GreenDao的使用完全解析

    在Android 中的数据库操作,除了Android 原生的SqliteOpenHelper 之外,还有许多优秀的三方框架可以使用,比如GreenDao, OrmLite,ActiveAndroid,以及Litepal,都是比较不错的.无论是从性能上还是,使用难度上,都是比较友好的!其中GreenDao尤其出众,使用者众多,好评一片.之前一直用的都是Litepal,专门学习一下,特此记录

    greendao 中核心操作数据库的类说明

    • DaoMaster

      DaoMaster保存数据库对象(SQLiteDatabase)并管理特定模式的DAO类(而不是对象)。它有静态方法来创建表或删除它们。它的内部类OpenHelper和DevOpenHelper是SQLiteOpenHelper实现,它们在SQLite数据库中创建模式。

    • DaoSession

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

    • XXXDao

      数据访问对象(DAO)持久存在并查询实体。对于每个实体,greenDAO生成DAO。它具有比DaoSession更多的持久性方法,例如:count,loadAll和insertInTx。

    这几个类都会自动生成在build.gradle内指定的目录下

    集成

    在project 的build.gradle中添加以下内容:

      dependencies {
            classpath 'com.android.tools.build:gradle:3.4.1'
            classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2' // add plugin
         
        }
    

    然后在moudle 的build.gradle中添加如下内容:

    apply plugin: 'org.greenrobot.greendao' // apply plugin
    
    android{
        ...
         greendao{
            schemaVersion 1 //数据库的版本
            daoPackage 'com.sunkaisens.ffmpegtest.greendao'//greendao 自动生成的辅助类
            targetGenDir 'src/main/java'//固定目录
        }
        
    }
    ...
    
    dependencies {
        implementation 'org.greenrobot:greendao:3.2.2' // add library
    }
    
    

    至此,集成完毕

    还需要在Application 中进行初始化操作,
    内容如下:

    public class MyApp extends Application {
    
        private static final String DATANAME_NAME = "sunkaisens.db";//数据库名称
        private static DaoSession daoSession;
    
        @Override
        public void onCreate() {
            super.onCreate();
    
            initDaoSession();
        }
    
        private void initDaoSession() {
    
            DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(this, DATANAME_NAME);
            SQLiteDatabase database = helper.getWritableDatabase();
            DaoMaster daoMaster = new DaoMaster(database);
            daoSession = daoMaster.newSession();
    
        }
        public static DaoSession getSession() {
            return daoSession;
        }
    }
    
    

    记得在manifests文件中声名.name属性

    操作数据库

    先说明以下greendao 对象映射的一些注解说明,参考GreenDao3 api、注解说明

    • @Entity

      指定一个数据库实体

    public @interface Entity {  
      
        /** 
         * 在数据库中表的名称,默认为实体的类名 
         */  
        String nameInDb() default "";  
      
        /** 
         *  定义索引,可以跨越多个列(默认为实体类成员变量的个数) 
         */  
        Index[] indexes() default {};  
      
        /** 
         * 标记创建数据库表 
         * 若一个表映射多个实体类或者创建表外应的GreenDao,设置为false 
         */  
        boolean createInDb() default true;  
      
        /** 
         *  告知GreenDao当前实体属于哪个schema 
         */  
        String schema() default "default";  
      
        /** 
         *  实体活动状体标志位(默认为false) 
         *  若设置为true,实体有更新、删除和刷新方法 
         */  
        boolean active() default false;  
    }  
    
    
    • @Convert:

      这个类十分有用,可以将数据库中字段类型与entity中的类型进行你需要的转换

    public @interface Convert {  
        /** 转换类*/  
        Class<? extends PropertyConverter> converter();  
      
        /** 
         * 在数据库中持久化的列 
         * 此受限于GreenDao所支持的类 
         */  
        Class columnType();  
    }  
    
    
    • @Id

      设置主键 Long型,可以通过@Id(autoincrement = true)设置自增长。通过这个注解标记的字段必须是Long,数据库中表示它就是主键,并且默认是自增的。

    public @interface Id {  
        /** 
          * 设置是否为自增长,默认为false 
          */  
        boolean autoincrement() default false;  
    }  
    
    
    • @Index

    使用@Index作为一个属性来创建一个索引;定义多列索引(@link Entity#indexes())

    public @interface Index {  
        /** 
         * 通过逗号间隔创建表的属性索引,例如 “propertyA,propertyB,propertyC” 
         * 若要指定排序, 需在列明以后添加 ASC(升序) 或者DESC(降序) ,  例如 "propertyA DESC, propertyB ASC" 
         *  只有实体类中使用 {@link Entity#indexes()} 才可设置 
         */  
        String value() default "";  
      
        /** 
         * 表的可选索引 
         * 默认为实体类中的成员变量 
         */  
        String name() default "";  
      
        /** 
         * 是否为属性设置唯一属性,默认为false 
         */  
        boolean unique() default false;  
    }  
    
    
    • @JoinEntity

    定义表连接关系

    public @interface JoinEntity {  
        /** 添加的实体类 */  
        Class<?> entity();  
      
        /** 源表的列索引 */  
        String sourceProperty();  
      
        /** 连接表内拥有源实体的属性*/  
        String targetProperty();  
    }  
    
    
    • @JoinProperty

    定义名称和引用名称属性关系

    public @interface JoinProperty {  
        /** 实体中的名称,对应于引用的名称 */  
        String name();  
      
        /** 引用的名称 */  
        String referencedName();  
    }  
    
    
    • @OrderBy

    排序

    public @interface OrderBy {  
        /** 
         * 通过逗号间隔创建表的属性索引,例如 “propertyA,propertyB,propertyC” 
         * 若要指定排序, 需在列明以后添加 ASC(升序) 或者DESC(降序) ,  例如 "propertyA DESC, propertyB ASC" 
         *  默认按升序排序 
         *  若不设置默认根据主键排序 
         */  
        String value() default "";  
    }  
    
    
    • @Property

    指定数据库数据字段名

    @Retention(RetentionPolicy.SOURCE)
    @Target(ElementType.FIELD)
    public @interface Property {
        /**
         * Name of the database column for this property. Default is field name.
         */
        String nameInDb() default "";
    }
    
    
    • @Unique

    向数据库列添加了一个唯一的约束

    • @Transient

    表明这个字段不会被写入数据库,只是作为一个属性存在

    函数说明:

    void    attachEntity(T entity):  
      
    long    count():获取数据库中数据的数量  
      
    // 数据删除相关  
    void    delete(T entity):从数据库中删除给定的实体  
    void    deleteAll() :删除数据库中全部数据  
    void    deleteByKey(K key):从数据库中删除给定Key所对应的实体  
    void    deleteByKeyInTx(java.lang.Iterable<K> keys):使用事务操作删除数据库中给定的所有key所对应的实体  
    void    deleteByKeyInTx(K... keys):使用事务操作删除数据库中给定的所有key所对应的实体  
    void    deleteInTx(java.lang.Iterable<T> entities):使用事务操作删除数据库中给定实体集合中的实体  
    void    deleteInTx(T... entities):使用事务操作删除数据库中给定的实体  
      
    // 数据插入相关  
    long    insert(T entity):将给定的实体插入数据库  
    void    insertInTx(java.lang.Iterable<T> entities):使用事务操作,将给定的实体集合插入数据库  
    void    insertInTx(java.lang.Iterable<T> entities, boolean setPrimaryKey):使用事务操作,将给定的实体集合插入数据库,  
                                                                                                                    并设置是否设定主键  
    void    insertInTx(T... entities):将给定的实体插入数据库  
    long    insertOrReplace(T entity):将给定的实体插入数据库,若此实体类存在,则覆盖  
    void    insertOrReplaceInTx(java.lang.Iterable<T> entities):使用事务操作,将给定的实体插入数据库,若此实体类存在,则覆盖  
    void    insertOrReplaceInTx(java.lang.Iterable<T> entities, boolean setPrimaryKey):使用事务操作,将给定的实体插入数据库,若此实体类存在,则覆盖  
                                                                                                                                并设置是否设定主键  
    void    insertOrReplaceInTx(T... entities):使用事务操作,将给定的实体插入数据库,若此实体类存在,则覆盖  
    long    insertWithoutSettingPk(T entity):将给定的实体插入数据库,但不设定主键  
      
    // 新增数据插入相关API  
    void    save(T entity):将给定的实体插入数据库,若此实体类存在,则更新  
    void    saveInTx(java.lang.Iterable<T> entities):将给定的实体插入数据库,若此实体类存在,则更新  
    void    saveInTx(T... entities):使用事务操作,将给定的实体插入数据库,若此实体类存在,则更新  
      
    // 加载相关  
    T   load(K key):加载给定主键的实体  
    java.util.List<T>     loadAll():加载数据库中所有的实体  
    protected java.util.List<T>   loadAllAndCloseCursor(android.database.Cursor cursor) :从cursor中读取、返回实体的列表,并关闭该cursor  
    protected java.util.List<T>   loadAllFromCursor(android.database.Cursor cursor):从cursor中读取、返回实体的列表  
    T   loadByRowId(long rowId) :加载某一行并返回该行的实体  
    protected T     loadUnique(android.database.Cursor cursor) :从cursor中读取、返回唯一实体  
    protected T     loadUniqueAndCloseCursor(android.database.Cursor cursor) :从cursor中读取、返回唯一实体,并关闭该cursor  
      
    //更新数据  
    void    update(T entity) :更新给定的实体  
    protected void  updateInsideSynchronized(T entity, DatabaseStatement stmt, boolean lock)   
    protected void  updateInsideSynchronized(T entity, android.database.sqlite.SQLiteStatement stmt, boolean lock)   
    void    updateInTx(java.lang.Iterable<T> entities) :使用事务操作,更新给定的实体  
    void    updateInTx(T... entities):使用事务操作,更新给定的实体 
    
    

    举例:

    @Entity()
    public class User {
    
        @Id(autoincrement = true)
        private Long id;
    
        @NotNull //不能为空
        @Unique //唯一
        @Property(nameInDb = "username")
        private String name;
    
    
        @NotNull
        @Unique
        @Property(nameInDb = "userage")
        private int age;
    
        @Transient //表明这个字段不会被写入数据库,只是作为一个属性存在
        private String like;
    
        @Generated(hash = 955858333)
        public User(Long id, @NotNull String name, int age) {
            this.id = id;
            this.name = name;
            this.age = age;
        }
    
        @Generated(hash = 586692638)
        public User() {
        }
    
        public Long getId() {
            return this.id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    
        public String getName() {
            return this.name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return this.age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "User{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    ", age=" + age +
                    ", like='" + like + '\'' +
                    '}';
        }
    }
    
    ...
    
    //插入数据
     User user = new User(null, "张三", 23);
     long insert =MyApp.getSession().getUserDao().insertOrReplace(user);
    //删除数据
    MyApp.getSession().getUserDao().delete(user);
    MyApp.getSession().getUserDao().deleteAll();
    
    如果需要按条件删除,可以先按条件查询:
    //查询 age >= 26 的 user
     List<User> userList = userDao.queryBuilder().where(UserDao.Properties.Age.ge(26)).list();
    
    然后遍历集合删除即可
    
    修改 同理,先查出数据然后修改数据,在更新
     //取出符合条件的唯一数据,必须保证比对的条件在数据库内是唯一的,不然会报错
     User unique = userDao.queryBuilder().where(UserDao.Properties.Name.eq("value")).unique();
     unique.setAge(44);
     userDao.update(unique);
    
    
    

    QueryBuilder的使用

    QueryBuilder的常见方法:

    • where(WhereCondition cond, WhereCondition... condMore): 查询条件,参数为查询的条件!
    • or(WhereCondition cond1, WhereCondition cond2, WhereCondition... condMore): 嵌套条件或者,用法同or。
    • and(WhereCondition cond1, WhereCondition cond2, WhereCondition... condMore): 嵌套条件且,用法同and。
    • join(Property sourceProperty, Class<J> destinationEntityClass):多表查询,后面会讲。
      输出结果有四种方式,选择其中一种最适合的即可,list()返回值是List,而其他三种返回值均实现Closeable,需要注意的不使用数据时游标的关闭操作:
    • list ()所有实体都加载到内存中。结果通常是一个没有魔法的 ArrayList。最容易使用。
    • listLazy ()实体按需加载到内存中。首次访问列表中的元素后,将加载并缓存该元素以供将来使用。必须关闭。
    • listLazyUncached ()实体的“虚拟”列表:对列表元素的任何访问都会导致从数据库加载其数据。必须关闭。
    • listIterator ()让我们通过按需加载数据(懒惰)来迭代结果。数据未缓存。必须关闭。
    • orderAsc() 按某个属性升序排;
    • orderDesc() 按某个属性降序排;

    GreenDao中SQL语句的缩写,我们也了解下,源码在Property中,使用的时候可以自己点进去查询即可:

    • 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" 不为空;

    相关文章

      网友评论

          本文标题:greendao 的使用

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