Apache Torque Criteria: как присоединиться к подзапросу

Допустим, у меня есть следующий оператор SQL. Я хотел бы преобразовать это в Torque Criteria:

SELECT table.name, subq1.total AS 'TOTAL', subq2.total2 AS 'SECOND TOTAL'
FROM table
LEFT JOIN (
    SELECT c.login, COUNT(*) AS 'total'
    FROM table2 INNER JOIN table3
    WHERE table3.field = 2
    GROUP BY table3.login
    ) AS subq1 ON(subq1.login = table.login)
LEFT JOIN(...) AS subq2 ON (subq2.login = table.login)

Не имеет значения сам подзапрос. Единственная проблема здесь заключается в том, как выполнить это левое соединение.

4 ответа

Решение

В итоге я разделил каждый подзапрос отдельным методом. Но я также мог бы использовать Критерий. Что-то вроде:

Criterion criterion = myCriteria.getCriterion(MyTablePeer.STARTINGDATE);

Criterion c1 = myCriteria.getNewCriterion(criterion.getTable(), 
        criterion.getColumn(), 
        "something", Criteria.LESS_THAN);
c1.and(myCriteria.getNewCriterion(criterion.getTable(), 
        criterion.getColumn(),
        someDate, Criteria.GREATER_THAN));
criterion.or(c1);
myCriteria.add(criterion);

так что идея такова: каждый критерий является подзапросом. и вы можете поставить "или" или "и" или что-то еще, и, в конце концов, присоединить критерий с основными критериями.

В принципе, я не думаю, что критерий крутящего момента подходит для этого типа запроса. Прежде всего вы выбираете конкретные столбцы. Критерии обычно используются для выбора объектов крутящего момента для запрашиваемой таблицы. Вы можете выбрать определенные столбцы, используя деревенские записи, так что на самом деле можно выбрать пользовательский столбец, используя критерии, но громоздкие *. Во-вторых, и это самое важное, я не верю, что ЛЕВОЕ соединение возможно. Критерии настроены на использование JOIN в основном как подзапрос AFAIK.

Пример подзапроса с использованием основных критериев "соединение" будет

Criteria criteria = new Criteria();
criteria.add(TABLEA.COLUMNA,somevalue);
criteria.add(TABLEB.COLUMNA,somevalue);
criteria.addJoin(TABLEA.COLUMNB,TABLEB.COLUMNB);
TABLEA.doSelect(criteria);

Это позволит выбрать записи из таблицы A, где столбец таблицы B a = somevalue и таблица столбца b = таблица b столбца b.

В общем, я бы порекомендовал прямой запрос для слишком сложных критериев.

public static List<Object> doDynamicQuery(String dynamicQuery){
  Connection connection = null;
  try{
   connection = Torque.getConnection(Torque.getDefaultDB());
   connection.setReadOnly(true);
   PreparedStatement statement = connection.prepareStatement(dynamicQuery);
   ResultSet set = statement.executeQuery();
   QueryDataSet dataSet = new QueryDataSet(set);
   return BasePeer.getSelectResults(dataSet);
  }
  catch(Exception e){
   log.error(e);
   return null;
  }
  finally{
   Torque.closeConnection(connection);
  }
 }

Вы можете сделать это, явно указав мапперы и выбранные столбцы:

Рассматривать

crit.addSelectColumn( MyTablePeer.COL1);
Collections.addAll( crit.getSelectColumns(), MyTable2Peer.getTableMap().getColumns()  );
crit.addJoin(MyTable2Peer.ID, MyTablePeer.ID2, Criteria.LEFT_JOIN);
//crit.where(...)
CompositeMapper cp = new CompositeMapper();
cp.addMapper( new IntegerMapper(), 0 ); // if you expect an int value
cp.addMapper( new BaseMyTable2RecordMapper(),1);
List<List<Object>> resultList = MyTable2Peer.doSelect( crit, cp );
// resultList.get(0).get( 1 ) instanceof MyTable2)

используя Torque, автоматически отображающий механизм. Там также существует ObjectListMapper.

Создайте в базе данных новое представление, реализующее ваш сложный запрос, а затем класс Torque OM, доступный только для чтения, который можно тривиально запросить из своего приложения.

Другие вопросы по тегам