Spring jdbcTemplate CRUD example
개 요
스프링에서 제공하는 jdbcTemplate 을 사용하여 Oracle 데이터베이스의 EMP 테이블에 입력, 출력, 수정, 삭제하는 기본적인 방법을 예제로 작성해본다
테스트환경
Spring 3 STS, Maven, Eclipse luna, Windows 7, JDK 1.7, Tomcat 8
http://www.beingjavaguys.com/2013/07/spring-jdbc-template-with-spring-mvc.html
http://examples.javacodegeeks.com/enterprise-java/spring/jdbc/spring-jdbctemplate-example/
Spring Web MVC를 위한 기본적인 라이브러리 외에 아래의 라이브러리를 추가로 설치한다.
pom.xml
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.3</version>
</dependency>
<!--<dependency>
<groupId>cn.guoyukun.jdbc</groupId>
<artifactId>oracle-ojdbc6</artifactId>
<version>11.2.0.3.0</version>
</dependency>-->
위의 spring-jdbc 는 http://mavenrepository.com 에서 Spring jdbc 로 검색하면 찾을 수 있으나 ojdbc6은 찾을 수 없기 때문에 로컬 시스템에 있는 JDBC 드라이버를 Local Repository 에 복사하고 <dependency>를 pom.xml 에 추가해야 한다
DataSource 를 빈 객체로 스프링 프레임워크에 등록하고 나중에 DAO 클래스를 작성할 때 DAO 클래스로 DataSource객체를 주입한다
servlet-context.xml 파일에 설정해야 하는 내용은 DataSource 설정 뿐이고 그 외에는 Annotation을 사용하여 처리한다
servlet-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<context:component-scan base-package="org.kdea.java" />
<context:component-scan base-package="org.kdea.service" />
<!-- Process annotations on registered beans like @Autowired... -->
<context:annotation-config/>
<!-- Enables the Spring MVC @Controller programming model -->
<mvc:annotation-driven/>
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
<beans:property name="contentType" value="text/html; charset=UTF-8"/>
</beans:bean>
<beans:bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<beans:property name="basename" value="/WEB-INF/messages/Messages"/>
<beans:property name="defaultEncoding" value="UTF-8" />
<beans:property name="cacheSeconds" value="180"/>
</beans:bean>
<beans:bean id="validator"
class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<beans:property name="validationMessageSource" ref="messageSource"/>
</beans:bean>
<beans:bean id="dataSource" class="oracle.jdbc.pool.OracleDataSource">
<beans:property name="dataSourceName" value="ds"/>
<beans:property name="URL" value="jdbc:oracle:thin:@localhost:1521:xe"/>
<beans:property name="user" value="scott"/>
<beans:property name="password" value="tiger"/>
</beans:bean>
</beans:beans>
위의 서블릿 설정파일에 등록된 'dataSource' 는 DB접속이 필요한 곳에서 'dataSource' 라는 이름을 사용하여 빈 객체를 사용할 수가 있다. @Autowired나 @Resource 등의 Annotation을 사용해서 자동주입(Dependency Injection)이 가능하다. 즉, 다음과 같이 사용하면 된다
@Autowired
private DataSource dataSource;
혹은, 아래처럼
@Resource(name="dataSource")
private DataSource dataSource;
EmpController.java
package org.kdea.java; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.servlet.ModelAndView; @Controller @RequestMapping("/emp/") public class EmpController { @Autowired private EmpService empService; @RequestMapping("list") public String getList(Model model){ model.addAttribute("list",empService.getEmpList()); return "emp/empList"; } @RequestMapping("info") public String getEmp(Model model, @RequestParam int empno){ model.addAttribute("empInfo",empService.getEmp(empno)); return "emp/empInfo"; } @RequestMapping("insert") public String inserEmp(@ModelAttribute Emp emp) { if(emp.getEmpno()==0) { return "emp/inputForm"; }else{ empService.insertEmp(emp); return "redirect:/emp/list"; } } @RequestMapping("edit") public ModelAndView editEmp(@RequestParam int empno, @ModelAttribute Emp emp) { emp = empService.getEmp(empno); return new ModelAndView("/emp/empEdit", "empInfo", emp); } @RequestMapping("update") public String updateEmp(@ModelAttribute Emp emp) { empService.updateEmp(emp); return "redirect:/emp/list"; } @RequestMapping("delete") public String deleteEmp(@RequestParam int empno) { empService.deleteEmp(empno); return "redirect:/emp/list"; } }
EmpService.java
package org.kdea.java; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class EmpService { @Autowired private EmpDAO empDao; public List<Emp> getEmpList(){ return empDao.getEmpList(); } public Emp getEmp(int empno) { return empDao.getEmp(empno); } public boolean insertEmp(Emp emp) { return empDao.insertEmp(emp); } public boolean updateEmp(Emp emp) { return empDao.updateEmp(emp); } public boolean deleteEmp(int empno) { return empDao.deleteEmp(empno); } }
EmpDAO.java
package org.kdea.java; import java.util.*; import javax.sql.DataSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Service; @Repository public class EmpDAO { @Autowired private DataSource dataSource; // 혹은 아래처럼 //@Resource(name="dataSource") //private DataSource dataSource; public List<Emp> getEmpList() { List<Emp> list = new ArrayList<Emp>(); String sql = "select * from emp2"; JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); list = jdbcTemplate.query(sql, new EmpRowMapper()); return list; } public boolean insertEmp(Emp emp) { String sql = "INSERT INTO emp2 "+ "(empno,ename,deptno,sal,job ) VALUES (?,?,?,?,?)"; JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); int rows = jdbcTemplate.update( sql, new Object[] { emp.getEmpno(),emp.getEname(),emp.getDeptno(), emp.getSal(),emp.getJob()} ); return rows>0 ? true : false; } public boolean deleteEmp(int empno) { String sql = "delete from emp2 where empno=?"; JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); int rows = jdbcTemplate.update(sql,empno); return rows>0 ? true : false; } public boolean updateEmp(Emp emp) { String sql = "UPDATE emp2 set deptno=?, sal=? where empno=?"; JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); int rows = jdbcTemplate.update( sql,emp.getDeptno(), emp.getSal(), emp.getEmpno()); return rows>0 ? true : false; } public Emp getEmp(int empno) { String sql = "select * from emp2 where empno=?"; JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); Emp emp = jdbcTemplate.queryForObject(sql, new Object[]{empno}, new EmpRowMapper()); return emp; } }
Spring JdbcTemplate 를 이용하여 특정 컬럼 1개만 가져오기
사번을 이용하여 사원의 이름을 가져오는 예
String query = "select name from employee where emp_id=?";
Object[] inputs = new Object[] {empId};
String empName = getJdbcTemplate().queryForObject(query, inputs, String.class);
사번을 이용하여 부서번호를 가져오는 예
String query = "select deptno from employee where emp_id=?";
Object[] inputs = new Object[] {empId};
int deptno = getJdbcTemplate().queryForObject(query, inputs, Integer.class);
총 행수를 가져오는 예
String sql = "SELECT COUNT(*) FROM CUSTOMER";
int total = getJdbcTemplate().queryForInt(sql);
Emp.java
package org.kdea.java; public class Emp { private int empno; private String ename; private java.sql.Date hiredate; private int deptno; private int sal; private String job; public int getEmpno() { return empno; } public void setEmpno(int empno) { this.empno = empno; } public String getEname() { return ename; } public void setEname(String ename) { this.ename = ename; } public java.sql.Date getHiredate() { return hiredate; } public void setHiredate(java.sql.Date hiredate) { this.hiredate = hiredate; } public int getDeptno() { return deptno; } public void setDeptno(int deptno) { this.deptno = deptno; } public int getSal() { return sal; } public void setSal(int sal) { this.sal = sal; } public String getJob() { return job; } public void setJob(String job) { this.job = job; } }
EmpRowMapper.java
package org.kdea.java; import java.sql.ResultSet; import java.sql.SQLException; import org.springframework.jdbc.core.RowMapper; public class EmpRowMapper implements RowMapper<Emp> { public Emp mapRow(ResultSet rs, int line) throws SQLException { EmpExtractor empExtractor = new EmpExtractor(); return empExtractor.extractData(rs); } }
EmpExtractor.java
package org.kdea.java; import java.sql.ResultSet; import java.sql.SQLException; import org.springframework.dao.DataAccessException; import org.springframework.jdbc.core.ResultSetExtractor; public class EmpExtractor implements ResultSetExtractor<Emp> { public Emp extractData(ResultSet resultSet) throws SQLException, DataAccessException { Emp emp = new Emp(); emp.setEmpno(resultSet.getInt("EMPNO")); emp.setEname(resultSet.getString("ENAME")); emp.setHiredate(resultSet.getDate("HIREDATE")); emp.setDeptno(resultSet.getInt("DEPTNO")); emp.setSal(resultSet.getInt("SAL")); emp.setJob(resultSet.getString("JOB")); return emp; } }
WEB-INF/views/emp/empList.jsp
<%@ page language="java" contentType="text/html; charset=EUC-KR" pageEncoding="EUC-KR"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!DOCTYPE htm> <html> <head> <meta charset="EUC-KR"> <title>사원정보 리스트</title> </head> <body> <h2>사원정보 리스트</h2> <c:forEach var="emp" items="${list}"> ${emp.empno } <a href="info.do?empno=${emp.empno}">${emp.ename}</a> <br> </c:forEach> <p> <a href="insert.do">사원정보 추가</a> </body> </html>
WEB-INF/views/emp/empInfo.jsp
<%@ page language="java" contentType="text/html; charset=EUC-KR" pageEncoding="EUC-KR"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!DOCTYPE htm> <html> <head> <meta charset="EUC-KR"> <title>사원정보 상세 페이지</title> </head> <body> <h2>사원정보 상세 페이지</h2> 사번 ${empInfo.empno } <br> 이름 ${empInfo.ename } <br> 부서 ${empInfo.deptno } <br> 입사 ${empInfo.hiredate } <br> 직무 ${empInfo.job } <br> 급여 ${empInfo.sal } <br> <p> <a href="edit.do?empno=${empInfo.empno}">사원정보 수정</a> <a href="delete.do?empno=${empInfo.empno}">사원정보 삭제</a> </body> </html>
WEB-INF/views/emp/empEdit.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> <%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> <!DOCTYPE htm> <html> <head> <meta charset="UTF-8"> <title>사원정보 수정 페이지</title> </head> <body> <h2>사원정보 수정 페이지</h2> <form:form method="post" action="update" modelAttribute="empInfo"> <form:hidden path="empno"/> 사번 ${empInfo.empno } <br> 이름 ${empInfo.ename } <br> 부서 <form:input path="deptno"/> <br> 입사 ${empInfo.hiredate } <br> 직무 ${empInfo.job } <br> 급여 <form:input path="sal"/> <br> <p> <input type="submit" value="변경사항 적용"> </form:form> </body> </html>
WEB-INF/views/emp/inputForm.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>사원정보 입력 폼</title> <style> body { font-size: 20px; color: teal; } td { font-size: 15px; color: black; width: 100px; height: 22px; text-align: left; } .heading { font-size: 18px; color: white; font: bold; background-color: orange; border: thick; } </style> </head> <body> <h2>사원정보 입력 폼 </h2> <div> <form:form method="post" action="insert.do" modelAttribute="emp"> <table> <tr> <td>EMPNO :</td> <td><form:input path="empno" /></td> </tr> <tr> <td>ENAME :</td> <td><form:input path="ename" /></td> </tr> <tr> <td>DEPTNO :</td> <td><form:input path="deptno"/></td> </tr> <tr> <td>JOB :</td> <td><form:input path="job" /></td> </tr> <tr> <td> </td> <td><input type="submit" value="Save" /></td> </tr> <tr> <td colspan="2"><a href="list">사원정보 리스트 보기</a></td> </tr> </table> </form:form> </div> </body> </html>