Android GreenDao数据库—高级详解

上一节讲述了GreenDao数据库的基础讲解:Android GreenDao数据库—基础详解

 

 

 

本章节讲述GreenDao数据库的高级讲解

 

 

 

一.创建实体类后自动生成的Dao类

 

Android GreenDao数据库—高级详解_第1张图片

 

public class UserInfoDao extends AbstractDao {

    public static final String TABLENAME = "USER_INFO";

    /**
     * Properties of entity UserInfo.
* Can be used for QueryBuilder and for referencing column names. */ public static class Properties { public final static Property Id = new Property(0, Long.class, "id", true, "_id"); public final static Property Name = new Property(1, String.class, "name", false, "NAME"); public final static Property Age = new Property(2, String.class, "age", false, "AGE"); } public UserInfoDao(DaoConfig config) { super(config); } public UserInfoDao(DaoConfig config, DaoSession daoSession) { super(config, daoSession); } /** Creates the underlying database table. */ public static void createTable(Database db, boolean ifNotExists) { String constraint = ifNotExists? "IF NOT EXISTS ": ""; db.execSQL("CREATE TABLE " + constraint + "\"USER_INFO\" (" + // "\"_id\" INTEGER PRIMARY KEY AUTOINCREMENT ," + // 0: id "\"NAME\" TEXT," + // 1: name "\"AGE\" TEXT);"); // 2: age } /** Drops the underlying database table. */ public static void dropTable(Database db, boolean ifExists) { String sql = "DROP TABLE " + (ifExists ? "IF EXISTS " : "") + "\"USER_INFO\""; db.execSQL(sql); } @Override protected final void bindValues(DatabaseStatement stmt, UserInfo entity) { stmt.clearBindings(); Long id = entity.getId(); if (id != null) { stmt.bindLong(1, id); } String name = entity.getName(); if (name != null) { stmt.bindString(2, name); } String age = entity.getAge(); if (age != null) { stmt.bindString(3, age); } } @Override protected final void bindValues(SQLiteStatement stmt, UserInfo entity) { stmt.clearBindings(); Long id = entity.getId(); if (id != null) { stmt.bindLong(1, id); } String name = entity.getName(); if (name != null) { stmt.bindString(2, name); } String age = entity.getAge(); if (age != null) { stmt.bindString(3, age); } } @Override public Long readKey(Cursor cursor, int offset) { return cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0); } @Override public UserInfo readEntity(Cursor cursor, int offset) { UserInfo entity = new UserInfo( // cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0), // id cursor.isNull(offset + 1) ? null : cursor.getString(offset + 1), // name cursor.isNull(offset + 2) ? null : cursor.getString(offset + 2) // age ); return entity; } @Override public void readEntity(Cursor cursor, UserInfo entity, int offset) { entity.setId(cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0)); entity.setName(cursor.isNull(offset + 1) ? null : cursor.getString(offset + 1)); entity.setAge(cursor.isNull(offset + 2) ? null : cursor.getString(offset + 2)); } @Override protected final Long updateKeyAfterInsert(UserInfo entity, long rowId) { entity.setId(rowId); return rowId; } @Override public Long getKey(UserInfo entity) { if(entity != null) { return entity.getId(); } else { return null; } } @Override public boolean hasKey(UserInfo entity) { return entity.getId() != null; } @Override protected final boolean isEntityUpdateable() { return true; } }

 

从上述代码可以看出,创建实体类后自动创建的Dao其实给我们按照实体类的属性创建了表

 

表名:(实体类类名:UserInfo)

public static final String TABLENAME = "USER_INFO";

 

 

建表:

/** Creates the underlying database table. */
    public static void createTable(Database db, boolean ifNotExists) {
        String constraint = ifNotExists? "IF NOT EXISTS ": "";
        db.execSQL("CREATE TABLE " + constraint + "\"USER_INFO\" (" + //
                "\"_id\" INTEGER PRIMARY KEY AUTOINCREMENT ," + // 0: id
                "\"NAME\" TEXT," + // 1: name
                "\"AGE\" TEXT);"); // 2: age
    }

 

 

删表:

 /** Drops the underlying database table. */
    public static void dropTable(Database db, boolean ifExists) {
        String sql = "DROP TABLE " + (ifExists ? "IF EXISTS " : "") + "\"USER_INFO\"";
        db.execSQL(sql);
    }

 

 

实体类属性:

private Long id;//主键 Long型,可以通过@Id(autoincrement = true)设置自增长
private String name;
private String age;

 

由上可知,自动创建的Dao类会根据实体类类名和属性进行创建表,删除表等等操作。

 

 

 

 

二.注解介绍

 

1.@Entity:用来声明类实体,表示它将映射为数据表 。


@Entity()括号内可加入更详细的设置,如: 


nameInDb =“TABLE_NAME” ——> 声明该表的表名,默认取类名 。


createInDb = true ——> 是否创建表,默认为true。


generateConstructors = true ——> 是否生成含所有参数的构造函数,默认为true。


generateGettersSetters = true ——> 是否生成getter/setter,默认为true。

 

 

 

2.@Id:用来声明某变量为表的主键,类型使用Long 。


@Id()括号可加入autoincrement = true表明自增长。

 

 

3.@Unique:用来声明某变量的值需为唯一值。

 

 

4.@NotNull:用来声明某变量的值不能为null。

 

 

5.@Property 
 

@Property(nameInDb = “URL”) 用来声明某变量在表中的实际字段名为URL。

 

 

6.@Transient:用来声明某变量不被映射到数据表中。

 

 

 

7.@ToOne、@ToMany:用来声明”对一”和“对多”关系。

 

 

 

 

 

三.语句讲解

 

1.增

Android GreenDao数据库—高级详解_第2张图片

 

1.1.插入单条数据

    /**
     * 插入一条记录
     */

    public void insertUser() {
        //获取实体类
        UserInfo userInfo=new UserInfo();
        userInfo.setId(id);
        userInfo.setName("张三");
        userInfo.setAge("29");
        //获取相应的Dao
        UserInfoDao userInfoDao= MyApplication.getDaoInstant().getUserInfoDao();
        //插入一条数据
        userInfoDao.insert(userInfo);
    }

 

 

1.2.插入多条数据

    /**
     * 插入多条记录
     */

    public void insertUserList() {
        //获取实体类
        UserInfo userInfo1=new UserInfo();
        userInfo1.setId(id);
        userInfo1.setName("张三");
        userInfo1.setAge("29");

        UserInfo userInfo2=new UserInfo();
        userInfo2.setId(id+1);
        userInfo2.setName("李四");
        userInfo2.setAge("39");

        List list=new ArrayList<>();
        list.add(userInfo1);
        list.add(userInfo2);

        //获取相应的Dao
        UserInfoDao userInfoDao= MyApplication.getDaoInstant().getUserInfoDao();
        //插入多条数据
        userInfoDao.insertInTx(list);
    }

 

 

 

2.插入或替换(插入的数据如果已经存在表中,则替换掉旧数据(根据主键来检测是否已经存在))

Android GreenDao数据库—高级详解_第3张图片

 

2.1.插入或替换一条数据

 /**
     * 插入或替换一条记录
     */

    public void insertUser() {
        //获取实体类
        UserInfo userInfo=new UserInfo();
        userInfo.setId(id);
        userInfo.setName("张三");
        userInfo.setAge("29");
        //获取相应的Dao
        UserInfoDao userInfoDao= MyApplication.getDaoInstant().getUserInfoDao();
        //插入或替换一条数据
        userInfoDao.insertOrReplace(userInfo);
    }

 

 

2.2.插入或替换多条数据

  /**
     * 插入或替换多条记录
     */

    public void insertUserList() {
        //获取实体类
        UserInfo userInfo1=new UserInfo();
        userInfo1.setId(id);
        userInfo1.setName("张三");
        userInfo1.setAge("29");

        UserInfo userInfo2=new UserInfo();
        userInfo2.setId(id+1);
        userInfo2.setName("李四");
        userInfo2.setAge("39");

        List list=new ArrayList<>();
        list.add(userInfo1);
        list.add(userInfo2);

        //获取相应的Dao
        UserInfoDao userInfoDao= MyApplication.getDaoInstant().getUserInfoDao();
        //插入或替换多条数据
        userInfoDao.insertOrReplaceInTx(list);
    }

 

 

3.删

Android GreenDao数据库—高级详解_第4张图片

 

3.1.删除一条数据

    /**
     * 删除一条记录
     */

    public void deleteUser() {
        //获取实体类
        UserInfo userInfo=new UserInfo();
        userInfo.setId(id);
        userInfo.setName("张三");
        userInfo.setAge("29");
        //获取相应的Dao
        UserInfoDao userInfoDao= MyApplication.getDaoInstant().getUserInfoDao();
        //删除一条数据
        userInfoDao.delete(userInfo);
    }

 

 

3.2.删除多条数据

    /**
     * 删除多条记录
     */

    public void deleteUser() {
        //获取实体类
        UserInfo userInfo1=new UserInfo();
        userInfo1.setId(id);
        userInfo1.setName("张三");
        userInfo1.setAge("29");

        UserInfo userInfo2=new UserInfo();
        userInfo2.setId(id+1);
        userInfo2.setName("李四");
        userInfo2.setAge("39");
        
        List list=new ArrayList<>();
        list.add(userInfo1);
        list.add(userInfo2);
        
        //获取相应的Dao
        UserInfoDao userInfoDao= MyApplication.getDaoInstant().getUserInfoDao();
        //删除多条数据
        userInfoDao.deleteInTx(list);
    }

 

 

3.3.删除全部数据

    /**
     * 删除所有记录
     */

    public void deleteUser() {
        //获取相应的Dao
        UserInfoDao userInfoDao= MyApplication.getDaoInstant().getUserInfoDao();
        //删除所有数据
        userInfoDao.deleteAll();
    }

 

 

4.改

Android GreenDao数据库—高级详解_第5张图片

 

 

4.1.修改一条数据

    /**
     * 更新一条记录
     */

    public void updateUser() {
        //获取实体类
        UserInfo userInfo=new UserInfo();
        userInfo.setId(id);
        userInfo.setName("张三更新");
        userInfo.setAge("30");
        //获取相应的Dao
        UserInfoDao userInfoDao= MyApplication.getDaoInstant().getUserInfoDao();
        //更新一条数据
        userInfoDao.update(userInfo);
    }

 

 

4.2.修改多条数据

    /**
     * 更新多条记录
     */

    public void updateUser() {
        //获取实体类
        UserInfo userInfo1=new UserInfo();
        userInfo1.setId(id);
        userInfo1.setName("张三更新");
        userInfo1.setAge("30");

        //获取实体类
        UserInfo userInfo2=new UserInfo();
        userInfo2.setId(id+1);
        userInfo2.setName("李四更新");
        userInfo2.setAge("40");
        
        List list=new ArrayList<>();
        list.add(userInfo1);
        list.add(userInfo2);
        
        //获取相应的Dao
        UserInfoDao userInfoDao= MyApplication.getDaoInstant().getUserInfoDao();
        //更新多条数据
        userInfoDao.updateInTx(list);
    }

 

 

5.查

 

5.1.查询全部数据

 

5.1.1.QueryBuilder 查询全部

 /**
     * 查询数据列表
     */

    public List queryUserList() {
        UserInfoDao userInfoDao= MyApplication.getDaoInstant().getUserInfoDao();
        QueryBuilder qb = userInfoDao.queryBuilder();
        List list = qb.list();
        return list;
    }

 

 

5.1.2.loadAll 查询全部

    /**
     * 查询数据列表
     */

    public List queryUserList() {
        UserInfoDao userInfoDao= MyApplication.getDaoInstant().getUserInfoDao();
        List list = userInfoDao.loadAll();
        return list;
    }

 

 

5.2.查询数量

    /**
     * 查询数据列表数量
     */

    public long queryUserList() {
        UserInfoDao userInfoDao= MyApplication.getDaoInstant().getUserInfoDao();
        long count=userInfoDao.count();
        return count;
    }

 

 

5.3.条件查询

 

5.3.1.精确查询(where)

 

/**
     * 查询多条数据 姓名=“张三”
     */

    public List queryUserList() {
        UserInfoDao userInfoDao= MyApplication.getDaoInstant().getUserInfoDao();
        QueryBuilder qb = userInfoDao.queryBuilder();
        List list = qb.where(UserInfoDao.Properties.Name.eq("张三")).list();
        return list;
    }

 

    /**
     * 查询一条数据 姓名=“张三”
     */

    public UserInfo queryUserList() {
        UserInfoDao userInfoDao= MyApplication.getDaoInstant().getUserInfoDao();
        QueryBuilder qb = userInfoDao.queryBuilder();
        UserInfo userInfo = qb.where(UserInfoDao.Properties.Name.eq("张三")).unique();
        return userInfo;
    }

 

 

5.3.2.模糊查询(like)

/**
     * 查询数据列表 姓名以“张” 开头
     */

    public List queryUserList() {
        UserInfoDao userInfoDao= MyApplication.getDaoInstant().getUserInfoDao();
        QueryBuilder qb = userInfoDao.queryBuilder();
        List list = qb.where(UserInfoDao.Properties.Name.like("张%")).list();
        return list;
    }

 

 /**
     * 查询数据列表 姓名以“三” 结尾
     */

    public List queryUserList() {
        UserInfoDao userInfoDao= MyApplication.getDaoInstant().getUserInfoDao();
        QueryBuilder qb = userInfoDao.queryBuilder();
        List list = qb.where(UserInfoDao.Properties.Name.like("%三")).list();
        return list;
    }

 

 

 

5.3.3.区间查询

 

插入的数据

 /**
     * 插入多条记录
     */

    public void insertUser() {
        UserInfo userInfo=new UserInfo();
        userInfo.setId(id);
        userInfo.setName("张三");
        userInfo.setAge("30");

        UserInfo userInfo1=new UserInfo();
        userInfo1.setId(id+12);
        userInfo1.setName("李四");
        userInfo1.setAge("39");

        UserInfo userInfo2=new UserInfo();
        userInfo2.setId(id+13);
        userInfo2.setName("旺旺");
        userInfo2.setAge("20");

        UserInfo userInfo3=new UserInfo();
        userInfo3.setId(id+14);
        userInfo3.setName("王伟");
        userInfo3.setAge("59");

        List list=new ArrayList<>();
        list.add(userInfo);
        list.add(userInfo1);
        list.add(userInfo2);
        list.add(userInfo3);

        UserInfoDao userInfoDao= MyApplication.getDaoInstant().getUserInfoDao();
        userInfoDao.insertInTx(list);
    }

 

大于 gt

/**
     * 查询数据列表 年龄大于30
     */

    public List queryUserList() {
        UserInfoDao userInfoDao= MyApplication.getDaoInstant().getUserInfoDao();
        QueryBuilder qb = userInfoDao.queryBuilder();
        List list = qb.where(UserInfoDao.Properties.Age.gt("30")).list();
        return list;
    }

Android GreenDao数据库—高级详解_第6张图片

 

 

 

大于等于 ge

/**
     * 查询数据列表 年龄大于等于30
     */

    public List queryUserList() {
        UserInfoDao userInfoDao= MyApplication.getDaoInstant().getUserInfoDao();
        QueryBuilder qb = userInfoDao.queryBuilder();
        List list = qb.where(UserInfoDao.Properties.Age.ge("30")).list();
        return list;
    }

Android GreenDao数据库—高级详解_第7张图片

 

 

小于 lt

 /**
     * 查询数据列表 年龄小于30
     */

    public List queryUserList() {
        UserInfoDao userInfoDao= MyApplication.getDaoInstant().getUserInfoDao();
        QueryBuilder qb = userInfoDao.queryBuilder();
        List list = qb.where(UserInfoDao.Properties.Age.lt("30")).list();
        return list;
    }

Android GreenDao数据库—高级详解_第8张图片

 

 

 

小于等于 le

/**
     * 查询数据列表 年龄小于等于30
     */

    public List queryUserList() {
        UserInfoDao userInfoDao= MyApplication.getDaoInstant().getUserInfoDao();
        QueryBuilder qb = userInfoDao.queryBuilder();
        List list = qb.where(UserInfoDao.Properties.Age.le("30")).list();
        return list;
    }

Android GreenDao数据库—高级详解_第9张图片

 

 

 

两者之间 between (包含 开头和结尾)

/**
     * 查询数据列表 年龄【30,59】
     */

    public List queryUserList() {
        UserInfoDao userInfoDao= MyApplication.getDaoInstant().getUserInfoDao();
        QueryBuilder qb = userInfoDao.queryBuilder();
        List list = qb.where(UserInfoDao.Properties.Age.between("30","59")).list();
        return list;
    }

Android GreenDao数据库—高级详解_第10张图片

 

 

 

 

5.4.升序降序

 

插入的数据和5.3.3一样

 

升序

    /**
     * 查询数据列表 按年龄升序排序
     */

    public List queryUserList() {
        UserInfoDao userInfoDao= MyApplication.getDaoInstant().getUserInfoDao();
        QueryBuilder qb = userInfoDao.queryBuilder();
        List list = qb.orderAsc(UserInfoDao.Properties.Age).list();
        return list;
    }

 

Android GreenDao数据库—高级详解_第11张图片

 

 

降序

/**
     * 查询数据列表 按年龄降序排序
     */

    public List queryUserList() {
        UserInfoDao userInfoDao= MyApplication.getDaoInstant().getUserInfoDao();
        QueryBuilder qb = userInfoDao.queryBuilder();
        List list = qb.orderDesc(UserInfoDao.Properties.Age).list();
        return list;
    }

Android GreenDao数据库—高级详解_第12张图片

 

 

组合

 /**
     * 查询数据列表 年龄【30,59】然后再降序排序
     */

    public List queryUserList() {
        UserInfoDao userInfoDao= MyApplication.getDaoInstant().getUserInfoDao();
        QueryBuilder qb = userInfoDao.queryBuilder();
        List list = qb.where(UserInfoDao.Properties.Age.between("30","59")).orderDesc(UserInfoDao.Properties.Age).list();
        return list;
    }

Android GreenDao数据库—高级详解_第13张图片

 

 

 

 

 

四.缓存问题

 

如果GreenDao开启了缓存,所以当你调用 某一条查询语句 取得 A实体,然后对 A实体 进行修改并更新到数据库,接着再调用 某一条查询语句 取得 A实体,会发现X实体的内容依旧是修改前的。其实你的修改已经更新到数据库中,只是查询采用了缓存,所以直接返回了第一次查询的实体。

 

//清空所有数据表的缓存数据
DaoSession daoSession =MyApplication.getDaoInstant();
daoSession .clear();

//清空某个数据表的缓存数据
UserInfoDao movieCollectDao = MyApplication.getDaoInstant().getUserInfoDao();
movieCollectDao.detachAll();

 

本人代码 没有设置缓存

 

    /**
     * 各种点击事件的方法
     */

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.activity_greendaocache_textview1://1.查
                userInfo=queryUserList();
                String result="ID:"+userInfo.getId()+"  姓名:"+userInfo.getName()+"  "+"年龄:"+userInfo.getAge();
                textView.setText(result);
                break;
            case R.id.activity_greendaocache_textview2://2.改
                if(null!=userInfo){
                    //修改
                    userInfo.setAge("1111");
                    userInfo.setName("张三");
                    //将修改的内容更新到数据库
                    UserInfoDao userInfoDao=MyApplication.getDaoInstant().getUserInfoDao();
                    userInfoDao.update(userInfo);
                }
                break;
            case R.id.activity_greendaocache_textview3://3.查
                UserInfo userInfo=queryUserList();
                String results="ID(新):"+userInfo.getId()+"  姓名(新):"+userInfo.getName()+"  "+"年龄(新):"+userInfo.getAge();
                textView.setText(results);
                break;
            case R.id.activity_greendaocache_textview11://1.查(清缓存)

                break;
            case R.id.activity_greendaocache_textview22://2.改(清缓存)

                break;
            case R.id.activity_greendaocache_textview33://3.查(清缓存)

                break;
            default:
                break;
        }
    }

