티스토리 뷰
JDBC(Java Database Connectivity)
- JDBC(Java Database Connectivity)는 자바 데이터 접근 기술의 근간이라 할 정도로 대부분의 개발자가 쉽게 이해할 수 있어 많이 사용하는 데이터 액세스 기술이다.
- 그러나 시간이 지남에 따라 SQL문이 복잡해지면서 개발이나 유지관리에 어려움이 생기기 시작했다.
- 특히 Conneciton 객체 같은 공유 리소스를 제대로 처리해 주지 않으면 버그를 발생시키는 원인이 되곤 했다.
- 스프링에서 제공하는 JDBC는 이러한 기존 JDBC의 장점과 단순함을 유지하면서 단점을 보완했다.
- 간결한 API뿐만 아니라 확장된 JDBC의 기능도 제공한다.
- 실제 개발 시에는 스프링 JDBC보다는 마이바티스나 하이버네이트 같은 DB연동 관련 프레임워크를 사용한다.
- 다음은 예제에 사용하는 파일 목록이다.
파일 | 설명 |
web.xml | ContextLoaderListener를 이용해 빈 설정 XML 파일들을 읽어 들인다. |
action-servlet.xml | 스프링에서 필요한 여러 가지 빈을 설정한다. |
action-dataSource.xml | 스프링 JDBC 설정에 필요한 정보를 설정한다. |
jdbc.properties | DB 연결 정보를 저장한다. |
action-service.xml | 서비스 빈 생성을 설정한다. |
* WebContent/WEB-INF/ web.xml
- 한 개의 XML 파일에서 모든 빈을 설정하면 복잡해서 관리하기 어려우므로 빈의 종류에 따라 XML 파일에
나누어 설정한다. 그러면 톰캣 실행 시 web.xml에서 스프링의 ContextLoaderListener를 이용해 빈 설정 XML 파일들을 읽어들인다.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<listener>
<listener-class>
<!-- 여러 설정 파일을 읽어 들이기 위해 스프링의 ContextLoaderlistener를 설정한다. -->
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
<!-- 애플리케이션 실행 시 ContextLoaderListener로 해당 위치의 설정 파일을 읽어 들인다. -->
/WEB-INF/config/action-service.xml
/WEB-INF/config/action-dataSource.xml
</param-value>
</context-param>
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
* WebContent/WEB-INF/action-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
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.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!-- 컨트롤러에서ModelAndView 인자로 뷰이름이 반환되면 InternalResourceViewResolver의 프로퍼티 prefix 속성에 지정된 /test 폴더에서
ModelAndView 인자로넘어온 뷰이름에 해당되는 JSP를 선택해 DispatcherServlet으로 보낸다. -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/views/" />
<property name="suffix" value=".jsp" />
</bean>
<!-- memberController 빈에 methodNameResolver 빈과 memberResolver 빈을 주입한다. -->
<bean id="memberController" class="com.spring.member.controller.MemberControllerImpl">
<property name="methodNameResolver">
<ref local="methodResolver" />
</property>
<property name="memberService" ref="memberService" />
</bean>
<bean id="methodResolver" class="org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver">
<property name="mappings">
<props>
<prop key="/member/listMembers.do">listMembers</prop>
<prop key="/member/addMember.do">addMember</prop>
<prop key="/member/memberForm.do">memberForm</prop>
<prop key="/member/memberDetail.do">memberDetail</prop>
</props>
</property>
</bean>
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/member/*.do">memberController</prop>
</props>
</property>
</bean>
</beans>
* WebContent/WEB-INF/config/action-service.xml
- 해당 파일에서 memberService 빈을 설정하도록 한다.
- 데이터베이스와 연동할 때 필요한 memberDAO 빈을 주입하는 기능을 한다.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
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.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!-- memberService 빈의 memberDAO 속성에 memberDAO 빈을 주입한다. -->
<bean id="memberService" class="com.spring.member.service.MemberServiceImpl">
<property name="memberDAO" ref="memberDAO" />
</bean>
</beans>
* WebContent/WEB-INF/config/action-dataSource.xml
- 이 파일은 스프링에서 사용할 데이터베이스 연동 정보를 설정한다.
- 먼저 jdbc.properties 파일에서 DB 연결정보를 가져온 후 이 연결 정보를 이용해 스프링에서 제공하는
SimpleDriverDataSoure로 id가 dataSource인 빈을 생성한다. 그리고 dataSource 빈을 memberDAO 빈으로 주입한다.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
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.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!-- PropertyPlaceholderConfigurer 는 클래스 빈으로 등록하면 외부의 프로퍼티에 저장된 정보를 스프링 설정파일에서 사용할 수 있다. -->
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>/WEB-INF/config/jdbc.properties</value>
</list>
</property>
</bean>
<!-- jdbc.properties 파일의 4가지설정 정보로 스프링의 SimpleDriverDataSource 빈 생성 시 DB에 연결한다. -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
<property name="driverClass" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<!-- 생성된 dataSource빈을 memberDAO 빈에 주입한다. -->
<bean id="memberDAO" class="com.spring.member.dao.MemberDAOImpl">
<property name="dataSource" ref="dataSource" />
</bean>
</beans>
* WebContent/WEB-INF/config/jdbc.properties
- 데이터베이스 연결 정보를 작성한다.
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/[DB]
jdbc.username=root
jdbc.password=pwd
JdbcTemplate을 이용한 회원 정보 조회
- JdbcTemplate을 이용한 회원 조회 과정은 다음과 같다.
- DAO 클래스에서 실제 스프링의 JDBC 기능을 제공하는 클래스는 JdbcTemplat이다.
JdbcTemplate 클래스에서 제공하는 SQL 관련 메서드
기능 | 메서드 |
insert, update, delete 관련 메서드 | int update(String query) |
int update(String query, Object[] args) | |
int update(String query, Object[] args, int[] argTypes) | |
select 기능 메서드 | int queryForInt(String query) |
int queryForInt(String query, Object[] args) | |
long queryForLong(String query) | |
int queryForLong(String query, Object[] args) | |
Object queryForObject(String query, Class requiredType) | |
List queryForList(String query) | |
List queryForList(String query, Object[] args) |
* MemberController.java
- 자신의 속성 memberService에 설정 파일에서 생성된 memberService 빈을 주입하기 위해 반드시 setter를
구현해야 한다.
package com.spring.member.controller;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;
import com.spring.member.service.MemberService;
public class MemberControllerImpl extends MultiActionController{
private MemberService memberService;
public void setMemberService(MemberService memberService) {
this.memberService = memberService;
}
public ModelAndView listMembers(HttpServletRequest request, HttpServletResponse response) throws Exception{
String viewName = getViewName(request);
List membersList = memberService.listMembers();
ModelAndView mav = new ModelAndView(viewName);
mav.addObject("membersList",membersList);
return mav;
}
private String getViewName(HttpServletRequest request) throws Exception {
String contextPath = request.getContextPath();
String uri = (String)request.getAttribute("javax.servlet.include.request_uri");
if(uri == null || uri.trim().equals("")) {
uri = request.getRequestURI();
}
//http://localhost:port/member/listMember.do로 요청시
int begin = 0; //
if(!((contextPath==null)||("".equals(contextPath)))){
begin = contextPath.length(); // 전체 요청명 의 길이를 구함
}
int end;
if(uri.indexOf(";")!=-1){
end=uri.indexOf(";"); //요청 uri에 ';'가 있을 경우 ';'문자 위치를 구함
}else if(uri.indexOf("?")!=-1){
end=uri.indexOf("?"); //요청 uri에 '?'가 있을 경우 '?' 문자 위치를 구함
}else{
end=uri.length();
}
//http://localhost:8090/member/listMember.do로 요청시 먼저 '.do'를 제거한 http://localhost:8090/member/listMember를 구한 후,
//다시 http://localhost:8090/member/listMember에서 역순으로 첫번째 '/' 위치를 구한 후, 그 뒤의 listMember를 구한다.
String fileName=uri.substring(begin,end);
if(fileName.indexOf(".")!=-1){
fileName=fileName.substring(0,fileName.lastIndexOf(".")); //요청명에서 역순으로 최초 '.'의 위치를 구한후, '.do' 앞에까지의 문자열을 구함
}
if(fileName.lastIndexOf("/")!=-1){
fileName=fileName.substring(fileName.lastIndexOf("/"),fileName.length()); //요청명에서 역순으로 최초 '/'의 위치를 구한후, '/' 다음부터의 문자열을 구함
}
return fileName;
}
}
* MemberSerivce.java
package com.spring.member.service;
import java.util.List;
public interface MemberService {
public List listMembers();
}
* MemberServiceImpl.java
- 자신의 속성인 memberDAO에 빈을 주입하기 위해 setter를 구현한다.
package com.spring.member.service;
import java.util.List;
import com.spring.member.dao.MemberDAO;
public class MemberServiceImpl implements MemberService{
private MemberDAO memberDAO;
public void setMemberDAO(MemberDAO memberDAO) {
this.memberDAO = memberDAO;
}
@Override
public List listMembers() {
return memberDAO.selectAllMembers();
}
}
* MemberDAO.java
package com.spring.member.dao;
import java.util.List;
import org.springframework.dao.DataAccessException;
import com.spring.member.vo.MemberVO;
public interface MemberDAO {
public List selectAllMembers();
public int addMember(MemberVO memberVO) throws DataAccessException;
}
* MemberDAOImpl.java
- 자신의 속성 jdbcTemplate에 dataSource 빈을 주입하기 위해 setter를 이용한다.
package com.spring.member.dao;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.sql.DataSource;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import com.spring.member.vo.MemberVO;
public class MemberDAOImpl implements MemberDAO{
private JdbcTemplate jdbcTemplate;
public void setDataSource(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
public List selectAllMembers() throws DataAccessException{
String query = "select id, pwd, name, email, joinDate" +
" from t_member" +
" order by joinDate desc";
List membersList = new ArrayList();
// JdbcTemplate 클래스의 query() 메서드 인자로 select 문을 전달해 조회한 레코드의 개수만큼 MemberVO 객체를 생성한다.
// 각 레코드의 값을 속성에 저장하고 다시 memberList에 저장한다.
membersList = this.jdbcTemplate.query(query, new RowMapper<Object>(){
@Override
public Object mapRow(ResultSet rs, int rowNum) throws SQLException{
MemberVO memberVO = new MemberVO();
memberVO.setId(rs.getString("id"));
memberVO.setPwd(rs.getString("pwd"));
memberVO.setName(rs.getString("name"));
memberVO.setEmail(rs.getString("email"));
memberVO.setJoinDate(rs.getDate("joinDate"));
return memberVO;
}
});
return membersList;
}
public int addMember(MemberVO memberVO) throws DataAccessException {
String id = memberVO.getId();
String pwd = memberVO.getPwd();
String name = memberVO.getName();
String email = memberVO.getEmail();
String query ="INSERT INTO t_member(id, pwd, name, email) VALUES (" +
"'" + id + "' , " +
"'" + pwd + "' , " +
"'" + name + "' , " +
"'" + email + "') " ;
System.out.println(query);
int result = jdbcTemplate.update(query);
System.out.println(result);
return result;
}
}
* views/listMembers.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" isELIgnored="false"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
request.setCharacterEncoding("utf-8");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원 정보</title>
</head>
<body>
<table border="1" align="left" width="800" >
<tr align="center" bgcolor="lightgreen">
<td><b>아이디</b></td>
<td><b>비밀번호</b></td>
<td><b>이름</b></td>
<td><b>이메일</b></td>
<td><b>가입일</b></td>
</tr>
<c:forEach var="member" items="${membersList }">
<tr align="center">
<td>${member.id }</td>
<td>${member.pwd }</td>
<td>${member.name }</td>
<td>${member.email }</td>
<td>${member.joinDate }</td>
</c:forEach>
</table>
</body>
</html>
- 코드 작성 후 /member/listMembers.do 로 요청해 본다.
- 테이블 및 데이터 추가 관련 정보는 다음 글을 참고한다.
https://dev1023.tistory.com/71
- 실제 개발에서는 스프링의 JDBC보다는 마이바티스를 이용해서 DB와 연동한다.
'Spring' 카테고리의 다른 글
[Spring]스프링 애너테이션 (0) | 2024.08.17 |
---|---|
[Spring]MyBatis 연동하기 (0) | 2024.08.17 |
[Spring]스프링 MVC (0) | 2024.08.17 |
[Spring]의존성 주입 (0) | 2024.08.16 |
[Spring]스프링이란? (0) | 2024.08.16 |
- Total
- Today
- Yesterday
- Spring
- html css
- CSS
- 스프링
- FMT
- HTML
- Spring MVC
- CSS 속성
- Java Server Page
- Session
- script element
- react
- 세션
- Network
- javaserverpage
- Binding
- 네트워크
- Redux
- 미들웨어
- JSP
- httpServletRequest
- a 태그
- nodejs
- 제이쿼리
- 서브넷팅
- 서블릿
- el
- 리액트
- 내장객체
- Servlet
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |