본문 바로가기

개발관련/코드로 배우는 스프링 웹 프로젝트(개정판)

Part1 - 스프링 개발 환경 구축 Chapter03

코드로 배우는 스프링 웹 프로잭트 Part1

Chapter03 스프링과 Oracle DataBase 연동

이 책의 예제들은 Oracle 11g XE를 이용해서 작성합니다.

본격적인 예제를 작성하기 전에 오라클을 설치하고 스프링 프로젝트에서 간단히 테스트 하는 것을 목표로 합니다.

 

3.1 오라클 설치

이 책에서는 오라클 11G 버전을 사용 하고 있지만 최신 버전으로 진행 하겠습니다.

저는 로컬에 다운 받지 않고 가상데스크톱을 띄워 거기에 오라클을 설치 하겠습니다.

 

파일 다운로드

google에 oracle 19c 다운로드 라고 검색 합니다.

아래 링크에 접속 후 로그인 하시면 다운로드 받을 수 있습니다.

https://www.oracle.com/kr/database/technologies/oracle19c-windows-downloads.html

다운로드 파일 압축 해제 후 실행

다운받은 파일을 압축을 해제 한 후 setup.exe를 관리자 권한으로 실행 합니다.

전부 다 Default로 설치 하다가 시스템 클래스만 서버 클래스로 설정 했습니다.

비밀번호도 넣어줍니다.

 

3.2 SQL Developer 설치

오라클 설치가 완료 되면 이제 오라클 데이터베이스를 컨트롤 할 툴을 설치 해줍니다.

그게 바로 SQL Developer 입니다.

 

구글에 sqldeveloper를 검색 합니다.

각자 자신 PC 사양에 맞는 툴을 설치해줍니다.

저는 Windows 64비트용을 설치 하도록 하겠습니다.

다운받은 파일의 압축을 해지하고 sqldeveloper.exe 파일을 실행해주면 됩니다.

SqlDeveloper가 실행되면 왼쪽 상단 +버튼을 누릅니다.

접속 정보를 넣고 테스트를 눌렀을때 왼쪽 하단 성공이 나오는지 확인 합니다.

테스트버튼을 눌러 성공이 뜨는지 확인 후 저장을 해줍니다.

이렇게 오라클 설치 및 오라클을 사용하기 위한 툴인 SQLDeveloper 설치까지 완료 되었습니다.

 

3.2.1 예제에 사용하는 계정 생성

SQL Developer에 System 계정으로 접속 한 후에는 예제에서 사용 할 계정을 생성해줍니다.

계정명 : c##book_ex

기본 테이블 스페이스 : USERS

임시 테이블 스페이스 : TEMP 

아래 내용을 입력 후 실행 메뉴로 사용자를 생성 합니다.

 

오라클 12c부터는 공통계정앞에 c##을 붙이도록 네이밍 규칙이 변경되었습니다.

C## 키워드가 붙는 이유는 12c 버전부터 등장하는 CDB, PDB 개념 때문이라고 합니다.

 

CREATE USER c##book_ex IDENTIFIED BY book_ex
DEFAULT TABLESPACE USERS
TEMPORARY TABLESPACE TEMP;

권한을 부여 해줍니다.

GRANT CONNECT , DBA TO C##BOOK_EX;

 

접속이 잘 되는지를 확인 해보기 위해 기존 연결을 해지하고 새로 생성한 c##book_ex계정으로 접속 합니다.

생성한 c##book_ex 계정으로 로그인이 잘 되는지까지 확인이 완료 되었습니다.

 

 

3.2.2 8080포트 변경

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

웹 개발시 많이 사용하는 Tomcat의 기본 포트가 8080이기 떄문에 동시에 오라클과 Tomcat이 8080 포트를 사용 하는 문제를 가지게 됩니다.

이 문제를 해결하기 위해 오라클의 포트를 변경 해주는것이 좋습니다.

 

SQL Developer를 이용해서 처음 테스트 했던 system 계정으로 접속합니다.

접속 후에는 현재 사용하는 포트가 몇번인지 확인 합니다.

select dbms_xdb.gethttpport from dual;

포트번호가 0으로 나오는데 당황하지 말고 9090으로 변경 해주도록 하겠습니다.

 

exec dbms_xdb.sethttpport(9090);

다시 처음 select 문으로 select 했을때 변경된 포트 번호를 확인 할 수 있습니다.

 

3.3 프로젝트의 JDBC 연결

본격적인 프로젝트에 앞서 JDBC 연결에 문제가 없는지를 확인해야 합니다.

예제 프로잭트에서 준비한 jUnit을 이용해서 테스트를 진행하는 코드를 작성해 봅니다.

 

jdbc jar 파일을 직접 프로젝트에 추가 시키도록 하겠습니다.

 

SQL Developer를 다운 받았으면 해당 폴더 내에 lib 폴더가 있습니다.

거기에 ojdbc.jar가 있습니다.

예제 프로젝트를 선택 한 후 Build Path를 이용해서 ojdbc8.jar파일을 경로에 추가합니다.

나중에 war파일을 만들때 jar파일이 포함될 수 있도록 Web Deployment Assembly 항목에도 jar파일을 추가합니다.

 

Web Deplyment Assembly 항목에서는 Add 버튼을 눌러 Java Build path를 선택합니다.

 

 

3.3.1 JDBC 테스트 코드

JDBC 드라이버가 정상적으로 추가 되었고, 데이터베이스의 연결이 가능 하다면 이를 눈으로 확인 할 수 있게 테스트 코드를 작성합니다.

