美文网首页
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