GreenDao3使用说明
来源:互联网 发布:java listfiles 排序 编辑:程序博客网 时间:2024/06/06 05:51
GreenDao 3
一个将对象映射到 SQLite 数据库中的轻量且快速的ORM解决方案
资料
Github
官网
android-database-sqlcipher Github
数据库加密
GreenDaoUpgradeHelper Github
数据库升级辅助
导入
- 在项目的 build.gradle 添加:
buildscript { repositories { mavenCentral() } dependencies { classpath 'org.greenrobot:greendao-gradle-plugin:3.2.0' }}// 使用数据库升级辅助GreenDaoUpgradeHelper时添加allprojects { repositories { ... maven { url "https://jitpack.io" } }}
- 在模组的 build.gradle 中添加:
apply plugin: 'org.greenrobot.greendao'dependencies { compile 'org.greenrobot:greendao:3.2.0' // 数据库加密时添加 compile 'net.zetetic:android-database-sqlcipher:3.5.1' // 使用数据库升级辅助GreenDaoUpgradeHelper时添加 compile 'com.github.yuweiguocn:GreenDaoUpgradeHelper:v1.2.0'}
- 设置 Schema,在模组的 build.gradle 中添加:
- schemaVersion:数据库schema版本号,通过
*OpenHelpers
迁移数据,schema改变值增加。默认为1 - daoPackage:生成DAOs、DaoMaster、DaoSession的包名。默认为entities所在包名。
- targetGenDir:生成DAOs、DaoMaster、DaoSession的目录。默认为
build/generated/source/greendao
- generateTests: 设置
true
自动生成单元测试。 - targetGenDirTests: 设置生成单元测试目录。默认为
src/androidTest/java
- schemaVersion:数据库schema版本号,通过
greendao { schemaVersion 1 daoPackage 'com.example.greendaodemo.dao' targetGenDir 'src/main/java'}
- 混淆
### greenDAO 3-keepclassmembers class * extends org.greenrobot.greendao.AbstractDao {public static java.lang.String TABLENAME;}-keep class **$Properties# If you do not use SQLCipher:-dontwarn org.greenrobot.greendao.database.**# If you do not use RxJava:-dontwarn rx.**
基本用法
实体
@Entity( // schema 名,多个 schema 时设置关联实体。插件产生不支持,需使用产生器 // schema = "myschema", // 标记一个实体是否处于活动状态,活动实体有 update、delete、refresh 方法。默认为 false active = false, // 表名,默认为类名 nameInDb = "AWESOME_USERS", // 定义多列索引 indexes = { @Index(value = "name DESC", unique = true) }, // 标记是否创建表,默认 true。多实体对应一个表或者表已创建,不需要 greenDAO 创建时设置 false createInDb = true, // 是否产生所有参数构造器。默认为 true。无参构造器必定产生 generateConstructors = true, // 如果没有 get/set 方法,是否生成。默认为 true generateGettersSetters = true)public class User { // 主键,autoincrement设置自增 @Id(autoincrement = true) private Long id; // 唯一,默认索引 @Unique private Long userId; // 列名,默认使用变量名。变化:customName --> CUSTOM_NAME @Property(nameInDb = "USERNAME") private String name; // 索引,unique设置唯一,name设置索引别名 @Index(unique = true) private long fk_dogId; // 非空 @NotNull private String horseName; // 忽略,不持久化,可用关键字transient替代 @Transient private int tempUsageCount; // 对一,实体属性与外联实体中的ID相对应。默认自动自动生成。fk和对象联动,同时改变。对象懒加载 @ToOne(joinProperty = "fk_dogId") private Dog dog; // 对多,referencedJoinProperty 指定实体中与外联实体属性相对应的外键 @ToMany(referencedJoinProperty = "fk_userId") private List<Cat> cats; // 对多,@JoinProperty注解:name 实体中的属性;referencedName 外联实体中的属性。 @ToMany(joinProperties = { @JoinProperty(name = "horseName", referencedName = "name") }) private List<Horse> horses; // 对多,@JoinEntity注解:entity 中间表;sourceProperty 实体属性;targetProperty 外链实体属性 @ToMany @JoinEntity( entity = JoinSheepToUser.class, sourceProperty = "uId", targetProperty = "sId" ) private List<Sheep> sheep;}@Entitypublic class JoinSheepToUser { @Id private Long id; private Long uId; private Long sId;}@Entitypublic class Sheep { @Id private Long id; private String name;}
@Generated
:greenDao生产代码注解,手动修改报错@Keep
:替换@Generated,greenDao不再生成,也不报错。@Generated(无hash)也有相同的效果@ToOne
:fk 和对象联动,同时改变。对象懒加载,第一次请求后立即获取对象@ToMany
:集合懒加载并缓存,之后获取集合不查找数据库,即集合数据不变。须手动修改集合,或调用reset方法清理集合
初始化
// Application 中执行// DevOpenHelper 每次数据库升级会清空数据,一般用于开发DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(this, "notes-db", null);Database db = helper.getWritableDb();DaoSession daoSession = new DaoMaster(db).newSession();// 在使用的地方获取 DAONoteDao noteDao = daoSession.getNoteDao();
Dao 增加
long insert(T entity) // 插入指定实体void insertInTx(T... entities)void insertInTx(java.lang.Iterable<T> entities)void insertInTx(java.lang.Iterable<T> entities, boolean setPrimaryKey)long insertWithoutSettingPk(T entity) // 插入指定实体,无主键long insertOrReplace(T entity) // 插入或替换指定实体void insertOrReplaceInTx(T... entities)void insertOrReplaceInTx(java.lang.Iterable<T> entities)void insertOrReplaceInTx(java.lang.Iterable<T> entities, boolean setPrimaryKey)void save(T entity) // 依赖指定的主键插入或修改实体void saveInTx(T... entities)void saveInTx(java.lang.Iterable<T> entities)
Dao 删除
void deleteAll() // 删除所有void delete(T entity) // 删除指定的实体void deleteInTx(T... entities)void deleteInTx(java.lang.Iterable<T> entities)void deleteByKey(K key) // 删除指定主键对应的实体void deleteByKeyInTx(K... keys)void deleteByKeyInTx(java.lang.Iterable<K> keys)
Dao 修改
void update(T entity)void updateInTx(T... entities)void updateInTx(java.lang.Iterable<T> entities)
Dao 其它
void refresh(T entity) // 从数据库获取值刷新本地实体long count() // 数量boolean detach(T entity) // 从域中分离实体void detachAll() // 从域中分离所有实体AbstractDaoSession getSession()Database getDatabase()java.lang.String getTablename()java.lang.String[] getAllColumns()java.lang.String[] getPkColumns()java.lang.String[] getNonPkColumns()Property getPkProperty()Property[] getProperties()
Dao 查询
java.util.List<T> loadAll()T load(K key)T loadByRowId(long rowId)
QueryBuilder 查询
List joes = userDao.queryBuilder() // 查询 User .where(Properties.FirstName.eq("Joe")) // 首名为 Joe .orderAsc(Properties.LastName) // 末名升序排列 .list(); // 返回集合// Joe,>= 1970.10QueryBuilder qb = userDao.queryBuilder();qb.where(Properties.FirstName.eq("Joe"), qb.or(Properties.YearOfBirth.gt(1970), qb.and(Properties.YearOfBirth.eq(1970), Properties.MonthOfBirth.ge(10))));List youngJoes = qb.list();
QueryBuilder<T> queryBuilder() // Dao// QueryBuilderQueryBuilder<T> where(WhereCondition cond, WhereCondition... condMore) // 条件,AND 连接QueryBuilder<T> whereOr(WhereCondition cond1, WhereCondition cond2, WhereCondition... condMore) // 条件,OR 连接QueryBuilder<T> distinct() // 去重,例如使用联合查询时QueryBuilder<T> limit(int limit) // 限制返回数QueryBuilder<T> offset(int offset) // 偏移结果起始位,配合limit(int)使用QueryBuilder<T> orderAsc(Property... properties) // 排序,升序QueryBuilder<T> orderDesc(Property... properties) // 排序,降序QueryBuilder<T> orderCustom(Property property, java.lang.String customOrderForProperty) // 排序,自定义QueryBuilder<T> orderRaw(java.lang.String rawOrder) // 排序,SQL 语句QueryBuilder<T> preferLocalizedStringOrder() // 本地化字符串排序,用于加密数据库无效QueryBuilder<T> stringOrderCollation(java.lang.String stringOrderCollation) // 自定义字符串排序,默认不区分大小写WhereCondition and(WhereCondition cond1, WhereCondition cond2, WhereCondition... condMore) // 条件,AND 连接WhereCondition or(WhereCondition cond1, WhereCondition cond2, WhereCondition... condMore) // 条件,OR 连接
Query 重复查询
// Joe,1970Query query = userDao.queryBuilder().where( Properties.FirstName.eq("Joe"), Properties.YearOfBirth.eq(1970)).build();List joesOf1970 = query.list();// Maria,1977query.setParameter(0, "Maria");query.setParameter(1, 1977);List mariasOf1977 = query.list();
// QueryBuilderQuery<T> build()CursorQuery buildCursor()CountQuery<T> buildCount()DeleteQuery<T> buildDelete()// Query// 设置查询参数,从 0 开始Query<T> setParameter(int index, java.lang.Object parameter)Query<T> setParameter(int index, java.lang.Boolean parameter)Query<T> setParameter(int index, java.util.Date parameter)void setLimit(int limit) // 限制返回数void setOffset(int offset) // 偏移结果起始位,配合limit(int)使用// Query 绑定线程,执行非本线程的 Query 抛异常,调用获取本线程 QueryQuery<T> forCurrentThread() // 获取本线程 Query
获取查询结果
// QueryBuilder、QueryT unique() // 返回唯一结果或者 nullT uniqueOrThrow() // 返回唯一非空结果,如果 null 则抛异常java.util.List<T> list() // 返回结果集进内存// 懒加载,须在 try/finally 代码中关闭。LazyList<T> listLazy() // 第一次使用返回结果集,所有数据使用后会自动关闭LazyList<T> listLazyUncached() // 返回虚拟结果集,数据库读取不缓存CloseableListIterator<T> listIterator() // 懒加载数据迭代器,不缓存,所有数据使用后会自动关闭// QueryBuilder、CountQuerylong count() // 获取结果数量
SQL 查询
// QueryBuilder.where() 配合 WhereCondition.StringCondition() 实现SQL查询Query query = userDao.queryBuilder() .where(new WhereCondition.StringCondition("_ID IN (SELECT USER_ID FROM USER_MESSAGE WHERE READ_FLAG = 0)")) .build();// Dao.queryRawCreate() 实现SQL查询Query query = userDao.queryRawCreate( ", GROUP G WHERE G.NAME=? AND T.GROUP_ID=G._ID", "admin");
// Daojava.util.List<T> queryRaw(java.lang.String where, java.lang.String... selectionArg)Query<T> queryRawCreate(java.lang.String where, java.lang.Object... selectionArg)Query<T> queryRawCreateListArgs(java.lang.String where, java.util.Collection<java.lang.Object> selectionArg)// WhereCondition.PropertyConditionPropertyCondition(Property property, java.lang.String op)PropertyCondition(Property property, java.lang.String op, java.lang.Object value)PropertyCondition(Property property, java.lang.String op, java.lang.Object[] values)// WhereCondition.StringConditionStringCondition(java.lang.String string)StringCondition(java.lang.String string, java.lang.Object value)StringCondition(java.lang.String string, java.lang.Object... values)
DeleteQuery 删除查询
DeleteQuery<T> buildDelete() // QueryBuilder
查询日志
QueryBuilder.LOG_SQL = true;QueryBuilder.LOG_VALUES = true;
DaoSession 增删改查
// DaoSession 的方法转换成 Dao 的对应方法执行<T> long insert(T entity)<T> long insertOrReplace(T entity)<T> void delete(T entity)<T> void deleteAll(java.lang.Class<T> entityClass)<T> void update(T entity)<T,K> T load(java.lang.Class<T> entityClass, K key)<T,K> java.util.List<T> loadAll(java.lang.Class<T> entityClass)<T> QueryBuilder<T> queryBuilder(java.lang.Class<T> entityClass)<T,K> java.util.List<T> queryRaw(java.lang.Class<T> entityClass, java.lang.String where, java.lang.String... selectionArgs)<T> void refresh(T entity)
进阶用法
联合查询
// 芝麻街住户QueryBuilder<User> queryBuilder = userDao.queryBuilder();queryBuilder.join(Address.class, AddressDao.Properties.userId) .where(AddressDao.Properties.Street.eq("Sesame Street"));List<User> users = queryBuilder.list();// 欧洲超过百万人口的城市QueryBuilder qb = cityDao.queryBuilder().where(Properties.Population.ge(1000000));Join country = qb.join(Properties.CountryId, Country.class);Join continent = qb.join(country, CountryDao.Properties.ContinentId, Continent.class, ContinentDao.Properties.Id);continent.where(ContinentDao.Properties.Name.eq("Europe"));List<City> bigEuropeanCities = qb.list();// 爷爷叫林肯的人QueryBuilder qb = personDao.queryBuilder();Join father = qb.join(Person.class, Properties.FatherId);Join grandfather = qb.join(father, Properties.FatherId, Person.class, Properties.Id);grandfather.where(Properties.Name.eq("Lincoln"));List<Person> lincolnDescendants = qb.list();
// QueryBuilder,联合查询<J> Join<T,J> join(java.lang.Class<J> destinationEntityClass, Property destinationProperty)<J> Join<T,J> join(Property sourceProperty, java.lang.Class<J> destinationEntityClass)<J> Join<T,J> join(Property sourceProperty, java.lang.Class<J> destinationEntityClass, Property destinationProperty)<J> Join<T,J> join(Join<?,T> sourceJoin, Property sourceProperty, java.lang.Class<J> destinationEntityClass, Property destinationProperty)
自定义类型
默认支持类型:byte[]
、String
、Date
、 boolean
、int
、short
、long
、float
、double
、byte
、 Boolean
、Integer
、Short
、Long
、Float
、Double
、Byte
// enum 转换为 Integer@Entitypublic class User { @Id private Long id; @Convert(converter = RoleConverter.class, columnType = Integer.class) private Role role; public enum Role { DEFAULT(0), AUTHOR(1), ADMIN(2); final int id; // 使用稳定的 id 来转换,不要使用不稳定的名字和顺序 Role(int id) { this.id = id; } } public static class RoleConverter implements PropertyConverter<Role, Integer> { @Override public Role convertToEntityProperty(Integer databaseValue) { if (databaseValue == null) { return null; } for (Role role : Role.values()) { if (role.id == databaseValue) { return role; } } return Role.DEFAULT; // 准备一个默认值,防止数据移除时崩溃 } @Override public Integer convertToDatabaseValue(Role entityProperty) { // 判断返回 null return entityProperty == null ? null : entityProperty.id; } }}
升级
使用 DevOpenHelper 每次升级数据库,表会删除重建,推荐开发使用。实际使用中建立类继承 DaoMaster.OpenHelper,实现 onUpgrade()
public class MySQLiteOpenHelper extends DaoMaster.OpenHelper { public MySQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory) { super(context, name, factory); } @Override public void onUpgrade(Database db, int oldVersion, int newVersion) { if (oldVersion == newVersion) { Log.d("onUpgrade", "数据库是最新版本" + oldVersion + ",不需要升级"); return; } Log.d("onUpgrade", "数据库从版本" + oldVersion + "升级到版本" + newVersion); switch (oldVersion) { case 1: String sql = ""; db.execSQL(sql); case 2: default: break; } }}// 初始化使用 MySQLiteOpenHelperMySQLiteOpenHelper helper = new MySQLiteOpenHelper(this, "notes-db", null);Database db = helper.getWritableDb();DaoSession daoSession = new DaoMaster(db).newSession();
另有升级辅助库 GreenDaoUpgradeHelper,通过 MigrationHelper 在删表重建的过程中,使用临时表保存数据并还原。
注意:MigrationHelper.migrate()
,暂时只接收 SQLiteDatabase ,不接收 Database,影响加密的使用。可修改源码支持。
public class MySQLiteOpenHelper extends DaoMaster.OpenHelper { public MySQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory) { super(context, name, factory); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { MigrationHelper.migrate(db,TestDataDao.class,TestData2Dao.class,TestData3Dao.class); }}// 初始化MigrationHelper.DEBUG = true; //如果你想查看日志信息,请将DEBUG设置为trueMySQLiteOpenHelper helper = new MySQLiteOpenHelper(this, "test.db", null);DaoMaster daoMaster = new DaoMaster(helper.getWritableDatabase());
高阶用法
SQLCipher 加密
- 使用
getEncryptedReadableDb()
和getEncryptedWritableDb()
获取加密的数据库 - 256位AES加密,会提升APK的大小
- Robolectric 测试时,须使用非加密数据库
DevOpenHelper helper = new DevOpenHelper(this, "notes-db-encrypted.db");Database db = helper.getEncryptedWritableDb("<your-secret-password>");DaoSession daoSession = new DaoMaster(db).newSession();
RxJava
// DaoSessionRxTransaction rxTx() // 返回 IO 线程下的 ObservablesRxTransaction rxTxPlain() // 返回无线程调度的 Observables// DaoRxDao<T,K> rx()RxDao<T,K> rxPlain()// QueryBuilderRxQuery<T> rx()RxQuery<T> rxPlain()
2 0
- GreenDao3使用说明
- GreenDao3 使用说明
- GreenDao3 使用说明
- greenDao3的使用说明
- GreenDao3-注解
- GreenDao3.0
- 使用说明
- 使用说明
- GreenDao3.1用法详解
- GreenDao3的集成
- GreenDao3.0学习(一)
- GreenDao3.0学习(二)
- GreenDao3 api、注解说明
- GreenDao3.0学习(三)
- greenDao3的基本使用
- GreenDao3使用笔记
- GreenDao3.0简单使用
- GreenDao3 数据库升级问题
- 大数据(二)
- 笔记
- 2016年9,10,11月份工作心得
- ajax data 参数与 dateType 参数 400(request error)
- github托管
- GreenDao3使用说明
- 三角函数
- 【LeetCode】405 Convert a Number to Hexadecimal (java实现)
- Visual Studio 2010 C++网络爬虫
- FFmpeg3.2最新版编译Mediacodec For Android脚本
- CentOS7中启动/停止/重启服务命令
- 微信开发第二天(创建第一个微信小程序)
- C语言程序练习三
- Linux学习之:七种运行级别