Mybatis传list参数调用oracle存储过程的解决方法
怎么利用MyBatis传List类型参数到数据库存储过程中实现批量插入数据?
MyBatis中参数是List类型时怎么处理?大家都知道MyBatis批处理大量数据是很难做到事务回滚的(事务由Spring管理),都将逻辑写在存储中又是及其头疼的一件事(参数长度也有限制),那么我想的是将参数在后台封装为单个或多个list集合,直接通过MyBatis将此参数传到数据库存储过程中,一来摆脱了MyBatis批量插入数据的诸多限制(例如:不能实时返回主键、foreach标签循环集合长度有限制),二来就是在存储中灵活的控制事务,但是这又会涉及两个问题,MyBatis的xml文件中该怎么封装,利用BaseTypeHandler吗?
对于这个问题,经过一天的研究终于算是跑通了,说一下解决办法:
1.建立数据库表,大家应该都有自己的库表了,所以这一步基本上就可以跳过了。我之所以在这里把库表贴出来是为了让大家对应里面的参数。
数据库表:
createtableZD_UNIT_MENU ( unit_idVARCHAR2(32), menu_idVARCHAR2(32) )
2.在数据库中建立相应的java对象(Oracle中的类型)和数组:
CREATEORREPLACETYPEunit_menu_objASOBJECT( unitIdVARCHAR2(32), menuIdVARCHAR2(32) ); CREATEORREPLACETYPEunit_menu_tableAStableOFunit_menu_obj;
3.存储过程:
createorreplaceproceduresave_unit_power(list0inunit_menu_table,result0outint)as sql_bindvarchar(200); begin FORiIN1..list0.countLOOP sql_bind:='insertintoZD_UNIT_MENU(UNIT_ID,MENU_ID)values('''||list0(i).unitId||''','''||list0(i).menuId||''')'; executeimmediatesql_bind; endloop; commit; --返回结果,执行成功的话返回1 result0:=1; --捕捉异常,回滚操作 EXCEPTION WHENOTHERSTHEN result0:=-1;--执行失败的话返回-1 ROLLBACK; endsave_unit_power;
4.再看看mybatis的配置吧:
5.看看我是如何调用的?我直接贴我的server代码了,dao层的就没必要了:
Listlist=newArrayList (); Map _map=newHashMap (); String[]menuIds=menuTreeIds.split(","); JSONObjectjob=newJSONObject(); intresult=-1; for(inti=0;i 6.非常关键的一点儿,细心的人应该会注意到,在mapper.xml配置中,有typeHandler配置,里面配置的实际上是我写的一个类,这个类的作用就是讲java中的list转换成数据库中我们建立的对象和数组,看代码吧:
packagecom.zd.util; importjava.sql.CallableStatement; importjava.sql.Connection; importjava.sql.DriverManager; importjava.sql.ResultSet; importjava.sql.SQLException; importjava.util.ArrayList; importjava.util.List; importoracle.sql.ARRAY; importoracle.sql.ArrayDescriptor; importoracle.sql.STRUCT; importoracle.sql.StructDescriptor; importorg.apache.ibatis.type.BaseTypeHandler; importorg.apache.ibatis.type.JdbcType; importcom.zd.model.system.UnitMenu; publicclassListHandlerextendsBaseTypeHandler{ @Override publicObjectgetNullableResult(ResultSetarg0,Stringarg1) throwsSQLException{ //TODOAuto-generatedmethodstub returnnull; } @Override publicObjectgetNullableResult(CallableStatementarg0,intarg1) throwsSQLException{ //TODOAuto-generatedmethodstub returnnull; } @SuppressWarnings("unchecked") @Override publicvoidsetNonNullParameter(java.sql.PreparedStatementparameterSetter,inti, Objecto,JdbcTypejdbcType)throwsSQLException{ Connectionconn=null; try{ if(null!=o){ Listlist=(ArrayList )o; conn=DriverManager.getConnection("jdbc:oracle:thin:@192.168.1.88:1521:orcl","tctscm","tctscm"); //这里必须得用大写,而且必须要引入一个包,如果不引入这个包的话字符串无法正常转换,包是:orai18n.jar ARRAYarray=getArray(conn,"UNIT_MENU_OBJ","UNIT_MENU_TABLE",list); parameterSetter.setArray(i,array); } }catch(Exceptione){ e.printStackTrace(); }finally{ if(null!=conn){ conn.close(); } } } @SuppressWarnings("rawtypes") privateARRAYgetArray(Connectioncon,StringOracleObj,StringOraclelist,List listData)throwsException{ ARRAYarray=null; ArrayDescriptordesc=ArrayDescriptor.createDescriptor(Oraclelist,con); STRUCT[]structs=newSTRUCT[listData.size()]; if(listData!=null&&listData.size()>0){ StructDescriptorstructdesc=newStructDescriptor(OracleObj,con); for(inti=0;i 以上所述是小编给大家介绍的Mybatis传list参数调用oracle存储过程的解决方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!