Android 数据库框架greenDao的使用

四 GreenDAO 框架的使用

4.1 GreenDAO 是一种轻量级快速ORM 框架,可将对象映射到 SQLite 数据库中

4.2 ORM 框架,即 Object-Relational Mapping,它的作用是在关系型数据库和对象之间作一个映射,这样,我们在具体操作数据库的时候,就不需要再去和复杂的 SQL 语句打交道,只是像平时操作对象一样操作它就可以了

 4.3 GreenDAO主要类介绍

DaoMaster:DaoMaster保存数据库对象(SQLiteDatabase)并管理特定模式的DAO类(而不是对象)。它有静态方法来创建表或删除它们。它的内部类OpenHelper和DevOpenHelper是SQLiteOpenHelper实现,它们在SQLite数据库中创建模式。
DaoSession:管理特定模式的所有可用DAO对象,您可以使用其中一个getter方法获取该对象。DaoSession还提供了一些通用的持久性方法,如实体的插入,加载,更新,刷新和删除。
DAO:数据访问对象(DAO)持久存在并查询实体。对于每个实体,greenDAO生成实体XXDAO。它具有比DaoSession更多的持久性方法,例如:count,loadAll和insert等。
Entities :可持久化对象。通常, 实体对象代表一个数据库行使用标准 Java 属性(如一个POJO 或 JavaBean )。
4.4 GreenDAO的使用

工程目录build.gradle里面引入greenDao的插件

dependencies {
    classpath "com.android.tools.build:gradle:7.0.0"
    classpath 'org.greenrobot:greendao-gradle-plugin:3.3.0'
}
app的build.gradle里面使用插件,配置数据库,并引入greenDao的依赖库

plugins {
    id 'com.android.application'
    id 'org.greenrobot.greendao'
}
 
android {
    compileSdk 32
 
    defaultConfig {
        applicationId "com.greendao.demo"
        minSdk 21
        targetSdk 32
        versionCode 1
        versionName "1.0"
    }
}
 
greendao {
    //指定数据库schema版本号,迁移等操作会用到
    schemaVersion 1
    //设置生成数据库文件的目录,默认是在build中,可以将生成的文件放到我们的java目录中
    targetGenDir 'src/main/java'
    //设置生成的数据库相关文件的包名,默认为entity所在的包名
    daoPackage 'com.greendao.demo.greendao.database'
}
 
 
dependencies {
  implementation 'org.greenrobot:greendao:3.3.0'
}

4.5 封装数据库管理器DaoManager,用来创建数据库、创建数据库表、包含增删改查的操作以及数据库的升级

/**
 * 创建数据库、创建数据库表、包含增删改查的操作以及数据库的升级
 */
public class DaoManager
{
    private static final String TAG = DaoManager.class.getSimpleName();
    private static final String DB_NAME = "diary.db";
 
    private Context context;
 
    //多线程中要被共享的使用volatile关键字修饰
    private volatile static DaoManager manager ;
    private static DaoMaster sDaoMaster;
    private static DaoMaster.DevOpenHelper sHelper;
    private static DaoSession sDaoSession;
 
    /**
     * 单例模式获得操作数据库对象
     *
     * @return
     */
    public static DaoManager getInstance()
    {
        synchronized (DaoManager.class) {
            if (manager == null) {
                manager = new DaoManager();
            }
        }
        return manager;
    }
 
    private DaoManager()
    {
        setDebug();
    }
 
    public void init(Context context)
    {
        this.context = context;
    }
 
    /**
     * 判断是否有存在数据库,如果没有则创建
     *
     * @return
     */
    public DaoMaster getDaoMaster()
    {
        if (sDaoMaster == null)
        {
            sHelper = new DaoMaster.DevOpenHelper(context, DB_NAME, null);
            sDaoMaster = new DaoMaster(sHelper.getWritableDatabase());
        }
        return sDaoMaster;
    }
 