    /**
     * 查询一条数据列表 姓名=“张三”
     */

    public UserInfo queryUserList() {
        UserInfoDao userInfoDao= MyApplication.getDaoInstant().getUserInfoDao();
        QueryBuilder qb = userInfoDao.queryBuilder();
        UserInfo userInfo = qb.where(UserInfoDao.Properties.Name.eq("张三")).unique();
        return userInfo;
    }

 

1.查

Android GreenDao数据库—高级详解_第14张图片

 

 

3.查

Android GreenDao数据库—高级详解_第15张图片

 

 

 

 

 

 

五.加密

 

1.默认获取

    private void setupDatabase() {
        //创建数据库shop.db 创建SQLite数据库的SQLiteOpenHelper的具体实现
        DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(this, "greendaodemo.db", null);
        //获取SQLiteDatabase对象
        SQLiteDatabase db = helper.getReadableDatabase();
        //获取数据库对象
        DaoMaster daoMaster = new DaoMaster(db);
        //获取dao对象管理者
        daoSession = daoMaster.newSession();
    }

 

1.1.获取 SQLiteDatabase 对象

//获取SQLiteDatabase对象
SQLiteDatabase db = helper.getReadableDatabase();

1.2.获取 DaoMaster 对象

//获取数据库对象
DaoMaster daoMaster = new DaoMaster(db);

1.3.此时 DaoMaster 构造方法

public DaoMaster(SQLiteDatabase db) {
     this(new StandardDatabase(db));
}

 

 

2.加密获取

 

2.1.添加配置

implementation 'net.zetetic:android-database-sqlcipher:3.5.7'

 

2.2.获取

