스프링프레임워크 & 마이바티스
(Spring Framework, MyBatis)
4-3-2. Spring JDBC에서 DB 접근하는 방법 –
NamedParameterJdbcTemplate
이름없는 ? 대싞 이름을 부여해서 바인드 변수 처리가 가능하다.
public class PersonDao {
@Autowired
private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
@Override
public void createPerson(Integer id, String firstname, String lastname) {
String SQL = "INSERT INTO person (id, firstname, lastname)
VALUES (:id, :firstname, :lastname)";
Map namedParameters = new HashMap();
namedParameters.put(“id", id);
namedParameters.put(“firstname", firstname);
namedParameters.put(“lastname", lastname);
namedParameterJdbcTemplate.update(SQL, namedParameters);
}
}
4-3-3. Spring JDBC에서 DB 접근하는 방법 - SimpleJdbcTemplate
 JdbcTemplate의 모든 기능과 NamedParameterJdbcTemplate의 기능을 합친 것으로 자바5의
auto boxing과 varargs(String…args, 가변길이 매개변수) 기능을 포함하고 있다.
[JdbcTemplate Style]
public class PersonDao {
private JdbcTemplate jdbcTemplate;
public void setDataSource(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
public Person findPerson(Integer id, String lastname) {
String sql = "select id, firstname, lastname from PERSON where id = ? and lastname = ?";
RowMapper<person> mapper = new RowMapper<person>() {
public Person mapRow(ResultSet rs, int rowNum) throws SQLException {
Person person = new Person();
person.setId(rs.getLong("id"));
person.setFirstName(rs.getString("firstname"));
person.setLastName(rs.getString("lastname"));
return person;
}
};
// SELECT인 경우 Mapper가 뒤에 오고 그 앞에 매개변수들을 객체배열에 담아 넘긴다.
// Person 타입으로 형 변환도 필요하다.
return (Person) jdbcTemplate.queryForObject(sql, new Object[] {id, lastname}, mapper);
}
[SimpleJdbcTemplate Style]
public class PersonDao {
private SimpleJdbcTemplate simpleJdbcTemplate;
public void setDataSource(DataSource dataSource) {
this. simpleJdbcTemplate = new SimpleJdbcTemplate (dataSource);
}
public Person findPerson(Integer id, String lastname) {
String sql = "select id, firstname, lastname from PERSON where id = ? and lastname = ?";
RowMapper<person> mapper = new RowMapper<person>() {
public Person mapRow(ResultSet rs, int rowNum) throws SQLException {
Person person = new Person();
person.setId(rs.getLong("id"));
person.setFirstName(rs.getString("firstname"));
person.setLastName(rs.getString("lastname"));
return person;
}
};
// SELECT인 경우 Mapper가 쿼리문 다음에 오고 그 뒤에 가변길이 매개변수 형태로 넘기
는
// 객체배열 형태로 받는다. Person 타입으로 형 변환도 필요없다.
return simpleJdbcTemplate.queryForObject(sql, mapper, id, lastname);
}
4-3-4. Spring JDBC에서 DB 접근하는 방법 – SimpleJdbcCall
 DataBase에 SQL로 만들어져 있는 저장함수, 프로시저를 다루기 위한 클래스로 최소한의 구
성으로 DB함수, Procedure에 접근할 수 있다.
오라클 서버쪽 패키지(Package) 및 함수(Function)
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 types.currtype;
sql_string VARCHAR2(500);
BEGIN
sql_string := 'SELECT empno, ename, sal FROM EMP WHERE DEPTNO = :1’ ;
OPEN emp_cursor FOR sql_string USING v_deptno;
RETURN emp_cursor;
CLOSE emp_cursor;
END;
/
New  Project  Spring Legacy Project
Project Name : springjdbc
Simple Projects : Simple Spring Maven
[pom.xml에 추가]
<dependences>
…
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.1.0.7.0</version>
</dependency>
</dependences>
<repositories>
<repository>
<id>oracle</id>
<name>ORACLE JDBC Repository</name>
<url>https://maven.oracle.com</url>
</repository>
</repositories>
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 서비스를 위한 인터페이스[EmpDao.java]
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);
}
DAO 서비스를 위한 클래스[EmpDao.java]
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;
}
/*
* 여런건의 EMP 데이터를 BatchPreparedStatementSetter 를 이용하여 일괄 인서트
*/
@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);
}
/* 오라클 Stored Function 을 호출하여 10 번 부서 사원리스트 출력(REF CURSOR) */
@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");
}
}
매퍼 클래스[EmpMapper.java]
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;
}
}
XML 설정 파일[src/main/resources/jdbc.xml]
<?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-4.2.xsd ">
<!-- Initialization for data source -->
<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.27:1521:onj</value>
</property>
<property name="username">
<value>scott</value>
</property>
<property name="password">
<value>tiger</value>
</property>
</bean>
<bean id="empDao" class=" edu.onj.function.EmpDaoImpl">
<property name="dataSource" ref="dataSource" />
</bean>
</beans>
클라이언트 main 함수[JdbcClient.java]
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 에서 부서코드가 10 인 데이터 추출
List<Emp> emps = empDao.listEmp(10);
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();
}
}
위 예제의 listEmp() 메소드를 기존 자바 JDBC의 CallableStatementCallback을 이용한 방식으로 변
경하면 다음과 같다.
@Override
public List<Emp> listEmp2(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);
}

