Android 数据库GreenDao的使用完全解析

一:什么是GreenDao?
GreenDao是Android平台下的一个ORM(“对象/关系映射”)框架。它将Java对象映射成数据库表,之后你就可以面对对象来存储,更新,删除,查询Objects.
image.png
二:GreenDao的优点
1.高性能
2.易于使用的强大API,涵盖关系和连接
3.最小的内存消耗
4.库的大小(<100kB)以保持较低的构建时间并避免65K方法限制
5.数据库加密:GreenDao支持SQLCipher,以确保用户的数据安全
三:GreenDao的使用
GreenDao的三个核心类:分别是DaoMaster,DaoSession,XXXDao,这三个类都会自动创建,无需自己编写。
DaoMaster:DaoMaster保存数据库对象(SQLiteDatabase)并管理特定模式的DAO类(而不是对象)。他的静态方法来创建表或者删除它们。它的内部OpenHelper和DevOpenHelper是SQLiteOpenHelper实现,它们在SQLite数据库中创建模式。
DaoSession:管理特定模式的所有可用DAO对象,你可以使用其中一个getter方法获取该对象。DaoSession还提供了一些通用的持久方法,如实体的插入,加载,更新,刷新和删除。
XXXDao:数据访问对象(DAO)持久存在并查询实体。对于每一个实体,GreenDao生成DAO.它具有DaoSession更多的持久性方法
Entities:可持久化对象。通常,实体对象代表一个数据库行,使用标准java属性。
image.png
四:Android Studio中使用GreenDao
1.遇到编译问题
image.png

Unable to find method 'org.gradle.api.tasks.TaskInputs.property(Ljava/lang/String;Ljava/lang/Object;)Lorg/gradle/api/tasks/TaskInputs;'

image.png
最后这一句的中文意思是:您的项目可能使用的第三方插件与项目中的其他插件或项目所要求的Gradle版本不兼容。在损坏Gradle进程的情况下,您还可以尝试关闭IDE,然后杀死所有Java进程
解决方式:把GreenDao版本升级成3.3.0就没有问题了
image.png
image.png
原因可能是:*Gradle 的版本和库的Gradle版本不兼容,引发的Bug
如果,不是GreeDao的问题,那么可能是项目中使用的库需要的定的构建版本工具与版本不兼容*
2.使用GreenDao,需要添加GreenDao Gradle并添加GreenDao库:
第一步:在工程的build.gradle文件下添加:

dependencies {
 classpath 'com.android.tools.build:gradle:3.2.1'
 classpath 'org.greenrobot:greendao-gradle-plugin:3.3.0' // 1.第一步,添加插件 更好支持GreenDao
 // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files}

第二步:在相关Moudle:app的build.gradle文件下添加:

apply plugin: 'org.greenrobot.greendao' //第二步apply plugin
dependencies {
 implementation 'org.greenrobot:greendao:3.3.0' // 第三步:添加库
}

第三步:配置数据库相关信息

android{

greendao{
 schemaVersion 2 //数据库版本号,升级时可配置
 daoPackage  'com.soudao.test.greendao'//dao的包名,包名默认是entity实体类所在的包
 targetGenDir 'src/main/java'//生成数据库文件的目录DaoMaster和DaoSession
}

}

schemaVersion: 数据库schema版本,也可以理解为数据库版本号
daoPackage:设置DaoMaster 、DaoSession、Dao包名
targetGenDir:设置DaoMaster 、DaoSession、Dao目录
targetGenDirTest:设置生成单元测试目录
generateTests:设置自动生成单元测试用例
五:创建实体类@Entity

@Entity
public class Teacher {
    @Id
 private Long id;
 private String name;
 @Transient
 private  int tempUsageCount;
 }

点击Build-->Make Project编译项目会自动编译生成get,set方法并且在配置的com.soudao.test.greendao目录下生成三个文件DaoMaster,DaoSession,XXXDao文件。
image.png

@Entity
public class Teacher {
    @Id
 private Long id;
 private String name;
 @Transient
 private  int tempUsageCount;
 @Generated(hash = 1434396195)
    public Teacher(Long id, String name) {
        this.id = id;
 this.name = name;
 }
    @Generated(hash = 1630413260)
    public Teacher() {
    }
    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;
 }
}

