ActiveAndroid 开源项目教程:Android ORM 框架的完整指南
还在为 Android 开发中的 SQLite 数据库操作而烦恼吗?每次都要手动编写繁琐的 SQL 语句,处理数据库连接和游标管理?ActiveAndroid 正是为了解决这些痛点而生的轻量级 ORM(Object-Relational Mapping,对象关系映射)框架。
通过本文,你将掌握:
- ✅ ActiveAndroid 的核心概念和架构设计
- ✅ 快速集成和配置 ActiveAndroid
- ✅ 数据模型定义和注解使用技巧
- ✅ 完整的 CRUD(增删改查)操作示例
- ✅ 高级查询和关联关系处理
- ✅ 类型序列化和自定义配置
什么是 ActiveAndroid?
ActiveAndroid 是一个采用 Active Record 模式的 Android ORM 框架,它允许开发者通过面向对象的方式操作 SQLite 数据库,无需编写任何 SQL 语句。每个数据库记录都被封装成一个类,提供了 save()、delete() 等便捷方法。
核心架构设计
快速开始
1. 添加依赖
在项目的 build.gradle 中添加:
repositories {
mavenCentral()
maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
}
dependencies {
compile 'com.michaelpardo:activeandroid:3.1.0-SNAPSHOT'
}
2. 配置 Application
在 AndroidManifest.xml 中配置:
<application
android:name=".MyApplication"
android:allowBackup="true"
...>
</application>
创建自定义 Application 类:
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
Configuration.Builder config = new Configuration.Builder(this);
config.setDatabaseName("myapp.db");
config.setDatabaseVersion(1);
config.addModelClasses(User.class, Post.class, Comment.class);
ActiveAndroid.initialize(config.create());
}
@Override
public void onTerminate() {
super.onTerminate();
ActiveAndroid.dispose();
}
}
数据模型定义
基础模型类
@Table(name = "Users", id = "UserId")
public class User extends Model {
@Column(name = "username", notNull = true, unique = true)
public String username;
@Column(name = "email", length = 100)
public String email;
@Column(name = "age")
public int age;
@Column(name = "is_active", index = true)
public boolean isActive;
@Column(name = "created_at")
public Date createdAt;
}
注解详解
ActiveAndroid 提供了丰富的注解来控制数据库表结构:
| 注解属性 | 说明 | 示例 |
|---|---|---|
name | 列名/表名 | @Column(name = "user_name") |
notNull | 非空约束 | @Column(notNull = true) |
unique | 唯一约束 | @Column(unique = true) |
length | 字段长度 | @Column(length = 100) |
index | 创建索引 | @Column(index = true) |
关联关系
@Table(name = "Posts")
public class Post extends Model {
@Column(name = "title", notNull = true)
public String title;
@Column(name = "content", length = 1000)
public String content;
@Column(name = "author")
public User author; // 外键关联
@Column(name = "tags", indexGroups = {"tag_group"})
public String tags;
}
@Table(name = "Comments")
public class Comment extends Model {
@Column(name = "content")
public String content;
@Column(name = "post", onDelete = ForeignKeyAction.CASCADE)
public Post post; // 级联删除
@Column(name = "user")
public User user;
}
CRUD 操作实战
创建(Create)
// 创建新用户
User user = new User();
user.username = "john_doe";
user.email = "john@example.com";
user.age = 25;
user.isActive = true;
user.createdAt = new Date();
// 保存到数据库
Long userId = user.save();
System.out.println("用户ID: " + userId);
// 批量创建
List<User> users = new ArrayList<>();
for (int i = 0; i < 10; i++) {
User newUser = new User();
newUser.username = "user" + i;
newUser.email = "user" + i + "@example.com";
users.add(newUser);
}
// 批量保存
ActiveAndroid.beginTransaction();
try {
for (User u : users) {
u.save();
}
ActiveAndroid.setTransactionSuccessful();
} finally {
ActiveAndroid.endTransaction();
}
读取(Read)
// 查询所有用户
List<User> allUsers = new Select().from(User.class).execute();
// 条件查询
User user = new Select()
.from(User.class)
.where("username = ?", "john_doe")
.executeSingle();
// 复杂查询
List<User> activeUsers = new Select()
.from(User.class)
.where("age > ? AND is_active = ?", 18, true)
.orderBy("created_at DESC")
.limit(10)
.execute();
// 关联查询
List<Post> userPosts = new Select()
.from(Post.class)
.where("author = ?", userId)
.execute();
更新(Update)
// 加载用户
User user = User.load(User.class, 1L);
if (user != null) {
user.email = "new_email@example.com";
user.isActive = false;
user.save(); // 自动更新
}
// 批量更新
new Update(User.class)
.set("is_active = ?", false)
.where("age < ?", 18)
.execute();
删除(Delete)
// 删除单个对象
User user = User.load(User.class, 1L);
if (user != null) {
user.delete();
}
// 条件删除
new Delete()
.from(User.class)
.where("is_active = ?", false)
.execute();
// 清空表
new Delete().from(User.class).execute();
高级查询功能
聚合查询
// 计数
long userCount = new Select().from(User.class).count();
// 分组统计
String sql = "SELECT age, COUNT(*) as count FROM Users GROUP BY age";
Cursor cursor = Cache.openDatabase().rawQuery(sql, null);
// 最大最小值
User oldestUser = new Select()
.from(User.class)
.orderBy("age DESC")
.executeSingle();
连接查询
// 内连接
List<Post> postsWithAuthors = new Select()
.from(Post.class)
.join(User.class).on("Posts.author = Users.Id")
.execute();
// 左连接
List<Post> allPosts = new Select()
.from(Post.class)
.leftJoin(User.class).on("Posts.author = Users.Id")
.execute();
分页查询
int page = 2;
int pageSize = 20;
List<User> users = new Select()
.from(User.class)
.orderBy("created_at DESC")
.offset((page - 1) * pageSize)
.limit(pageSize)
.execute();
类型序列化
ActiveAndroid 支持自定义类型序列化器:
public class DateSerializer extends TypeSerializer {
@Override
public Class<?> getDeserializedType() {
return Date.class;
}
@Override
public Class<?> getSerializedType() {
return Long.class;
}
@Override
public Object serialize(Object data) {
if (data == null) return null;
return ((Date) data).getTime();
}
@Override
public Object deserialize(Object data) {
if (data == null) return null;
return new Date((Long) data);
}
}
配置序列化器:
Configuration.Builder config = new Configuration.Builder(this);
config.addTypeSerializer(DateSerializer.class);
数据库迁移
版本升级
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
Configuration.Builder config = new Configuration.Builder(this);
config.setDatabaseName("myapp.db");
config.setDatabaseVersion(2); // 升级版本号
config.addModelClasses(User.class, Post.class, Comment.class);
ActiveAndroid.initialize(config.create());
}
}
手动迁移
// 在适当的地方执行迁移脚本
SQLiteDatabase db = Cache.openDatabase();
db.execSQL("ALTER TABLE Users ADD COLUMN phone_number TEXT;");
性能优化建议
1. 批量操作使用事务
ActiveAndroid.beginTransaction();
try {
for (int i = 0; i < 1000; i++) {
User user = new User();
user.username = "user" + i;
user.save();
}
ActiveAndroid.setTransactionSuccessful();
} finally {
ActiveAndroid.endTransaction();
}
2. 合理使用索引
@Table(name = "Products")
public class Product extends Model {
@Column(name = "name", index = true)
public String name;
@Column(name = "category", indexGroups = {"category_index"})
public String category;
@Column(name = "price", indexGroups = {"category_index"})
public double price;
}
3. 缓存策略
// 调整缓存大小
Configuration.Builder config = new Configuration.Builder(this);
config.setCacheSize(2048); // 默认1024
// 手动管理缓存
Cache.clear();
Cache.removeEntity(user);
常见问题解决
1. 数据库锁定问题
// 使用 try-with-resources 确保资源释放
try (SQLiteDatabase db = Cache.openDatabase()) {
// 数据库操作
}
2. 模型变更处理
// 清空缓存并重新初始化
Cache.clear();
ActiveAndroid.dispose();
ActiveAndroid.initialize(config);
3. 数据类型转换
// 自定义类型处理
public class BigDecimalSerializer extends TypeSerializer {
@Override
public Class<?> getDeserializedType() {
return BigDecimal.class;
}
@Override
public Class<?> getSerializedType() {
return String.class;
}
@Override
public Object serialize(Object data) {
return data != null ? data.toString() : null;
}
@Override
public Object deserialize(Object data) {
return data != null ? new BigDecimal(data.toString()) : null;
}
}
最佳实践总结
-
模型设计原则
- 保持模型类简单清晰
- 合理使用注解控制数据库结构
- 避免过度设计关联关系
-
性能优化
- 批量操作使用事务
- 为常用查询字段添加索引
- 合理设置缓存大小
-
代码组织
- 统一管理数据模型类
- 使用 Repository 模式封装数据访问
- 编写单元测试验证数据操作
-
错误处理
- 妥善处理数据库异常
- 实现重试机制
- 记录操作日志
结语
ActiveAndroid 作为一个轻量级的 Android ORM 框架,极大地简化了 SQLite 数据库操作。通过本文的全面介绍,你应该已经掌握了从基础配置到高级特性的所有知识点。
在实际项目中,建议根据具体需求选择合适的 ORM 方案。对于简单的数据存储需求,ActiveAndroid 是一个优秀的选择;对于复杂的业务场景,可以考虑结合其他数据库框架使用。
记住,好的工具只是手段,清晰的数据模型设计和合理的架构规划才是项目成功的关键。希望 ActiveAndroid 能够帮助你提升开发效率,构建更优秀的 Android 应用!
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



