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

从SQLite迁移至Realm:如何打印Realm查询语句?

刚好我之前做过SQLite到Realm的迁移,也纠结过怎么把Realm的链式查询转换成像SQL那样直观的语句打印出来,给你分享两个实用的办法:

方法一:利用Realm原生API获取查询语句

Realm的RealmQuery对象自带了getQueryString()方法,能直接返回当前查询的条件表达式,我们只需要结合实体类名、排序规则等信息,就能拼接出类似SQL的语句。

拿你给出的查询为例,代码实现如下:

// 先构建你的Realm查询
RealmQuery<Patient> query = realm.where(Patient.class)
        .equalTo("revision", "8")
        .and()
        .beginGroup()
        .like("long_description", "*bone*").or()
        .like("code", "*bone*")
        .endGroup()
        .sort("code");

// 获取Realm原生的查询条件字符串
String realmQueryExpr = query.getQueryString();
// 拼接成SQL风格的语句
String sqlLikeQuery = String.format("SELECT * FROM Patient WHERE %s ORDER BY code", realmQueryExpr);

// 打印输出
System.out.println(sqlLikeQuery);

这段代码会输出:

SELECT * FROM Patient WHERE revision = "8" AND (long_description LIKE "bone" OR code LIKE "bone") ORDER BY code

注意:Realm的like查询用*作为通配符,而SQL用%,如果需要完全匹配SQL的格式,你可以手动替换字符串:

String sqlLikeQuery = String.format("SELECT * FROM Patient WHERE %s ORDER BY code", 
    realmQueryExpr.replace("*", "%"));
方法二:自定义工具类生成完美匹配SQL风格的语句

如果原生API返回的格式还是不符合你的预期,或者你想更灵活控制输出格式,可以自己封装一个工具类,在构建Realm查询的同时记录条件,最后生成完全贴合SQL的语句。

比如写一个简单的日志工具类:

public class RealmQuerySqlLogger<T> {
    private final Class<T> entityClass;
    private final StringBuilder conditionBuilder = new StringBuilder();
    private String sortField;

    public RealmQuerySqlLogger(Class<T> entityClass) {
        this.entityClass = entityClass;
    }

    // 记录equalTo条件
    public RealmQuerySqlLogger<T> equalTo(String field, Object value) {
        appendCondition(String.format("%s = '%s'", field, value));
        return this;
    }

    // 记录like条件,自动把Realm的*换成SQL的%
    public RealmQuerySqlLogger<T> like(String field, String pattern) {
        String sqlPattern = pattern.replace("*", "%");
        appendCondition(String.format("%s LIKE '%s'", field, sqlPattern));
        return this;
    }

    // 分组开始
    public RealmQuerySqlLogger<T> beginGroup() {
        conditionBuilder.append("(");
        return this;
    }

    // 分组结束
    public RealmQuerySqlLogger<T> endGroup() {
        conditionBuilder.append(")");
        return this;
    }

    // 逻辑AND
    public RealmQuerySqlLogger<T> and() {
        conditionBuilder.append(" AND ");
        return this;
    }

    // 逻辑OR
    public RealmQuerySqlLogger<T> or() {
        conditionBuilder.append(" OR ");
        return this;
    }

    // 记录排序字段
    public RealmQuerySqlLogger<T> sort(String field) {
        this.sortField = field;
        return this;
    }

    // 拼接条件的辅助方法
    private void appendCondition(String condition) {
        if (conditionBuilder.length() > 0 
            && !conditionBuilder.toString().endsWith("(")
            && !conditionBuilder.toString().endsWith(" AND ")
            && !conditionBuilder.toString().endsWith(" OR ")) {
            conditionBuilder.append(" AND ");
        }
        conditionBuilder.append(condition);
    }

    // 生成SQL风格的查询语句
    public String toSqlString() {
        StringBuilder sql = new StringBuilder(String.format("SELECT * FROM %s", entityClass.getSimpleName()));
        if (conditionBuilder.length() > 0) {
            sql.append(" WHERE ").append(conditionBuilder);
        }
        if (sortField != null) {
            sql.append(" ORDER BY ").append(sortField);
        }
        return sql.toString();
    }
}

使用这个工具类的方式也很简单,和构建Realm查询同步进行即可:

// 1. 用工具类记录查询条件
RealmQuerySqlLogger<Patient> queryLogger = new RealmQuerySqlLogger<>(Patient.class)
        .equalTo("revision", "8")
        .and()
        .beginGroup()
        .like("long_description", "*bone*")
        .or()
        .like("code", "*bone*")
        .endGroup()
        .sort("code");

// 打印SQL风格语句
System.out.println(queryLogger.toSqlString());

// 2. 正常执行Realm查询
RealmQuery<Patient> query = realm.where(Patient.class)
        .equalTo("revision", "8")
        .and()
        .beginGroup()
        .like("long_description", "*bone*").or()
        .like("code", "*bone*")
        .endGroup()
        .sort("code");
RealmResults<Patient> results = query.findAll();

这次输出的语句就和你原来的SQL几乎完全一致了:

SELECT * FROM Patient WHERE revision = '8' AND (long_description LIKE '%bone%' OR code LIKE '%bone%') ORDER BY code

小提示

  • 对于复杂查询(比如关联查询、聚合函数),原生API的getQueryString()可能无法完全转换成标准SQL,这时候自定义工具类的灵活性就体现出来了。
  • 如果是Kotlin项目,写法类似,Realm的RealmQuery同样有queryString属性可以直接获取查询表达式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:21:07