当前位置: 首页 > news >正文

ibatis 调用oracle 带自定义数组参数的存储过程,oracle存储过程接收 自定义 table 数组类型参数...

oracle存储过程接收自定义数组类型参数

2016年10月29日 09:53:23 ntuloser 阅读数:1092 标签: oraclejava存储mybatis 更多

个人分类: 数据库

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ntuloser/article/details/52962988

在使用oracle进行批量插入的时,如果数据量较小可以使用insert all的语法进行批量插入。如果数据量较大,再使用insert all的语句插入就会发生错误,因为这个语法会受到限制,oracle不允许一次性插入的列数乘以行数>1000,这时就可以考虑使用存储过程批量插入了。

使用存储过程批量插入很显然要接收一个数组当参数,而且这个数组里的元素类型应该和java里自定义的数据模型对应。我项目里数据层使用的是MyBatis,就整理整理MyBatis的实现过程。当然不管是MyBatis还是Hibernatge、JDBC都是一个道理,关键的一步都是将java数据模型转换成数据库数据模型。

以user表为例,user表字段:id、username、age、phone、email,对user表进行批量插入。思考一下,java里有个user类,批量插入,那么传入数据类型应该是List,但是数据库可不认识这个数据模型,所以为了让数据库认识,需要将java模型转换成数据库模型。

创建数据库类型和java数据模型对应create or replace type user_type as object(

age number,

username nvarchar2(20),

phone nvarchar2(20),

email nvarchar2(50)

)

1

2

3

4

5

6

注意这里字符串类型一定要定义为nvarchar,否则字符串类型在转换时会乱码无法插入数据库

2.数据模型有了,还得有个能存放此类型的数组

create or replace type user_type_arr as table of user_type

1

3.接着可以创建存储过程了

create or replace procedure user_insert_pro(userList in user_type_arr) as

begin

for i in 1 .. userList.count loop

insert into users(

id,

username,

age,

phone,

email

)

values

(

user_seq.nextval,

userList(i).username,

userList(i).age,

userList(i).phone,

userList(i).email

);

end loop;

end user_insert_pro;

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21数据库的准备工作就完成了,下面是java代码的工作。我使用的是MyBatis,要在Mapper里配置一个parameterMap

1

typeHandler="com.jy.typeHandler.UserListHandler"/>

1

2

3

4

然后写mybatis里写存储过程调用时的参数类型就定义为这个parameterMap ,这样的意义就是配置的typeHandler会将java里传入的ArrayList转换成对应的数据库类型。UserListHandler代码如下

package com.jy.typeHandler;

import java.sql.CallableStatement;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.util.ArrayList;

import java.util.List;

import org.apache.ibatis.type.BaseTypeHandler;

import org.apache.ibatis.type.JdbcType;

import com.jy.model.User;

import oracle.sql.ARRAY;

import oracle.sql.ArrayDescriptor;

import oracle.sql.STRUCT;

import oracle.sql.StructDescriptor;

@SuppressWarnings("rawtypes")

public class UserListHandler extends BaseTypeHandler

{

@Override

public Object getNullableResult(ResultSet arg0, String arg1) throws SQLException

{

return null;

}

@Override

public Object getNullableResult(ResultSet arg0, int arg1) throws SQLException

{

return null;

}

@Override

public Object getNullableResult(CallableStatement arg0, int arg1) throws SQLException

{

return null;

}

@SuppressWarnings("unchecked")

@Override

public void setNonNullParameter(PreparedStatement preparedStatement, int i, Object obj, JdbcType arg3)

throws SQLException

{

Connection conn = null;

try

{

if (null != obj)

{

List list = (ArrayList) obj;

conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "root", "root");

// 数据库的type名必须大写

ARRAY array = getArray(conn, "USER_TYPE", "USER_TYPE_ARR", list);

preparedStatement.setArray(i, array);

}

} catch (Exception e)

{

e.printStackTrace();

} finally

{

if (null != conn)

{

conn.close();

}

}

}

private ARRAY getArray(Connection con, String OracleObj, String Oraclelist, List data) throws Exception

