java操作Oracle数据库——ARRAY、TABLE类型批量入库



java操作Oracle数据库——ARRAY、TABLE类型批量入库

首先是我的数据库表(PLSQL操作)

 

  1. create table TEST_TABLE
  2. (
  3.   yid      NUMBER,
  4.   ytel     VARCHAR2(50),
  5.   yanumber VARCHAR2(50)
  6. );

这里记录两种方式:不管哪种方式、一定要记得导入orai18n.jar否则一遇到字符串就乱码、添加不到数据

点击下载orai18n.jar

第一种:
在数据库中建立相应的java对象(Oracle中的类型)和数组.

 

 

  1. CREATE OR REPLACE TYPE yOracleObject(类型名称) AS OBJECT(
  2.        yid number,ytel varchar2(50),yanumber varchar2(50)
  3. );

数组:

 

 

  1. CREATE OR REPLACE TYPE y_Oracle_LIST(数组名称) AS VARRAY(5000) OF yOracleObject(类型名称);

创建完毕后在Types下面可以看到创建好的类型。

存储过程:

 

 

  1. CREATE OR REPLACE PROCEDURE proc_test_new(y_Array IN y_oracle_list,
  2.                                           p_out   OUT NUMBER) AS
  3.   v_yID     number;
  4.   v_yTel    varchar(50);
  5.   v_anumber varchar(50);
  6.   v_type    yoracleobject;
  7. begin
  8.   FOR I IN 1 .. y_Array.COUNT LOOP
  9.     v_type    := y_Array(i);
  10.     v_yID     := v_type.yid;
  11.     v_yTel    := v_type.ytel;
  12.     v_anumber := v_type.yanumber;
  13.     insert into test_table values (v_yID, v_yTel, v_anumber);
  14.   end loop;
  15.   commit;
  16.   p_out := 0;
  17. EXCEPTION
  18.   WHEN OTHERS THEN
  19.     p_out := -1;
  20.     ROLLBACK;
  21. END;

 

