У h2 есть запрос / предложение, подобное WHERE IN в MySQL?

0

Мой код в настоящее время выглядит следующим образом:

public List<DeviceOrganizationMetadataHolder> getChildrenByParentId(List<String> parentIds) throws DeviceOrganizationDAOException {
        List<DeviceOrganizationMetadataHolder> children = new ArrayList<>();
        Connection conn;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        DeviceOrganizationMetadataHolder deviceMetadataHolder;
        String[] data = parentIds.toArray(new String[parentIds.size()]);
        try {
            conn = this.getConnection();
            String sql = "SELECT * FROM DEVICE_ORGANIZATION_MAP WHERE DEVICE_PARENT IN (?)";
            stmt = conn.prepareStatement(sql);
            data = parentIds.toArray(data);
            stmt.setObject(1, data);
            rs = stmt.executeQuery();
            while (rs.next()) {
                deviceMetadataHolder = this.loadOrganization(rs);
                children.add(deviceMetadataHolder);
            }
        } catch (SQLException e) {
            throw new DeviceOrganizationDAOException("Error occurred for device list with while retrieving children.", e);
        } finally {
            DeviceManagementDAOUtil.cleanupResources(stmt, rs);
            return children;
        }
}

Однако, хотя в модульных тестах я пытаюсь передать массив с parentIds, возврат остается равным нулю. То, что я могу оценить из этого, является одним из следующих:

  1. Данные массива не получают должным образом чтения, поэтому вывод идет как null.
  2. WHERE IN не поддерживается h2, иначе существует другая реализация, которая должна использоваться вместо этого.

Где я ошибаюсь?

EDIT. Был аналогичный повторяющийся вопрос, который был помечен. Хотя он предложил использовать StringBuilder и цикл, я искал ответ о том, как это можно сделать более чистым способом с использованием самого запроса.

Теги:
prepared-statement
h2
where-in

2 ответа

1

Попробуйте установить параметр в виде списка вместо массива, т.е. заменить

stmt.setObject(1, data);

с

stmt.setObject(1, Arrays.asList(data));
0

Догадаться.

В h2database GitHub возникла проблема, связанная с этой точной проблемой. Последующие предлагаемые изменения, и это сработало !

Код после редактирования выглядит следующим образом:

public List<DeviceOrganizationMetadataHolder> getChildrenByParentId(List<String> parentIds) throws DeviceOrganizationDAOException {
        List<DeviceOrganizationMetadataHolder> children = new ArrayList<>();
        Connection conn;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        DeviceOrganizationMetadataHolder deviceMetadataHolder;
        Object[] data = parentIds.toArray();
        try {
            conn = this.getConnection();
            String sql = "SELECT * FROM DEVICE_ORGANIZATION_MAP WHERE DEVICE_PARENT IN (SELECT * FROM TABLE(x VARCHAR = ?))";
            stmt = conn.prepareStatement(sql);
            stmt.setObject(1, data);
            rs = stmt.executeQuery();
            while (rs.next()) {
                deviceMetadataHolder = this.loadOrganization(rs);
                children.add(deviceMetadataHolder);
            }
        } catch (SQLException e) {
            throw new DeviceOrganizationDAOException("Error occurred for device list with while retrieving children.", e);
        } finally {
            DeviceManagementDAOUtil.cleanupResources(stmt, rs);
            return children;
        }
}

Как вы можете видеть, я использовал массив объектов для данных и добавил дополнительный запрос в основной запрос. Следуя инструкциям, приведенным в выпуске GitHub, к тройнику, он работал безупречно.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню