Android中使用OrmLite实现指定多表查询的方法咨询
如何用OrmLite实现你的跨表查询需求
嘿,我来帮你搞定这个OrmLite的跨表查询问题~你给出的SQL是要关联mycampaignlist和redeemlanguagedata两张表,筛选出lang_type=2的记录,同时获取前者的所有字段和后者的三个特定字段。下面给你两种实用的实现方式:
方法一:用QueryBuilder构建关联查询
这种方式更符合OrmLite的ORM风格,可读性强,也方便后续维护。
步骤1:确保实体类配置正确
首先你得有对应两张表的实体类,用OrmLite的注解标记:
@DatabaseTable(tableName = "mycampaignlist") public class MyCampaignList { // 示例字段,根据你的实际表结构调整 @DatabaseField(id = true) private int campaignId; @DatabaseField private String campaignCode; // 其他字段... // getter、setter方法 } @DatabaseTable(tableName = "redeemlanguagedata") public class RedeemLanguageData { @DatabaseField private int lang_type; @DatabaseField private String campaign_name; @DatabaseField private String description; @DatabaseField private String terms_condition; // 其他字段... // getter、setter方法 }
步骤2:创建DTO接收联合结果
因为查询结果包含两张表的字段,我们需要一个数据传输对象(DTO)来封装结果:
public class CampaignWithLanguageInfo { // 来自mycampaignlist的字段 private int campaignId; private String campaignCode; // 其他mycampaignlist字段... // 来自redeemlanguagedata的字段 private String campaignName; private String description; private String termsCondition; // 构造器要和查询结果的字段顺序对应 public CampaignWithLanguageInfo(int campaignId, String campaignCode, /* 其他mycampaignlist字段 */ String campaignName, String description, String termsCondition) { this.campaignId = campaignId; this.campaignCode = campaignCode; // 赋值其他字段 this.campaignName = campaignName; this.description = description; this.termsCondition = termsCondition; } // getter、setter方法 }
步骤3:用QueryBuilder构建并执行查询
try { // 获取两张表的Dao实例 Dao<MyCampaignList, Integer> campaignDao = getHelper().getDao(MyCampaignList.class); Dao<RedeemLanguageData, Void> langDao = getHelper().getDao(RedeemLanguageData.class); // 创建两个表的QueryBuilder QueryBuilder<MyCampaignList, Integer> campaignQb = campaignDao.queryBuilder(); QueryBuilder<RedeemLanguageData, Void> langQb = langDao.queryBuilder(); // 关联两张表,选择需要的字段,添加筛选条件 campaignQb.join(langQb) .selectRaw("m.*, r.campaign_name, r.description, r.terms_condition") .where().eq("r.lang_type", 2); // 执行查询并映射到DTO List<CampaignWithLanguageInfo> resultList = campaignQb.queryRaw(new RawRowMapper<CampaignWithLanguageInfo>() { @Override public CampaignWithLanguageInfo mapRow(String[] columnNames, String[] resultColumns) throws SQLException { // 注意:resultColumns的顺序和你SELECT语句中的字段顺序完全一致 return new CampaignWithLanguageInfo( Integer.parseInt(resultColumns[0]), resultColumns[1], // 依次解析其他mycampaignlist字段 resultColumns[/* campaign_name对应的索引 */], resultColumns[/* description对应的索引 */], resultColumns[/* terms_condition对应的索引 */] ); } }); // 这里就可以使用resultList了 } catch (SQLException e) { e.printStackTrace(); // 处理异常 }
方法二:直接执行原生SQL
如果你更习惯用原生SQL语句(就是你给出的那一段),这种方式更直接,适合复杂查询场景:
try { Dao<MyCampaignList, Integer> campaignDao = getHelper().getDao(MyCampaignList.class); // 你的原生SQL,用?作为参数占位符更安全 String rawSql = "SELECT m.*, r.campaign_name, r.description, r.terms_condition FROM mycampaignlist m, redeemlanguagedata r WHERE r.lang_type = ?"; // 执行查询并映射结果 GenericRawResults<CampaignWithLanguageInfo> rawResults = campaignDao.queryRaw( rawSql, new RawRowMapper<CampaignWithLanguageInfo>() { @Override public CampaignWithLanguageInfo mapRow(String[] columnNames, String[] resultColumns) throws SQLException { // 和上面一样,按字段顺序解析结果 return new CampaignWithLanguageInfo( Integer.parseInt(resultColumns[0]), resultColumns[1], // 其他字段解析 resultColumns[/* campaign_name索引 */], resultColumns[/* description索引 */], resultColumns[/* terms_condition索引 */] ); } }, "2" // 替换SQL中的?参数 ); List<CampaignWithLanguageInfo> resultList = rawResults.getResults(); // 记得关闭结果集 rawResults.close(); } catch (SQLException e) { e.printStackTrace(); }
一些额外提醒
- 如果两张表之间有外键关联(比如
mycampaignlist有字段关联redeemlanguagedata的主键),建议把join(langQb)改成join(langQb, "m.foreign_key_column", "r.primary_key_column"),这样是显式内连接,比隐式交叉连接更高效规范。 - 映射结果时,一定要核对
resultColumns的顺序和SELECT语句的字段顺序,否则会出现字段赋值错误。 - 要是不想创建DTO,也可以直接用
String[]或者Map<String, String>来接收结果,省略RawRowMapper即可。
内容的提问来源于stack exchange,提问作者aj0822ArpitJoshi
相关产品推荐
相关产品推荐

