jdbcTemplate 调用存储过程。 入参 array 返回 cursor

需求:

java传入一个list object。从数据库找到相关的数据并返回。

如果循环取数据,那么会产生N条SQL。(N为 list 的size)

开始计划使用临时表,先把list数据插入到数据库。可以使用批量插入,虽然也需要产生N条SQL,但是性能应该会比N个查询快很多。(不过没有实践)。

同事提醒说可以用存储过程,批量查询。之前并没有这么使用过。开始以为要使用in(id1, id2)那么查询。之前存储过程也没怎么使用过。大部分都是直接操作SQL。


首先创建存储过程,

1)创建TYPE

CREATE OR REPLACE TYPE TEST_OBJECT AS OBJECT
(
   COLUMN1 VARCHAR2(50),
   COLUMN2 NUMBER(10,2)
)


2 )  创建TYPE OF TABLE 

CREATE OR REPLACE TYPE "TEST_OBJECT_ARRAY" AS TABLE OF TEST_OBJECT 


3) 创建存储过程

CREATE OR REPLACE PROCEDURE PROC_DD_GETPERSONINFO(V_TEST_LIST IN TEST_OBJECT ,
P_CUR OUT SYS_REFCURSOR
)

入参是一个就可以变成一个数组,在使用的时候类似于临时表使用。

SELECT * FROM TABLE(V_TEST_LIST)



4) 编写java代码

@Repository
public class DataCacheDaoImpl implements DataCacheDao {

	@Autowired
	JdbcTemplate jdbcTemplate;

	private ARRAY getArray(List list, Connection con) throws SQLException {
		STRUCT[] struts = new STRUCT[list.size()];
		int i = 0;
		for (TestObject cr : list) {

			Object[] obs = { cr.getContractNumber(), cr.getReceiveAmount() };
			//mapping to object
			StructDescriptor st = new StructDescriptor("TEST_OBJECT", con);
			struts[i] = new STRUCT(st, con, obs);
		}

		//mapping to array 
		ArrayDescriptor arrayDept = ArrayDescriptor.createDescriptor("TEST_OBJECT_ARRAY", con);
		ARRAY deptArrayObject = new ARRAY(arrayDept, con, struts);
		return deptArrayObject;
	}

	@Override
	public List getContractRepaymentList(List list) {

		return jdbcTemplate.execute(new CallableStatementCreator() {

			@Override
			public CallableStatement createCallableStatement(Connection con) throws SQLException {

				if (con.isWrapperFor(OracleConnection.class)) {
					con = con.unwrap(OracleConnection.class);
				}

				String callProcedure = "{call PROC_DD_GETPERSONINFO(?,?)}";
				CallableStatement cs = con.prepareCall(callProcedure);
				ARRAY array = getArray(list, con);

				cs.setArray(1, array);
				cs.registerOutParameter(2, OracleTypes.CURSOR);

				return cs;
			}

		}, new CallableStatementCallback>() {

			@Override
			public List doInCallableStatement(CallableStatement cs)
					throws SQLException, DataAccessException {

				List list = new ArrayList<>();

				cs.execute();
				// 得到返回的cursor
				ResultSet rs = (ResultSet) cs.getObject(2);
				while (rs.next()) {
					TestObjectResponse response = new TestObjectResponse();
					// 组装你的bean
					list.add(response);
				}
				return list;
			}
		});
	}
}







你可能感兴趣的:(spring,JDBC,存储过程,Array,Cursor,setArray)