5.1 Greendao使用

1.概述

ORM(Object Relation Mapping 即 对象关系映射),就是将面向对象编程语言里的对象与数据库关联起来的一种技术,而greenDao就是实现这种技术之一,所以说greenDao其实就是一种将java object 与SQLite Database关联起来的桥梁,它们之间的关系 如下图所示;
在这里插入图片描述

2.优点

greenDao可以说是当今最流行,最高效而且还在迭代的关系型数据库。而且greenDao3.0还支持RxJava操作,greenDao如此受欢迎离不开以下几点:

  • 存取速度快
    每秒中可以操作数千个实体 下图是几种常见关系型数据库性能比较;

  • 支持数据库加密
    支持android原生的数据库SQLite,也支持SQLCipher(在SQLite基础上加密型数据库)。

  • 轻量级
    greenDao的代码库仅仅100k大小

  • 激活实体
    处于激活状态下的实体可以有更多操作方法

  • 支持缓存
    能够将使用的过的实体存在缓存中,下次使用时可以直接从缓存中取,这样可以使性能提高N个数量级

  • 代码自动生成
    greenDao 会根据modle类自动生成实体类(entities)和Dao对象,并且Dao对象是根据entities类量身定做的并且一 一对应。

3.配置

Project下的build.gradle文件加入

dependencies {
    //greenDao生产代码插件 步骤2
    classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2' // add plugin
}

Module下的build.gradle文件加入

apply plugin: 'org.greenrobot.greendao' // apply plugin 步骤3
android {
...
    //greendao配置 步骤5
    greendao {
        //数据库版本号,升级时修改
        schemaVersion 1
        //生成的DAO,DaoMaster和DaoSession的包路径。默认与表实体所在的包路径相同
        daoPackage 'com.example.xts.greendaodemo.db'
        //生成源文件的路径。默认源文件目录是在build目录中的(build/generated/source/greendao)
        targetGenDir 'src/main/java'
    }
}

dependencies {
    //greenDAO配置 步骤4
    implementation 'org.greenrobot:greendao:3.2.2' // add library
    implementation 'org.greenrobot:greendao-generator:3.2.2'
}

创建实体对象

@Entity
public class Bean {
@Id
private Long id;
private String date;
@Unique
private String key;
private int step;
....
}

注意:编写完实体类以后在实体类界面下按下Ctrl+F9(Make project),程序会自动编译生成dao文件,生成的文件一共有三个。

4.核心类

  • DaoMaster
    是GreenDao的入口也是greenDao顶级对象,对于一个指定的表单持有数据库对象(SQLite数据库)并且能够管理DAO类,能够创建表和删除表,其内部类OpenHelper 与DevOpenHelper是创建SQlite数据库的SQLiteOpenHelper的具体实现
  • DaoSession
    对于一个指定的表单可以管理所有的Dao 对象。也能够对实体类执行 insert ,load,update,refresh.delete操作。DaoSession也能跟踪 identity scope:即session查询后的实体会存在缓存中,并给该实体生成一个flag来追踪该实体,下次再次查询时会直接从缓存中取出来而不是从数据库中取出来
  • DAO
    能够持久访问和查询实体类,比起DaoSession有更多的持久化方法 count, loadAll,insertInt等等;Entities - 可持久化对象, 通常,实体是使用标准Java属性(如POJO或JavaBean)表示数据库行的对象。

5.注解

@Entity

告诉GreenDao 该Bean类需要持久化。只有使用@Entity注释的Bean类才能被dao类操作; @Entity可以在不使用参数下使用

  • schema
    指定实体的架构的名称,geenDao可以为每个架构生成独立的类集。多个实体属于不同的架构时,他们之间应该没有关联性。注意:gradle插件不适合多架构模式. 详见:https://greenrobot.org/greendao/documentation/modelling-entities/
 	/**
     * Specifies schema name for the entity: greenDAO can generate independent sets of classes for each schema.
     * Entities which belong to different schemas should <strong>not</strong> have relations.
     */
    String schema() default "default";
  • active = true,
    该实体属于激活状态,激活状态的实体有更新,删除,刷新方法;

  • nameInDb = “AWESOME_USERS”
    给这个表指定一个名字,默认情况下是名字是类名

  • indexes = { @Index(value = “name DESC”, unique = true) },
    // 可以给多个属性定义索引和其他属性.

  • createInDb = false,
    是否使用GreenDao创建该表,默认为true,false时不创建

  • generateConstructors = true
    是否所有的属性构造器都应该被生成,无参构造器总是被要求

  • generateGettersSetters = true
    如果该类中没有set get方法是否自动生成

  • protobuf
    把对象转换成protobuf形式的数据

