h2是否有类似于MySQL中的WHERE IN的查询/子句?

时间:2017-12-13 08:09:55

标签: mysql prepared-statement h2 where-in

我的代码目前如下:

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传递数组,但返回仍然为null。 我可以从中判断出以下情况之一:

  1. 数组数据未正确读取,因此输出为空。
  2. h2 不支持WHERE IN,否则需要使用不同的实现
  3. 我在哪里错了?

    编辑 - 标记了类似的duplicate question。虽然它建议使用StringBuilder和循环,但我一直在寻找一个答案,说明如何使用查询本身以更干净的方式完成它。

2 个答案:

答案 0 :(得分:1)

尝试将参数设置为列表而不是数组,即替换

stmt.setObject(1, data);

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

答案 1 :(得分:0)

想出来。

在h2database GitHub上发布了issue关于这个确切问题的信息。按照建议的编辑和工作

编辑后的代码如下:

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

正如您所看到的,我已经使用Object数组代替数据,并在主查询中添加了一个额外的查询。 按照GitHub问题中的说明进行开球,它完美无缺。