You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Android Room中使用SQLite Case表达式按指定列升降序查询数据

实现方案

1. 预定义MediaStore列与Room字段的映射关系

首先建立常量映射表,统一关联MediaStore的列名和你Room实体的字段名,同时做合法列名校验,避免SQL注入风险:

// 键为MediaStore列名,值为对应Room实体字段名
public static final Map<String, String> COLUMN_MAPPING = new HashMap<>();
static {
    COLUMN_MAPPING.put(MediaStore.Audio.Media.TITLE, "_title");
    COLUMN_MAPPING.put(MediaStore.Audio.Media.ALBUM, "_album");
    COLUMN_MAPPING.put(MediaStore.Audio.Media.ARTIST, "_artist");
    COLUMN_MAPPING.put(MediaStore.Audio.Media.COMPOSER, "_composer");
    COLUMN_MAPPING.put(MediaStore.Audio.Media.DATE_ADDED, "_dateAdded");
    COLUMN_MAPPING.put(MediaStore.Audio.Media.DURATION, "_duration");
    // 其他需要的字段按需补充
}

2. 定义Room DAO的动态查询方法

使用@RawQuery注解实现动态SQL查询,支持自定义列、自定义排序规则:

@Dao
public interface SongDao {
    // 动态查询,直接传入拼装好的SupportSQLiteQuery对象
    @RawQuery
    List<SongEntity> querySongs(SupportSQLiteQuery query);
}

3. 拼装查询逻辑实现复用

参考你原MediaStore查询的逻辑,拼装对应Room查询语句:

// 入参1:要查询的MediaStore列名集合 对应原方法的columns()参数
// 入参2:排序用的MediaStore列名 对应原方法的SortOrder参数
// 入参3:是否升序排序 true为ASC false为DESC
public List<SongEntity> querySongsFromRoom(List<String> mediaStoreColumns, String sortMediaStoreColumn, boolean isAsc) {
    // 1. 校验并转换要查询的列名
    List<String> roomColumns = new ArrayList<>();
    for (String mediaCol : mediaStoreColumns) {
        if (COLUMN_MAPPING.containsKey(mediaCol)) {
            roomColumns.add(COLUMN_MAPPING.get(mediaCol));
        }
    }
    // 如果没有合法列,默认查所有字段
    if (roomColumns.isEmpty()) {
        roomColumns.add("*");
    }

    // 2. 校验并转换排序字段
    String orderClause = "";
    if (COLUMN_MAPPING.containsKey(sortMediaStoreColumn)) {
        String roomSortColumn = COLUMN_MAPPING.get(sortMediaStoreColumn);
        orderClause = "ORDER BY " + roomSortColumn + (isAsc ? " ASC" : " DESC");
    }

    // 3. 拼装SQL语句,这里示例条件和原逻辑对齐,你可以按需扩展其他查询条件
    String sql = "SELECT " + TextUtils.join(",", roomColumns) + " FROM SongEntity " + orderClause;

    // 4. 构造查询对象执行查询
    SimpleSQLiteQuery query = new SimpleSQLiteQuery(sql);
    return songDao.querySongs(query);
}

注意事项

  • 所有动态拼接的列名必须经过COLUMN_MAPPING的存在性校验,禁止直接拼接外部传入的未校验字符串,避免SQL注入风险
  • 如果需要加过滤条件,推荐使用SimpleSQLiteQuery的绑定参数功能,不要直接拼接条件值,示例如下:
    // 比如要查询时长大于1分钟的歌曲
    String sql = "SELECT " + TextUtils.join(",", roomColumns) + " FROM SongEntity WHERE _duration > ? " + orderClause;
    SimpleSQLiteQuery query = new SimpleSQLiteQuery(sql, new Object[]{60 * 1000});
    

内容的提问来源于stack exchange,提问作者1234567

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 16:45:03