I'm trying to query data from a PostGIS database using MyBatis, ignoring the geospatial data. I have the following table in the database:
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)
)
I'm trying to map this with MyBatis using this annotation:
@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
);
And the target class has fields like this:
public class Geometry {
private long id;
private String type;
private String label;
...
}
Unfortunately this does not work, instead I get a
org.postgresql.util.PSQLException: The column index is out of range: 2, number of columns: 1.
How do I query just the subset of columns from the database?
The problem is that ST_GeomFromText('POINT(#{longitude} #{latitude})', 4326)
is mapped by MyBatis to a prepared statement looking like this: ST_GeomFromText('POINT(? ?)', 4326)
, which doesn't actually contain the expected parameters since the question marks are within quotes.
The solution is to either use string concatenation (as in ST_GeomFromText('POINT(' || #{longitude} || ' ' || #{latitude} || ')', 4326)
or use string substitution instead: ST_GeomFromText('POINT(${longitude} ${latitude})', 4326)
, which puts the values into the SQL statement directly instead of using parameters of prepared statements.
The following mapping works (note the two dollar symbols for longitude and latitude):
@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
);
精彩评论