设为首页 收藏本站
查看: 598|回复: 0

[经验分享] Oracle存储过程做大数据量插入

[复制链接]

尚未签到

发表于 2016-8-6 13:48:22 | 显示全部楼层 |阅读模式

0
踩 最近在项目中用到了JAVA客户端传递对象数组到Oracle存储过程做大数据量插入,比如10万级别.
下面做一个插入10万条记录的示例步骤,,为了容易理解,表的结果很简单.
1,假设表结构如下:
源码copy to clipboard打印?
01.CREATE TABLE UKBNOVCTCORDER(   
02.LosingLEName varchar2(200),   
03.LosingLECode varchar2(200)   
04.)  
CREATE TABLE UKBNOVCTCORDER(
LosingLEName varchar2(200),
LosingLECode varchar2(200)
)2,在数据库建立一个type,对应JAVA端要传入的对象结构:
源码copy to clipboard打印?
01.CREATE OR REPLACE TYPE BUT_UKBNOV_CTC_ORDER_REC AS OBJECT (   
02.  losingLEName VARCHAR2(200),   
03.     losingLECode VARCHAR2(200)   
04.);  
CREATE OR REPLACE TYPE BUT_UKBNOV_CTC_ORDER_REC AS OBJECT (
losingLEName VARCHAR2(200),
losingLECode VARCHAR2(200)
);3,为了数组传输,建立一个数组类型的type:
CREATE OR REPLACE TYPE BUT_UKBNOV_CTC_ORDER_TAB AS TABLE OF BUT_UKBNOV_CTC_ORDER_REC
4,建立存储过程做插入工作:
源码copy to clipboard打印?
01.CREATE OR REPLACE procedure bulkInsertCTDORDER(i_orders IN BUT_UKBNOV_CTC_ORDER_TAB)   
02.as   
03.ctcOrder BUT_UKBNOV_CTC_ORDER_REC;   
04.begin   
05.    FOR idx IN i_orders.first()..i_orders.last() LOOP   
06.        ctcOrder:=i_orders(idx);   
07.        INSERT INTO UKBNOVCTCORDER   
08.          (LosingLEName,   
09.           LosingLECode)   
10.        VALUES   
11.          (ctcOrder.losingLEName,   
12.           ctcOrder.losingLECode);   
13.    end loop;   
14.    exception when others then   
15.    raise;   
16.end;  
CREATE OR REPLACE procedure bulkInsertCTDORDER(i_orders IN BUT_UKBNOV_CTC_ORDER_TAB)
as
ctcOrder BUT_UKBNOV_CTC_ORDER_REC;
begin
FOR idx IN i_orders.first()..i_orders.last() LOOP
ctcOrder:=i_orders(idx);
INSERT INTO UKBNOVCTCORDER
(LosingLEName,
LosingLECode)
VALUES
(ctcOrder.losingLEName,
ctcOrder.losingLECode);
end loop;
exception when others then
raise;
end;5,建立JAVA端java bean对象,(为节省版面,下面的get set方法省略,)
源码copy to clipboard打印?
01.public class UkbnovCTCOrder  {   
02.    private String losingLEName;   
03.    private String losingLECode;   
04......  
public class UkbnovCTCOrder  {
private String losingLEName;
private String losingLECode;
.....在JAVA端访问存储过程插入数据,需要做JAVA数据类型和存储过程类型type的映射,下面的StructDescriptor是mapping Oracle端AS OBJECT类型,
tabDesc 是mapping Oracle端数组 AS TABLE OF类型的.
源码copy to clipboard打印?
01.Connection con = null;   
02.CallableStatement cstmt = null;        
03.try {                  
04.    con = OracleConnection.getConn();   
05.    List<UkbnovCTCOrder> orderList = new ArrayList<UkbnovCTCOrder>();   
06.    for(int i=0;i<100000;i++){   
07.        orderList.add(new UkbnovCTCOrder("losingLEName"+i,"losingLECode+"+i));   
08.    }               
09.    StructDescriptor recDesc = StructDescriptor.createDescriptor("BUT_UKBNOV_CTC_ORDER_REC", con);   
10.    ArrayList<STRUCT> pstruct = new ArrayList<STRUCT>();   
11.    for (UkbnovCTCOrder ord:orderList) {                  
12.        Object[] record = new Object[2];   
13.        record[0] = ord.getLosingLEName();   
14.        record[1] = ord.getLosingLECode();   
15.        STRUCT item = new STRUCT(recDesc, con, record);                  
16.        pstruct.add(item);   
17.    }              
18.    ArrayDescriptor tabDesc = ArrayDescriptor.createDescriptor("BUT_UKBNOV_CTC_ORDER_TAB", con);               
19.    ARRAY vArray = new ARRAY(tabDesc, con, pstruct.toArray());                     
20.    cstmt = con.prepareCall("{call bulkInsertCTDORDER(?)}");        
21.    cstmt.setArray(1, vArray);                    
22.    cstmt.execute();   
23.    con.commit();  
Connection con = null;
CallableStatement cstmt = null;     
try {               
con = OracleConnection.getConn();
List<UkbnovCTCOrder> orderList = new ArrayList<UkbnovCTCOrder>();
for(int i=0;i<100000;i++){
orderList.add(new UkbnovCTCOrder("losingLEName"+i,"losingLECode+"+i));
}            
StructDescriptor recDesc = StructDescriptor.createDescriptor("BUT_UKBNOV_CTC_ORDER_REC", con);
ArrayList<STRUCT> pstruct = new ArrayList<STRUCT>();
for (UkbnovCTCOrder ord:orderList) {               
Object[] record = new Object[2];
record[0] = ord.getLosingLEName();
record[1] = ord.getLosingLECode();
STRUCT item = new STRUCT(recDesc, con, record);               
pstruct.add(item);
}           
ArrayDescriptor tabDesc = ArrayDescriptor.createDescriptor("BUT_UKBNOV_CTC_ORDER_TAB", con);            
ARRAY vArray = new ARRAY(tabDesc, con, pstruct.toArray());                  
cstmt = con.prepareCall("{call bulkInsertCTDORDER(?)}");     
cstmt.setArray(1, vArray);                 
cstmt.execute();
con.commit();6,如果每次调用都需要做Java bean的到Oracle的"AS OBJECT"类型的mapping,则很繁琐,可以然Java bean实现oracle.sql.ORAData,这样就不用在调用时候在做mapping了.
java bean对象如下,为节省版面get set方法省略.
源码copy to clipboard打印?
01.public class UkbnovCTCOrder1 implements ORAData {   
02.    private String losingLEName;   
03.    private String losingLECode;   
04.    public static final String _ORACLE_TYPE_NAME = "BUT_UKBNOV_CTC_ORDER_REC";      
05.    protected MutableStruct _struct;   
06.    static int[] _sqlType = { OracleTypes.VARCHAR, OracleTypes.VARCHAR };   
07.    static ORADataFactory[] _factory = new ORADataFactory[_sqlType.length];   
08.    public UkbnovCTCOrder1() {   
09.        _struct = new MutableStruct(new Object[_sqlType.length], _sqlType, _factory);   
10.    }   
11.    public Datum toDatum(Connection conn) throws SQLException {   
12.        _struct.setAttribute(0, this.losingLEName);   
13.        _struct.setAttribute(1, this.losingLECode);   
14.        return _struct.toDatum(conn, _ORACLE_TYPE_NAME);   
15.    }   
16.    public UkbnovCTCOrder1(String losingLEName, String losingLECode) {   
17.        this();   
18.        this.losingLEName = losingLEName;   
19.        this.losingLECode = losingLECode;   
20.    }   
21.....  
public class UkbnovCTCOrder1 implements ORAData {
private String losingLEName;
private String losingLECode;
public static final String _ORACLE_TYPE_NAME = "BUT_UKBNOV_CTC_ORDER_REC";   
protected MutableStruct _struct;
static int[] _sqlType = { OracleTypes.VARCHAR, OracleTypes.VARCHAR };
static ORADataFactory[] _factory = new ORADataFactory[_sqlType.length];
public UkbnovCTCOrder1() {
_struct = new MutableStruct(new Object[_sqlType.length], _sqlType, _factory);
}
public Datum toDatum(Connection conn) throws SQLException {
_struct.setAttribute(0, this.losingLEName);
_struct.setAttribute(1, this.losingLECode);
return _struct.toDatum(conn, _ORACLE_TYPE_NAME);
}
public UkbnovCTCOrder1(String losingLEName, String losingLECode) {
this();
this.losingLEName = losingLEName;
this.losingLECode = losingLECode;
}
....调用的时候不需要再做Java bean 到Oracle "AS OBJECT"数据类型的mapping,只需要做数组类型的mapping,如下:
源码copy to clipboard打印?
01.Connection con = null;   
02.CallableStatement cstmt = null;        
03.try {        
04.    con = OracleConnection.getConn();              
05.    System.out.println(new Date());   
06.    List<UkbnovCTCOrder1> orderList = new ArrayList<UkbnovCTCOrder1>();   
07.    for(int i=0;i<100000;i++){   
08.        orderList.add(new UkbnovCTCOrder1("losingLEName"+i,"losingLECode+"+i));   
09.    }           
10.    ArrayDescriptor tabDesc = ArrayDescriptor.createDescriptor("BUT_UKBNOV_CTC_ORDER_TAB", con);               
11.    ARRAY vArray = new ARRAY(tabDesc, con, orderList.toArray());         
12.      
13.    cstmt = con.prepareCall("{call bulkInsertCTDORDER(?)}");        
14.    cstmt.setArray(1, vArray);                  
15.    cstmt.execute();   
16.    con.commit();  
Connection con = null;
CallableStatement cstmt = null;     
try {     
con = OracleConnection.getConn();           
System.out.println(new Date());
List<UkbnovCTCOrder1> orderList = new ArrayList<UkbnovCTCOrder1>();
for(int i=0;i<100000;i++){
orderList.add(new UkbnovCTCOrder1("losingLEName"+i,"losingLECode+"+i));
}        
ArrayDescriptor tabDesc = ArrayDescriptor.createDescriptor("BUT_UKBNOV_CTC_ORDER_TAB", con);            
ARRAY vArray = new ARRAY(tabDesc, con, orderList.toArray());      
cstmt = con.prepareCall("{call bulkInsertCTDORDER(?)}");     
cstmt.setArray(1, vArray);               
cstmt.execute();
con.commit();上面的示例在插入10万条记录只用了5秒(当然也和这里的表结构字段少有关系).
原文链接:http://blog.csdn.net/kkdelta/article/details/7226331

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-253719-1-1.html 上篇帖子: 应用Oracle组件实现动态Web数据库 下篇帖子: oracle体系结构三部曲之进程结构
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表