(책) 자바 웹을 다루는 기술

Chap 22 스프링 JDBC 기능

EunaSon 2023. 9. 17. 01:14

22.1 스프링 JDBC로 데이터베이스와의 연동 설정하기 824p

22.2 JdbcTemplate 클래스 이용해 회원 정보 조회하기 830p


22.1 스프링 JDBC로 데이터베이스와의 연동 설정하기

824p

JDBC(Java Database Connectivity) 는 많이 사용되는 데이터 액세스 기술임. 스프링에서 제공하는 JDBC는 기존 JDBC의 장점과 단순함을 유지하면서 개발이나 유지관리의 어려움 등 단점을 보완했음. 간결한 API 뿐만 아니라 확장된 JDBC의 기능도 제공함.

실제 개발을 진행할 때는 스프링 JDBC 기능 보다는 마이바티스나 하이버네이트 같은 데이터베이스 연동 관련 프레임워크를 사용하지만, 스프링 JDBC의 기본적인 기능을 알아두면 도움이 되므로 22장에서 간단히 짚고 넘어가자.

 

새 프로젝트 pro22를 생성, pro21의 lib 폴더의 라이브러리와 web.xml, action-servlet.xml을 복사 후 같은 위치(WEB-INF 폴더 아래)에 붙여넣자.

그리고 스프링 JDBC 실습에 필요한 XML 파일들을 준비하자.

WEB-INF 폴더 아래 config 폴더 생성 후 action-dataSource.xml, action-service.xml, jdbc.properties 를 생성함.

 

web.xml : ContextLoaderListener를 이용해 빈 설정 XML 파일들을 읽어들임

action-servlet.xml : 스프링에서 필요한 여러 가지 빈을 설정함

action-dataSource.xml : 스프링 JDBC 설정에 필요한 정보를 설정함

jdbc.properties : 데이터베이스 연결 정보를 저장함

action-service.xml : 서비스 빈 생성을 설정함(DB 연동시 필요한 memberDAO 빈을 주입하는 기능을 함)

 

action-dataSource.xml과 action-service.xml 의 <beans> 태그는 21장에서 실습한 action-servlet.xml의 것을 복붙하면 됨

 

[ web.xml ]

하나의 xml 파일에서 모든 빈을 다 설정하면 너무 복잡해짐

-> 빈의 종류에 따라 여러 XML 파일에 나누어 설정하고,

web.xml에서 스프링의 ContextLoaderListener 를 이용해 빈 설정 XML 파일들을 읽어들임

<xml ...>
<web-app ...>
<listener>
    <listener-class>
        org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/config/action-service.xml
        /WEB-INF/config/action-dataSource.xml
    </param-value>
</context-param>

...  <!-- *.do 요청에 대해 DispatcherServlet이 받도록 <servlet> 과 <servlet-mapping> 태그 설정-->

[ action-servlet.xml ]

뷰 관련 빈, 요청을 처리할 빈 + 메서드 를 설정함

*** 빈 주입 시 주입받는 클래스에서는 주입되는 빈에 대한 setter가 반드시 구현되어야 함

...
// 기존 view 관련 빈
<bean id="viewResolver"
      class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
    <property name="prefix" value="/WEB-INF/views/" />
    <property name="suffix" value=".jsp" />
</bean>

// /member/*.do로 들어오는 요청 처리할 컨트롤러 
<bean id="memberController" class="com.spring.member.comtroller.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>

// /member/*.do로 요청 들어오면 memberController가 처리하도록 설정
<bean id="urlMapping"
      class="org.springframwork.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="mappings">
        <props>
            <prop key="/member/*.do">memberController</prop>
        </props>
    </property>
</bean>

methodResolver 빈 : 요청명에 따라 호출할 메서드 이름을 지정

-> memberController 빈 : methodResolver 빈, memberService 빈 주입

