我想在两个表中加入并获取两个表中的所有列,我这样做了:
QueryBuilder<A, Integer> aQb = aDao.queryBuilder();
QueryBuilder<B, Integer> bQb = bDao.queryBuilder();
aQb.join(bQb).prepare();
这相当于:
SELECT 'A'.* FROM A INNER JOIN B WHERE A.id = B.id;
但我想:
SELECT * FROM A INNER JOIN B WHERE A.id = B.id;
其他问题是在B领域接受订单时,例如:
aQb.orderBy(B.COLUMN, true);
我收到错误消息“没有表格列B”。
答案 0 :(得分:3)
当您使用QueryBuilder
时,它希望返回B
个对象。它们不能包含A
中B
的所有字段。如果这就是你的意思,它不会充实外国子领域。该功能尚未越过ORMLite的 lite 屏障。
也不支持在join-table上进行排序。你当然可以添加bQb.orderBy(B.COLUMN, true)
,但我认为这不会做你想要的。
你当然可以使用raw-queries,尽管它不是最佳的。
答案 1 :(得分:1)
实际上,我设法在不将整个查询编写为原始查询的情况下执行此操作。这样,我就不需要替换我的查询构建器代码(这非常复杂)。为实现这一目标,我遵循了以下步骤:
(假设我有两个表, my_table 和 my_join_table 及其daos,我想在列< my_table 上订购我的查询< my_join_table 的strong> order_column_1
1-加入了两个查询构建器&amp;使用QueryBuilder.selectRaw(String... columns)
方法包含原始表的+我要在外部排序中使用的列。例如:
QueryBuilder<MyJoinTable, MyJoinPK> myJoinQueryBuilder = myJoinDao.queryBuilder();
QueryBuilder<MyTable, MyPK> myQueryBuilder = myDao.queryBuilder().join(myJoinQueryBuilder).selectRaw("`my_table`.*", "`my_join_table`.`order_column` as `order_column_1`");
2-按照以下条款包括我的订单:
myQueryBuilder.orderByRaw("`order_column_1` ASC");
3-设置所有选择列和&amp;按条款排序,是时候准备声明了:
String statement = myQueryBuilder.prepare().getStatement();
4-从dao获取表格信息: TableInfo tableInfo =((BaseDaoImpl)myDao).getTableInfo();
5-创建了我的自定义列到对象映射器,它只忽略未知的列名。我们通过这样做避免了我们的custon列(在这种情况下为order_column_1
)的映射错误。例如:
RawRowMapper<MyTable> mapper = new UnknownColumnIgnoringGenericRowMapper<>(tableInfo);
6-查询表格中的结果:
GenericRawResults<MyTable> results = activityDao.queryRaw(statement, mapper);
7-最后,将通用原始结果转换为列表:
List<MyTable> myObjects = new ArrayList<>();
for (MyTable myObject : results) {
myObjects.add(myObject);
}
这是我通过修改(只是吞下异常)com.j256.ormlite.stmt.RawRowMapperImpl
创建的自定义行映射器,以避免未知的列映射错误。您可以将其复制并粘贴到项目中:
import com.j256.ormlite.dao.RawRowMapper;
import com.j256.ormlite.field.FieldType;
import com.j256.ormlite.table.TableInfo;
import java.sql.SQLException;
public class UnknownColumnIgnoringGenericRowMapper<T, ID> implements RawRowMapper<T> {
private final TableInfo<T, ID> tableInfo;
public UnknownColumnIgnoringGenericRowMapper(TableInfo<T, ID> tableInfo) {
this.tableInfo = tableInfo;
}
public T mapRow(String[] columnNames, String[] resultColumns) throws SQLException {
// create our object
T rowObj = tableInfo.createObject();
for (int i = 0; i < columnNames.length; i++) {
// sanity check, prolly will never happen but let's be careful out there
if (i >= resultColumns.length) {
continue;
}
try {
// run through and convert each field
FieldType fieldType = tableInfo.getFieldTypeByColumnName(columnNames[i]);
Object fieldObj = fieldType.convertStringToJavaField(resultColumns[i], i);
// assign it to the row object
fieldType.assignField(rowObj, fieldObj, false, null);
} catch (IllegalArgumentException e) {
// log this or do whatever you want
}
}
return rowObj;
}
}
这是非常hacky&amp;对于这个操作来说似乎有些过分,但我肯定需要它并且这种方法效果很好。