文章参考自:老罗GreenDao数据库课程以及 Nate - Android框架-GreenDao

前言

  1. android中的数据存储:
    网络存储
    数据库存储
    SharedPreference 存储
    ContentProvider存储
    文件存储

  2. GreenDao简介:
    是一款优秀的ORM框架(Object Relational Mapping)
    对象关系映射,其思想将关系数据库中表的数据映射成为对象。程序员就可以将对数据库的操作转化为对对象的操作。其目的是让程序员以面向对象的思想来实现对数据库的操作。
    是对SQlite数据库的封装

  3. 优秀的ORM框架还有
    OrmLite 、 SugarOrm 、 LitePal 、 GreenDao

  4. 关系型数据库Sql和非关系型数据库NoSql
    关系型数据库最典型的数据结构是表,是由二维表及其之间的联系说组成的一个数据组织,代表数据库是MySql、Oracle
    非关系型数据库严格上不是一种数据库,是一种数据结构化存储方法的集合,可以是文档或者是键值对等,代表数据库是MongoDB、Redis

  5. Android原生Api操作数据库有什么不便
    要手动拼装SQL
    要自己写操作数据库的常规代码
    不能自动把数据库中的数据映射
    没有实现级联查询

  6. 为什么要选择GreenDao
    性能、文档、流行性、上手方便、拓展性

  7. GreenDao资料查询地址
    GreenDao的Github地址: https://github.com/greenrobot/greenDAO
    GreenDao官网: http://greenrobot.org/greendao/
    GreenDao Api地址: http://greenrobot.org/files/greendao/javadoc/current/

使用

  1. GreenDao依赖配置:
// 在project的build.gradle中配置:buildscript {    repositories {        jcenter()        mavenCentral() // add repository    }    dependencies {        classpath 'com.android.tools.build:gradle:3.1.1'        classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2' // add plugin    }}// 在module的build.gradle中配置:apply plugin: 'com.android.application'apply plugin: 'org.greenrobot.greendao' // apply plugin dependencies {    implementation 'org.greenrobot:greendao:3.2.2' // add library}
  1. GreenDao混续配置:
-keep class org.greenrobot.greendao.**{*;}-keepclassmembers class * extends org.greenrobot.greendao.AbstractDao {    public static java.lang.String TABLENAME;}-keep class **$Properties-keep public interface org.greenrobot.greendao.**-keep class net.sqlcipher.database.**{*;}-keep public interface net.sqlcipher.database.**-dontwarn net.sqlcipher.database.**-dontwarn org.greenrobot.greendao.**-dontwarn rx.**
  1. GreenDao版本配置:
// module的build.gradle中配置greendao版本号和数据库目录android{    greendao{        // 设置数据库版本号        schemaVersion 1        // 设置自动生成的数据库文件目录        targetGenDir 'src/main/java'        // 设置自动生成的数据库文件包名        daoPackage 'test.zhr.com.greendaodemo.auto'    }}

上面配好之后,自己创建一个实体类,这个实体类对应的就是数据库中的一个表,实体类中的每一个字段,就对应表中的每一个字段。
实体类创建完后,添加一些注解,在id上添加 @Id(autoincrement = true) 注解,在实体类上添加 @Entity 注解
点击 Build—Make Project 生成需要自动生成的文件,生成的三个类在module的build.gradle中配置的daoPackage 目录下,这三个类如下: xxx(实体类名)Dao 、DaoMaster 、DaoSession。
注意:为了解决

API 'variant.getJavaCompiler()' is obsolete and has been replaced with 'variant.getJavaCompileProvider()'. It will be removed at the end of 2019

配置的targetGenDir可以注释掉,如果不注释的话自动生成的数据库文件会在app/src/main/java/test/zhr/com/greendaodemo/auto文件夹下
删除的话 则会生成在默认目录app/build/generated/sourse/greendao/test/zhr/com/greendaodemo/auto文件夹下

DaoMaster是GreenDao的总入口,负责DaoSession的创建和整个库的运行
DaoSession会话层,操作具体的Dao对象,包括Dao对象的注册。提供了基本的持久化方法,比如实体对象的insert、load、update、delete操作
xxxDao 生成的Dao对象,它提供比DaoSession更具体的方法,比如count、loadAll和insertInTx等
xxxEntity 实体类,和表中的字段一一对应

具体的流程:
DaoMaster----create—DaoSession—create&manage—xxxDao—load&save—xxxEntity

二次封装