-> urlMapping 빈 : /member/*.do 로 들어오는 요청을 memberController 빈이 처리하도록 설정함

 

[ action-service.xml ]

memberService 빈 - db 연동에 필요한 memberDAO 빈을 주입함

(memberDAO 빈은 아래 action-dataSource.xml에서 생성)

...
<bean id="memberService" class="com.spring.member.service.MemberServiceImpl">
    <property name="memberDAO" ref="memberDAO" />
</bean>
</beans>

[ action-dataSource.xml ]

...
// 1.
<bean id="propertyConfigurer"
      class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
        <list>
            <value>/WEB-INF/config/jdbc.properties</value>
        </list>
    </property>
</bean>

// 2.
<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>

// 3.
<bean id="memberDAO" class="com.spring.member.dao.MemberDAOImpl">
    <property name="dataSource>" ref="dataSource" /> <!--생성된 datasource 빈을 memberDAO빈에 주입-->
</bean>
...

1. jdbc.properties 파일에서 db 연결에 필요한 정보를 가져올 수 있도록 함

2. jdbc.propertis 파일의 4가지 설정 정보로 SimpleDriverDataSource 빈을 생성해서 db에 연결함

3. memberDAO 빈을 생성, dataSource 빈을 주입함

 

[ jdbc.properties ]

config 폴더 우클릭 > New > File을 선택해서 생성함

DB 연결 정보를 작성함

 

jdbc.driverClassName=oracle.jdbc.driver.OracleDriver

jdbc.url=jdbc:oracle:thin:@localhost:1521:XE

jdbc.username=scott (나는 다른걸로 해뒀음)

jdbc:password=tiger

 

=> XML 설정파일에 의해 생성된 각 빈의 주입 과정은 다음과 같음

 

22.2 JdbcTemplate 클래스 이용해 회원 정보 조회하기

830p

이제 자바 클래스와 JSP를 이용해 회원 테이블에서 조회한 회원 정보를 JSP에 출력해보자

 

com.spring.member 패키지 아래

  controller 패키지 - MemberController.java, MemberControllerImpl.java

  dao 패키지 - MemberDAO.java, MemberDAOImpl.java

  service 패키지 - MemberService.java, MemberServiceImpl.java

  vo 패키지 - MemberVO.java

 

WebContent/WEB-INF 아래 view 폴더에 listMember.jsp, memberForm.jsp

 

위의 파일들을 생성함

 

DAO 클래스에서 실제 스프링의 JDBC 기능을 제공하는 클래스는 JDbcTemplate임

▼ 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)
iong queryForLong(String query)
long queryForLongt(String query, Object[] args)
Object queryForObject(String query, Class requiredType)
List queryForList(String query)
List queryForList(String query, Object[] args)

 

[ MemberControllerImpl 클래스 ]

속성 memberService에 설정파일에서 생성된 memberService빈을 주입하기 위해 setter를 구현해야 함

...
public class MemberControllerImpl extends MultiActionController implements MemberController {
    private MemberService memberService;
    public void setMemberService(MemberService memberService) {
        this.memberService = memberService;
    }
    
    // /member/listmembers.do 로 요청 시 호출됨
    public ModelAndView listMembers(...) ... {
        String viewName = getViewName(request); // 아래에서 구현했음, 21? 20? 장 보면 나와있음
        List membersList - memberService.listMembers();
        ModelAndView mav = new ModelAndView(viewName);
        mav.addObject("membersList", membersList);
        return mav;
    }
    ...
}

 

[ MemberServiceImpl 클래스 ] 

memberDAO 속성에 빈을 주입하기 위해 setter를 구현해야 함

...
public class MemberServiceImpl implements MemberService {
    private MEmberDAO memberDAO;
    
    public void setMemberDAO(MemberDAO memberDAO){
        this.memberDAO = memberDAO;
    }
    
    @Override
    public List listMEmbers() ... {
        List membersList = null;
        membersList = memberDAO.selectAllMembers();
        return membersList;
    }
}

 

[ MemberDAOImpl 클래스 ]

jdbcTemplate 속성에 dataSource 빈을 주입하기 위해 setter를 구현함

...
public class MemberDAOImpl implements MemberDAO {
    private JdbcTemplate jdbcTemplate;
    
    // 설정 파일에서 생성한 dataSource 빈을 JdbcTemplate 클래스 생성자의 인자로 입력함
    public void setDataSource(DataSource dataSource) {
        this.jdbcTemplate = new JdbcTemplate(dataSource);
    }
    
    /* JdbcTemplate 클래스의 query() 메서드의 인자로 select문을 전달해서
    조회한 레코드의 개수만큼 MemberVO 객체를 생성함, 각 레코드의 값을 setter 로 저장 후 membersList에 저장 */
    @Override
    public List selectAllMembers() ... {
        String query = "~~~";
        List membersList = new ArrayList();
        membersList = this.jdbcTemplate.query(query, new RowMapper() {
            public Object mapRow(ResultSet rs, int rowNum) ... {
                MemberVO memberVO = new MEmberVO();
                memberVO.setId(rs.getString("id"));
                ...
                return memberVO;
            }
        });
        return membersList;
    }
    
    @Override
    public int addMember(MemberVO memberVO) ... {
        String id = memberVO.getId();
        ...
        String query = "insert into ~~~";
        int result = jdbcTemplate.update(query);
        return result;
    }
}

 

[ listMembers.jsp ]

조회한 회원 정보를 표시해줌