ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Chapter 3. 스프링과 Oracle Database 연동
    코드로 배우는 스프링 웹 프로젝트_intellij 2021. 4. 14. 15:43

    이 책의 예제들은 Oracle을 사용해서 작성합니다. 오라클 설치가 다들 되어 있을 것이다라는 전제를 두고 책의 설치 부분은 패스하도록 하겠습니다.

    일단 book_ex라는 이름을 가진 Oracle Database 유저를 생성하겠습니다.(저는 window power shell 유저이기에 교재에 나온 SQLdeveloper를 사용해도 됩니다.)

    book_ex라는 유저가 정상적으로 수행되었습니다.

     

    계정으로 행위를 하기 위해서는 권한이나 role이 필요하므로 GRANT문을 통해서 부여하겠습니다. 

    오라클은 기본적으로 8080포트를 이용해서 웹 환경으로도 데이터베이스를 접근할 수 있습니다. 

    하지만 여기서 발생하는 문제가 Tomcat이 주로 8080을 사용하기 때문에 포트번호를 옮겨 주도록 하겠습니다.

     

    다시한번 포트번호를 조회해보면

    포트번호가 정상적으로 수정된 것을 확인할 수 있습니다.

     

    JDBC 연결


    본격적인 예제를 구성하기 위해서는 반드시 JDBC 연결에 문제가 없는지 확인을 해야합니다. 우선 JDBC 연결을 하기 위해서는 JDBC Driver가 필요한데 이는 오라클에서 설치할 수 있습니다. SqlDeveloper를 설치했다면 jdbc/lib 경로에 ojdbc.jar 파일이 존재할 것입니다.

    import lombok.extern.log4j.Log4j;
    import org.junit.Test;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    
    import static org.junit.Assert.fail;
    
    @Log4j
    public class JDBCTests {
        static {
            try{
                Class.forName("oracle.jdbc.OracleDriver");
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    
        @Test
        public void testConnection(){
            try(Connection con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE","System","root")){
                log.info(con);
            }catch (Exception e){
                fail(e.getMessage());
            }
        }
    }
    

    이러한 클래스를 만들어 테스트를 해봤을 때 아래와 같은 결과가 나온다면 정상적으로 데이터베이스가 연결되어 con이 출력된 것이다.

     

     

    커넥션 풀 설정


    여러 명의 사용자를 동시에 처리해야 하는 웹 어플리케이션의 경우 데이터베이스 연겨를 이용할 때 Connection Pool을 이용한다. 아예스프링이 커넥션 풀을 등록해서 사용하는 것이 좋습니다. Java에서는 DataSource라는 인터페이스를 통해서 커넥션 풀을 사용합니다. DataSource를 통해 매번 데이터베이스와 연결하는 방식이 아닌, 미리 연결을 맺어주고 반환하는 구조를 이용하여 성능 향상을 꾀합니다.

     

    커넥션 풀은 여러 종류가 있고 spring-jdbc 라이브러리를 이용하는 방식도 있지만 교재는 HikariCP를 선택하고 있어서 이것을 사용해 보겠습니다.

    (HikariCP는 스프링 부트에서도 사용)

    pom.xml에 추가

            <dependency>
                <groupId>com.zaxxer</groupId>
                <artifactId>HikariCP</artifactId>
                <version>2.7.4</version>
            </dependency>

    XML 방식) applicationContext.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"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="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-4.3.xsd">
    <!-- Root : Context: defines shared resources visible to all other web componenets-->
        <bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
            <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"></property>
            <property name="jdbcurl" value="jdbc:oracle:thin:@localhost:1521:XE"></property>
            <property name="username" value="system"></property>
            <property name="password" value="root"></property>
        </bean>
        <!--HikariCP configuration-->
        <bean id ="dataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
            <constructor-arg ref="hikariConfig"></constructor-arg>
        </bean>
    
        <context:component-scan base-package="org.mido.sample"></context:component-scan>
    </beans>

    스프링에서 applicationContext은 스프링이 로딩되면서 읽어들이는 문서이다. 주로 이미 만들어진 클래스들을 이용해서 스프링의 빈으로 등록할 때 사용된다. 일반적인 상황이라면 프로젝트에 직접 작성하는 클래스들은 어노테이션을 이용하는 경우가 많고, 외부 jar 파일 등으로 사용하는 클래스들은 <bean>태그를 이용해서 작성하는 경우가 많다.

     

    Java 방식) RootConfig

    package org.mido.config;
    
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    
    import javax.sql.DataSource;
    import com.zaxxer.hikari.HikariConfig;
    import com.zaxxer.hikari.HikariDataSource;
    @Configuration
    @ComponentScan(basePackages = {"org.mido.sample"})
    public class RootConfig {
        @Bean
        public DataSource dataSource(){
            HikariConfig hikariConfig = new HikariConfig();
            hikariConfig.setDriverClassName("oracle.jdbc.driver.OracleDriver");
            hikariConfig.setJdbcUrl("jdbc:oracle:thin:@localhost:1521:XE");
            hikariConfig.setUsername("system");
            hikariConfig.setPassword("root");
    
            HikariDataSource dataSource = new HikariDataSource(hikariConfig);
            return dataSource;
        }
    }
    

     

    Java 설정을 이용하는 경우에는 앞에서 작성한 RootConfig 클래스와 @Bean을 이용해서 처리합니다. @Bean은 XML 설정에서 <bean>태그와 동일한 역할을 수행합니다. @Bean이 선언된 메서드의 실행 결과로 반환된 객체는 스프링 객체(Bean)으로 등록됩니다.

     

    스프링이 시작되면 applicationContext를 읽어서 id가 dataSources인 객체가 처리됩니다.

     

    스프링을 처음 배운다면 빈을 정의한다음에는 항상 테스트를 작성하는 습관을 가지는게 좋습니다.

     

    * applicationContext나 RootConfig에서 에러 발생시 에러코드 확인

     

    src>test>java>DataSourceTests 클래스를 만듭니다.

    import lombok.extern.log4j.Log4j;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.mido.config.RootConfig;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    
    import javax.sql.DataSource;
    import java.sql.Connection;
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration("file:/web/WEB-INF/applicationContext.xml")
    //Java 설정을 사용하는 경우
    //@ContextConfiguration(classes={RootConfig.class})
    @Log4j
    public class DataSourceTests {
      @Setter(onMethod_={@Autowired})
        private DataSource dataSource;
        @Test
        public void testConnection(){
            try(Connection con = dataSource.getConnection()){
                log.info(con);
            }catch (Exception e){
                org.junit.Assert.fail(e.getMessage());;
            }
        }
    }
    

    Java로 설정한 경우를 사용하는 방법과  applicationContext를 사용한 방식에 따라 @ContextConfiguration를 사용하는 것이 다른데 자신이 맞게 설정한 것에 따라 맞추어 주면 된다.

    테스트 코드는 스프링에 빈으로 등록된 DataSource를 이용해서 Connection을 제대로 처리할 수 있는지 확인해 보는 용도입니다. testConnection()을 실행해보면 내부적으로 HikariCP가 시작되고 종료되는 로그를 확인할 수 있습니다.

    실행 결과로 서버의 로그를 확인하는 것으로 설정에 문제가 없음을 알 수 있다.


    에러코드


    나는 hikari와 관련한 것들을 intellij에서 인식하지 못해서 당황한 에러가 발생했는데 can not resolve symbol등의 에러와 전혀 import를 할 수 없는 에러였다. 이러한 에러를 고치는 방법은 두가지가 있는데

    1) build>rebuild project

    2) File> invalidate Caches

     

Designed by Tistory.