主要是封装了Dao的管理类和Dao的工具类以及GreenDao数据库的升级及加密

// DaoManagerpackage com.zhr.test.dao;import android.content.Context;import com.zhr.test.auto.DaoMaster;import com.zhr.test.auto.DaoSession;import org.greenrobot.greendao.query.QueryBuilder;public class DaoManager {    private static final String DB_NAME = "student.sqlite";    private volatile static DaoManager mDaoManager;    private MyGreenDaoOpenHelper mHelper;    private DaoMaster mDaoMaster;    private DaoSession mDaoSession;    private Context mContext;    /**     * 私有构造方法,不让其通过构造创建对象     */    private DaoManager(){}    /**     * 使用单例模式获取操作数据对象     * @return     */    public static DaoManager getInstance(){        DaoManager instance = null;        if(null == mDaoManager){            synchronized (DaoManager.class){                if(null == instance){                    instance = new DaoManager();                    mDaoManager = instance;                }            }        }        return mDaoManager;    }    /**     * 获取上下文对象     * @param context     */    public void initContext(Context context){        this.mContext = context;    }    /**     * 判断数据库是否存在 不存在则创建     * @return     */    public DaoMaster getDaoMaster(){        if(null == mDaoMaster){            mHelper = new MyGreenDaoOpenHelper(mContext, DB_NAME, null);            mDaoMaster = new DaoMaster(mHelper.getWritableDb());//            mDaoMaster = new DaoMaster(mHelper.getEncryptedWritableDb(DeviceUtils.getUniqueDeviceId()));        }        return mDaoMaster;    }    /**     * 完成对数据库的增删改查     * @return     */    public DaoSession getDaoSession(){        if(null == mDaoSession){            if(null == mDaoMaster){                mDaoMaster = getDaoMaster();            }            mDaoSession = mDaoMaster.newSession();        }        return mDaoSession;    }    /**     * 打开数据库调试日志 默认是关闭的     */    public void setDebug(){        QueryBuilder.LOG_SQL = true;        QueryBuilder.LOG_VALUES = true;    }    /**     * 数据库开启 使用完毕一定要关闭     */    public void closeDb(){        closeHelper();        closeDaoSession();    }    private void closeHelper(){        if(null != mHelper){            mHelper.close();            mHelper = null;        }    }    private void closeDaoSession(){        if(null != mDaoSession){            mDaoSession.clear();            mDaoSession = null;        }    }}---------------------------------------------------------------------------------------------// DaoUtilspackage com.zhr.test.dao;import android.content.Context;import com.zhr.test.auto.StudentDao;import com.zhr.test.entity.Student;import org.greenrobot.greendao.query.QueryBuilder;import org.greenrobot.greendao.query.WhereCondition;import java.util.ArrayList;import java.util.List;/** * 完成对Student表的具体操作 * insert、insertOrReplace、save、update的区别 * insert 插入的对象id必须唯一,在id重复的时候插入会异常 * update 根据id去更新数据,id重复则更新,不重复不更新 * insertOrReplace 插入的对象id可以不唯一,id重复时会更新数据,没有重复时则插入 * save insert或者update 根据id去更新数据,id重复则更新,不重复-如果手动指定则不更新 * (一般也不会手动指定),不重复-自动生成则插入 * * insertOrReplace以及save的使用场景分析 * save:本地数据库提交数据给线上数据库,id是由本地数据库生成的,不会出现没有id的情况,使用save更高效,其他情况一律使用insertOrReplace * insertOrReplace:线上数据库同步数据到本地数据库,用的是线上数据库的id,使用insertOrReplace * 综上,如果id在本地生成,绝对存在的情况使用save;不保证绝对存在使用insertOrReplace */public class DaoUtils {    private DaoManager mDaoManager;    public DaoUtils(Context context){        mDaoManager = DaoManager.getInstance();        mDaoManager.initContext(context);        mDaoManager.setDebug();    }    /**     * 插入一条数据     * @param object     * @return     */    public boolean insert(Object object){        boolean flag = false;        try {            flag = mDaoManager.getDaoSession().insertOrReplace(object) != -1;        } catch (Exception e) {            e.printStackTrace();        }        return flag;    }    /**     * 插入多条数据,需要开辟新的线程     * @param objects     * @return     */    public boolean insertMult(final List<?> objects){        boolean flag = false;        try {            mDaoManager.getDaoSession().runInTx(new Runnable() {                @Override                public void run() {                    for(Object object : objects){                        if(object instanceof Student){                            mDaoManager.getDaoSession().insertOrReplace(object);                        }                    }                }            });            flag = true;        } catch (Exception e) {            e.printStackTrace();        }        return flag;    }    /**     * 保存一条数据     * 比较save和insertOrReplace的区别     * @param student     * @return     */    public boolean save(Student student){        boolean flag = false;        try {            mDaoManager.getDaoSession().getStudentDao().save(student);            flag = true;        } catch (Exception e) {            e.printStackTrace();        }        return flag;    }    /**     * 保存多条数据     * 比较save和insertOrReplace的区别     * @param students     * @return     */    public boolean saveMult(List<Student> students){        boolean flag = false;        try {            for(Student student : students) {                mDaoManager.getDaoSession().getStudentDao().saveInTx(student);            }            flag = true;        } catch (Exception e) {            e.printStackTrace();        }        return flag;    }    /**     * 根据主键删除一条数据     * 若id未找到则不会删除数据 若找到则会删除数据     * @param object     * @return     */    public boolean deleteById(Object object){        boolean flag = false;        try {            mDaoManager.getDaoSession().delete(object);            flag = true;        } catch (Exception e) {            e.printStackTrace();        }        return flag;    }    /**     * 删除表中的所有数据     * @return     */    public boolean deleteAll(Class<?> entityClass){        boolean flag = false;        try {            mDaoManager.getDaoSession().deleteAll(entityClass);            flag = true;        } catch (Exception e) {            e.printStackTrace();        }        return flag;    }    /**     * 根据主键更新一条数据     * 若id未找到则不会更新数据 若找到则会更新数据     * @param object     * @return     */    public boolean updateById(Object object){        boolean flag = false;        try {            mDaoManager.getDaoSession().update(object);            flag = true;        } catch (Exception e) {            e.printStackTrace();        }        return flag;    }    /**     * 根据id查找一条数据 没有查到会异常     * @param entityClass     * @param id     * @return     */    public Object quaryById(Class<?> entityClass , Long id){        return mDaoManager.getDaoSession().load(entityClass , id);    }    /**     * 查找表中的所有数据     * @param entityClass     * @return     */    public List<?> quaryAll(Class<?> entityClass){        return mDaoManager.getDaoSession().loadAll(entityClass);    }    /**     * QueryBuilder中的查询语句     * where             使用and连接多个查询条件,返回的是数据     * whereor           使用or连接多个查询条件,返回的是数据     * and               使用and构成多个查询条件,返回的是查询条件     * or                使用or构成多个查询条件,返回的是查询条件     * orderAsc          以字段升序排列 不要以String类型的参数进行排序     * orderDesc         以字段降序排列     * orderCustom       自定义排序,根据属性和排序方案进行排序     * orderRaw          自定义排序,用SQL语句进行排序     * list              返回满足查询条件的结果集,如果有多条则无法查出并且报错     * lazyList          懒加载集合,使用时才加载,一般在多表级联查询时效果明显。源码使用了锁机制,完善了多线程并发的操作     * listIterator      使用迭代器遍历集合数据     * count             结果集的数量     * unique            返回唯一结果或者null     * distinct          过滤掉重复字段(感觉无效)     * offset            每次的偏移量,配合limit使用     * limit             限制的数量     *     * eq                等于xx     * gt                大于xx     * ge                大于等于xx     * lt                小于xx     * le                小于等于xx     * between           [xx , xx]区间值     * in                等于xx或者等于xx     * like              根据关键字模糊查询xx,模糊查询的关键字前后需要加%xx%     * notEq             不等于xx     * notIn             不等于xx或者不等于xx,注意如果只传入一个值的时候和notEq意思一样     * isnull            为空     * isNotNull 不为空     *     * 查找表中的数据集     * @param entityClass     * @return     */    public QueryBuilder<?> quaryList(Class<?> entityClass){        return mDaoManager.getDaoSession().queryBuilder(entityClass);    }    /******************************不常用  功能测试的方法*******************************/    public List<Student> builderQuary(Class<Student> entityClass){        QueryBuilder<Student> builder = mDaoManager.getDaoSession().queryBuilder(entityClass);        // 查询年龄大于等于25的数据条数//        long count = builder.where(StudentDao.Properties.Age.ge(25)).count();        // 查询年龄大于等于25或者小于等于20的数据条数//        long count = builder.whereOr(StudentDao.Properties.Age.ge(25), StudentDao.Properties.Age.le(20)).count();        // 查询年龄在[20 , 25]之间的数据条数//        long count = builder.where(StudentDao.Properties.Age.between(20, 25)).count();        // 查询年龄为20或者为25的数据条数//        long count = builder.where(StudentDao.Properties.Age.in(20, 25)).count();        // 查询年龄为20或者为25的数据条数//        long count = builder.whereOr(StudentDao.Properties.Age.eq(20), StudentDao.Properties.Age.eq(25)).count();        // 使用模糊查询必须把要查询的内容百分号包裹        // 查询地址中带有京字的数据条数//        long count = builder.where(StudentDao.Properties.Address.like("京")).count();        // 查询年龄为20或者为25的数据条数//        WhereCondition or = builder.or(StudentDao.Properties.Age.eq(20), StudentDao.Properties.Age.eq(25));//        long count = builder.where(or).count();        // 查询年龄为19的唯一一条数据,如果有多条则无法查出并且报错//        Student unique = builder.where(StudentDao.Properties.Age.eq(19)).build().unique();        long count = builder.where(StudentDao.Properties.Age.eq(19)).buildCount().count();        return new ArrayList<>();    }    /**     * 原生sql语句查找数据     * 若未查找到的话 则不会返回数据     * @param entityClass     * @return     */    public List<Student> nativeQuary(Class<Student> entityClass){//        return mDaoManager.getDaoSession().queryRaw(entityClass, "where name like ? and _id > ?",new String[]{"%李%" , "1"});        return mDaoManager.getDaoSession().queryBuilder(entityClass).where(new WhereCondition.StringCondition(                // 在Student表中根据外键idNo查询idCard表中大于100岁的身份证属于哪个派出所                "ID_NO IN " + "(SELECT ID_NO FROM ID_CARD WHERE AGE > 100)")).list();    }}

