Как запросить подмножество столбцов из PostGIS, используя MyBatis? - PullRequest
2 голосов
/ 15 октября 2011

Я пытаюсь запросить данные из базы данных PostGIS, используя MyBatis, игнорируя геопространственные данные. У меня есть следующая таблица в базе данных:

CREATE TABLE salesgeometry
(
  id bigint NOT NULL,
  label character varying(255),
  type character varying(255),
  geom geometry,
  CONSTRAINT salesgeometry_pkey PRIMARY KEY (id ),
  CONSTRAINT enforce_dims_geom CHECK (st_ndims(geom) = 2),
  CONSTRAINT enforce_srid_geom CHECK (st_srid(geom) = 4326)
)

Я пытаюсь сопоставить это с MyBatis, используя эту аннотацию:

@Select("SELECT id, type, label FROM salesgeometry WHERE ST_Within(" +
        "ST_GeomFromText('POINT(#{longitude} #{latitude})', 4326), geom) " +
        "AND type = #{type}")
Geometry getGeometryAtLocation(
        @NotNull @Param("type") String geometryType,
        @NotNull @Param("longitude") BigDecimal longitude, 
        @NotNull @Param("latitude") BigDecimal latitude
);

И целевой класс имеет такие поля:

public class Geometry {
    private long id;
    private String type;
    private String label;
    ...
}

К сожалению, это не работает, вместо этого я получаю

org.postgresql.util.PSQLException: The column index is out of range: 2, number of columns: 1.

Как запросить только подмножество столбцов из базы данных?

1 Ответ

0 голосов
/ 16 октября 2011

Проблема в том, что MyBatis сопоставляет ST_GeomFromText('POINT(#{longitude} #{latitude})', 4326) с подготовленным оператором, похожим на это: ST_GeomFromText('POINT(? ?)', 4326), который на самом деле не содержит ожидаемых параметров, поскольку знаки вопроса заключены в кавычки.

решение состоит в том, чтобы либо использовать конкатенацию строк (как в ST_GeomFromText('POINT(' || #{longitude} || ' ' || #{latitude} || ')', 4326), либо вместо этого использовать подстановку строк: ST_GeomFromText('POINT(${longitude} ${latitude})', 4326), что напрямую помещает значения в оператор SQL вместо использования параметров подготовленных операторов.

Следующее отображение работает(обратите внимание на два символа доллара для долготы и широты):

@Select("SELECT id, type, label FROM salesgeometry WHERE ST_Within(" +
        "ST_GeomFromText('POINT(${longitude} ${latitude})', 4326), geom) " +
        "AND type = #{type}")
Geometry getGeometryAtLocation(
        @NotNull @Param("type") String geometryType,
        @NotNull @Param("longitude") BigDecimal longitude, 
        @NotNull @Param("latitude") BigDecimal latitude
);
...