`

mybatis 映射oracle spatial JGeometry 类型并调用存储过程。

 
阅读更多
有个需求是经纬度坐标字符串通过 http请求,后台调用一个 oracle存储过程.

因为调用oracle库,并且需要用到spatial特性的geometry类型的字段,所以就用了oracle自己的类库。
oracle.spatial.geometry.JGeometry。

我这里涉及到4个jar包。
sdoapi.jar
sdotopo.jar
sdoutl.jar
sdonm.jar

jar包一般需要从oracle官网下载,如果有服务器端,一般 在${ORACLE_HOME}md/jlib 目录可以找到。

如果mybatis 想要映射到JGeometry类型,需要将设置类型成STRUCT.
必须实现mybatis提供的接口。参考下面的博客。
http://blog.csdn.net/zhaowenbo168/article/details/46943509

上面博客中有个问题,就是如果你用到某些连接池,mybatis调用 TypeHandler的时候,包装的连接不能强制转成 OracleConnection ,需要判断连接池中的连接是否是OracleConnection的包装,如果是需要拆包,然后利用原始连接构造STRUCT对象。看下面代码setParameter方法。
import java.sql.*;

import oracle.jdbc.driver.OracleConnection;
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
        Connection conn = ps.getConnection();
        OracleConnection oracleConnection= null;
        if(conn.isWrapperFor(OracleConnection.class)){
            oracleConnection = conn.unwrap(OracleConnection.class);
            STRUCT dbObject = JGeometry.store(parameter, oracleConnection);
            ps.setObject(i, dbObject);
        }
        else{
            STRUCT dbObject = JGeometry.store(parameter, conn);
            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;
    }

}


接下来就是配置xml文件了。mybatisconfig.xml
<?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 alias="Usermodel" type="com.xxx.model.Usermodel"/>
        <typeAlias type="oracle.spatial.geometry.JGeometry" alias="JGeometry" />
        <typeAlias type="com.xxx.model.GeometryTest" alias="Geometry"/>

    </typeAliases>

    <typeHandlers>
        <typeHandler handler="com.xxx.config.SdoGeometryTypeHandler" javaType="JGeometry"/>
    </typeHandlers>
    <!-- 配置Mapper文件的路径 -->
    <mappers>
        <mapper resource="conf/mybatis-config.xml"/>
    </mappers>
</configuration>


mybatis-config.xml: 下面select id =calcost 就是调用存储过程,mapping接口中定义参数是HashMap,包括输入参数,输出参数。
<?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.navinfo.smap_tollgate.mapper.TollMapping">
    <!--  查询单条记录  -->


    <select id="usermodelByKey" parameterType="String" resultType="Usermodel">

select a.userid,a.accesskey,a.expiration  from ni_user a where to_date(a.expiration,'YYYYmmDDhh24MISS') - SYSDATE >0 AND A.accesskey = #{key}
    </select>

    <select id="calcost" parameterType="java.util.HashMap" statementType="CALLABLE">

            {call PRO_SHAPE_MATCH.PRO_TOLL_ENTRY(#{geom,mode=IN,javaType=JGeometry,jdbcType=STRUCT},
            #{s_x,mode=IN,jdbcType=DOUBLE},
            #{s_y,mode=IN,jdbcType=DOUBLE},
            #{e_x,mode=IN,jdbcType=DOUBLE},
            #{e_y,mode=IN,jdbcType=DOUBLE},
            #{buf_dis,mode=IN,jdbcType=INTEGER},
            #{cost,mode=OUT,jdbcType=DOUBLE})}

    </select>

    <select id="callProceTest" parameterType="java.util.HashMap" statementType="CALLABLE">

        {call NAVI_SHAPE_MATCH.TEST_OUT(#{x,mode=IN,jdbcType=VARCHAR},#{y,mode=OUT,jdbcType=VARCHAR})}

    </select>

    <resultMap id="defaultResultMap" type="Geometry">
        <result property="link_pid" column="link_pid" />
        <result property="geometry" column="geometry" javaType="JGeometry" jdbcType="STRUCT" />
    </resultMap>

    <select id="callGeoTest" resultMap="defaultResultMap">

        select link_pid,geometry from rd_link_test where rownum=1

    </select>

    <insert id="insert" parameterType="Geometry">
        INSERT INTO rd_link_test(link_pid, geometry) VALUES(#{link_pid}, #{geometry,javaType=JGeometry,jdbcType=STRUCT})
    </insert>

</mapper>


mapping接口:
public interface TollMapping {

     Usermodel usermodelByKey(String key);

     void calTollcost(Map<String,Object> map);

     void callProceTest(Map<String,Object> map);

     GeometryTest callGeoTest();

     void insert(GeometryTest gt);

}


服务调用:
@Service
public class TollService {

    @Autowired
    TollMapping tollMapping;

 private static final int gtypeLine = 2002;

    private static final int gtypePoint = 2001;

    private static final int srid = 8307;

    private static final int[] elementInfo= new int[]{1,2,1};

    private JGeometry getGeomLineByLineString(double[] ordinArray){

        return new JGeometry(gtypeLine,srid,elementInfo,ordinArray);
    }

private double getCostByMap(double[] ordinArray,double s_x,double s_y,double e_x,double e_y){
        Map<String,Object> gMap = new HashMap<>();
        gMap.put("geom",getGeomLineByLineString(ordinArray));
        gMap.put("s_x",s_x);
        gMap.put("s_y",s_y);
        gMap.put("e_x",e_x);
        gMap.put("e_y",e_y);
        gMap.put("buf_dis",80);
        return getToll(gMap);
    }



    private double getToll(Map<String,Object> map){
//        try {
//            return getTollCostFeeJbdc(map);
//        }
//        catch (Exception e){
//            e.printStackTrace();
//            return 0;
//        }
        tollMapping.calcost(map);
        return (double)map.get("cost");
    }
}


调用calcost后,输出参数得到的值,自然映射到map中。

下面是jdbc方式调用geometry相关的存储过程。

private double getTollJbdc(Map<String,Object> map) throws SQLException, ClassNotFoundException {

        String url = "jdbc:oracle:thin:@" + "192.168.1.120" + ":" + 1521 + ":" + "orcl";
        Class.forName("oracle.jdbc.driver.OracleDriver");
        Connection conn = DriverManager.getConnection(url, "test", "1");

        String procedure = "{call PRO_SHAPE_MATCH.PRO_TOLL_ENTRY(?,?,?,?,?,?,?)}";

        CallableStatement cstmt = conn.prepareCall(procedure);

        OracleConnection oc = (OracleConnection) cstmt.getConnection();

        STRUCT struct = JGeometry.store((JGeometry) map.get("geom"),oc);
        double tocost =0;
        try {
            cstmt.setObject(1, struct);

            cstmt.setDouble(2, (double) map.get("s_x"));
            cstmt.setDouble(3, (double) map.get("s_y"));
            cstmt.setDouble(4, (double) map.get("e_x"));
            cstmt.setDouble(5, (double) map.get("e_y"));
            cstmt.setInt(6,(int)map.get("buf_dis"));
            cstmt.registerOutParameter(7, Types.DOUBLE);

            cstmt.executeUpdate();

            tocost = cstmt.getDouble(7);
        }catch (Exception e){
            e.printStackTrace();
        }
        finally {
            cstmt.close();
            conn.close();
        }

        return tocost;

    }

分享到:
评论

相关推荐

    springboot整合mybatis调用oracle存储过程

    本文将深入探讨如何在Spring Boot项目中整合MyBatis,实现调用Oracle存储过程并处理游标返回的数据。 首先,我们需要在Spring Boot项目中引入相关的依赖。在`pom.xml`文件中添加Oracle JDBC驱动(ojdbc66-oracle...

    springboot mybatis 动态调用oracle存储过程,通过存储过程名称,就能动态调用存储过程、java动态调用or

    能不能写个动态的业务,只输入存储过程名称,自动获取存储过程参数,并且参数的数据从前台传递过来...只根据输入不同的存储过程名称、参数内容,自动调用不同的存储过程。 已经使用在多个项目中 全开源项目 请放心下载

    Mybatis调用Oracle存储过程的方法图文详解

    Mybatis调用Oracle存储过程的方法详解 Mybatis是一款流行的持久层框架,广泛应用于Java企业级应用开发中。 Oracle存储过程是一种高效的数据库操作方式,通过存储过程可以实现复杂的业务逻辑操作。那么,如何使用...

    spring mybatis 调用oracle存储过程

    本文将深入探讨如何在Spring和MyBatis集成环境中调用Oracle数据库的存储过程,包括无返回值、返回结果集以及返回多个结果的情况。 首先,让我们理解基础概念。Spring是一个全面的后端开发框架,它提供了依赖注入、...

    SpringBoot+mybatis+Oracle整合代码

    SpringBoot简化了Spring应用的初始搭建以及开发过程,而MyBatis则是一个优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。当这两个框架与Oracle数据库整合时,可以构建出高效、稳定的后台服务。 在...

    mybatis连接oracle实例

    在Eclipse中创建一个JUnit测试类,注入`TestService`,并调用其方法进行数据库操作,如查询、插入、更新或删除,以验证MyBatis是否成功连接到Oracle数据库。 通过以上步骤,你就完成了MyBatis连接Oracle数据库的...

    Mybatis传list参数调用oracle存储过程的解决方法

    但是,如何将List类型参数传递给Oracle存储过程,实现批量插入数据却是一个棘手的问题,本文将给大家介绍Mybatis传List参数调用Oracle存储过程的解决方法。 使用Mybatis传List参数调用Oracle存储过程的解决方法 在...

    mybatis调用存储过程

    在调用过程中,如果出现错误,MyBatis会抛出异常,如`SQLException`。可以捕获这些异常,获取错误信息进行调试。此外,使用日志框架(如Log4j或Logback)可以帮助跟踪和分析MyBatis的执行过程。 6. 动态SQL与存储...

    mybatis调用orclae存储过程

    下面将详细介绍如何使用MyBatis来调用Oracle存储过程。 ### 1. 创建Oracle存储过程 首先,我们需要在Oracle数据库中创建一个存储过程。例如,假设我们有一个名为`INSERT_EMPLOYEE`的存储过程,用于插入新的员工...

    ibatis调用oracle存储过程分页

    ibatis调用oracle存储过程分页

    mybatis映射生成工具

    MyBatis是一个优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。MyBatis可以使用简单的XML或注解进行配置和原始映射,将接口和Java的...

    mybatis + oracle demo

    【标题】"mybatis + oracle demo"是一个关于如何结合MyBatis框架与Oracle数据库进行实际操作的示例项目。这个项目旨在为初学者提供一个简单易懂的起点,帮助他们快速掌握MyBatis在Oracle环境下的应用。 【描述】...

    SpringBoot+Mybatis+Oracle代码demo

    - **简介**:Mybatis是一个优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。Mybatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。 - **特性**:XML或注解方式进行映射,灵活的SQL构建,动态...

    Mybatis 处理 CLOB、BLOB 类型数据

    MyBatis 提供了对 CLOB 和 BLOB 类型的内置支持,通过将 CLOB 类型映射到 Java 的 String 类型,BLOB 类型映射到 byte[] 类型。 在使用 MyBatis 时,需要在实体类中定义对应的字段类型,例如: ```java public ...

    mybatis调用储存过程

    4. **处理结果**:如果存储过程有返回值,可以通过`resultType`指定返回结果的类型,MyBatis会自动将结果映射到指定类型。对于`OUT`参数,MyBatis会在执行完存储过程后自动填充。 5. **在Service层调用**:在业务...

    mybatis-oracle逆向工程工具

    1. **MyBatis框架**:MyBatis是一个优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。MyBatis可以使用简单的XML或注解进行配置和原始映射...

    MyBatis调用存储过程

    在MyBatis的映射文件(mapper.xml)中,我们需要为存储过程创建一个`&lt;select&gt;`标签,但与通常的查询不同,这里需要设置`id`(标识符)、`resultMap`(结果映射)以及`statementType="CALLABLE"`,这表明这是一个调用...

    解决mybatis使用char类型字段查询oracle数据库时结果返回null问题

    "解决mybatis使用char类型字段查询oracle数据库时结果返回null问题" 在使用mybatis框架对Oracle数据库进行查询操作时,如果使用char类型字段作为查询条件,可能会出现结果返回null的问题。这种情况下,需要对char...

    mybatis 整合oracle (含增删改查)

    MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。在实际开发中,将 MyBatis 整合到 Oracle 数据库进行数据操作,包括增删改查,是常见的需求。以下将详细介绍这个过程。 1. **环境准备**...

    mybatis连接Oracle所用的jar包

    MyBatis是一个优秀的Java持久层框架,它支持定制化SQL、存储过程以及高级映射。在使用MyBatis与Oracle数据库进行交互时,通常需要一些特定的库来确保连接和操作的顺利进行。这里提到的两个jar包,"ojdbc6.jar"和...

Global site tag (gtag.js) - Google Analytics