数据库升级: https://github.com/yuweiguocn/GreenDaoUpgradeHelper

// 在project的build.gradle中配置:allprojects {repositories {maven { url "https://jitpack.io" }}}// 在module的build.gradle中配置:dependencies {    implementation 'org.greenrobot:greendao:3.2.0'    implementation 'io.github.yuweiguocn:GreenDaoUpgradeHelper:v2.2.1'}// 混淆配置-keepclassmembers class * extends org.greenrobot.greendao.AbstractDao {    public static void dropTable(org.greenrobot.greendao.database.Database, boolean);    public static void createTable(org.greenrobot.greendao.database.Database, boolean);}// 创建一个GreenDaoOpenHelper类 继承 DaoMaster.OpenHelperpublic class MyGreenDaoOpenHelper extends DaoMaster.OpenHelper {    public MyGreenDaoOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory) {        super(context, name, factory);    }    @Override    public void onUpgrade(Database db, int oldVersion, int newVersion) {        MigrationHelper.migrate(db, new MigrationHelper.ReCreateAllTableListener() {            @Override            public void onCreateAllTables(Database db, boolean ifNotExists) {                DaoMaster.createAllTables(db, ifNotExists);            }            @Override            public void onDropAllTables(Database db, boolean ifExists) {                DaoMaster.dropAllTables(db, ifExists);            }            // 可传入多个xxxDao.class        } , StudentDao.class);    }}// 在创建DaoMaster的时候使用该GreenDaoOpenHelper类/** * 判断数据库是否存在 不存在则创建 * @return */public DaoMaster getDaoMaster(){    if(null == mDaoMaster){    mHelper = new MyGreenDaoOpenHelper(mContext, DB_NAME, null);        mDaoMaster = new DaoMaster(mHelper.getWritableDatabase());    }    return mDaoMaster;}

