GreenDAO 核心组件、属性及方法详解
GreenDAO 是一个高效的 Android ORM 框架,主要包含五大核心组件:Entity(实体类)、DaoMaster(数据库管理)、DaoSession(会话管理)、DAO(数据访问对象)和 QueryBuilder(查询构建)。实体类通过注解定义表结构,支持主键、索引、关联关系等特性。DaoMaster 负责数据库创建和版本升级,DaoSession 提供事务管理和 DAO 访问。DAO 组件实现完整的 CRUD 操作,而 QueryBuilder 支持条件查询、排序分页等高级功能。该框架通过注解简化数据库操作,并提供延迟加载、批量处理等优化机制。
主要包含以下核心组件和它们的常用属性、方法:
一、核心组件概述
-
Entity(实体类)
- 对应数据库表
- 使用
@Entity
注解定义
-
DaoMaster
- 数据库创建和版本管理工具
- 管理所有 DAO 类
-
DaoSession
- 提供对具体 DAO 的访问
- 管理数据库会话和事务
-
DAO(数据访问对象)
- 提供对单个实体的 CRUD 操作
- 每个实体对应一个 DAO 类
-
QueryBuilder
- 用于构建复杂查询
- 支持条件过滤、排序、分页等
二、Entity(实体类)注解及属性
常用注解
@Entity(
nameInDb = "USER", // 数据库表名
indexes = { // 索引定义
@Index(value = "name, age DESC", unique = true)
},
schema = "myschema", // 模式名称
active = true // 是否生成Active实体(支持持久化方法)
)
public class User {
@Id(autoincrement = true) // 主键,自增
private Long id;
@Property(nameInDb = "USER_NAME") // 数据库字段名
private String name;
@NotNull // 非空约束
private int age;
@Unique // 唯一约束
private String email;
@Transient // 不持久化的字段
private int tempField;
// 关系注解
@ToOne(joinProperty = "addressId") // 一对一关系
private Address address;
@ToMany(referencedJoinProperty = "userId") // 一对多关系
private List<Order> orders;
@Generated(hash = 123456789) // GreenDAO自动生成的构造方法和方法
// ...
}
三、DaoMaster 常用方法
// 创建或打开数据库
DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(context, "mydb.db");
Database db = helper.getWritableDb(); // 可写数据库
Database db = helper.getReadableDb(); // 只读数据库
// 创建 DaoMaster
DaoMaster daoMaster = new DaoMaster(db);
// 手动升级数据库(需自定义 MigrationHelper)
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);
}
});
四、DaoSession 常用方法
// 获取 DaoSession
DaoSession daoSession = daoMaster.newSession();
// 获取具体 DAO
UserDao userDao = daoSession.getUserDao();
OrderDao orderDao = daoSession.getOrderDao();
// 执行事务
daoSession.runInTx(() -> {
// 事务内操作
userDao.insert(new User());
orderDao.deleteAll();
});
// 清除所有缓存实体
daoSession.clear();
五、DAO 常用方法(以 UserDao 为例)
1. 插入操作
// 插入单个实体
long id = userDao.insert(user);
// 插入或替换(主键存在则更新)
userDao.insertOrReplace(user);
// 批量插入(高效)
userDao.insertInTx(users);
2. 查询操作
// 通过主键获取
User user = userDao.load(1L);
// 获取所有记录
List<User> users = userDao.loadAll();
// 使用 QueryBuilder 查询
List<User> users = userDao.queryBuilder()
.where(UserDao.Properties.Age.gt(18))
.orderAsc(UserDao.Properties.Name)
.limit(10)
.list();
// 查询唯一记录
User user = userDao.queryBuilder()
.where(UserDao.Properties.Email.eq("test@example.com"))
.unique();
3. 更新操作
// 更新单个实体
user.setName("New Name");
userDao.update(user);
// 批量更新
userDao.updateInTx(users);
4. 删除操作
// 通过主键删除
userDao.deleteByKey(1L);
// 删除实体
userDao.delete(user);
// 删除所有记录
userDao.deleteAll();
// 批量删除
userDao.deleteInTx(users);
5. 其他常用方法
// 统计记录数
long count = userDao.count();
// 刷新实体(从数据库重新加载)
userDao.refresh(user);
// 检查实体是否已被持久化
boolean isAttached = userDao.isEntityUpdateable(user);
六、QueryBuilder 常用方法
1. 条件查询
// 相等条件
queryBuilder.where(UserDao.Properties.Name.eq("John"));
// 范围条件
queryBuilder.where(UserDao.Properties.Age.between(20, 30));
// LIKE 条件
queryBuilder.where(UserDao.Properties.Name.like("%test%"));
// IN 条件
queryBuilder.where(UserDao.Properties.Id.in(1L, 2L, 3L));
// 复合条件(AND)
queryBuilder.where(
UserDao.Properties.Age.gt(18),
UserDao.Properties.Gender.eq("F")
);
// 复合条件(OR)
queryBuilder.where(
Or(UserDao.Properties.Age.lt(20), UserDao.Properties.Name.like("A%"))
);
2. 排序与分页
// 升序排序
queryBuilder.orderAsc(UserDao.Properties.CreateTime);
// 降序排序
queryBuilder.orderDesc(UserDao.Properties.Name);
// 分页
queryBuilder.offset(10).limit(20); // 跳过前10条,取20条
3. 查询结果处理
// 返回列表
List<User> users = queryBuilder.list();
// 返回唯一结果(不存在或多条记录会抛出异常)
User user = queryBuilder.uniqueOrThrow();
// 返回第一条记录
User firstUser = queryBuilder.listLazy().get(0);
// 只查询特定字段(投影)
queryBuilder.select(UserDao.Properties.Id, UserDao.Properties.Name).list();
4. 优化查询
// 延迟加载(适用于大结果集)
List<User> lazyList = queryBuilder.listLazy();
// 迭代器方式(内存友好)
CloseableListIterator<User> iterator = queryBuilder.listLazyUncached().iterator();
try {
while (iterator.hasNext()) {
User user = iterator.next();
// 处理用户
}
} finally {
iterator.close();
}
七、关系操作(示例)
1. 一对一关系
// User 实体中定义
@ToOne(joinProperty = "addressId")
private Address address;
// 加载关联对象
userDao.refresh(user); // 刷新后会加载 address
Address address = user.getAddress();
2. 一对多关系
// User 实体中定义
@ToMany(referencedJoinProperty = "userId")
private List<Order> orders;
// 加载关联列表
List<Order> orders = user.getOrders(); // 第一次调用会触发加载
3. 多对多关系
需要通过中间表实现,例如:
// User 实体
@ToMany(joinProperties = {
@JoinProperty(name = "id", referencedName = "userId")
})
private List<UserOrder> userOrders;
// 通过中间表获取订单
List<Order> orders = new ArrayList<>();
for (UserOrder userOrder : user.getUserOrders()) {
orders.add(userOrder.getOrder());
}
八、高级功能
1. 原生 SQL 查询
// 执行原生 SQL 查询
Cursor cursor = daoSession.getDatabase().rawQuery(
"SELECT * FROM USER WHERE AGE > ?",
new String[]{"18"}
);
// 解析 Cursor
try {
while (cursor.moveToNext()) {
long id = cursor.getLong(0);
String name = cursor.getString(1);
// 处理数据
}
} finally {
cursor.close();
}
2. 加密数据库
// 使用 SQLCipher 加密数据库
DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(context, "encrypted-db") {
@Override
public Database getWritableDb(String password) {
return super.getWritableDb(password);
}
};
Database db = helper.getWritableDb("your-password");
DaoMaster daoMaster = new DaoMaster(db);
3. 数据库迁移
public class MigrationHelper {
public static void migrate(Database db, int oldVersion, int newVersion) {
if (oldVersion < 2) {
// 添加新表
NewEntityDao.createTable(db, false);
}
if (oldVersion < 3) {
// 添加新字段
db.execSQL("ALTER TABLE USER ADD COLUMN NEW_FIELD TEXT;");
}
}
}