需求:
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<TestObject> 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<TestObjectResponse> getContractRepaymentList(List<TestObject> 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<List<TestObjectResponse>>() {
@Override
public List<TestObjectResponse> doInCallableStatement(CallableStatement cs)
throws SQLException, DataAccessException {
List<TestObjectResponse> list = new ArrayList<>();
cs.execute();
// 得到返回的cursor
ResultSet rs = (ResultSet) cs.getObject(2);while (rs.next()) {TestObjectResponse response = new TestObjectResponse();// 组装你的beanlist.add(response);}return list;}});}}