@Id

一般会选择Long属性作为Entity ID(即数据库中的主键)

autoincrement (默认 false) 表示主键会自增如果false就会使用旧值

@Index

官方解释用于两个地方:

 * Can be used to:
 * - specifies that the property should be indexed
 * - define multi-column index through {@link Entity#indexes()}

1.定义索引的属性
2.定义多列索引在indexes()

name :不使用默认名称,自定义索引名称
value:指定字段的名称
unique : 给索引增加一个唯一约束,迫使该值唯一

@Covert

数据类型的转换

   @Convert(converter = NoteTypeConverter.class, columnType = String.class)
    private NoteType type;

public enum NoteType {
    TEXT, LIST, PICTURE
}

public class NoteTypeConverter implements PropertyConverter<NoteType, String> {
    @Override
    public NoteType convertToEntityProperty(String databaseValue) {
        return NoteType.valueOf(databaseValue);
    }

    @Override
    public String convertToDatabaseValue(NoteType entityProperty) {
        return entityProperty.name();
    }
}

@NotNUll

不能为null

@OrderBy

排序行为 “propertyA DESC, propertyB ASC”

@Propertry

定义属性名称 String nameInDb() default “”;

@Transient

禁止修饰的字段生成表里得列

@Unique

修改对象的数据唯一性

@ToOne

建立一对一 ( 1 : 1) 关系

@Entity
public class Order {
    @Id 
    private Long id;

    private long customerId;

    @ToOne(joinProperty = "customerId")
    private Customer customer;
}

@Entity
public class Customer {
    @Id 
    private Long id;
}

@ToMany

建立一对多 (1:N ) 关系

@Entity
public class Customer {
    @Id 
    private Long id;

    @ToMany(referencedJoinProperty = "customerId")
    @OrderBy("date ASC")
    private List orders;
}

@Entity
public class Order {
    @Id private Long id;
    private Date date;
    private long customerId;
}

@JoinEntity

建立多对多(N : M)关系

@Entity
public class Product {
    @Id private Long id;

    @ToMany
    @JoinEntity(
            entity = JoinProductsWithOrders.class,
            sourceProperty = "productId",
            targetProperty = "orderId"
    )
    private List ordersWithThisProduct;
}

@Entity
public class JoinProductsWithOrders {
    @Id private Long id;
    private Long productId;
    private Long orderId;
}

@Entity
public class Order {
    @Id private Long id;
}

@JoinProperty

主要适用与ToMany


@Entity
public class User {
    @Id private Long id;
    @Unique private String authorTag;
 
    @ToMany(joinProperties = {  @JoinProperty(name = "authorTag", referencedName = "ownerTag")
    })
    private List<Site> ownedSites;
}
 
@Entity
public class Site {
    @Id private Long id;
    @NotNull private String ownerTag;
}

@Keep

修饰字段和方法,类型在重新运行生成对象的时候保持不变

6.数据库初始化及操作

6.1初始化

创建一个application类,在application中完成DaoSession的初始化,避免以后重复初始化,便于使用。

public class BaseApp extends Application {private static BaseApp sInstance;
    private DaoMaster.DevOpenHelper mHelper;
    private DaoMaster mDaoMaster;
    private DaoSession mDaoSession;@Override
    public void onCreate() {
        super.onCreate();
        sInstance = this;
        setDatabase();
    }/**
     * 设置greenDao
     */
    private void setDatabase() {
        //通过DaoMaster内部类DevOpenHelper可以获取一个SQLiteOpenHelper 对象
        // 可能你已经注意到了,你并不需要去编写「CREATE TABLE」这样的 SQL 语句,因为 greenDAO 已经帮你做了。
        // 注意:默认的 DaoMaster.DevOpenHelper 会在数据库升级时,删除所有的表,意味着这将导致数据的丢失。
        // 所以,在正式的项目中,你还应该做一层封装,来实现数据库的安全升级。
        // 此处MyDb表示数据库名称 可以任意填写
​
        mHelper = new DaoMaster.DevOpenHelper(this, "MyDb", null);
        SQLiteDatabase db = mHelper.getWritableDatabase();
        mDaoMaster = new DaoMaster(db);
        mDaoSession = mDaoMaster.newSession();
    }public static BaseApp getInstance(){
        return sInstance;
    }public DaoSession getDaoSession(){
        return mDaoSession;
    }
}

//获取xxxDao对象

private BeanDao mBeanDao = BaseApp.getInstance().getDaoSession().getBeanDao();

6.1 插入数据

        //插入一条数据
        //mBeanDao.insert(new Bean(...));
        //插入多条数据
        //mBeanDao.insertInTx();
        //插入或者替换,如果不存在就插入,存在就修改(insert+update)
        //mBeanDao.insertOrReplace(new Bean(...));//插入或替换多条数据
        //mBeanDao.insertOrReplaceInTx(beans);

6.2 删除数据

//删除一条数据
mBeanDao.delete(new Bean(100l, date, 12+"",10));
//删除一条数据,根据key也就是id
//mBeanDao.deleteByKey();
//删除所有数据
// mBeanDao.deleteAll();
//删除一组数据(对象)
//mBeanDao.deleteInTx();
//删除一组数据(根据id)
//mBeanDao.deleteByKeyInTx();

6.3 修改数据

//更新一条数据
//mBeanDao.update(new Bean(1l, date, 1800));
//更新一组数据,没有对应id的不做处理
ArrayList beans = new ArrayList<>();
for (int i = 0; i < 5; i++) {
beans.add(new Bean((long)i,new Date().toString(),i+10+"",i+100));
}
mBeanDao.updateInTx(beans);

6.4 查询数据

        //查询所有
        //List<Bean> list = mBeanDao.queryBuilder().list();
        List<Bean> list = mBeanDao.loadAll();//精确查找
        Bean unique = mBeanDao.queryBuilder().where(BeanDao.Properties.Key.eq("2")).unique();//精确查找
        /*List<Bean> list2 = mBeanDao.queryBuilder().where(BeanDao.Properties.Step.eq(100)).list();
      */
        //模糊查找,查找以1打头的key
        /*List<Bean> list2 = mBeanDao.queryBuilder().where(BeanDao.Properties.Key.like("1%")).list();
       *///区间查询
        //大于gt()
        List<Bean> list2 = mBeanDao.queryBuilder().where(BeanDao.Properties.Step.gt(102)).list();//大于等于ge()
        //小于 lt()
        //小于等于le()
        //介于中间between(100,102)//查询大于step 大于102 的数据,并按照id升序排列
        List<Bean> list2 = mBeanDao.queryBuilder().where(BeanDao.Properties.Step.
                gt(102))
                .orderAsc(BeanDao.Properties.Id).list();
        //orderDesc降序排列
  • eq():==
  • noteq():!=
  • gt(): >
  • lt():<
  • ge:>=
  • le:<=
  • like():包含
  • between:俩者之间
  • in:在某个值内
  • notIn:不在某个值内

6.5 分页查询

limit(int): 限制查询的数量;
offset(int): 每次返回的数量; offset不能单独使用;

6.6 查询与LazyList类:

list() 缓存查询结果;list()类型一般为ArrayList
listLazy() 懒查询,只有当调用list()中的实体对象时才会执行查询操作并且只缓存第一次被查询的结果,需要关闭
listlazyUncached() 懒查询,只有当调用list()中的实体对象时才会执行查询操作并且不缓存;
listIterator() 对查询结果进行遍历,不缓存,需要关闭;

后面三个方法是LazyList类中的方法,LazyList为了执行不同的缓存策略其内部持有数据库的cursor对象;一般情况下这三个方法执行完毕后会自动关闭cursor;但是防止在还没有执行完查询结果时,对象被终结cursor还是无法被关闭的情况发生,需要手动关闭close();

发布了138 篇原创文章 · 获赞 18 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/chentaishan/article/details/105367990
5.1