Apache Torque Criteria: как присоединиться к подзапросу - PullRequest
0 голосов
/ 11 января 2011

Допустим, у меня есть следующий оператор 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 ]

1 голос
/ 12 января 2011

В принципе, я не думаю, что критерий крутящего момента подходит для этого типа запроса. Прежде всего вы выбираете конкретные столбцы. Критерии обычно используются для выбора объектов крутящего момента для запрашиваемой таблицы. Вы можете выбрать определенные столбцы, используя деревенские записи, так что на самом деле можно выбрать пользовательский столбец, используя критерии, но громоздкие *. Во-вторых, и это самое важное, я не верю, что ЛЕВОЕ соединение возможно. Критерии настроены на использование 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);
  }
 }
0 голосов
/ 06 июня 2014

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

Рассмотрим

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)

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

0 голосов
/ 03 мая 2011

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

0 голосов
/ 14 января 2011

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

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);

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

...