java代码:

 

  1. import java.sql.CallableStatement;
  2. import java.sql.Connection;
  3. import java.sql.SQLException;
  4. import java.util.ArrayList;
  5. import com.chinaboxun.ordermanager.core.util.DbUtil;
  6. import oracle.jdbc.driver.OracleCallableStatement;
  7. import oracle.sql.ARRAY;
  8. import oracle.sql.ArrayDescriptor;
  9. import oracle.sql.STRUCT;
  10. import oracle.sql.StructDescriptor;
  11. @SuppressWarnings(“unchecked”)
  12. public class TestProc {
  13.     public static void main(String[] args) {
  14.         ArrayList arrayL = new ArrayList();
  15.         TestBean t = new TestBean();
  16.         t.setYid(1);
  17.         t.setYtel(“1236″);
  18.         t.setYanumber(“骚年”);
  19.         arrayL.add(t);
  20.         TestBean t1 = new TestBean();
  21.         t1.setYid(2);
  22.         t1.setYtel(“1236″);
  23.         t1.setYanumber(“骚年”);
  24.         arrayL.add(t1);
  25.         TestBean t2 = new TestBean();
  26.         t2.setYid(3);
  27.         t2.setYtel(“1236″);
  28.         t2.setYanumber(“骚年”);
  29.         arrayL.add(t2);
  30.         TestBean t3 = new TestBean();
  31.         t3.setYid(4);
  32.         t3.setYtel(“1236″);
  33.         t3.setYanumber(“骚年”);
  34.         arrayL.add(t3);
  35.         TestBean t4 = new TestBean();
  36.         t4.setYid(5);
  37.         t4.setYtel(“1236″);
  38.         t4.setYanumber(“骚年”);
  39.         arrayL.add(t4);
  40.         try {
  41.             /*
  42.              * 记得判断一下list集合的大小、如果集合大于你在数据设置的数组大小了、那么就要分批次提交
  43.              * 我的是y_Oracle_LIST AS VARRAY(5000)
  44.              * 那么当list集合的值等于5000的时候就入库了、
  45.              * 然后剩下的数据又从新用一个list来装、在继续判断……
  46.              * 这里只是简单的演示、就不具体操作判断了
  47.              */
  48.             int backVal = newTest(arrayL);
  49.             System.out.println(backVal==0?”成功!”:”失败!”);
  50.         } catch (SQLException e) {
  51.             e.printStackTrace();
  52.         }
  53.     }
  54.     /**
  55.      * 将java中的arrayList转化
  56.      * @param con 数据库连接对象
  57.      * @param Oraclelist 数据数组类型名称
  58.      * @param objlist 要存储的list对象
  59.      * @return oracle.sql.ARRAY
  60.      * @throws Exception
  61.      */
  62.     private static ARRAY getOracleArray(Connection con, String Oraclelist,
  63.             ArrayList objlist) throws Exception {
  64.         ARRAY list = null;
  65.         if (objlist != null && objlist.size() > 0) {
  66.             /**
  67.              * 必须大写类型名称
  68.              * 否则会报错:java.sql.SQLException: 无效的名称模式: M_ORDER.yoracleobject
  69.              */
  70.             StructDescriptor structdesc = new StructDescriptor(
  71.                     ”YORACLEOBJECT”, con);
  72.             STRUCT[] structs = new STRUCT[objlist.size()];
  73.             Object[] result = new Object[0];
  74.             for (int i = 0; i < objlist.size(); i++) {
  75.                 result = new Object[3];
  76.                 TestBean t = (TestBean)(objlist.get(i));
  77.                 result[0] = t.getYid();
  78.                 result[1] = t.getYtel();
  79.                 result[2] = t.getYanumber();
  80.                 /*
  81.                  * 一定要记得导入orai18n.jar
  82.                  * 否则一遇到字符串就乱码、添加不到数据
  83.                  */
  84.                 structs[i] = new STRUCT(structdesc, con, result);
  85.             }
  86.             ArrayDescriptor desc = ArrayDescriptor.createDescriptor(Oraclelist,
  87.                     con);
  88.             list = new ARRAY(desc, con, structs);
  89.         } else {
  90.             ArrayDescriptor desc = ArrayDescriptor.createDescriptor(Oraclelist,
  91.                     con);
  92.             STRUCT[] structs = new STRUCT[0];
  93.             list = new ARRAY(desc, con, structs);
  94.         }
  95.         return list;
  96.     }
  97.     /**
  98.      * 入库
  99.      * @param peoleList 要存储的list对象
  100.      * @return
  101.      * @throws SQLException
  102.      */
  103.     public static int newTest(ArrayList peoleList) throws SQLException{
  104.         Connection con = null;
  105.         CallableStatement stmt = null;
  106.         int backVal = -1;
  107.         try {
  108.             DbUtil d = new DbUtil();
  109.             con = d.getCon();
  110.             if (con != null) {
  111.                 stmt = con.prepareCall(“{call proc_test_new(?,?)}”);
  112.                 ARRAY adArray = getOracleArray(con, ”Y_ORACLE_LIST”,peoleList);
  113.                 ((OracleCallableStatement) stmt).setARRAY(1, adArray);
  114.                 stmt.registerOutParameter(2, java.sql.Types.INTEGER);
  115.                 stmt.execute();
  116.                 backVal = stmt.getInt(2);
  117.             }
  118.         } catch (Exception e) {
  119.             e.printStackTrace();
  120.         } finally {
  121.             if(stmt!=null){
  122.                 stmt.close();
  123.             }
  124.             if(con!=null){
  125.                 con.close();
  126.             }
  127.         }
  128.         return backVal;
  129.     }
  130. }

第二种:不用判断list集合大小、不用考虑数组长度的做法就是用table。
使用的类型:你要新增的数据有多少字段就添加相应个数的类型


 

 

  1. create or replace type i_table is table of number;
  2. create or replace type t_table is table of varchar2(30);
  3. create or replace type a_table is table of varchar2(30);

存储过程:

 

 

  1. create or replace procedure pro_forall_insert(v_1 i_table,
  2.                                               v_2 t_table,
  3.                                               v_3 a_table) as
  4. begin
  5.   forall i in 1 .. v_1.count
  6.     insert into test_table values (v_1(i), v_2(i), v_3(i));
  7. END;

