spring jdbc,오라클 함수(oracle function)호출(ref cursor) 방법3가지,SimpleJdbcCall
,CallableStatement, StoredProcedure, SqlOutParameter
spring jdbc를 이용하여 오라클 함수를 호출하는
방법은 3가지 정도로 요약된다. 예제를 통해
확인하자.
[오라클 함수가 아래와 같다면]
create or replace package types
as
type currtype is ref cursor;
end;
/
create or replace function getEmp(v_deptno in number) return
types.currtype
AS
emp_cursor currtype;
sql_string VARCHAR2(500);
BEGIN
sql_string := 'SELECT empno, ename, sal FROM EMP WHERE DEPTNO = '||
v_deptno;
OPEN emp_cursor FOR sql_string ;
RETURN emp_cursor;
CLOSE emp_cursor;
END;
/
1. SimpleJdbcCall 이용방법
DTO
역할을 하는 Emp.java
package edu.onj.function;
public class Emp {
private String
empno;
private String
ename;
private String
sal;
public Emp()
{}
public
Emp(String empno, String ename, String sal) {
this.empno =
empno;
this.ename =
ename;
this.sal =
sal;
}
public void
setEmpno(String empno) {
this.empno =
empno;
}
public void
setEname(String ename) {
this.ename =
ename;
}
public void
setSal(String sal) {
this.sal =
sal;
}
public String
getEmpno() {
return
empno;
}
public String
getEname() {
return
ename;
}
public String
getSal() {
return
sal;
}
}
-DAO단
interface 및 구현클래스
package edu.onj.function;
import java.util.List;
import javax.sql.DataSource;
public interface EmpDao {
public void
setDataSource(DataSource ds);
public int[]
createEmpList(final List<Emp> emps);
public
List<Emp> listEmp(Integer empno);
}
package edu.onj.function;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Types;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import oracle.jdbc.OracleTypes;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.SqlOutParameter;
import org.springframework.jdbc.core.SqlParameter;
import
org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.core.simple.SimpleJdbcCall;
public class EmpDaoImpl implements EmpDao {
private
DataSource dataSource;
private
JdbcTemplate jdbcTemplate;
public void
setDataSource(DataSource dataSource) {
this.dataSource
= dataSource;
this.jdbcTemplate = new
JdbcTemplate(dataSource);
}
public
DataSource getDataSource() {
return
dataSource;
}
@Override
public int[]
createEmpList(final List<Emp> emps) {
String SQL =
"insert into emp(empno, ename, sal) values (?, ?, ?)";
BatchPreparedStatementSetter setter = null;
setter = new
BatchPreparedStatementSetter() {
@Override
public int
getBatchSize() {
return
emps.size();
}
@Override
public void
setValues(PreparedStatement ps, int index)
throws
SQLException {
Emp emp =
emps.get(index);
int
parameterIndex = 1;
ps.setString(parameterIndex++,
emp.getEmpno());
ps.setString(parameterIndex++,
emp.getEname());
ps.setString(parameterIndex++, emp.getSal());
}
};
return
jdbcTemplate.batchUpdate(SQL, setter);
}
@Override
public
List<Emp> listEmp(Integer deptno) {
SimpleJdbcCall
simpleJdbcCall = new SimpleJdbcCall(this.dataSource)
.withSchemaName("scott")
.withFunctionName("getEmp")
.declareParameters(
new SqlOutParameter("emp_cursor", OracleTypes.CURSOR,
new EmpMapper()),
new SqlParameter("v_deptno", Types.INTEGER))
.withoutProcedureColumnMetaDataAccess();
SqlParameterSource params = new
MapSqlParameterSource("v_deptno", deptno);
//execute메서드는
Map형태러 리턴한다.
Map<String,
Object> resultSet = simpleJdbcCall.execute(params);
return
(List<Emp>) resultSet.get("emp_cursor");
}
}
-매퍼
클래스
package edu.onj.function;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.springframework.jdbc.core.RowMapper;
public class EmpMapper implements RowMapper<Emp> {
@Override
public Emp
mapRow(ResultSet rs, int rowNum) throws SQLException {
Emp emp = new
Emp();
emp.setEmpno(rs.getString("empno"));
emp.setEname(rs.getString("ename"));
emp.setSal(rs.getString("sal"));
return
emp;
}
}
-클라이언트
main함수
package edu.onj.function;
import java.util.ArrayList;
import java.util.List;
import
org.springframework.context.support.GenericXmlApplicationContext;
public class JdbcClient {
public static
void main(String[] args) {
GenericXmlApplicationContext ctx = new
GenericXmlApplicationContext();
ctx.load("jdbc.xml");
ctx.refresh();
EmpDaoImpl
empDao = (EmpDaoImpl)ctx.getBean("empDao");
//1. EMP TABLE의
empno가 1001인 데이터 추출
List<Emp>
emps = empDao.listEmp(1001);
System.out.println("------------------ all select
------------------");
for (Emp emp :
emps) {
System.out.println("empno-->" +
emp.getEmpno());
System.out.println("ename-->" +
emp.getEname());
System.out.println("sal -->" +
emp.getSal());
}
emps.clear();
//2.
BatchPreparedStatementSetter를 이용하여 List에 있는것을 일괄 Insert
emps.add(new
Emp("9701", "1001길동", "10010"));
emps.add(new
Emp("9702", "1002길동", "10020"));
emps.add(new
Emp("9703", "1003길동", "10030"));
emps.add(new
Emp("9704", "1004길동", "10040"));
emps.add(new
Emp("9705", "1005길동", "10050"));
empDao.createEmpList(emps);
//3.spring JDBC
SimpleJdbcCall을 이용한 오라클 함수(ref cursor리턴)호출을 통한 10번 부서 EMP 추출
ArrayList<Emp> emps2 =
(ArrayList<Emp>)empDao.listEmp(new Integer(10));
for(Emp e:
emps2) {
System.out.println(e.getEmpno() + ":" + e.getEname()
+ ":" + e.getSal());
}
ctx.close();
}
}
2. 기존 JDBC처럼 CallableStatement이용
@Override
public
List<Emp> listEmp(final Integer deptno){
CallableStatementCallback<List<Emp>> cb
= new CallableStatementCallback<List<Emp>>() {
@Override
public
List<Emp> doInCallableStatement(CallableStatement cs)
throws
SQLException, DataAccessException {
cs.registerOutParameter(1,
OracleTypes.CURSOR);
cs.setInt(2,
deptno);
cs.execute();
ResultSet rs =
(ResultSet) cs.getObject(1);
List<Emp>
emps = new ArrayList<Emp>();
EmpMapper mapper
= new EmpMapper();
for (int i = 0;
rs.next(); i++) {
emps.add(mapper.mapRow(rs, i));
}
return
emps;
}
};
return
jdbcTemplate.execute("{? = call getEmp(?)}", cb);
}
3. Spring Framework의 StoredProcedure를
상속받아서
public class Emp {
private Integer
empno;
private String
ename;
private Integer
sal;
public Integer
getEmpno() {
return
empno;
}
public void
setEmpno(Integer empno) {
this.empno =
empno;
}
public String
getEname() {
return
ename;
}
public void
setEname(String ename) {
this.ename =
ename;
}
public Integer
getSal() {
return
sal;
}
public void
setSal(Integer sal) {
this.sal =
sal;
}
}
import java.util.List;
import javax.sql.DataSource;
public interface EmpDao {
public void
setDataSource(DataSource ds);
public
List<Emp> listEmp(Integer deptno);
}
import java.sql.ResultSet;
import java.sql.SQLException;
import org.springframework.jdbc.core.RowMapper;
public class EmpMapper implements RowMapper<Emp> {
@Override
public Emp
mapRow(ResultSet rs, int rowNum) throws SQLException {
// TODO
Auto-generated method stub
Emp emp = new
Emp();
emp.setEmpno(rs.getInt("empno"));
emp.setEname(rs.getString("ename"));
emp.setSal(rs.getInt("sal"));
return
emp;
}
}
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import onj.edu.jdbc1.Customer;
import org.springframework.context.ApplicationContext;
import
org.springframework.context.support.ClassPathXmlApplicationContext;
public class JdbcClient {
public static
void main(String[] args) {
// TODO
Auto-generated method stub
ApplicationContext ctx = new
ClassPathXmlApplicationContext("third2.xml");
EmpJDBCTemplate
empJDBCTemplate = (EmpJDBCTemplate)ctx.getBean("empJDBCTemplate");
ArrayList<Emp> list = new
ArrayList<Emp>();
list =
(ArrayList<Emp>) empJDBCTemplate.listEmp(20);
for (Emp
emp:list){
System.out.println("empno --> "+emp.getEmpno()+"
ename --> "+emp.getEname()+" sal --> "+emp.getSal() );
}
}
}
import
java.sql.Types;
import java.util.*;
import java.util.*;
import
javax.sql.DataSource;
import oracle.jdbc.OracleTypes;
import org.springframework.jdbc.core.SqlOutParameter;
import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.object.StoredProcedure;
import oracle.jdbc.OracleTypes;
import org.springframework.jdbc.core.SqlOutParameter;
import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.object.StoredProcedure;
public
class EmpJDBCTemplate extends StoredProcedure implements EmpDao {
private DataSource dataSource;
private static final String SQL = "getEmp";
private DataSource dataSource;
private static final String SQL = "getEmp";
public EmpJDBCTemplate(DataSource dataSource) {
// TODO Auto-generated constructor stub
super(dataSource, SQL);
setFunction(true);
declareParameter(new SqlOutParameter("emp_cursor", OracleTypes.CURSOR, new EmpMapper()));
declareParameter(new SqlParameter("v_deptno", Types.INTEGER));
}
@Override
public List<Emp> listEmp(Integer deptno) {
Map<String, Object> resultSet = execute(deptno);
ArrayList<Emp> list = (ArrayList) resultSet.get("emp_cursor");
return list;
}
}
<?xml
version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
<bean
id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName">
<value>oracle.jdbc.driver.OracleDriver</value>
</property>
<property name="url">
<value>jdbc:oracle:thin:@192.168.0.7:1521:onj</value>
</property>
<property name="username">
<value>scott</value>
</property>
<property name="password">
<value>tiger</value>
</property>
</bean>
<property name="driverClassName">
<value>oracle.jdbc.driver.OracleDriver</value>
</property>
<property name="url">
<value>jdbc:oracle:thin:@192.168.0.7:1521:onj</value>
</property>
<property name="username">
<value>scott</value>
</property>
<property name="password">
<value>tiger</value>
</property>
</bean>
<bean
id="empJDBCTemplate"
class="onj.practice.third3.EmpJDBCTemplate">
<constructor-arg ref="dataSource"/>
</bean>
</beans>
<constructor-arg ref="dataSource"/>
</bean>
</beans>
댓글 없음:
댓글 쓰기