【问题标题】:Inserting int[] into PostgreSql with iBatis使用 iBatis 将 int[] 插入 PostgreSql
【发布时间】:2011-01-14 19:15:13
【问题描述】:

... 有没有一种简单的方法可以在 iBatis 的帮助下将 Java int[] 插入 PostgreSql? (旧的,不是新的 MyBatis)

不确定我是否需要自定义类型处理程序,但我很难找到可以说明正在发生的事情的代码示例。

提前致谢。

ps:

自最初发布以来,我能够从 DB 中读取数组并在域对象中填充 int[]。但还不能写入数据库:-(

所以在域模型中有:

int[] crap = null;

使用 getter 和 setter,自定义属性处理程序如下所示:

public class ArrayTypeHandler implements TypeHandlerCallback {
public void setParameter(ParameterSetter setter, Object parameter) throws SQLException {

    if( parameter == null){
        setter.setNull( Types.ARRAY);
    } else {
        setter.setArray( (Array) Arrays.asList(parameter ) );
    }

}

public Object getResult(ResultGetter getter) throws SQLException {
    Array array = getter.getResultSet().getArray(getter.getColumnName());
    if( !getter.getResultSet().wasNull()){
         return array.getArray();
    } else { return null; }

}

public Object valueOf(String string) {
    throw new UnsupportedOperationException("Not supported yet.");
}

}

sqlMapConfig.xml:

<typeHandler javaType="java.sql.Array" jdbcType="ARRAY" callback="project.persistance.sqlmapdao.ArrayTypeHandler"  />

尝试更新时出现以下错误:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.jdbc.UncategorizedSQLException: SqlMapClient operation; uncategorized SQLException for SQL []; SQL state [null]; error code [0];   

---项目/persistance/sql_xml/Article.xml中出现错误。
--- 应用参数映射时发生错误。
--- 检查 updateArticle-InlineParameterMap.
--- 检查“废话”属性的参数映射。
--- 原因:java.lang.NullPointerException;嵌套异常是 com.ibatis.common.jdbc.exception.NestedSQLException:
--- 项目/persistance/sql_xml/Article.xml中出现错误。
--- 应用参数映射时发生错误。
--- 检查 updateArticle-InlineParameterMap.
--- 检查“废话”属性的参数映射。
--- 原因:java.lang.NullPointerException

...关于我缺少什么的任何提示? 谢谢

===

...我一直努力到 ClassCastExceptiong :-)

尝试设置属性:

    public void setParameter(ParameterSetter setter, Object parameter) throws SQLException {
    int[] c = (int[]) parameter;

    setter.setArray( (java.sql.Array) c  );
}

...以及随之而来的异常:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.jdbc.UncategorizedSQLException: SqlMapClient operation; uncategorized SQLException for SQL []; SQL state [null]; error code [0];   

---项目/persistance/sql_xml/Article.xml中出现错误。
--- 应用参数映射时发生错误。
--- 检查 updateArticle-InlineParameterMap.
--- 检查“废话”属性的参数映射。
--- 原因:java.lang.ClassCastException: java.util.ArrayList;嵌套异常是 com.ibatis.common.jdbc.exception.NestedSQLException:
--- 项目/persistance/sql_xml/Article.xml中出现错误。
--- 应用参数映射时发生错误。
--- 检查 updateArticle-InlineParameterMap.
--- 检查“废话”属性的参数映射。
--- 原因:java.lang.ClassCastException: java.util.ArrayList

...不过我今天已经吃过了。 谢谢

【问题讨论】:

  • 您要在一行还是多行中插入int[]
  • 一行,col类型为整数[]

标签: java postgresql ibatis


【解决方案1】:

【讨论】:

  • ... 似乎正是我一直在寻找的东西,会试一试,谢谢!
【解决方案2】:

根据 Jeremy 的回答引用的页面,我不久前编写了自己的处理程序(有一些 hack)。如果您觉得它有用:

public class ArrayIntsTypeHandlerCallback implements TypeHandlerCallback {

     /**
      * to write an integer array in db. Object should be Integer[]
      */    
      public void setParameter(ParameterSetter setter, Object parameter) throws SQLException  {
          Connection con = setter.getPreparedStatement().getConnection();
          // hack: if using poolable connection from dbcp must get inside true connection! 
          if(con instanceof org.apache.commons.dbcp.PoolableConnection ) {
              con =     ((org.apache.commons.dbcp.PoolableConnection)con).getInnermostDelegate();
          }
          Array array = con.createArrayOf("integer", (Object[])parameter);
          setter.setArray(array);
        }

      /**
       * read integer array from db. returns Integer[]
       */
      public Object getResult(ResultGetter getter) throws SQLException {
        Array array = getter.getArray();
        if (!getter.getResultSet().wasNull()) {
          return array.getArray();
        } else {
          return null;
        }
      }

      public Object valueOf(String s) {
        throw new UnsupportedOperationException("Not implemented");
      }


    }

【讨论】:

  • ...这仅适用于 jdk 1.6 还是 1.5 兼容?
  • IIRC createArrayOf 自带 JDBC-4,JDK 1.6 自带
【解决方案3】:

...终于明白了。从一开始就是这样:

...第一: reading the int[]

...第二:第二,在搜索和偶然发现一个implementation of the java.sql.Array interface(虽然只有jdk 1.6)并在mailing list from 2005上发帖。

TypeHandlerCallbac iterface中setParameter方法的最终实现:

    public void setParameter(ParameterSetter setter, Object parameter) throws SQLException {
    setter.setArray( this.convertIntegerToPgSqlArray( (int[]) parameter ) );
}

...

    private java.sql.Array convertIntegerToPgSqlArray(final int[] p) {
    if (p == null || p.length < 1) {
        return null;
    }
    Array a = new Array() {

        public String getBaseTypeName() {
            return "int4";
        }

        public int getBaseType() {
            return 0;
        }

        public Object getArray() {
            return null;
        }

        public Object getArray(Map<String, Class<?>> map) {
            return null;
        }

        public Object getArray(long index, int count) {
            return null;
        }

        public Object getArray(long index, int count, Map<String, Class<?>> map) {
            return null;
        }

        public ResultSet getResultSet() {
            return null;
        }

        public ResultSet getResultSet(Map<String, Class<?>> map) {
            return null;
        }

        public ResultSet getResultSet(long index, int count) {
            return null;
        }

        public ResultSet getResultSet(long index, int count,
            Map<String, Class<?>> map) {
            return null;
        }

        public String toString() {
            String fp = "{";
            if (p.length == 0) {
            } else {
                for (int i = 0; i < p.length - 1; i++) {
                    fp += p[i] + ",";
                }
                fp += p[p.length - 1];
            }
            fp += "}";
            return fp;
        }
    };
        return a;
}

最后感谢所有人,希望这可以节省其他人一些时间:-)

PS:作为最后的仅供参考,当我将问题发布到 MyBatis 邮件列表时,我得到的回复如下:

这个有几个问题...

  1. Arrays.asList() 不适用于原始数组。见这里:

    http://code.google.com/p/mybatis/source/detail?r=3467

    关于我们在 MyBatis 3 中为处理原始数组所做的更改。

  2. 那么,您可能无法将 java.util.List 强制转换为 java.sql.Array。 要制作 java.sql.Array,您需要使用一些实用程序 您的 JDBC 驱动程序,或切换到 JDK6 并使用 Connection.createArrayOf(...) 方法。

在 JDBC 中对 ARRAY 类型的支持一团糟,将它与 原始数组增加了另一层混乱:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-10
    • 1970-01-01
    • 1970-01-01
    • 2013-05-27
    • 1970-01-01
    • 1970-01-01
    • 2022-11-24
    • 1970-01-01
    相关资源
    最近更新 更多