实体类相关属性的注解:
@Id :主键 Long型,可以通过@Id(autoincrement = true)设置自增长
@Property:设置一个非默认关系映射所对应的列名,默认是的使用字段名 举例:@Property (nameInDb="name")
@NotNull:设置数据库表当前列不能为空
@Transient :添加次标记之后不会生成数据库表的列
@Index:使用@Index作为一个属性来创建一个索引,通过name设置索引别名,也可以通过unique给索引添加约束(@Index(unique = true)//设置唯一性)
@Unique:向数据库列添加了一个唯一的约束
@ToOne:表示一对一关系
@OrderBy:更加某一字段排序 ,例如:@OrderBy(“date ASC”)
六:实现增删改查
1.上面我们已经获取到DaoMaster 、DaoSession、Dao类
我们创建一个数据库管理类DBManager

public class DBManager {
    private Context context;//定义一个上下文
 private final static String dbName = "test_db";//定义一个数据库名
 private static DBManager mInstance;//单例
 private DaoMaster.DevOpenHelper openHelper;//在构造方法里创建一个DaoMaster.DevOpenHelper
 private DaoSession mDaoSession;//会话层操作具体的DAO对象
 private SQLiteDatabase db;//获取一个数据库操作类
 public DBManager(Context context) {
        this.context = context;
 openHelper = new DaoMaster.DevOpenHelper(context, dbName, null);
 }
    /*
 * 双重检索获取DBManager对象的单例*/
 public static DBManager getInstance(Context context) {
        if (mInstance == null) {
            synchronized (DBManager.class) {
                if (mInstance == null) {
                    mInstance = new DBManager(context);
 }
            }
        }
        return mInstance;
 }
    /**
 * 获取可读的数据库
 */
 public SQLiteDatabase getReadableDatabase() {
        if (openHelper == null) {
            openHelper = new DaoMaster.DevOpenHelper(context, dbName, null);
 }
        SQLiteDatabase db = openHelper.getReadableDatabase();
 return db;
 }
    /**
 * 获取可写的数据库
 */
 public SQLiteDatabase getWritableDatabase() {
        if (openHelper == null) {
            openHelper = new DaoMaster.DevOpenHelper(context, dbName, null);
 }
        db = openHelper.getWritableDatabase();
 return db;
 }
    /**
 * 获取可写的会话层
 */
 public DaoSession getWriteDaoSession() {
        DaoMaster daoMaster = new DaoMaster(getWritableDatabase());
 mDaoSession = daoMaster.newSession();
 return mDaoSession;
 }
    /**
 * 获取可读的会话层
 */
 public DaoSession getReadDaoSession() {
        DaoMaster daoMaster = new DaoMaster(getReadableDatabase());
 mDaoSession = daoMaster.newSession();
 return mDaoSession;
 }
}

1.DBManager.getInstance(this);等价于DaoMaster.DevOpenHelper helper=new DaoMaster.DevOpenHelper(this,"test_db");
单例获取DaoMaster.DevOpenHelper对象
2.DBManager.getInstance(this).getWritableDatabase()等价于SQLiteDatabase db=helper.getWritableDatabase();
3.DBManager.getInstance(this).getWriteDaoSession()等价于
DaoMaster daoMaster=new DaoMaster(db);
DaoSession daoSession=daoMaster.newSession();
这三步获取到DaoSession会话层对象可以去操作
删除一条数据

 public void deleteUser(Student student) {
        DaoSession daoSession = DBManager.getInstance(this).getWriteDaoSession();
        UserDao userDao = daoSession.getStudentDao();
        userDao.delete(student);
    }

插入一条数据

 public void insertUser(Student student) {
        DaoSession daoSession = DBManager.getInstance(this).getWriteDaoSession();
        UserDao userDao = daoSession.getStudentDao();
        userDao.insert(student);
    }

更新一条数据

public void updateUser(Student student) {
        DaoSession daoSession = DBManager.getInstance(this).getWriteDaoSession();
        UserDao userDao = daoSession.getStudentDao();
        userDao.update(student);
    }

查询学生列表

public List<User> queryUserList() {
       DaoSession daoSession = DBManager.getInstance(this).getReadDaoSession();
        UserDao userDao = daoSession.getStudentDao();
        QueryBuilder<Student> qb = userDao.queryBuilder();
        List<Student> list = qb.list(); 
        return list;
    }

等还可以查询针对用户的筛选。具体需要举一反三。
结语:不积跬步,无以致千里。不积小流,无以成江海。


Rocky_ruan
57 声望5 粉丝

不积跬步,无以至千里