Spring

230203 Spring과 MySQL 연결환경 구축과 테스트

주영재 2023. 2. 3. 19:34

JDBC

드라이버 로딩-DB연결-SQL작성 및 전송-자원해제

전통적인 JDBC프로그래밍

  1. Connection 객체 생성
  2. PrepareStatement 객체생성
  3. SQL문 실행
  4. ResultSet객체 생성 결과처리

장점:가장 빠름
단점:똑같은 코드 반복, 작업 반복


Spring 연결


연결할 때, 
Spring-JDBC라는 모듈이 필요하다.

커넥션 풀
-DB연결을 이용할 때 매번 연결하는 방식이 아닌 
미리 연결을 해 놓고, Connection Pool로 바로 연결.(미리 연결지어놓는 것.)
-속도면에서 빠르며, 최근 유행하는 HikariCP 라이브러리 사용

1.Mysql Connector(커넥터)
2.Spring-JDBC
3.히카리CP(커넥션풀)
4.Spring-test에서 테스트


설치

모든 모듈은 MVN Repository에서.(https://mvnrepository.com/)
porm.xml에서.

 


1. Mysql Connector(커넥터)

mvn repository에서 mysql connector검색하고 
MySQL Connector Java로 가면 있다.
db와 맞춰서 8.0.32버전으로

porm.xml에 추가.

<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
	<version>8.0.32</version>
</dependency>


dependencies 태그 안에.

 

 


2.Spring-JDBC

스프링 jdbc모듈

<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-jdbc</artifactId>
	<version>${org.springframework-version}</version>
</dependency>


로, 기존 버전을 맞춰주기.


3.히카리CP(커넥션풀)

HikariCP검색
HikariCP
HikariCP is a "zero-overhead" production ready JDBC connection pool.
로.

버전은 3.3.1로.

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


4.Spring-test에서 테스트

하기 전에, 테스트환경 구축

spring-test모듈, JUnit기능 필요

spring-test 검색
Spring TestContext Framework
모듈 가져와서 버전 맞추기

<!-- 테스트환경: spring-test모듈 and junit기능 -->
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-test</artifactId>
	<version>${org.springframework-version}</version>
	<scope>test</scope>
</dependency>

<!-- Test버전은 최소 4.12이상 -->
<dependency>
	<groupId>junit</groupId>
	<artifactId>junit</artifactId>
	<version>4.12</version>
	<scope>test</scope>
</dependency>

 

junit
이미 있다.
위치만 변경하고, 버전변경. 4.12로

다 받고 maven update.


db와 연결

미리 bean으로 만들어놓는 작업

이 위치는 servlet-context.xml에서 하는게 아님.
전역에서 처리되야 하고, 가장 먼저 처리되어야 함.
->root-context.xml에서! 
web.xml을 보면 root-context.xml이 전역설정으로 되어 있다.

 

 

우선
root-context.xml namespaces에서
jdbc 체크


DataSource와 HikariCP 빈으로 등록
hickaricp에서 제공하는 것들로 만든다.
hikariconfig, hikaridatsource

이건 제공받는 것이기 때문에 @Autowired가 아닌 직접 입력하는 방법으로 사용.

<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/spring?serverTimezone=Asia/Seoul""/>
spring-> 스키마.
serverTimezone~은 한국시간으로 서버시간을 의미하는 것.
다른컴퓨터로 들어가면 localhost, spring이 변경

<bean class="com.zaxxer.hikari.HikariDataSource">
는 생성자로 hikariconfig를 받는다. 위에서 생성한 것 넣기.

 

 

이때,  DB연결은 외부에 노출되면 안됨(스키마, 아이디, 비밀번호, 경로 등이 다 들어있다.). 프로퍼티 파일에 넣고 정보를 보관하면 됨.
외부 프로퍼티스를 읽도록.

 

.properties파일에 키=값 형태로 지정

classpath:/를 하면 spring에서 읽는 위치는  src/main/resources파일 아래의 파일의 경로를 참조한다.
값 참조는 ${}로 한다.

프로퍼티 이름은 location, value는 경로

 src/main/resources에 DB-config폴더 생성
 폴더 내부에 hikari.properties파일 생성(반드시 확장자가 properties여야 한다.)
 이 파일 내에 키=값으로 저장
여기서 주석은 ##으로


 
물론, 나중엔 db에 특정 ip로만 접근가능하게 핸들링을 한다.

 

 

 

root-context.xml에서

	<!-- 데이터베이스 정보는 외부 파일로 관리 -->
	<!-- classpath:/ 자바/리소스 경로를 가르킵니다 -->
	<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="location" value="classpath:/DB-config/hikari.properties"/>
	</bean>
	
	<!-- 데이터베이스 설정 -->
	<bean id="hikari" class="com.zaxxer.hikari.HikariConfig">
		<property name="driverClassName" value="${ds.driverclassName}"/>
		<property name="jdbcUrl" value="${ds.jdbcUrl}"/>
		<property name="username" value="${ds.username}"/>
		<property name="password" value="${ds.password}"/>
	</bean>
	
	 
	 <!-- 오라클 -->
	 <!-- <bean id="hikari" class = "com.zaxxer.hikari.HikariConfig">
      <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
      <property name="jdbcUrl" value="jdbc:oracle:thin:@localhost:1521:xe"/>
      <property name="username" value="jsp"/>
      <property name="password" value="jsp"/>
   </bean> -->
	 
	 <!-- 데이터베이스 정보를 주입 -->
	<bean id="ds" class="com.zaxxer.hikari.HikariDataSource">
		<constructor-arg ref="hikari"/>
	</bean>





추가:HikariCP주요 옵션들
autoCommit : 자동commit설정 (기본:true)
connectionTimeout : pool에서 커넥션을 얻어오기전까지 기다리는 최대 시간 (기본:30초)
maximumPoolSize : pool에 유지시킬 수 있는 최대 커넥션 수(기본:10개)
maxLifetime : 커넥션 풀에서 살아있을 수 있는 커넥션의 최대 수명시간. (기본 30분)


참고 라이브러리
https://github.com/brettwooldridge/HikariCP#configuration-knobs-baby


무조건적으로 테스트를 하기보다는, 간단한 설정이나 에러가 나는 부분에서 테스트 라이브러리 사용.
스프링에서 기본적으로 Junit 라이브러리 제공

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("file:src/main/webapp/WEB-INF/spring/**/root-context.xml")
public class JdbcTemplateTest {
	@Autowired
	DataSource datasource;

	@Autowired
	JdbcTemplate jdbcTemplate;

	@Test
	public void testTemplate() {
		try {
		Connection conn = datasource.getConnection();
		System.out.println(">>>>>>>>>>>>>>connection출력:" + conn);

		System.out.println(">>>>>>>>>>>>>>템플릿객체생성:" + jdbcTemplate);
		} catch (Exception e) {
			e.printStackTrace();
		}
}



@RunWith : 스프링 프레임워크가 독립적으로 실행되도록 구동환경 설정
@ContextConfiguration : 사용할 스프링 설정 파일 경로 지정. file:/부터 시작한다.
@Test : 해당 어노테이션이 붙은 메서드를 실행. 메인처럼.

이외에도 여러 어노테이션이 존재.



src/test/java에
com.simple.basic으로 패키지 이름 바꾸고
JDBCTest클래스 생성

@BeforeClass : 해당 클래스에서 단 한번 실행. static으로
@Before : 각 테스트 코드를 실행하기 전에 우선실행

 

package com.simple.basic;


import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class) //junit으로 테스트환경을 구성
@ContextConfiguration("file:src/main/webapp/WEB-INF/config/root-context.xml") //동작시킬 스프링 설정파일
public class JDBCTest {

	@BeforeClass //해당 클래스에서 단 한번 실행 -static
	public static void loadTest() {
		System.out.println("beforeClass");
	}
	
	@Before //각 테스트 코드를 실행하기 전에 우선실행
	public void testCode() {
		System.out.println("Before");
	}

	
	@Test //test코드로 실행함
	public void testCode01() {
		System.out.println("실행됨1");
	}
	
	@Test //test코드로 실행함
	public void testCode02() {
		System.out.println("실행됨2");
	}
	
	
	
	
	
}

 

콘솔출력문

INFO : org.springframework.test.context.support.DefaultTestContextBootstrapper - Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener]
INFO : org.springframework.test.context.support.DefaultTestContextBootstrapper - Using TestExecutionListeners: [org.springframework.test.context.web.ServletTestExecutionListener@1b1426f4, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener@32b260fa, org.springframework.test.context.support.DependencyInjectionTestExecutionListener@581ac8a8, org.springframework.test.context.support.DirtiesContextTestExecutionListener@6d4e5011, org.springframework.test.context.transaction.TransactionalTestExecutionListener@57d7f8ca, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener@76c3e77a]
beforeClass
INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from URL [file:src/main/webapp/WEB-INF/config/root-context.xml]
INFO : org.springframework.context.support.GenericApplicationContext - Refreshing org.springframework.context.support.GenericApplicationContext@242b836: startup date [Fri Feb 03 19:33:38 KST 2023]; root of context hierarchy
INFO : org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor - JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
INFO : com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Starting...
INFO : com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Start completed.
Before
실행됨1
Before
실행됨2
INFO : org.springframework.context.support.GenericApplicationContext - Closing org.springframework.context.support.GenericApplicationContext@242b836: startup date [Fri Feb 03 19:33:38 KST 2023]; root of context hierarchy
INFO : com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown initiated...
INFO : com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown completed.

 

JUnit


DB와 연결되었으면

 

JDBCTest.java

package com.simple.basic;

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;

@RunWith(SpringJUnit4ClassRunner.class) //junit으로 테스트환경을 구성
@ContextConfiguration("file:src/main/webapp/WEB-INF/config/root-context.xml") //동작시킬 스프링 설정파일
public class JDBCTest {

	
	
	@Autowired
	DataSource dataSource;
	
	
	@Test //test코드로 실행함
	public void testCode01() {
		//System.out.println("실행됨1");
		
		try {
			//DataSource에서 conn객체 얻음
			Connection conn=dataSource.getConnection();
			System.out.println(conn);
		} catch (Exception e) {
		}
	}

	
	
}

을 실행하면 콘솔창에

HikariProxyConnection@219638321 wrapping com.mysql.cj.jdbc.ConnectionImpl@3a91d146

이 출력됨.
->conn이 있다!

이렇게 test에서 확인하고, 자바코드로 옮기면 된다.