当数据库中的表或者字段更新时,将数据库的版本号加一,在打包覆盖安装之前的版本即可

数据库加密:https://github.com/sqlcipher/android-database-sqlcipher

// 在module的build.gradle中配置:dependencies {    implementation 'net.zetetic:android-database-sqlcipher:4.2.0'}// 在创建DaoMaster的时通过 mHelper.getEncryptedWritableDb() 对数据库进行加密/** * 判断数据库是否存在 不存在则创建 * @return */public DaoMaster getDaoMaster(){    if(null == mDaoMaster){mHelper = new MyGreenDaoOpenHelper(mContext, DB_NAME, null);        mDaoMaster = new DaoMaster(mHelper.getEncryptedWritableDb(DeviceUtils.getUniqueDeviceId()));    }    return mDaoMaster;}

增删改查功能测试

package com.zhr.test;import android.content.Context;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.util.Log;import android.view.View;import com.zhr.test.auto.StudentDao;import com.zhr.test.auto.TeacherDao;import com.zhr.test.dao.DaoUtils;import com.zhr.test.entity.CreditCard;import com.zhr.test.entity.DetailInfo;import com.zhr.test.entity.IdCard;import com.zhr.test.entity.Student;import com.zhr.test.entity.StudentAndTeacher;import com.zhr.test.entity.Teacher;import java.util.ArrayList;import java.util.List;public class MainActivity extends AppCompatActivity {    private static final String TAG = "MainActivity";    private Context mContext = MainActivity.this;    private DaoUtils mDaoUtils;    private int mOffset = 0;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mDaoUtils = new DaoUtils(mContext);    }    public void insert(View view){        long idCardId = 1324;        String name = "张三";        Student student = new Student();        student.setId(25L);        student.setName(name);        student.setAge(180);        student.setAddress("上海");        student.setIdCardId(idCardId);        List<DetailInfo> detailInfos = new ArrayList<>();        DetailInfo detailInfo = new DetailInfo();        detailInfo.setComeFrom("杭州");        detailInfo.setParentName("张三丰");        detailInfos.add(detailInfo);        student.setDetailInfos(detailInfos);        IdCard idCard = new IdCard();        idCard.setId(idCardId);        idCard.setName(name);        idCard.setOrganization("上海市公安局");        List<CreditCard> creditCards = new ArrayList<>();        CreditCard creditCard1 = new CreditCard();        CreditCard creditCard2 = new CreditCard();        creditCard1.setWhichBank("建行");        creditCard1.setCreditCardId(student.getId());        creditCard2.setWhichBank("工行");        creditCard2.setCreditCardId(student.getId());        creditCards.add(creditCard1);        creditCards.add(creditCard2);        boolean insert;        if(null != mDaoUtils){            insert = mDaoUtils.insert(student);            insert = mDaoUtils.insert(idCard);            insert = mDaoUtils.insertMult(creditCards);        }else{            insert = false;        }        Log.i(TAG , "插入一条数据至数据库成功?:" + insert);    }    public void insertMutl(View view){        List<Student> students = new ArrayList<>();        for(int i = 1; i < 11 ; i++){            Student student = new Student();            student.setId((long) i);            student.setName("三李三" + i);            student.setAge(18 + i);            student.setAddress("上海");            students.add(student);        }        List<Teacher> teachers = new ArrayList<>();        for(int i = 1; i < 4 ; i++){            Teacher teacher = new Teacher();            teacher.setId((long) i);            teacher.setName("王王王" + i);            teacher.setAge(18 + i);            teacher.setAddress("上海");            teachers.add(teacher);        }        List<StudentAndTeacher> studentAndTeachers = new ArrayList<>();        // 1号老师带34567号学生        StudentAndTeacher sat1 = new StudentAndTeacher(null , 3L , 1L);        StudentAndTeacher sat2 = new StudentAndTeacher(null , 4L , 1L);        StudentAndTeacher sat3 = new StudentAndTeacher(null , 5L , 1L);        StudentAndTeacher sat4 = new StudentAndTeacher(null , 6L , 1L);        StudentAndTeacher sat5 = new StudentAndTeacher(null , 7L , 1L);        // 2号老师带 45678号学生        StudentAndTeacher sa1 = new StudentAndTeacher(null , 4L , 2L);        StudentAndTeacher sa2 = new StudentAndTeacher(null , 5L , 2L);        StudentAndTeacher sa3 = new StudentAndTeacher(null , 6L , 2L);        StudentAndTeacher sa4 = new StudentAndTeacher(null , 7L , 2L);        StudentAndTeacher sa5 = new StudentAndTeacher(null , 8L , 2L);        // 3号老师带 56789号学生        StudentAndTeacher s1 = new StudentAndTeacher(null , 5L , 3L);        StudentAndTeacher s2 = new StudentAndTeacher(null , 6L , 3L);        StudentAndTeacher s3 = new StudentAndTeacher(null , 7L , 3L);        StudentAndTeacher s4 = new StudentAndTeacher(null , 8L , 3L);        StudentAndTeacher s5 = new StudentAndTeacher(null , 9L , 3L);        studentAndTeachers.add(sat1);        studentAndTeachers.add(sat2);        studentAndTeachers.add(sat3);        studentAndTeachers.add(sat4);        studentAndTeachers.add(sat5);        studentAndTeachers.add(sa1);        studentAndTeachers.add(sa2);        studentAndTeachers.add(sa3);        studentAndTeachers.add(sa4);        studentAndTeachers.add(sa5);        studentAndTeachers.add(s1);        studentAndTeachers.add(s2);        studentAndTeachers.add(s3);        studentAndTeachers.add(s4);        studentAndTeachers.add(s5);        boolean insertMutl;        if(null != mDaoUtils){            insertMutl = mDaoUtils.insertMult(students);            insertMutl = mDaoUtils.insertMult(teachers);            insertMutl = mDaoUtils.insertMult(studentAndTeachers);//            insertMutl = mDaoUtils.saveMult(students);        }else{            insertMutl = false;        }        Log.i(TAG, "插入多条数据至数据库成功?:" + insertMutl);    }    public void update(View view){        Student student = new Student();        // 根据主键去更新数据        student.setId(7L);        student.setName("李四1");        student.setAge(100);        student.setAddress("shanghai");        boolean update;        if(null != mDaoUtils){            update = mDaoUtils.updateById(student);        }else{            update = false;        }        Log.i(TAG, "更新一条数据至数据库成功?:" + update);    }    public void delete(View view){        Student student = new Student();        student.setId(1L);        boolean delete;        if(null != mDaoUtils){            delete = mDaoUtils.deleteById(student);        }else{            delete = false;        }        Log.i(TAG, "删除一条数据至数据库成功?:" + delete);    }    public void deleteAll(View view){        boolean deleteAll;        if(null != mDaoUtils){            deleteAll = mDaoUtils.deleteAll(Student.class);        }else {            deleteAll = false;        }        Log.i(TAG, "删除所有数据至数据库成功?:" + deleteAll);    }    public void quary(View view){        boolean quary;        Student student;        if(null != mDaoUtils){            try {                student = (Student) mDaoUtils.quaryById(Student.class , 2L);                Log.i(TAG, "id:" + student.getId() + ",name:" + student.getName()                        + ",age:" + student.getAge() + ",address:" + student.getAddress()                        + ",info:" + student.getDetailInfos());                quary = true;            } catch (Exception e) {                e.printStackTrace();                quary = false;            }        }else {            quary = false;        }        Log.i(TAG, "从数据库中查找一条数据成功?:" + quary);    }    public void quaryAll(View view){        boolean quaryAll;        if(null != mDaoUtils){            try {                List<Student> students = (List<Student>) mDaoUtils.quaryAll(Student.class);                for(Student student : students){                    Log.i(TAG, "id:" + student.getId() + ",name:" + student.getName()                        + ",age:" + student.getAge() + ",address:" + student.getAddress());                }                quaryAll = true;            } catch (Exception e) {                e.printStackTrace();                quaryAll = false;            }        }else {            quaryAll = false;        }        Log.i(TAG, "从数据库中查找所有数据成功?:" + quaryAll);    }    /**     * 使用复合条件查询语句进行查询操作     * @param view     */    public void quaryBuilder(View view){        boolean quaryBuilder;        if(null != mDaoUtils){            try {                // SQL原生语句查询//                List<Student> students = mDaoUtils.nativeQuary(Student.class);                // GreenDao 多种条件查询//                List<Student> students = (List<Student>) mDaoUtils.quaryList(Student.class).where(StudentDao.Properties.Age.eq(18) , StudentDao.Properties.Address.eq("上海")).list();                // 年龄降序排列//                List<Student> students = (List<Student>) mDaoUtils.quaryList(Student.class).where(StudentDao.Properties.Name.like("%李%")).orderDesc(StudentDao.Properties.Age).list();                // 使用迭代器遍历集合数据//                Iterator<Student> iterator = (Iterator<Student>) mDaoUtils.quaryList(Student.class).orderDesc(StudentDao.Properties.Age).listIterator();//                while (iterator.hasNext()){//                    Student next = iterator.next();//                    Log.i(TAG, "Student: " + next);//                }                // 分页加载数据//                int limit = 2;//                LazyList<Student> students = (LazyList<Student>)mDaoUtils.quaryList(Student.class).offset(mOffset * limit).limit(limit).listLazy();//                mOffset++;//                // lazyList 使用完要关闭//                students.close();                // 查询完了之后删除查询出来的数据//                QueryBuilder<Student> where = (QueryBuilder<Student>) mDaoUtils.quaryList(Student.class).where(StudentDao.Properties.Age.eq(18), StudentDao.Properties.Address.eq("上海"));//                where.buildDelete().executeDeleteWithoutDetachingEntities();//                for(Student student : students){//                    Log.i(TAG, "id:" + student.getId() + ",name:" + student.getName()//                      + ",age:" + student.getAge() + ",address:" + student.getAddress()//                            + ",organization: " + student.getIdCard().getOrganization());//                }                // 查询上海大于100岁的身份证属于哪个派出所  一对一  一对多   关联查询//                List<Student> students = (List<Student>) mDaoUtils.quaryList(Student.class).where(StudentDao.Properties.Age.gt(100) , StudentDao.Properties.Address.eq("上海")).list();//                for(Student student : students){//                    Log.i(TAG, "name: " + student.getName() + ",organization: " + student.getIdCard().getOrganization() + ",creditCard: " + student.getCreditCards());//                }//                List<Student> students = (List<Student>) mDaoUtils.quaryList(Student.class).where(StudentDao.Properties.Id.eq(5)).list();//                for(Student student : students){//                    Log.i(TAG, "teachers: " + student.getTeachers());//                }//                List<Teacher> teachers = (List<Teacher>) mDaoUtils.quaryList(Teacher.class).where(TeacherDao.Properties.Id.eq(1)).list();//                for(Teacher teacher : teachers){//                    Log.i(TAG, "students: " + teacher.getStudents());//                }                // 多线程查询                new Thread(){                    @Override                    public void run() {                        List<Student> list = (List<Student>) mDaoUtils.quaryList(Student.class).build().forCurrentThread().list();                        Log.i(TAG, "list " + list);                    }                }.start();                quaryBuilder = true;            } catch (Exception e) {                e.printStackTrace();                quaryBuilder = false;            }        }else {            quaryBuilder = false;        }        Log.i(TAG, "原生查询条件查询多条数据成功?:" + quaryBuilder);    }}

一对一查询

一般来说,一个学生对应一个身份证,新建一个IdCard 实体类。
在Student实体类中,声明一个idCardId。使用注解@ToOne()将idCardId和IdCard实体类中的id进行关联

@Entitypublic class Student {    /**     * 主键自增类型要设置为Long     */    @Id(autoincrement = true)    private Long id;    private String name;    private String address;    private int age;    private Long idCardId;    /**     * ToOne     * idCardId 作为外键和idCard的id进行关联     * 需在本Bean中声明一个idCardId字段     * 可以和idCard的id字段名不同     */    @ToOne(joinProperty = "idCardId")    private IdCard idCard;    }@Entitypublic class IdCard {    @Id(autoincrement = true)    private Long id;    private String name;    private String organization  }// 查询时使用 获取学生关联的身份证的信息,关联的字段为身份证idstudent.getIdCard().getOrganization();

一对多查询

一般来说,一个学生对应多个信用卡,新建一个CreditCard实体类。
在Student实体类中。使用注解@ToMany()将creditCardId和CreditCard实体类中的id进行关联,CreditCard实体类中需要声明creditCardId字段

@Entitypublic class Student {    /**     * 主键自增类型要设置为Long     */    @Id(autoincrement = true)    private Long id;    @NotNull    private String name;    @NotNull    private String address;    @NotNull    private int age;    private Long idCardId;    /**     * ToOne     * idCardId 作为外键和idCard的id进行关联     * 需在本Bean中声明一个idCardId字段     * 可以和idCard的id字段名不同     */    @ToOne(joinProperty = "idCardId")    private IdCard idCard;    /**     * ToMany     * creditCardId 作为外键和student的id进行关联     * 不需在本Bean中声明一个creditCardId字段     * 需要在creditCard中声明一个creditCardId字段     * 每一个creditCardI的对应的是此student的id     */    @ToMany(referencedJoinProperty  = "creditCardId")    private List<CreditCard> creditCards;}----------------------------------------------------------------------------------------// CreditCard@Entitypublic class CreditCard {    @Id(autoincrement = true)    private Long id;    @NotNull    private Long creditCardId;    @NotNull    private String whichBank;}// 查询时使用 获取学生关联的多个信用卡的信息,关联的字段为信用卡idstudents.get(i).getCreditCards().getCreditCardId();

多对多查询

一般来说,多个学生对应多个老师,新建一个Teacher实体类,并且新建一个学生和老师对应关系的StudentAndTeachcer实体类
在Student实体类中使用注解@ToMany()和 @JoinEntity()将studentId在StudentAndTeachcer类中和teacherId进行关联;在Teacher实体类中使用注解@ToMany()和 @JoinEntity()将teacherId在StudentAndTeachcer类中和studentId进行关联

@Entitypublic class Student {    /**     * 主键自增类型要设置为Long     */    @Id(autoincrement = true)    private Long id;    @NotNull    private String name;    @NotNull    private String address;    @NotNull    private int age;    private Long idCardId;    /**     * ToOne     * idCardId 作为外键和idCard的id进行关联     * 需在本Bean中声明一个idCardId字段     * 可以和idCard的id字段名不同     */    @ToOne(joinProperty = "idCardId")    private IdCard idCard;    /**     * ToMany     * creditCardId 作为外键和student的id进行关联     * 不需在本Bean中声明一个creditCardId字段     * 需要在creditCard中声明一个creditCardId字段     * 每一个creditCardI的对应的是此student的id     */    @ToMany(referencedJoinProperty  = "creditCardId")    private List<CreditCard> creditCards;    @ToMany    @JoinEntity(entity = StudentAndTeacher.class , sourceProperty = "studentId"        , targetProperty = "teacherId")    private List<Teacher> teachers;}-----------------------------------------------------------------------------------------------------------------------------------------------// Teacher@Entitypublic class Teacher {    /**     * 主键自增类型要设置为Long     */    @Id(autoincrement = true)    private Long id;    @NotNull    private String name;    @NotNull    private String address;    @NotNull    private int age;    @ToMany    @JoinEntity(entity = StudentAndTeacher.class , sourceProperty = "teacherId"            , targetProperty = "studentId")    List<Student> students;}-----------------------------------------------------------------------------------------------------------------------------------------------// Teacher@Entitypublic class StudentAndTeacher {    @Id(autoincrement = true)    Long id;    Long studentId;    Long teacherId;}

缓存字段为集合类型的数据

学生中有一个详细信息的字段,此字段为集合类型数据,将此数据以字符串的类型存储至数据库

@Entitypublic class Student {    /**     * 主键自增类型要设置为Long     */    @Id(autoincrement = true)    private Long id;    private String name;    private String address;    private int age;    private Long idCardId;        /**     * 如果不需要对其中的字段进行单独查询,只是做存储展示时     * 可以使用这种方法将集合转为字符串存储     */    @Convert(converter = ListConvert.class, columnType = String.class)    private List<DetailInfo> detailInfos;}---------------------------------------------------------------------------------------------// ListConvertpackage com.zhr.test;import com.alibaba.fastjson.JSON;import com.zhr.test.entity.DetailInfo;import org.greenrobot.greendao.converter.PropertyConverter;import java.util.List;/** * 参数转换类 将xxx类型转换为xxx类型存储在数据库 */public class ListConvert implements PropertyConverter<List<DetailInfo>, String> {    /**     * 字符串转集合     * @param databaseValue     * @return     */    @Override    public List<DetailInfo> convertToEntityProperty(String databaseValue) {        return JSON.parseArray(databaseValue , DetailInfo.class);    }    /**     * 集合转字符串     * @param entityProperty     * @return     */    @Override    public String convertToDatabaseValue(List<DetailInfo> entityProperty) {        return JSON.toJSONString(entityProperty);    }}

代码下载请移步:https://download.csdn.net/download/zxc514257857/11977445

更多相关文章

  1. SpringBoot 2.0 中 HikariCP 数据库连接池原理解析
  2. 一句话锁定MySQL数据占用元凶
  3. ContentProvider使用详解
  4. android viewmodel 数据刷新异常
  5. Android中Adapter使用ViewHolder优化
  6. Android学习系列(19)-App数据格式之解析Xml
  7. Android(安卓)GreenDao3.2.2简单使用
  8. [原]Android上GTalk以及Push机制的XMPP数据选择使用protobuf格式
  9. ContentProvider介绍

随机推荐

  1. Android中的多线程
  2. 哪里可以下载Android的源代码
  3. Android的Media架构介绍
  4. Android源码下载断线
  5. Android应用程序添加自定义的property属
  6. Android(安卓)Studio引入.so文件的正确姿
  7. Activity的四种启动模式和onNewIntent()
  8. [置顶] Android(安卓)上如何移植live555
  9. Android刷Recovery
  10. Android(安卓)Material Design 使用TabLa