{

ARRAY array = null;

ArrayDescriptor desc = ArrayDescriptor.createDescriptor(Oraclelist, con);

STRUCT[] structs = new STRUCT[data.size()];

StructDescriptor structdesc = new StructDescriptor(OracleObj, con);

for (int i = 0; i < data.size(); i++)

{

Object[] result = {

data.get(i).getAge(),

data.get(i).getUsername(),

data.get(i).getPhone(),

data.get(i).getEmail()

};

structs[i] = new STRUCT(structdesc, con, result);

}

array = new ARRAY(desc, con, structs);

return array;

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

再再Mapper里定义存储过程调用的语句

call user_insert_pro(?)

1

2

3

最后可以在java代码里用MyBatis调用存储过程了,MyBatis会基于刚才的配置,将java模型转换成数据库模型。

调用如下:

@org.junit.Test

public void test()

{

SqlSession session=sqlSessionFactory.openSession();

List list=new ArrayList();

for(int i=0;i<1000;i++)

{

list.add(new User("jy", 25, "oracle.com", "110"));

}

HashMap params=new HashMap();

params.put("userList", list);

session.insert("com.jy.dao.UserDao.userInsert", params);

session.close();

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

全剧终!

不管什么框架,主要找到java模型和数据库模型转换的方式就行了

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 郑歆炜:企业网络安全维护要减少人的因素
  • oracle11 更改用记名,oracle11g 修改字符集 修改为ZHS16GBK
  • 中国通货膨胀的实质原因探讨
  • linux的邮箱的配置文件,linux下Mail命令配置使用
  • TX早晚会有报应
  • linux 查看进程组,Linux session和进程组概述
  • 纯真IP数据库格式详解
  • linux 文件自启动,Linux 开机自启动应用程序(进程)
  • 白话 Ajax 及其入门基础(1)
  • linux 维护shell脚本,Linux运维 | Shell脚本(2)
  • 白话 Ajax 及其入门基础(2)
  • linux系统如何安装git,linux安装git_Linux系统中怎么安装Git
  • cookie概述
  • 共享nas盘添加本地用户 linux,一步一步地把NAS的硬盘共享给Linux
  • VBA教程
  • [Vue CLI 3] 配置解析之 css.extract
  • Computed property XXX was assigned to but it has no setter
  • django开发-定时任务的使用
  • es6--symbol
  • Intervention/image 图片处理扩展包的安装和使用
  • Quartz实现数据同步 | 从0开始构建SpringCloud微服务(3)
  • seaborn 安装成功 + ImportError: DLL load failed: 找不到指定的模块 问题解决
  • tweak 支持第三方库
  • 从0到1:PostCSS 插件开发最佳实践
  • 回顾 Swift 多平台移植进度 #2
  • 技术发展面试
  • 简单实现一个textarea自适应高度
  • 试着探索高并发下的系统架构面貌
  • 源码之下无秘密 ── 做最好的 Netty 源码分析教程
  • 怎么把视频里的音乐提取出来
  • const的用法,特别是用在函数前面与后面的区别
  • linux 淘宝开源监控工具tsar
  • ​软考-高级-系统架构设计师教程(清华第2版)【第9章 软件可靠性基础知识(P320~344)-思维导图】​
  • ### RabbitMQ五种工作模式:
  • ###C语言程序设计-----C语言学习(3)#
  • $.each()与$(selector).each()
  • (3)选择元素——(17)练习(Exercises)
  • (Redis使用系列) SpringBoot 中对应2.0.x版本的Redis配置 一
  • (附源码)springboot建达集团公司平台 毕业设计 141538
  • (个人笔记质量不佳)SQL 左连接、右连接、内连接的区别
  • (几何:六边形面积)编写程序,提示用户输入六边形的边长,然后显示它的面积。
  • (入门自用)--C++--抽象类--多态原理--虚表--1020
  • (五)c52学习之旅-静态数码管
  • (五)关系数据库标准语言SQL
  • (一)Java算法:二分查找
  • (转)c++ std::pair 与 std::make
  • (转)linux下的时间函数使用
  • (转)树状数组
  • .MSSQLSERVER 导入导出 命令集--堪称经典,值得借鉴!
  • .NET/C# 中你可以在代码中写多个 Main 函数,然后按需要随时切换
  • .NET_WebForm_layui控件使用及与webform联合使用
  • .php结尾的域名,【php】php正则截取url中域名后的内容
  • 。。。。。
  • ??myeclipse+tomcat
  • @ 代码随想录算法训练营第8周(C语言)|Day53(动态规划)