Skip to content

Instantly share code, notes, and snippets.

@nickfox-taterli
Created April 23, 2025 09:11
Show Gist options
  • Save nickfox-taterli/6ab1c3c04b6b5e8204485f88159cc09a to your computer and use it in GitHub Desktop.
Save nickfox-taterli/6ab1c3c04b6b5e8204485f88159cc09a to your computer and use it in GitHub Desktop.
安卓数据库操作简化笔记

简化ImageDbHelper操作。

1. 使用Room实现

1.1 定义Entity类

@Entity(tableName = "images")
public class ImageInfo {
    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "_id")
    private long id;
    
    @ColumnInfo(name = "md5")
    private String md5;
    
    @ColumnInfo(name = "path")
    private String path;
    
    @ColumnInfo(name = "size")
    private long size;
    
    @ColumnInfo(name = "width")
    private int width;
    
    @ColumnInfo(name = "height")
    private int height;
    
    @ColumnInfo(name = "date_added")
    private long dateAdded;
    
    // Getters and setters...
}

1.2 定义DAO接口

@Dao
public interface ImageDao {
    @Insert(onConflict = OnConflictStrategy.IGNORE)
    long insertImage(ImageInfo imageInfo);
    
    @Query("SELECT * FROM images WHERE md5 = :md5 LIMIT 1")
    ImageInfo getImageByMd5(String md5);
    
    @Query("SELECT * FROM images ORDER BY date_added DESC")
    List<ImageInfo> getAllImages();
    
    @Delete
    void deleteImage(ImageInfo imageInfo);
    
    @Update
    int updateImage(ImageInfo imageInfo);
    
    @Query("SELECT EXISTS(SELECT * FROM images WHERE md5 = :md5)")
    boolean isImageExists(String md5);
}

1.3 定义Database类

@Database(entities = {ImageInfo.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
    public abstract ImageDao imageDao();
    
    private static volatile AppDatabase INSTANCE;
    
    public static AppDatabase getInstance(Context context) {
        if (INSTANCE == null) {
            synchronized (AppDatabase.class) {
                if (INSTANCE == null) {
                    INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
                                    AppDatabase.class, "ImageDatabase.db")
                            .build();
                }
            }
        }
        return INSTANCE;
    }
}

1.4 使用示例

AppDatabase db = AppDatabase.getInstance(context);
ImageDao imageDao = db.imageDao();

// 插入
ImageInfo image = new ImageInfo();
// 设置image属性...
long id = imageDao.insertImage(image);

// 查询
List<ImageInfo> images = imageDao.getAllImages();

// 检查存在
boolean exists = imageDao.isImageExists("some_md5");

2. 使用GreenDAO实现

2.1 定义Entity类

@Entity
public class ImageInfo {
    @Id(autoincrement = true)
    private Long id;
    
    @Unique
    private String md5;
    private String path;
    private long size;
    private int width;
    private int height;
    private long dateAdded;
    
    // Getters and setters...
}

2.2 初始化GreenDAO

public class DaoManager {
    private static final String DB_NAME = "ImageDatabase.db";
    private static DaoSession daoSession;
    
    public static void init(Context context) {
        DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(context, DB_NAME);
        Database db = helper.getWritableDb();
        DaoMaster daoMaster = new DaoMaster(db);
        daoSession = daoMaster.newSession();
    }
    
    public static DaoSession getDaoSession() {
        return daoSession;
    }
}

2.3 使用示例

// 初始化 (在Application中)
DaoManager.init(context);

// 获取DAO
ImageInfoDao imageDao = DaoManager.getDaoSession().getImageInfoDao();

// 插入
ImageInfo image = new ImageInfo();
// 设置image属性...
long id = imageDao.insert(image);

// 查询
List<ImageInfo> images = imageDao.queryBuilder()
        .orderDesc(ImageInfoDao.Properties.DateAdded)
        .list();

// 检查存在
boolean exists = imageDao.queryBuilder()
        .where(ImageInfoDao.Properties.Md5.eq("some_md5"))
        .count() > 0;

3. 使用Realm实现

3.1 定义Model类

public class ImageInfo extends RealmObject {
    @PrimaryKey
    private long id;
    
    @Index
    private String md5;
    private String path;
    private long size;
    private int width;
    private int height;
    private long dateAdded;
    
    // Getters and setters...
    
    // Realm需要无参构造函数
    public ImageInfo() {}
}

3.2 初始化Realm

public class RealmManager {
    private static RealmConfiguration realmConfig;
    
    public static void init(Context context) {
        Realm.init(context);
        realmConfig = new RealmConfiguration.Builder()
                .name("ImageDatabase.realm")
                .schemaVersion(1)
                .build();
        Realm.setDefaultConfiguration(realmConfig);
    }
    
    public static Realm getRealm() {
        return Realm.getDefaultInstance();
    }
}

3.3 使用示例

// 初始化 (在Application中)
RealmManager.init(context);

// 获取Realm实例
Realm realm = RealmManager.getRealm();

// 插入
realm.executeTransaction(r -> {
    ImageInfo image = r.createObject(ImageInfo.class, generateId());
    // 设置image属性...
    image.setMd5("md5_value");
    // ...
});

// 查询
List<ImageInfo> images = realm.where(ImageInfo.class)
        .sort("dateAdded", Sort.DESCENDING)
        .findAll();

// 检查存在
boolean exists = realm.where(ImageInfo.class)
        .equalTo("md5", "some_md5")
        .count() > 0;

比较总结

  1. Room:

    • 官方推荐,与LiveData、ViewModel集成好
    • 编译时验证SQL查询
    • 需要较多的样板代码
  2. GreenDAO:

    • 性能优秀
    • 查询构建器API直观
    • 需要额外的初始化配置
  3. Realm:

    • 不是基于SQLite,有自己的数据库引擎
    • 自动更新对象,无需手动刷新
    • 跨平台支持好
    • 会增加APK大小

根据你的项目需求选择合适的ORM库。如果是新项目,推荐使用Room,因为它是Android官方维护的解决方案。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment