[Spring Boot]Oracle DB 연결하기
- -
최근 이직한 곳에서는 Oracle DB를 사용하고 있었습니다.
오랜만에 예전 기억도 되새길겸 연동 과정을 기록에 남겨봤습니다.
회사 환경과 동일하게 맞추기 위해 Spring Boot 환경에서 외부 톰캣을 사용했고, JNDI를 통해 DB 리소스를 가져왔습니다. DB연결에는 ojdbc를 이용했고, MyBatis 연결까지의 과정을 공유합니다.
테스트 환경
- Spring Boot 2.7.5
- JDK 1.8
- ojdbc8
- Maven
- MyBatis
1. 의존성 주입
Maven repository 접속해서 아래 의존성을 추가합니다.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<!-- dbcp2 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>
<!-- jdbc -->
<dependency>
<groupId>jdbc</groupId>
<artifactId>ojdbc8</artifactId>
<version>18.3.0.0</version>
<scope>provided</scope>
</dependency>
<!-- log4jdbc -->
<dependency>
<groupId>org.bgee.log4jdbc-log4j2</groupId>
<artifactId>log4jdbc-log4j2-jdbc4.1</artifactId>
<version>1.16</version>
</dependency>
ojdbc는 저작권 문제로 Maven 추가시에도 jar파일이 생성되지 않기 때문에 따로 다운로드를 받아 아래 경로에 추가합니다.
추가 경로1 : C:\Users\Admin\.m2\repository
추가 경로2 : tomcat 설치 경로 bin 폴더
2. Tomcat JNDI 설정
DB Connection 정보를 저장합니다. GlobalNamingResources 태그 안에 연결할 DB Resource추가합니다.
server.xml
<GlobalNamingResources>
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml" />
<Resource name="jdbc/testDB"
auth="Container"
type="javax.sql.DataSource"
driverClassName="oracle.jdbc.OracleDriver"
factory="org.apache.tomcat.dbcp.dbcp2.BasicDataSourceFactory"
url="jdbc:oracle:thin:@DB접속IP:1521:스키마"
username="접속계정"
password="패스워드"
maxActive="100"
maxIdle="30"
maxWait="10000"
/>
</GlobalNamingResources>
JNDI를 통해 WAS의 Datasource를 찾아갈때 연결시켜주는 링크(JNDI명)을 입력합니다.
global 속성은 server.xml에 정의된 JDNI Resource를 참조할 때 사용됩니다. global 속성이 설정되지 않은 경우 name 속성을 통해 Resource를 참조합니다. global과 name의 값을 동일하게 맞추어 사용합니다.
context.xml
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<WatchedResource>WEB-INF/tomcat-web.xml</WatchedResource>
<WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
<ResourceLink global="jdbc/testDB"
name="jdbc/testDB"
auth="Container"
type="javax.sql.DataSource" />
</Context>
3. Config 설정
mybatis 설정 파일을 생성합니다.
프로젝트의 전체적인 디렉토리 구조는 다음과 같습니다.
.
└── demo-project/
└── src/
└── main/
└── java/
├── com/
│ └── app/
│ └── demo/
│ ├── common/
│ │ └── config/
│ │ └── DataSourceConfig.java
│ └── domain/
│ └── test/
│ ├── controller/
│ │ └── TestController
│ ├── service/
│ │ └── TestService
│ ├── dao/
│ │ └── TestDao
│ └── dto/
│ └── Test001Dto
├── resources/
│ ├── mapper/
│ │ └── test/
│ │ └── testMapper.xml
│ ├── application.properties
│ ├── log4jdbc.log4j2.properties
│ ├── logback.xml
│ └── mybatis-config.xml
└── webapp
resources/mybatis-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/> <!-- DTO 카멜케이스 적용 -->
<setting name="callSettersOnNulls" value="true"/>
<setting name="jdbcTypeForNull" value="NULL"/>
</settings>
<typeAliases>
<typeAlias alias="list" type="java.util.List" />
<typeAlias alias="hashMap" type="java.util.HashMap" />
</typeAliases>
</configuration>
MyBatis와 데이터 소스를 설정하는 DataSourceConfig를 생성합니다.
dataSource 빈을 설정하여 testDB의 데이터 소스를 조회하고 반환합니다. java:/comp/env를 추가해야 WAS의 Datasource를 찾아갈 수 있습니다.
MyBatis 설정 파일과 매퍼 XML 파일의 위치를 지정하고, MyBatis의 SqlSessionFactory를 설정합니다.
@MapperScan을 통해 MyBatis 매퍼 인터페이스의 위치를 자동으로 스캔할 수 있도록 합니다.
@Slf4j
@MapperScan(value="com.app.demo.domain.**.dao")
@Configuration
public class DataSourceConfig {
public final static String MYBATIS_CONFIG_LOCATION_PATH = "classpath:mybatis-config.xml";
public final static String MAPPER_LOCATIONS_PATH = "classpath:mapper/**/*.xml";
private final static String JNDI_NAME = "java:/comp/env/jdbc/jndiName";
@Bean
public DataSource dataSource() throws NamingException {
try {
JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
log.info("================= :: DB Connection Info :: =================");
log.info(">> Connection JNDI : {} ", JNDI_NAME);
log.info("=============================================================");
return dataSourceLookup.getDataSource(JNDI_NAME);
} catch (DataSourceLookupFailureException ex) {
throw new NamingException("Could not find DataSource via JNDI lookup");
}
}
@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
sqlSessionFactoryBean.setConfigLocation(resolver.getResource(MYBATIS_CONFIG_LOCATION_PATH));
sqlSessionFactoryBean.setMapperLocations(resolver.getResources(MAPPER_LOCATIONS_PATH));
return sqlSessionFactoryBean.getObject();
}
@Bean
public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
4. 테스트
테스트를 위해 Controller, Service, Dao, Mapper를 생성해봅니다.
TestController
@Slf4j
@Controller
@RequiredArgsConstructor
@RequestMapping("test")
public class TestController {
private final TestService testService;
@GetMapping(value = "/dbTest")
public void dbTest() {
List<Test001Dto> resultList = testService.getTestDB();
log.info(resultList.toString());
}
}
TestService
@Service
@RequiredArgsConstructor
public class TestService {
private final TestDao testDao;
public List<Test001Dto> getTestDB() {
return testDao.getTestDB();
}
}
TestDao
public interface TestDao {
public List<Test001Dto> getTestDB();
}
TestDto
@Data
public class Test001Dto {
private int totAmt;
private int totVat;
private int pno;
}
testMapper
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.app.demo.domain.test.dao.TestDao">
<select id="getTestDB" resultType="com.app.demo.domain.test.dto.Test001Dto">
<![CDATA[
SELECT TOT_AMT, TOT_VAT, PNO
FROM KCTDI.TEST001
]]>
</select>
</mapper>
연결이 잘 되었다면 프로젝트 실행 시 아래처럼 로그가 조회됩니다.
쿼리 로그를 확인하기 위해 아래 log4jdbc 설정까지 마무리하고, 컨트롤러를 호출해봅니다.
더보기
log4jdbc 설정
application.properties
# Log Setting
logging.level.root=info
logging.level.com.wwl.app=debug
logging.level.jdbc.sqlonly=off
logging.level.jdbc.sqltiming=info
logging.level.jdbc.resultsettable=info
logging.level.jdbc.audit=off
logging.level.jdbc.resultset=off
logging.level.jdbc.connection=off
logging.config=classpath:logback-${spring.profiles.active}.xml
log4jdbc.log4j2.properties
log4jdbc.drivers=oracle.jdbc.OracleDriver
log4jdbc.spylogdelegator.name=net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator
log4jdbc.dump.sql.maxlinelength=0
logback.xml
<configuration scan="true">
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%-5level %d{yy-MM-dd HH:mm:ss}[%thread] [%logger{0}:%line] - %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT"/>
</root>
</configuration>
전체 코드는 GitHub에서 확인하실 수 있습니다.
'Framework > Spring' 카테고리의 다른 글
[Spring Boot]대량 데이터 저장하기 (0) | 2024.10.17 |
---|---|
[Error]Spring Security authenticate 302 (2) | 2024.09.02 |
[Spring Boot]@Async로 비동기 처리하기 (0) | 2024.07.18 |
[Spring Boot]Firebase Admin SDK를 이용해 푸쉬 보내기 (0) | 2024.07.04 |
[Spring Boot]이미지 파일 변환, base64 to multipartfile (0) | 2024.04.18 |
소중한 공감 감사합니다.