    private void setupDatabase() {
        //创建数据库shop.db 创建SQLite数据库的SQLiteOpenHelper的具体实现
        DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(this, "greendaodemo.db", null);
        //获取Database对象
        Database db = helper.getEncryptedReadableDb("1q2w3e4r");
        //获取数据库对象
        DaoMaster daoMaster = new DaoMaster(db);
        //获取dao对象管理者
        daoSession = daoMaster.newSession();
    }

 

 

2.3.获取 Database 对象

 //获取Database对象
Database db = helper.getEncryptedReadableDb("1q2w3e4r");

 

 

2.4.获取 DaoMaster 对象

 //获取数据库对象
 DaoMaster daoMaster = new DaoMaster(db);

 

 

2.5.此时DaoMaster构造方法

    public DaoMaster(Database db) {
        super(db, SCHEMA_VERSION);
        registerDaoClass(PeopleDao.class);
        registerDaoClass(UserInfoDao.class);
    }

 

 

2.6.获取 Database 对象 其他方法

Android GreenDao数据库—高级详解_第16张图片

 

 

 

3.说明

加密需要添加sqlcipher库,而该库体积庞大,使用后apk大小会增加大概10M,所以如果你的应用对安全性要求不高,不建议使用。

 

 

加密前APK大小

Android GreenDao数据库—高级详解_第17张图片

 

 

加密后APK大小

Android GreenDao数据库—高级详解_第18张图片

 

 

代码链接:https://github.com/wujianning/AndroidDBDemo

你可能感兴趣的:(Android,数据库)