用Mybatis JDBC访问 Oracle的XMLType数据类型

本文介绍如何使用Mybatis配合JDBC访问Oracle数据库中的XMLType数据。在Java环境中,需要JDK 5以上,Oracle10G驱动,xdb6.jar和xmlparserv2.jar。通过自定义TypeHandler处理XMLType,并扩展Mybatis枚举来支持未内置的XMLType。此外,还讨论了从Java传入XMLType参数到Oracle的方法。

你没看错,我也没有发神经。

这就是我要做的,用XML作为JAVA和数据库交流的载体。粗想一下是有些些反人类,不过如果能一次性取出多条多种数据集,也算是个不错的选择吧。本篇不深究是否值得这么去折腾,蛋,如果有一天你必须去面对这个无情的事实的时候,可以用下面的法子试试看。以下用Mybatis实现的,其实直接JDBC的访问也是一样的,本例只不过借用Mybatis搭好的架子而已。


先简单说说你需要的Java环境:JDK 5 以上,Oracle10G版本以上的驱动(我用的ojdbc6.jar),访问Oracle XMLType的组件包--xdb6.jar xmlparserv2.jar,还有就是DAO的---mybatis-3.2.0


这些包基本都可以从各自的官方获得,特别说一下xmlparserv2.jar,这傻逼玩意儿需要下载Oracle的开发工具比如SQLDeveloper之类的之后,在其内部寻找。Oracle官方没有直接下载的地儿——决逼坑爹!

好了开始:


1。先做一个用于处理XMLType的TypeHandler以便Mybatis识别你要处理的类型。

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLXML;

import oracle.sql.OPAQUE;
import oracle.xdb.XMLType;

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;

public class XMLTypeHandler extends BaseTypeHandler<SQLXML> {

	@Override
	public void setNonNullParameter(PreparedStatement ps, int i, SQLXML parameter, JdbcType jdbcType) throws SQLException {
		ps.setSQLXML(i, parameter);
	}

	@Override
	public SQLXML getNullableResult(ResultSet rs, String columnName) throws SQLException {
		return getXMLType(rs.getObject(columnName));
	}

	@Override
	public SQLXML getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
		return getXMLType(rs.getObject(columnIndex));
	}

	@Override
	public SQLXML getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
		return getXMLType(cs.getObject(columnIndex));
	}

	private SQLXML getXMLType(Object obj) throws SQLException {
		OPAQUE o = (OPAQUE)obj;
		XMLType xt = XMLType.createXML(o);
		return xt;
	}
}


2。Mybatis暂时还不支持XMLType也就是OPAQUE,我想以后的版本也许会支持。所以你需要想个办法让他暂时支持。这步没啥好办法,Mybatis用的枚举,这玩意儿不能继承,只能耍耍流氓了,把源代码Copy出来做如下处理:

实际就加了一个枚举值。

 *    Copyright 2009-2012 The MyBatis Team
package org.apache.ibatis.type;

import java.sql.Types;

public enum JdbcType {
  /*
   * This is added to enable basic support for the
   * ARRAY data type - but a custom type handler is still required
   */
  ARRAY(Types.ARRAY),
  BIT(Types.BIT),
  TINYINT(Types.TINYINT),
  SMALLINT(Types.SMALLINT),
  INTEGER(Types.INTEGER),
  BIGINT(Types.BIGINT),
  FLOAT(Types.FLOAT),
  REAL(Types.REAL),
  DOUBLE(Types.DOUBLE),
  NUMERIC(Types.NUMERIC),
  DECIMAL(Types.DECIMAL),
  CHAR(Types.CHAR),
  VARCHAR(Types.VARCHAR),
  LONGVARCHAR(Types.LONGVARCHAR),
  DATE(Types.DATE),
  TIME(Types.TIME),
  TIMESTAMP(Types.TIMESTAMP),
  BINARY(Types.BINARY),
  VARBINARY(Types.VARBINARY),
  LONGVARBINARY(Types.LONGVARBINARY),
  NULL(Types.NULL),
  OTHER(Types.OTHER),
  BLOB(Types.BLOB),
  CLOB(Types.CLOB),
  BOOLEAN(Types.BOOLEAN),
  CURSOR(-10), // Oracle
  UNDEFINED(Integer.MIN_VALUE + 1000),
  NVARCHAR(-9), // JDK6
  NCHAR(-15), // JDK6
  NCLOB(2011), // JDK6
  STRUCT(Types.STRUCT),
  SQLXML(Types.SQLXML),
  OPAQUE(OracleTypes.OPAQUE);

  public final int TYPE_CODE;
  private static Map<Integer,JdbcType> codeLookup = new HashMap<Integer,JdbcType>();

  static {
    for (JdbcType type : JdbcType.values()) {
      codeLookup.put(type.TYPE_CODE, type);
    }
  }

  JdbcType(int code) {
    this.TYPE_CODE = code;
  }

  public static JdbcType forCode(int code)  {
    return codeLookup.get(code);
  }

}

3。在Mybatis的配置文件中注册XMLType的Handler

	<typeHandlers>
	    <typeHandler
	        javaType="java.sql.SQLXML"
	        handler="com.core.db.typehandler.XMLTypeHandler"
	        />
	</typeHandlers>

4。在Mybatis的SQL配置文件中使用XMLType,例子是呼叫了一个存储过程。

	<update id="selectProperty" parameterType="map" statementType="CALLABLE">
		{
			call pkg.select_proc(
				#{id, mode=IN, jdbcType=NUMERIC}
				, #{results, mode=INOUT, javaType=java.sql.SQLXML, jdbcType=OPAQUE, jdbcTypeName=XMLTYPE}
			)
		}
	</update>

5。如何从JAVA侧传入XMLType的参数到Oracle

Connection conn = session.getConnection();
SQLXML sqlXml = conn.createSQLXML();
sqlXml.setString(strXML);
...
dbMapper.testXMLType(paramMap);

6。如何取得Oralce返回的XMLType

SQLXML  sqlXml = (SQLXML)paramMap.get("results");
System.out.println(sqlXml.getString());


完活儿!


另外变通写的做法也有,就是在数据库侧用XMLType(CLOB)等方式改写自己的SQL然后用CLOB等数据结构调用。不过,男人嘛就要对自己残忍一些,XML直接上,必须的!


评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值