    /**
     * 完成对数据库的添加、删除、修改、查询操作,仅仅是一个接口
     *
     * @return
     */
    public DaoSession getDaoSession()
    {
        if (sDaoSession == null)
        {
            if (sDaoMaster == null)
            {
                sDaoMaster = getDaoMaster();
            }
            sDaoSession = sDaoMaster.newSession();
        }
        return sDaoSession;
    }
 
    /**
     * 打开输出日志,默认关闭
     */
    public void setDebug()
    {
        if (BuildConfig.DEBUG)
        {
            QueryBuilder.LOG_SQL = true;
            QueryBuilder.LOG_VALUES = true;
        }
    }
 
    /**
     * 关闭所有的操作,数据库开启后,使用完毕要关闭
     */
    public void closeConnection()
    {
        closeHelper();
        closeDaoSession();
    }
 
    public void closeHelper()
    {
        if (sHelper != null)
        {
            sHelper.close();
            sHelper = null;
        }
    }
 
    public void closeDaoSession()
    {
        if (sDaoSession != null)
        {
            sDaoSession.clear();
            sDaoSession = null;
        }
    }
}
4.6 在项目Application里面初始化GreenDAO

DaoManager.getInstance().init(this);
4.7 以Uer表为例,创建一个User实体类。实体类开头必须加 @Entity 注解

@Entity
public class User {
    @Id(autoincrement = true)
    Long id;
    String account;
    String password;
    String name="tom";
    String avatar;
    int gender=0;
    String mobile;
    @Generated(hash = 998056223)
    public User(Long id, String account, String password, String name,
            String avatar, int gender, String mobile) {
        this.id = id;
        this.account = account;
        this.password = password;
        this.name = name;
        this.avatar = avatar;
        this.gender = gender;
        this.mobile = mobile;
    }
}
编译后User实体类目会自动生成GET,SET方法

