Android Room数据库中如何从带别名的查询获取数据
刚碰到过一模一样的问题,给你分享下我亲测有效的解决方案——Room其实对这种自定义查询结果的场景支持很灵活,不用死磕Entity类,用POJO就能完美搞定:
步骤1:创建用于承接查询结果的POJO类
首先新建一个普通的POJO类(比如叫Result.java),这个类不需要加@Entity注解,只需要定义和查询结果列名匹配的字段,以及对应的getter/setter方法就行(用public字段也可以,但封装起来更规范)。
举个例子,假设你的原Entity类UserTest.java是这样的:
@Entity(tableName = "user_test") public class UserTest { @PrimaryKey(autoGenerate = true) private int id; private String username; private String email; // 省略所有字段的getter和setter }
如果你的查询需要返回用户信息+统计总数(比如COUNT(*) AS rec_count),那Result.java可以这么写:
public class Result { // 原UserTest的字段,和数据库表字段对应 private int id; private String username; private String email; // 自定义统计字段,要和查询语句里的别名完全一致 private int rec_count; // 所有字段的getter和setter方法 public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public int getRec_count() { return rec_count; } public void setRec_count(int rec_count) { this.rec_count = rec_count; } }
小贴士:如果查询的别名和POJO字段名不想完全一致,可以用
@ColumnInfo(name = "别名")指定映射,比如@ColumnInfo(name = "rec_count") private int totalRecords;也能正常匹配。
步骤2:在Dao类中编写返回POJO的查询方法
接下来在你的UserDaoTest.java里,把查询方法的返回类型改成刚才创建的Result类(或者List<Result>,如果是多条结果的情况),同时确保SQL语句里的别名和POJO字段对应上。
比如这样写:
@Dao public interface UserDaoTest { // 示例:查询用户名包含"test"的用户,同时返回该条件下的总记录数 @Query("SELECT *, COUNT(*) OVER() AS rec_count FROM user_test WHERE username LIKE '%test%'") List<Result> getUsersWithTotalCount(); }
这里用窗口函数COUNT(*) OVER()给每条结果都带上总记录数,如果你是分组统计、单条结果+统计数,只需要调整@Query里的SQL语句就行,只要别名和POJO字段匹配就没问题。
额外提醒
其实不用把原Entity的所有字段都复制到POJO里——如果你的查询只需要部分字段+统计值,只在POJO里定义需要的字段就可以,Room会自动完成映射。比如你只需要username和rec_count,那Result里只保留这两个字段就行,不用写全所有UserTest的字段。
内容的提问来源于stack exchange,提问作者LEGEND MORTAL