#17.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/마이바티스학원추천

  • 1.
    스프링프레임워크 & 마이바티스 (SpringFramework, MyBatis) 4-3-2. Spring JDBC에서 DB 접근하는 방법 – NamedParameterJdbcTemplate 이름없는 ? 대싞 이름을 부여해서 바인드 변수 처리가 가능하다. public class PersonDao { @Autowired private NamedParameterJdbcTemplate namedParameterJdbcTemplate; @Override public void createPerson(Integer id, String firstname, String lastname) { String SQL = "INSERT INTO person (id, firstname, lastname) VALUES (:id, :firstname, :lastname)"; Map namedParameters = new HashMap(); namedParameters.put(“id", id); namedParameters.put(“firstname", firstname); namedParameters.put(“lastname", lastname); namedParameterJdbcTemplate.update(SQL, namedParameters); } } 4-3-3. Spring JDBC에서 DB 접근하는 방법 - SimpleJdbcTemplate  JdbcTemplate의 모든 기능과 NamedParameterJdbcTemplate의 기능을 합친 것으로 자바5의 auto boxing과 varargs(String…args, 가변길이 매개변수) 기능을 포함하고 있다.
  • 2.
    [JdbcTemplate Style] public classPersonDao { private JdbcTemplate jdbcTemplate; public void setDataSource(DataSource dataSource) { this.jdbcTemplate = new JdbcTemplate(dataSource); } public Person findPerson(Integer id, String lastname) { String sql = "select id, firstname, lastname from PERSON where id = ? and lastname = ?"; RowMapper<person> mapper = new RowMapper<person>() { public Person mapRow(ResultSet rs, int rowNum) throws SQLException { Person person = new Person(); person.setId(rs.getLong("id")); person.setFirstName(rs.getString("firstname")); person.setLastName(rs.getString("lastname")); return person; } }; // SELECT인 경우 Mapper가 뒤에 오고 그 앞에 매개변수들을 객체배열에 담아 넘긴다. // Person 타입으로 형 변환도 필요하다. return (Person) jdbcTemplate.queryForObject(sql, new Object[] {id, lastname}, mapper); } [SimpleJdbcTemplate Style] public class PersonDao { private SimpleJdbcTemplate simpleJdbcTemplate; public void setDataSource(DataSource dataSource) { this. simpleJdbcTemplate = new SimpleJdbcTemplate (dataSource); } public Person findPerson(Integer id, String lastname) { String sql = "select id, firstname, lastname from PERSON where id = ? and lastname = ?"; RowMapper<person> mapper = new RowMapper<person>() { public Person mapRow(ResultSet rs, int rowNum) throws SQLException { Person person = new Person(); person.setId(rs.getLong("id")); person.setFirstName(rs.getString("firstname")); person.setLastName(rs.getString("lastname")); return person;
  • 3.
    } }; // SELECT인 경우Mapper가 쿼리문 다음에 오고 그 뒤에 가변길이 매개변수 형태로 넘기 는 // 객체배열 형태로 받는다. Person 타입으로 형 변환도 필요없다. return simpleJdbcTemplate.queryForObject(sql, mapper, id, lastname); } 4-3-4. Spring JDBC에서 DB 접근하는 방법 – SimpleJdbcCall  DataBase에 SQL로 만들어져 있는 저장함수, 프로시저를 다루기 위한 클래스로 최소한의 구 성으로 DB함수, Procedure에 접근할 수 있다. 오라클 서버쪽 패키지(Package) 및 함수(Function) 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 types.currtype; sql_string VARCHAR2(500); BEGIN sql_string := 'SELECT empno, ename, sal FROM EMP WHERE DEPTNO = :1’ ; OPEN emp_cursor FOR sql_string USING v_deptno; RETURN emp_cursor; CLOSE emp_cursor; END; / New  Project  Spring Legacy Project Project Name : springjdbc Simple Projects : Simple Spring Maven
  • 4.
    [pom.xml에 추가] <dependences> … <dependency> <groupId>com.oracle</groupId> <artifactId>ojdbc6</artifactId> <version>11.1.0.7.0</version> </dependency> </dependences> <repositories> <repository> <id>oracle</id> <name>ORACLE JDBCRepository</name> <url>https://maven.oracle.com</url> </repository> </repositories> 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;
  • 5.
    } public String getEmpno(){ return empno; public String getEname() { return ename; } public String getSal() { return sal; } } DAO 서비스를 위한 인터페이스[EmpDao.java] 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); } DAO 서비스를 위한 클래스[EmpDao.java] 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;
  • 6.
    import org.springframework.jdbc.core.simple.SimpleJdbcCall; public classEmpDaoImpl 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; } /* * 여런건의 EMP 데이터를 BatchPreparedStatementSetter 를 이용하여 일괄 인서트 */ @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); } /* 오라클 Stored Function 을 호출하여 10 번 부서 사원리스트 출력(REF CURSOR) */ @Override public List<Emp> listEmp(Integer deptno) {
  • 7.
    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"); } } 매퍼 클래스[EmpMapper.java] 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; } } XML 설정 파일[src/main/resources/jdbc.xml] <?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-4.2.xsd "> <!-- Initialization for data source -->
  • 8.
    <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.27:1521:onj</value> </property> <property name="username"> <value>scott</value> </property> <property name="password"> <value>tiger</value> </property> </bean> <bean id="empDao" class=" edu.onj.function.EmpDaoImpl"> <property name="dataSource" ref="dataSource" /> </bean> </beans> 클라이언트 main 함수[JdbcClient.java] 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 에서 부서코드가 10 인 데이터 추출 List<Emp> emps = empDao.listEmp(10); System.out.println("------------------ all select ------------------"); for (Emp emp : emps) { System.out.println("empno-->" + emp.getEmpno());
  • 9.
    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(); } } 위 예제의 listEmp() 메소드를 기존 자바 JDBC의 CallableStatementCallback을 이용한 방식으로 변 경하면 다음과 같다. @Override public List<Emp> listEmp2(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);
  • 10.
    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); }