数据库表:
create table BOOK
(
book_id NUMBER not null,
book_name XMLTYPE,
book_price NUMBER
)
JavaBean:
public class Book { private Integer bookId; private String bookName; private Integer bookPrice; get(),set()....... }
<insert id="insert" parameterType="com.zfy.db.model.Book" > insert into BOOK (BOOK_ID, BOOK_PRICE, BOOK_NAME ) values (#{bookId}, #{bookPrice,jdbcType=INTEGER}, #{bookName} ) </insert>
JUNIT测试:插入操作
public String getXml() { File file = new File("E:\\test.xml"); InputStream ios = null; StringBuffer xml = new StringBuffer(); try { ios = new FileInputStream(file); byte[] b = new byte[(int) file.length()]; for (int i = 0; i < b.length; i++) { b[i] = (byte) ios.read(); } xml.append(new String(b)); } catch (Exception e) { } finally { try { if (ios != null) ios.close(); } catch (IOException e) { e.printStackTrace(); } } return xml.toString(); } //xmlType类型 @Test public void insertXMLTYPE() throws ParserConfigurationException, SAXException, IOException{ Book book = new Book(); book.setBookId(3); book.setBookName(getXml()); book.setBookPrice(33); session.insert("com.zfy.db.dao.BookMapper.insert",book); session.commit(); session.close(); }
报错如下:
org.apache.ibatis.exceptions.PersistenceException:
### Error updating database. Cause: java.sql.SQLException: ORA-01461: 仅能绑定要插入 LONG 列的 LONG 值
### The error may exist in com/zfy/db/mapping/BookMapper.xml
### The error may involve com.zfy.db.dao.BookMapper.insert-Inline
### The error occurred while setting parameters
### SQL: insert into BOOK (BOOK_ID, BOOK_PRICE, BOOK_NAME ) values (?, ?, ? )
### Cause: java.sql.SQLException: ORA-01461: 仅能绑定要插入 LONG 列的 LONG 值
at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:23)
at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:150)
at org.apache.ibatis.session.defaults.DefaultSqlSession.insert(DefaultSqlSession.java:137)
at com.zfy.controller.test.ControllerTest.insertXMLTYPE(ControllerTest.java:358)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:45)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Caused by: java.sql.SQLException: ORA-01461: 仅能绑定要插入 LONG 列的 LONG 值
at oracle.jdbc.driver.SQLStateMapping.newSQLException(SQLStateMapping.java:70)
at oracle.jdbc.driver.DatabaseError.newSQLException(DatabaseError.java:133)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:206)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:455)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:413)
at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:1034)
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:194)
at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:953)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1222)
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3387)
at oracle.jdbc.driver.OraclePreparedStatement.execute(OraclePreparedStatement.java:3488)
at oracle.jdbc.driver.OraclePreparedStatementWrapper.execute(OraclePreparedStatementWrapper.java:1374)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.ibatis.logging.jdbc.PreparedStatementLogger.invoke(PreparedStatementLogger.java:55)
at sun.proxy.$Proxy11.execute(Unknown Source)
at org.apache.ibatis.executor.statement.PreparedStatementHandler.update(PreparedStatementHandler.java:41)
at org.apache.ibatis.executor.statement.RoutingStatementHandler.update(RoutingStatementHandler.java:66)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59)
at sun.proxy.$Proxy9.update(Unknown Source)
at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:45)
at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:100)
at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:75)
at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:148)
... 26 more
现在两种解决方法:
1、用JDBC ,但不适合JDNI数据源
工具类:XmlTypeUtil.java
package com.zfy.com.util; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.io.UnsupportedEncodingException; import oracle.xml.parser.v2.DOMParser; public class XmlTypeUtil { public static org.w3c.dom.Document getDocument(String str) throws Exception{ if(getStr(str).equals("")){ return null; } org.w3c.dom.Document doc=null; try{ DOMParser parser = new DOMParser(); parser.parse(getStringInputString(str)); doc =parser.getDocument(); }catch(Exception e){ e.printStackTrace(); throw e; } return doc; } /** * org.w3c.dom.Document -> org.dom4j.Document * * @param doc * Document(org.w3c.dom.Document) * @return Document */ public static org.dom4j.Document parse(org.w3c.dom.Document doc) throws Exception { if (doc == null) { return (null); } org.dom4j.io.DOMReader xmlReader = new org.dom4j.io.DOMReader(); return (xmlReader.read(doc)); } /** * org.dom4j.Document -> org.w3c.dom.Document * * @param doc * Document(org.dom4j.Document) * @throws Exception * @return Document */ public static org.w3c.dom.Document parse(org.dom4j.Document doc) throws Exception { if (doc == null) { return (null); } java.io.StringReader reader = new java.io.StringReader(doc.asXML()); org.xml.sax.InputSource source = new org.xml.sax.InputSource(reader); javax.xml.parsers.DocumentBuilderFactory documentBuilderFactory = javax.xml.parsers.DocumentBuilderFactory .newInstance(); javax.xml.parsers.DocumentBuilder documentBuilder = documentBuilderFactory .newDocumentBuilder(); return (documentBuilder.parse(source)); } public static String getStr(Object obj) { String s = obj == null ? "" : String.valueOf(obj); if (s.equals("null")) { return ""; } return s; } public static InputStream getStringInputString(String str) throws UnsupportedEncodingException { InputStream f = new ByteArrayInputStream(getStr(str).getBytes("GBK")); return f; } }
public void insertXmlContent(String fileId, String xmlContent) throws Exception { Class.forName("oracle.jdbc.driver.OracleDriver"); Connection conn = java.sql.DriverManager.getConnection("jdbc:oracle:thin:@192.168.1.252:1521:orcl","dsci","dsci"); OraclePreparedStatement stmt = null; Document doc = XmlTypeUtil.getDocument(xmlContent); String sql = "insert into dsc_pro_xml_t0d0(xml_content) values (?)"; stmt = (OraclePreparedStatement) conn.prepareStatement(sql); XMLType xmlTypeContent = null; xmlTypeContent = XMLType.createXML(conn, doc); stmt.setObject(1, xmlTypeContent); stmt.executeUpdate(); }
先建立一个临时的表,其中的一个字段是clob类型;
再将要写入xmltype字段的xml doc写入这个临时的clob型的字段中;
最后insert into abc (id,xmldoc) values (abc_q.nextval , sys.xmlType.createXML((select content from 临时表 where id=......)));