工作的一个网络项目,该项目使用postgresql 9.3
postgis 2.1
。
有类型的列geography
表中,它只是一个存储point
。
现在我需要插入/选择通过JDBC与Java对象的类型。
看完后postgis
手册,并没有找到太多的信息相关。
这些问题是:
- 在Java的POJO模型类,什么Java数据类型应该用于列?
- 怎样写INSERT的SQL?
- 怎样写选择SQL检索值并投入Java对象?
- 如果
mybatis
使用,那么它影响回答上面的问题?
你不需要特殊类型POINT
的几何形状。 只要使用基本数据类型,如double
的坐标。
例如,插入一个新的geography
通过类型lon
和lat
参数,利用几何构造函数 :
INSERT INTO my_table (geog)
VALUES (ST_SetSRID(ST_MakePoint(:lon, :lat), 4326)::geography);
或者让他们回来为浮点数,利用几何存取函数 :
SELECT ST_Y(geog::geometry) AS lat, ST_X(geog::geometry) AS lon FROM my_table;
还有其他的输入/输出格式,例如以GeoJSON,WKT等
如果您使用的MyBatis,有在MyBatis的PostGIS的类型微小的项目。 它已被添加到Maven的中央,这样你就可以直接从Maven的使用它。
https://github.com/eyougo/mybatis-typehandlers-postgis
如果您使用的MyBatis,你可以有经纬度之间的转换使用透明地类型处理器 。 这是我如何做了它在你们这样,PostGIS中,MyBatis的,并且Gegraphy需要的场景。 使用类型处理器使得不同类别的处理,你可以换一个几何类型之中。 在我的情况坐标有两个double
属性, latitude
和longitude
。
协调课程
public class Coordinate {
private Double latitude;
private Double latitude;
... getters, setters, etc
}
声明困扰的类型处理器
@MappedJdbcTypes(JdbcType.JAVA_OBJECT)
@MappedTypes({Coordinate.class})
public class CoordinateTypeHandler extends BaseTypeHandler<Coordinate> {
@Override
public void setNonNullParameter(PreparedStatement ps, int i, Coordinate parameter, JdbcType jdbcType) throws SQLException {
// Convert Coordinate to Ibatis representation of Postgis point, e.g., "SRID=4326;POINT(2.294801 48.858007)"
Point point = new Point(parameter.getLongitude(), parameter.getLatitude());
point.setSrid(4326);
ps.setString(i, point.toString());
}
// Convert data read from Ibatis to actual Coordinate class
@Override
public Coordinate getNullableResult(ResultSet rs, String columnName) throws SQLException {
return from(rs.getString(columnName));
}
@Override
public Coordinate getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
return from(rs.getString(columnIndex));
}
@Override
public Coordinate getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
return from(cs.getString(columnIndex));
}
protected Coordinate from(String pointAsText) throws SQLException {
if (pointAsText != null) {
Point point = new Point(pointAsText);
return new Coordinate(point.getY(), point.getX());
}
return null;
}
}
然后准备ibatis的界面上选择。 请参阅使用'as coordinate'
在这里,它说,ibatis的寻找坐标类型的代表性,这是由处理CoordinateTypeHandler
刚刚定义。
重要的是要知道,是很重要的location
波纹管被声明为location geography(POINT, 4326)
对你的表定义。
@Select("SELECT " +
"ST_AsText(location) AS coordinate" +
"FROM " +
"mytable " +
"WHERE " +
"tableattribute = #{myattribute}")
List<Result> myFindMethod(
@Param("myattribute") Integer myattribute
);
该解决方案将提供一个干净的抽象坐标实物类的一个包装latitude
和longitude
属性到SRID=4326;POINT(2.294801 48.858007)
上PostGIS的表示。 考虑麦克T的解决方案,你需要重写相同(ST_SetSRID(ST_MakePoint(:lon, :lat), 4326)::geography)
你要创建你的API /服务的每一个查询。
使用TypeHandler
的目的是避免这种情况,一旦更改/添加你表示TypeHandler
,它直接反映了每次使用的查询as coordinate
。