org.zerock.persistence.JDBCTests 클래스를 추가 합니다.

package org.zerock.persistence;

import static org.junit.Assert.fail;

import java.sql.Connection;
import java.sql.DriverManager;

import org.junit.Test;

import lombok.extern.log4j.Log4j;

@Log4j
public class JDBCTests {

	static {
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Test
	public void testConnection() {

		try (Connection con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:orcl", "c##book_ex",
				"book_ex")) {

			log.info(con);
		} catch (Exception e) {
			fail(e.getMessage());
		}
	}

}

 

해당 클래스를 실행 해보겠습니다.

 

테스트가 정상적으로 완료 됬다면 데이터베이스가 연결된 Connection 객체가 출력 됩니다.

만일 데이터베이스에 문제가 있거나, JDBC 드라이버에 문제가 있다면 이후의 예제를 작성할 수 없기에 반드시 테스트코드를 만들어 실행 해봐야 합니다.

 

3.4 커넥션 풀 설정

일반적으로 여러 명의 사용자를 동시에 처리해야 하는 웹 어플리케이션의 경우 데이터베이스를 이용할 때는 커넥션풀(Connection Pool)을 이용하므로, 아예 스프링 커넥션 풀을 등록해서 사용 하는 것이 좋습니다.

Java에서는 DataSource 라는 인터페이스를 통해서 커넥션 풀을 사용합니다.

DataSource를통해 데이터베이스를 매번 연결하는 방식이 아닌 미리 연결을 맺어주고 반환하는 구조를 이용하여 성능 향상을 꾀합니다.

 

커넥션 풀은 여러 종류가 있고, spring-jdbc 라이브러리를 이용하는 방식도 있지만, 예제는 HikariCP를 이용해보겠습니다.

HikariCP는 스프링 부트 2.0에서도 사용될 만큼 빠르게 퍼지고 있습니다.

 

3.4.1 라이브러리 추가와 DataSource 설정

pom.xml을 수정해서 HikariCP를 추가합니다.

<!-- https://mvnrepository.com/artifact/com.zaxxer/HikariCP -->
<dependency>
	<groupId>com.zaxxer</groupId>
	<artifactId>HikariCP</artifactId>
	<version>2.7.4</version>
</dependency>

 

root-context.xml 안에 설정은 직접 <bean> 태그를 정의합니다.

<bean> 태그 안에는 <property>를 이용해서 여러 속성에 대해서 설정할 수 있습니다.

자세한 설정은 구글링를 통해 확인 해보시면 될것 같습니다.

<?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 https://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 components -->
	<bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
		<property name="driverClassName"
			value="net.sf.log4jdbc.sql.jdbcapi.DriverSpy"></property>
		<property name="jdbcUrl"
			value="jdbc:log4jdbc:oracle:thin:@localhost:1521:orcl"></property>
		<property name="username" value="c##book_ex"></property>
		<property name="password" value="book_ex"></property>
	</bean>

	<!-- HikariCP configuration -->
	<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource"
		destroy-method="close">
		<constructor-arg ref="hikariConfig" />
	</bean>
		<context:component-scan base-package="org.zerock.sample">
		</context:component-scan>
		
</beans>

스프링에서 root-context.xml은 스프링이 로딩되면서 읽어 들이느 ㅁ누서로, 주로 이미 만들어진 클래스들을 이용해서 스프링의 빈(bean)으로 등록할 때 사용합니다.

일반적인 상황이라면 프로젝트에 직접 작성하는 클래스들은 어노테이션을 이용하는 경우가 많고, 외부 jar파일등으로 사용하는 클래스들은 <bean> 태그를 이용해서 작성하는 경우가 대부분 입니다.

 

스프링이 시작되면 root-context.xml을 읽어서 아래와 같은 형태로 id가 dataSource인 객체가 처리됩니다.

초기에 스플이에 대한 경험이 많치 않다면 위와 같이 빈(bean)을 정의한 다음에는 항상 테스트를 작성하는 습관을 가지는것이 좋습니다.

src/test/java에 DataSourceTests클래스를 작성합니다.

package org.zerock.persistence;

import static org.junit.Assert.fail;

import java.sql.Connection;

import javax.sql.DataSource;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import lombok.Setter;
import lombok.extern.log4j.Log4j;


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("file:src/main/webapp/WEB-INF/spring/root-context.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) {
      fail(e.getMessage());
    }
  }
}

RunAs > jUnit Test로 실행해보면 아래와 같은 에러에 마주하게 됩니다.

자세히 들여다보면 Log4j2 클래스가 없다는 이야기 입니다.

 

없다고 하니,, Log4j2클래스를 추가 해줍시다.

pom.xml에 아래 dependency를 추가해 줍니다.

<dependency>
	<groupId>org.bgee.log4jdbc-log4j2</groupId>
	<artifactId>log4jdbc-log4j2-jdbc4</artifactId>
	<version>1.16</version>
</dependency>

그리고 src/main/resources에 log4jdbc.log4j2.properites도 추가 해주겠습니다.

log4jdbc.spylogdelegator.name=net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator

 

이렇게 하고 다시 실행해보면 정상 실행되어 Connection 객체를 가져오는 것을 확인 할 수 있습니다.

실행 결과는 서버의 로그를 확인 하는 것으로 설정에 문제가 있는지를 확인하는 수준이고, 불행하게도 아직 브라우저에서 최종 결과를 확인하지는 못합니다.

브라우저에서 최종 결과물을 확인하는것은 뒷부분에 나오는 여러 설정을 마친 후에 가능 합니다.