CREATE TABLE `zone_area` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(32) DEFAULT NULL, `location` geometry DEFAULT NULL, `geohash` varchar(20) GENERATED ALWAYS AS (st_geohash(`location`,8)) VIRTUAL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COMMENT='区';
ALTER TABLE zone_area ADD COLUMN `geohash` varchar(20) GENERATED ALWAYS AS (st_geohash(`location`,8)) VIRTUAL;
字段: 使用geometry类型存储空间点数据;
存储:
SET location = geomfromtext('point(108.9498710632 34.2588125935)'));
搜索: 查询方圆5公里数据? geohash字段是将二维通过geohash算法变成一维;
虚拟自增列 Generated Column是MySQL 5.7引入的新特性,Cenerated Column,就是数据库中这一列由其他列计算而得。
generated column always总是自动生成
FLOOR(X)表示向下取整,只返回值X的整数部分,小数部分舍弃。
CEILING(X) 表示向上取整,只返回值X的整数部分,小数部分舍弃。
#DECIMAL 四舍五入
SELECT CAST('123.456' AS DECIMAL) #123
SELECT CAST('123.456' AS DECIMAL(10,2)) #123.46
ROUND(X) -- 四舍五入
SELECT ROUND('123.456') #123
SELECT ROUND('123.456',2) #123.46
Mybatis如何处理
<方案1>
1.新增和更新方案: 直接手写sql进行更新
新增的话,先设置该字段为空,新增完后,走sql更新单独字段
@Update("update order set coordinate=geomfromtext(#{coordinate}) where id=#{id}")
void updateCoordinateById(@Param("id") Long id, @Param("coordinate") String coordinate);
2.查看
pom.xml
<!-- 空间几何 -->
<dependency>
<groupId>org.geolatte</groupId>
<artifactId>geolatte-geom</artifactId>
<version>1.8.2</version>
</dependency>
entity
@TableName(autoResultMap = true)
class Order {
@ApiModelProperty(value = "GPS")
@TableField(value = "coordinate",typeHandler = GeoPointTypeHandler.class)
private Point coordinate;
}
GeoPointTypeHandler
package com.xx.handler; import org.geolatte.geom.ByteBuffer; import org.geolatte.geom.Point; import org.geolatte.geom.codec.Wkb; import java.sql.CallableStatement; import java.sql.ResultSet; import java.sql.SQLException; /** * 自定义类型转换器映射空间几何数据 */ public class GeoPointTypeHandler extends BaseAttributeTypeHandler<Point > { @Override public Point getNullableResult(ResultSet resultSet, String columnName) throws SQLException { var bytes = (byte[])resultSet.getObject(columnName); return this.mapPoint(bytes); } @Override public Point getNullableResult(ResultSet resultSet, int i) throws SQLException { return (Point) resultSet.getObject(i); } @Override public Point getNullableResult(CallableStatement callableStatement, int i) throws SQLException { return (Point) callableStatement.getObject(i); } /* * bytes转Point对象 */ private Point mapPoint(byte[] bytes) { if (bytes == null) { return null; } try { Point point = (Point) Wkb.fromWkb(ByteBuffer.from(bytes)); return point; } catch (Exception e) { } return null; } }