@Entity
public class User {
    @Id(autoincrement = true)
    Long id;
    String account;
    String password;
    String name="tom";
    String avatar;
    int gender=0;
    String mobile;
    @Generated(hash = 998056223)
    public User(Long id, String account, String password, String name,
            String avatar, int gender, String mobile) {
        this.id = id;
        this.account = account;
        this.password = password;
        this.name = name;
        this.avatar = avatar;
        this.gender = gender;
        this.mobile = mobile;
    }
    @Generated(hash = 586692638)
    public User() {
    }
    public Long getId() {
        return this.id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getAccount() {
        return this.account;
    }
    public void setAccount(String account) {
        this.account = account;
    }
    public String getPassword() {
        return this.password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public String getName() {
        return this.name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getAvatar() {
        return this.avatar;
    }
    public void setAvatar(String avatar) {
        this.avatar = avatar;
    }
    public int getGender() {
        return this.gender;
    }
    public void setGender(int gender) {
        this.gender = gender;
    }
    public String getMobile() {
        return this.mobile;
    }
    public void setMobile(String mobile) {
        this.mobile = mobile;
    }
 
}
同时编译后还会在 build 目录下生成XXXDao实体类,通过DAO实体就能操作数据库了

 4.7 可以封装一个通用的增删改查工具类,这样像正常操作对象那样就可以了

/**
 * 通用greendao工具
 * @param <T>
 */
public class CommonDaoUtils<T> {
 
    private static final String TAG = CommonDaoUtils.class.getSimpleName();
 
    private DaoSession daoSession;
    private Class<T> entityClass;
    private AbstractDao<T, Long> entityDao;
 
    public CommonDaoUtils(Class<T> pEntityClass, AbstractDao<T, Long> pEntityDao)
    {
        DaoManager mManager = DaoManager.getInstance();
        daoSession = mManager.getDaoSession();
        entityClass = pEntityClass;
        entityDao = pEntityDao;
    }
 
    public DaoSession getDaoSession() {
        return daoSession;
    }
 
    /**
     * 插入记录,如果表未创建,先创建表
     *
     * @param pEntity
     * @return
     */
    public boolean insert(T pEntity)
    {
        boolean flag = entityDao.insert(pEntity) == -1 ? false : true;
        return flag;
    }
 
    /**
     * 插入记录数据存在则替换,数据不存在则插入
     *
     * @param pEntity
     * @return
     */
    public boolean insertOrReplace(T pEntity)
    {
        boolean flag = entityDao.insertOrReplace(pEntity) == -1 ? false : true;
        return flag;
    }
 
 
    /**
     * 插入多条数据,在子线程操作
     *
     * @param pEntityList
     * @return
     */
    public boolean insertMulti(final List<T> pEntityList)
    {
        try
        {
            daoSession.runInTx(new Runnable()
            {
                @Override
                public void run()
                {
                    for (T meizi : pEntityList)
                    {
                        daoSession.insertOrReplace(meizi);
                    }
                }
            });
            return true;
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return false;
    }
 
    /**
     * 修改一条数据
     *
     * @param pEntity
     * @return
     */
    public boolean update(T pEntity)
    {
        try
        {
            daoSession.update(pEntity);
            return true;
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return false;
    }
 
    /**
     * 删除单条记录
     *
     * @param pEntity
     * @return
     */
    public boolean delete(T pEntity)
    {
        try
        {
            //按照id删除
            daoSession.delete(pEntity);
            return true;
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return false;
    }
 
    /**
     * 删除所有记录
     *
     * @return
     */
    public boolean deleteAll()
    {
        try
        {
            //按照id删除
            daoSession.deleteAll(entityClass);
            return true;
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return false;
    }
 
    /**
     * 查询所有记录
     *
     * @return
     */
    public List<T> queryAll()
    {
        return daoSession.loadAll(entityClass);
    }
 
    /**
     * 根据主键id查询记录
     *
     * @param key
     * @return
     */
    public T queryById(long key)
    {
        return daoSession.load(entityClass, key);
    }
 
    /**
     * 使用native sql进行查询操作
     */
    public List<T> queryByNativeSql(String sql, String[] conditions)
    {
        return daoSession.queryRaw(entityClass, sql, conditions);
    }
 
 
    /**
     * 使用queryBuilder进行查询
     *
     * @return
     */
    public List<T> queryByQueryBuilder(WhereCondition cond, WhereCondition... condMore)
    {
        QueryBuilder<T> queryBuilder = daoSession.queryBuilder(entityClass);
        return queryBuilder.where(cond, condMore).list();
    }
    /**
     * 使用queryBuilder进行查询
     *
     * @return
     */
    public List<T> queryByBuilder(WhereCondition cond)
    {
        QueryBuilder<T> queryBuilder = daoSession.queryBuilder(entityClass);
        return queryBuilder.where(cond).list();
    }
 
}
4.8 再定义具体的Dao操作类,实现单独管理

public class DaoUserUtils
{
    private volatile static DaoUserUtils instance;
 
    public CommonDaoUtils<User> userCommonDaoUtils;
 
 
    public static DaoUserUtils getInstance()
    {
        synchronized (DaoUserUtils.class) {
            if(instance==null){
                instance = new DaoUserUtils();
            }
        }
 
        return instance;
    }
 
    private DaoUserUtils()
    {
        DaoManager mManager = DaoManager.getInstance();
 
        userCommonDaoUtils = new CommonDaoUtils(User.class,mManager.getDaoSession().getUserDao());
 
    }
 
 
    //新建用户
    public void daoInsertDefaultUser(){
        String account="boss1";
        String password="123456";
        if(daoQueryAllUser().size()==0){
            User user= new User();
            user.setAccount(account);
            user.setPassword(password);
            userCommonDaoUtils.insert(user);
        }
    }
 
    //查询用户
    public List<User> daoQueryAllUser(){
        return userCommonDaoUtils.queryAll();
    }
 
    //查询用户
    public User daoQueryUser(long id){
        return userCommonDaoUtils.queryById(id);
    }
 
 
    //删除用户
    public boolean deleteAllUser(){
        return userCommonDaoUtils.deleteAll();
    }
 
    //更新用户
    public boolean updateUser(User user){
        return userCommonDaoUtils.update(user);
    }
}
4.9 GreenDao提供有丰富的操作数据库接口,比如查询常用的三种方式:

load(entityClass, dataKey); 主键查询单条数据
loadAll():查询所有数据。
queryRaw():根据条件查询。
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() 按某个属性降序排;
以及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" 不为空;
4.10 queryRaw()原始sql语句查询

  /**
     * @param sql 查询语句
     * @param conditions 位字段赋值
     * @return
     */
    public List<T> queryByNativeSql(String sql, String[] conditions)
    {
        DaoMaster.DevOpenHelper sHelper= new DaoMaster.DevOpenHelper(context, DB_NAME, null);
        DaoSession daoSession = new DaoMaster(sHelper.getWritableDatabase());
      
        return daoSession.queryRaw(entityClass, sql, conditions);
    }
比如:

queryByNativeSql("where columnName=?", new String[]{coverId});
4.11 queryBuilder()纯api查询,不用写任何sql语句

/**
 * @param cond 一个条件
 * @param condMore 多个条件
 * @return
 */
public List<T> queryByQueryBuilder(WhereCondition cond, WhereCondition... condMore)
{
   DaoMaster.DevOpenHelper sHelper= new DaoMaster.DevOpenHelper(context, DB_NAME, null);
   DaoSession daoSession = new DaoMaster(sHelper.getWritableDatabase());
 
    QueryBuilder<T> queryBuilder = daoSession.queryBuilder(entityClass);
    return queryBuilder.where(cond, condMore).list();
}
比如:

queryByQueryBuilder(DiaryDao.Properties.Time.ge(startTime),DiaryDao.Properties.Time.le(endTime));
4.12 常用注解

表名字段注解,实体类注解,必须加在类前才起用

@Entity注解

只有在实体类中使用了@Entity注解GreenDao才会创建对应的表

@Entity配置:

schema:如果你有多个架构,你可以告诉GreenDao当前属于哪个架构。
active:标记一个实体处于活跃状态,活动实体有更新、删除和刷新方法。
nameInDb:在数据中使用的别名,默认使用的是实体的类名。
indexes:标记如果DAO应该创建数据库表(默认为true),如果您有多个实体映射到一个表,或者表的创建是在greenDAO之外进行的,那么将其设置为false。
createInDb:标记创建数据库表。
generateGettersSetters:如果缺少,是否应生成属性的getter和setter方法。
@Entity(
        schema = "myschema",
        active = true,
        nameInDb = "AWESOME_USERS",
        indexes = {
                @Index(value = "message DESC", unique = true)
        },
        createInDb = false,
        generateConstructors = true,
        generateGettersSetters = true
)
public class User{   
 
}
基础属性注解

@Id
@Id注解选择 long / Long属性作为实体ID。在数据库方面,它是主键。参数autoincrement = true 表示自增,id不给赋值或者为赋值为null即可(这里需要注意,如果要实现自增,id必须是Long)

@Entity
public class User{
    @Id(autoincrement = true)
    Long uid;
}
@Property
允许您定义属性映射到的非默认列名。如果不存在,GreenDAO将使用字段名称。会生成大写列名,如 name将成为 NAME

@Entity
public class User{
    @Id(autoincrement = true)
    Long id;
 
    //设置了,数据库中的表格属性名为"name",如果不设置,数据库中表格属性名为"NAME"
    @Property (nameInDb="name") 
    String name;
}
@NotNull

设置数据库表当前列不能为空

@Entity
public class User{
    @NotNull
    String password;
}
@Transient 

添加次标记之后不会生成数据库表的列。标记要从持久性中排除的属性。将它们用于临时状态等。或者,您也可以使用Java中的transient关键字

@Entity
public class User{
    @Transient
    boolean isChecked;
}
索引注解

@Index

创建一个索引,通过name设置索引别名,也可以通过unique给索引添加约束。

@Unique

向索引添加UNIQUE约束,强制所有值都是唯一的。

@Entity
public class User{
    @Id(autoincrement = true)
    Long id;
 
    @Index(unique = true)
    String account;
}
关系注解

@ToOne:

定义与另一个实体(一个实体对象)的关系

创建用户表和身份证表,一个人对应一个身份证

@Entity
public class Student {
    @Id(autoincrement = true)
    Long uid;
 
    String name;
 
    Long cardId;
 
    @ToOne(joinProperty = "cardId")
    Card card;
}
@Entity
public class Card {
    @Id(autoincrement = true)
    Long cardId;
 
    String carNo;
}
@ToMany:

定义与多个实体对象的关系

创建用户表和银行卡表,一个人对应多张银行卡

@Entity
public class Student {
    @Id(autoincrement = true)
    Long uid;
 
    @Property (nameInDb="name")
    String newm;
 
   //这个 uid是对应在 BankCard 中的 uid
    @ToMany(referencedJoinProperty = "uid")
    List<BankCard> bankCardList;
}
@Entity
public class BanKCard {
    @Id(autoincrement = true)
    Long cardId;
    String carNo;
 
    Long uid;
}

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
GreenDao是一个高效、轻量级、快速的ORM(对象关系映射)框架,可以方便地将Java对象映射到SQLite数据库中。下面是GreenDao的引入和使用步骤: 1. 在build.gradle文件中添加以下依赖: ```groovy dependencies { implementation 'org.greenrobot:greendao:3.3.0' } ``` 2. 在app/build.gradle文件中添加以下配置: ```groovy android { defaultConfig { //... javaCompileOptions { annotationProcessorOptions { arguments = ["schemaVersion": "1", "daoPackage": "com.example.myapp.db"] } } } } greendao { schemaVersion 1 daoPackage 'com.example.myapp.db' targetGenDir 'src/main/java' } ``` 这些配置将告诉GreenDao在编译时生成DAO(数据访问对象)类。schemaVersion是数据库的版本号,daoPackage是生成DAO类的包名,targetGenDir是DAO类的生成目录。 3. 创建实体类,例如: ```java @Entity public class User { @Id(autoincrement = true) private Long id; private String name; private int age; // getters and setters } ``` @Entity注解表示这是一个实体类,@Id注解表示这是主键,autoincrement = true表示主键自增。 4. 在app/src/main/java目录下创建一个名为“greenDao”的包,并在该包下创建一个名为“DaoMasterOpenHelper”的类。该类继承自DaoMaster.OpenHelper,用于创建和升级数据库。例如: ```java public class DaoMasterOpenHelper extends DaoMaster.OpenHelper { public DaoMasterOpenHelper(Context context, String name) { super(context, name); } @Override public void onCreate(Database db) { super.onCreate(db); } @Override public void onUpgrade(Database db, int oldVersion, int newVersion) { // 数据库升级逻辑 } } ``` 5. 初始化GreenDao,在Application类的onCreate()方法中添加以下代码: ```java public class MyApp extends Application { private DaoSession daoSession; @Override public void onCreate() { super.onCreate(); DaoMasterOpenHelper helper = new DaoMasterOpenHelper(this, "mydb"); Database db = helper.getWritableDb(); daoSession = new DaoMaster(db).newSession(); } public DaoSession getDaoSession() { return daoSession; } } ``` 这里创建了一个DaoMasterOpenHelper实例,并通过它获取可写的数据库,然后创建一个DaoSession实例。 6. 使用GreenDao,例如: ```java public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); DaoSession daoSession = ((MyApp) getApplication()).getDaoSession(); User user = new User(); user.setName("Tom"); user.setAge(18); daoSession.getUserDao().insert(user); List<User> userList = daoSession.getUserDao().queryBuilder() .where(UserDao.Properties.Age.gt(10)) .orderAsc(UserDao.Properties.Age) .list(); } } ``` 这里通过getApplication()方法获取MyApp实例,然后通过getDaoSession()方法获取DaoSession实例。接着创建了一个User实例并插入到数据库中。最后使用查询构建器查询年龄大于10的所有用户,并按年龄升序排序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值