java代码:

  1. import java.sql.CallableStatement;
  2. import java.sql.Connection;
  3. import java.sql.SQLException;
  4. import java.util.ArrayList;
  5. import com.chinaboxun.ordermanager.core.util.DbUtil;
  6. import oracle.jdbc.driver.OracleCallableStatement;
  7. import oracle.sql.ARRAY;
  8. import oracle.sql.ArrayDescriptor;
  9. import oracle.sql.STRUCT;
  10. import oracle.sql.StructDescriptor;
  11. @SuppressWarnings(“unchecked”)
  12. public class TestProc {
  13.     public static void main(String[] args) {
  14.         Connection con = null;
  15.         CallableStatement cstmt = null;
  16.         oracle.sql.ArrayDescriptor a = null;
  17.         oracle.sql.ArrayDescriptor b = null;
  18.         oracle.sql.ArrayDescriptor c = null;
  19.         DbUtil d = new DbUtil();
  20.         con = d.getCon();
  21.         if (1 == 1 )
  22.         {
  23.             Object[] s1 = new Object[10000];
  24.             Object[] s2 = new Object[10000];
  25.             Object[] s3 = new Object[10000];
  26.             for (int i = 0; i < 10000; i++) {
  27.                 s1[i] = new Integer(i);
  28.                 s2[i] = ”ttt”+i;
  29.                 s3[i] = ”aaa”+i;
  30.             }
  31.             try {
  32.                 a = oracle.sql.ArrayDescriptor.createDescriptor(“I_TABLE”, con);
  33.                 b = oracle.sql.ArrayDescriptor.createDescriptor(“T_TABLE”, con);
  34.                 c = oracle.sql.ArrayDescriptor.createDescriptor(“A_TABLE”, con);
  35.                 ARRAY a_test = new ARRAY(a, con, s1);
  36.                 ARRAY b_test = new ARRAY(b, con, s2);
  37.                 ARRAY c_test = new ARRAY(c, con, s3);
  38.                 cstmt = con.prepareCall(“{ call pro_forall_insert(?,?,?) }”);
  39.                 cstmt.setObject(1, a_test);
  40.                 cstmt.setObject(2, b_test);
  41.                 cstmt.setObject(3, c_test);
  42.                 cstmt.execute();
  43.                 con.commit();
  44.             } catch (Exception e) {
  45.                 e.printStackTrace();
  46.             }
  47.         }
  48.     }
  49. }

DbUtil工具类:

  1. import java.io.IOException;
  2. import java.io.InputStream;
  3. import java.sql.Connection;
  4. import java.sql.DriverManager;
  5. import java.util.Properties;
  6. public class DbUtil {
  7.     static Properties properties = null;
  8.     public DbUtil() {
  9.         // 读取.properties文件的信息
  10.         properties = new Properties();
  11.         InputStream in = getClass().getResourceAsStream(“/com/chinaboxun/ordermanager/config/ordermanager.properties”);
  12.         try {
  13.             properties.load(in);
  14.         } catch (IOException ex) {
  15.             System.out.println(ex.getMessage());
  16.             ex.printStackTrace();
  17.         }
  18.     }
  19.     /**
  20.      * <LI>获取连接对象</LI>
  21.      *
  22.      * @return
  23.      */
  24.      public Connection getCon() {
  25.             Connection connection = null;
  26.             try {
  27.                 String url=properties.getProperty(“jdbc.url”);
  28.                 String user=properties.getProperty(“jdbc.username”);
  29.                 String pwd=properties.getProperty(“jdbc.password”);
  30.                 String driver=properties.getProperty(“jdbc.driverClassName”);
  31.                 Class.forName(driver);
  32.                 connection = DriverManager.getConnection(url, user, pwd);
  33.             } catch (Exception err) {
  34.                   System.out.println(“错误:ConDB–>getCon()____JDBC连接失败!”);
  35.                 err.printStackTrace();
  36.                 return null;
  37.             }
  38.             return connection;
  39.     }
  40. }

ordermanager.properties属性文件:

  1. jdbc.driverClassName=oracle.jdbc.OracleDriver
  2. jdbc.url=jdbc:oracle:thin:@172.16.0.162:1521:ORCL
  3. jdbc.username=m_order
  4. jdbc.password=morder

 

最后:一定要记得导入orai18n.jar否则一遇到字符串就乱码、添加不到数据!

点击下载orai18n.jar

—————-编辑:20140110—————

一些加上jar继续报错如下错误的朋友可以考虑以下解决方案:

ERROR1:Non supported character set: oracle-character-set-852

ERROR2:oracle/i18n/text/converter/CharacterConverterOGS.getInstance(I)Loracle/i18n/text/converter/CharacterConverter;

以上两个错误可以采取一个方案,就是把type的数据类型改成:nVARCHAR2

 

如果坚持使用该jar的童鞋请将 nls_charset12.jar 加入到 classpath 中。在加上orai18n.jar