Mybatis映射Oracle Spatial和Jgeometry
来源:互联网 发布:太原师范学院教务网络 编辑:程序博客网 时间:2024/06/18 13:25
引子
最近要用到Oracle Spatial中SDO_Geometry数据结构,因为SDO_Geometry可以存储点、线、面等几何图形,关于SDO_Geometry的介绍网上很多,此处不再赘述。本文要介绍的是在java中实现对Oracle中的SDO_Geometry类型的字段的读写。
创建Oracle Spatial空间索引
创建Oracle的空间索引的例子网上很多,只列出步骤,不解释具体的原理。
1.创建表
CREATE TABLE GEOMETRY_TABLE( ID NUMBER, NAME VARCHAR2(30), GEOMETRY SDO_GEOMETRY,)
2.创建相应的空间元数据
元数据视图USER_SDO_GEOM_METADATA,可以select查看。
INSERT INTO USER_SDO_GEOM_METADATA VALUES('GEOMETRY_TABLE', 'GEOMETRY', MDSYS.SDO_DIM_ARRAY(MDSYS.SDO_DIM_ELEMENT('longitude', -180, 180, 0.005), MDSYS.SDO_DIM_ELEMENT('latitude', -90, 90, 0.005)), 8307);
USER_SDO_GEOM_METADATA视图包含的字段有TABLE_NAME,COLUMN_NAME,DIMINFO,SRID.对于SRID我们通常使用国际标准的Longitude/Latitude(8307)。使用的有很多标准,如果有兴趣的话可以去oracle的MDSYS用户下去查看,有个专门记录SRID值的表。
3.创建空间索引
CREATE INDEX GEO_INDEX ON GEOMETRY_TABLE(GEOMETRY) INDEXTYPE IS MDSYS.SPATIAL_INDEX;
Mybatis映射JGeometry和SDO_GEOMETRY
空间对象以SDO_GEOMETRY类型存储在数据库表中。要在Java中对其进行处理,必须首先使用JDBC从数据库中读取它们,然后把它们映射为Java类。Oracle Spatial提供了API接口。Oracle Spatial的Java API的jar包在Oracle安装目录($ORACLE_HOME/md/jlib )下(sdoapi.jar和sdoutl.jar),将其导入java的classpath。主要用的两个类JGeometry和J3D_Geometry,一个是二维的,一个是三维的。
在使用java读写数据库中包含SDO_GEOMETRY类型的表时可以使用JDBC来做,但是由于JDBC的缺点,所以采用Mybatis来做持久层和数据的映射。由于Mybatis不包含将JGeometry和SDO_GEOMETRY对应的TypeHandler,所以要建立自己的TypeHandler。
建立SdoGeometryTypeHandler
建立自己的Typehandler可以通过继承原始接口TypeHandler或者 BaseTypeHandler抽象类,两个差不多,我用的时通过继承原始接口TypeHandler。
在Mybatis中要实现自己的TypeHandler就需要实现Mybatis为我们提供的TypeHandler接口。在TypeHandler中定义了四个方法,下面解释这四个方法的作用:
Java代码
public interface TypeHandler<T> { /** * 用于定义在Mybatis设置参数时该如何把Java类型的参数转换为对应的数据库类型 * @param ps 当前的PreparedStatement对象 * @param i 当前参数的位置 * @param parameter 当前参数的Java对象 * @param jdbcType 当前参数的数据库类型 * @throws SQLException */ void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException; /** * 用于在Mybatis获取数据结果集时如何把数据库类型转换为对应的Java类型 * @param rs 当前的结果集 * @param columnName 当前的字段名称 * @return 转换后的Java对象 * @throws SQLException */ T getResult(ResultSet rs, String columnName) throws SQLException; /** * 用于在Mybatis通过字段位置获取字段数据时把数据库类型转换为对应的Java类型 * @param rs 当前的结果集 * @param columnIndex 当前字段的位置 * @return 转换后的Java对象 * @throws SQLException */ T getResult(ResultSet rs, int columnIndex) throws SQLException; /** * 用于Mybatis在调用存储过程后把数据库类型的数据转换为对应的Java类型 * @param cs 当前的CallableStatement执行后的CallableStatement * @param columnIndex 当前输出参数的位置 * @return * @throws SQLException */ T getResult(CallableStatement cs, int columnIndex) throws SQLException; }
建立一个名叫SdoGeometryTypeHandler的TypeHandler,具体代码如下:
Java代码
package com.instance.mybatis.handler;import java.sql.CallableStatement;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import oracle.spatial.geometry.JGeometry;import oracle.sql.STRUCT;import org.apache.ibatis.type.JdbcType;import org.apache.ibatis.type.MappedJdbcTypes;import org.apache.ibatis.type.MappedTypes;import org.apache.ibatis.type.TypeHandler;@MappedTypes({JGeometry.class})@MappedJdbcTypes({JdbcType.STRUCT})//这两个Mapped也可不需要public class SdoGeometryTypeHandler implements TypeHandler<JGeometry> { @Override public void setParameter(PreparedStatement ps, int i, JGeometry parameter, JdbcType jdbcType) throws SQLException { // TODO Auto-generated method stub STRUCT dbObject = JGeometry.store(parameter, ps.getConnection()); ps.setObject(i, dbObject); } @Override public JGeometry getResult(ResultSet rs, String columnName) throws SQLException { // TODO Auto-generated method stub STRUCT st = (STRUCT) rs.getObject(columnName); if (st != null) { return JGeometry.load(st); } return null; } @Override public JGeometry getResult(ResultSet rs, int columnIndex) throws SQLException { // TODO Auto-generated method stub STRUCT st = (STRUCT) rs.getObject(columnIndex); if (st != null) { return JGeometry.load(st); } return null; } @Override public JGeometry getResult(CallableStatement cs, int columnIndex) throws SQLException { // TODO Auto-generated method stub STRUCT st = (STRUCT) cs.getObject(columnIndex); if (st != null) { return JGeometry.load(st); } return null; }}
然后我们在Mybatis的配置文件中这样注册它:
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd" ><configuration> <typeAliases> <typeAlias type="oracle.spatial.geometry.JGeometry" alias="JGeometry" /> <typeAlias type="com.instance.domain.Geometry" alias="Geometry" /> </typeAliases> <typeHandlers> <typeHandler handler="com.albert.wen.instance.mybatis.handler.SdoGeometryTypeHandler" javaType="JGeometry" /> </typeHandlers> <mappers> <mapper resource="com/instance/mapper/GeometryDaoMapper.xml" /> </mappers></configuration>
下面就是GeometryDaoMapper.xml中如何使用自定义的TypeHandler了,查询和插入的SQL语句写法:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.instance.mapper.GeometryDaoMapper"> <resultMap id="defaultResultMap" type="Geometry"> <result property="id" column="id" /> <result property="name" column="name" /> <result property="geometry" column="geometry" javaType="JGeometry" jdbcType="STRUCT" /> </resultMap> <select id="select" resultMap="defaultResultMap"> SELECT id, name, geometry FROM geometry_table </select> <insert id="insert" parameterType="Geometry"> INSERT INTO geometry_table(id, name, geometry) VALUES(#{id}, #{name}, #{geometry,javaType=JGeometry,jdbcType=STRUCT}) </insert></mapper>
在网上找了一下,没有找到关于Mybatis将JGeometry和Oracle中的SDO_Geometry映射的例子,所以就将自己的实例发出来和大家分享一下,还有数据库的配置是使用spring完成的。因为是第一次写博客,还是用markdown写的,格式可能会有点乱。
- Mybatis映射Oracle Spatial和Jgeometry
- 后端JSP文件里Java语言如何操作Oracle Spatial提供的JGeometry对象
- 后端JSP文件里Java语言如何操作Oracle Spatial提供的JGeometry对象2
- oracle数据库,java读取空间数据类型JGeometry
- Spring+SpringMVC+hibernate spatial+oracle spatial 映射存储Geomety空间数据过程记录
- oracle spatial
- Oracle Spatial
- Oracle Spatial
- Oracle Spatial
- Oracle Spatial
- mybatis 输入映射和输出映射
- mybatis进阶--输入映射和输出映射
- 【MyBatis】输入映射和输出映射
- Mybatis 输入映射和输出映射
- MyBatis中输入映射和输出映射
- Mybatis 输入和输出映射
- 利用Oracle Spatial求几何对象的长度和面积
- Oracle Spatial 个人资质认证和公司资质认证
- iOS开发中self和super
- 控件背景透明代码
- 数据结构基础 之 深入理解二叉堆建立的时空复杂
- 如何在Ubuntu上安装LAMP服务器系统?
- Eclipse配置
- Mybatis映射Oracle Spatial和Jgeometry
- 【Android架构综述篇】之应用程序、应用程序访问硬件的流程
- 阿里云磁盘挂载
- nyoj915*+-字符串
- 南阳oj 动态规划 心急的c小加 题目236
- 内部类的使用
- 【bzoj2435】 NOI2011 道路修建 水题
- C++ protected等属性及继承之间的关系
- 控制台程序使用SendMessage进行进程间的通信