Project/javachip

[2nd Project]³ DBCP 연결 및 DB 불러오기 실패 해결 과정

ParkYeseul 2024. 9. 24. 10:02

'개발 스타또' 하려고 했으나,

회원가입 폼에서 DB로 데이터가 넘어가지지 않는 문제를 만났다.

그래서 나는 해결하는 과정을 기록 하려고 한닷 (오류야 우레시이~)(. ❛ ᴗ ❛.)

 

1차 프로젝트 끝내고 리뷰 하면서 느낀 건,

수 많은 오류와 장애들을 만나고 해결을 했지만

어떻게 해결 했더라? 가물가물했다.

 

요게 너-무 아쉬웠다.

개발 하느라 급한 마음에 놓친 부분이 없도록

기록하고 저장하는 습관을 기르자쿠👩

 

비슷한 오류 덤벼봐

나 덕을 쌓고 지식을 쌓았어.

흔들리지 않아.🍗

 


 

 

 

 

🥓DBCP연결 실패


DBCP 연결 실패 javax.naming.NameNotFoundException: Name [oracle_dbcp]은(는) 이 컨텍스트에 바인딩되지 않았습니다. [oracle_dbcp]을(를) 찾을 수 없습니다.

DBCP (database connection pool)

- 톰캣에서 DB와 작업을 효율적으로 하기 위해 연결 객체를 데이터베이스 풀로 관리하고 지원해주는 기법

- DBCP매니저가 어느 정도의 연결 객체를 확보해 놓고 있다가 사용자의 요청이 들어오면 연결객체를 지원해주고

작업이 다 끝나면 연결객체를 DBCP매니저에게 반환하도록 하는 기법

- 사용자의 요청을 처리하기 위해 매번 드라이버를 로드하고 연결객체를 생성하는 작업을 하지 않아도 됨

 

 

 DBCP 설정항목

maxTotal: 풀에서 유지할 수 있는 최대연결 수 지정. DBCP 크기 제어

maxIdle: 연결 풀이 유지할 수 있는 최대 유효(사용되지 않는)연결 수 지정

minIdle: 풀에서 유지할 수 있는 최소 유휴 연결 수 지정

maxwaitMillis:연결이 사용 가능해질 때까지 기다릴 수 있는 최대 시간(밀리초) 지정

 

톰캣에서 DBCP를 이용하기 위한 조치 사항들

1. 오라클이 JDBC 드라이버(ojdbc6.jar)파일을 톰캣의 lib폴더에 추가해줌

2. server 폴더의 server.xml 파일에서 GlobalNamingResources 요소에 Resource요소 추가하기

 

<Resource auth="Container"

dirverClassName="oracle.jdbc.OracleDriver"

minIdle="5"

maxIdle="10"

maxTotal="20"

maxWaitMillis="5000"

name="global_oracle_dbcp"

password="1234"

type="javax.sql.DataSource"

url="jdbc:oracle:thin:@localhost:1521:xe"

username="web_dev"/>

 

톰캣의 server.xml 파일에서 현재 웹 프로그램을 나타내는 Context요소에 ResourceLink 요소 추가하기

<ResourceLink global="global_oracle_dbcp"

name="oracle_dbcp"

type="javax.sql.DataSource"/>

 

JNDI(Java Naming and Directory Interface)

- 자바 프로그램 외부에 있는 자원을 사용 (lookup)하기 위해 지원되는 기술

- DBCP 에서는 톰캣의 server.xml 파일에 저장된 리소스 정보를 가져오기 위해 사용

- Context: JNDI에서 객체를 저장하고 검색하는데 사용되는 기본적인 인터페이스

- lookup(String name):지정된 이름으로 바인딩된 객체를 검색함

- InitialContext: Context 인터페이스를 구현한 기본 클래스. 애플리케이션이 JNDI 서비스를 처음 사용할 때 생성

JNDI를 사용하는데 필요한 환경 설정을 가져옴

- java: comp/env: 톰캣에 의해 제공되는 자원을 참조할 수 있는 컨텍스트

 

 

톰캣 Server.xml파일에 추가된 뉴 프로젝트  <contents></contents> 사이에

ResourceLink 요소를 추가 했더니! DBCP연결이 되었다.

(간단한 오류였지만, DB연결이 안된다고 눈 앞이 캄캄해지는 삐약이)

 

 

 

🥓🥓회원정보 입력 중 예외 발생ORA-00904:

첫 번째로 마주한 오류
ORA-01400: cannot insert NULL into ("WEB_DEV"."M_MEMBER"."M_EMAIL")라는 오류가 발생하고 있습니다. = m_email 필드에 NULL 값을 삽입할 수 없다.

당연하지. 테이블 짤 때 email은 not null로 만들었으니까!!!

 

DTO는 private String m_email;//이메일 이렇게 설정을 했는데 왜 자꾸 null값 오류가 나는지 

이해할 수 없었다.

일단 예외 처리에서 정확히 이메일에서 오류가 나는 게 맞는지

} catch (Exception e) {
    System.out.println("회원정보 입력 중 예외 발생: " + e.getMessage());
    e.printStackTrace();

e.getMessage()를 추가했다. 

 

정말 이메일을 null값으로 받아오고 있었다. 

DAO와 DTO 그리고 joinprocess.jsp를 살펴보았다.

 

일단 DTO를 다시 정의했다. 

그리고 DAO에서 SQL객체를 생성할 때

String sql = "INSERT INTO m_member (m_email, m_password, m_nickname, m_status, m_registration_type) VALUES (?, ?, ?, ?, ?)";

내가 Values의 값을 너무 많이 넣어서 

too many values java.sql.SQLSyntaxErrorException: ORA-00913: too many values

이런 오류가 나왔었다.

 

DAO도 DTO에 맞춰서 다시 생성하고

joinProcess.jsp에서도 다시 만든 코드들로 정리를 해보았다.

String email = request.getParameter("email"); // 사용자가 입력한 이메일 값
String password = request.getParameter("password"); // 사용자가 입력한 비밀번호 값
String nickname = request.getParameter("nickname"); // 사용자가 입력한 닉네임 값

// DTO 객체를 생성하여 입력받은 데이터를 저장함
// DTO는 데이터를 캡슐화하고, 해당 데이터를 전송하기 위한 객체임
M_MemberDTO dto = new M_MemberDTO();
dto.setM_email(email); // DTO에 이메일 값 설정
dto.setM_password(password); // DTO에 비밀번호 값 설정
dto.setM_nickname(nickname); // DTO에 닉네임 값 설정


결론은 디비에 테이블 생성 시 모든 컬럼들을 DTO에 정의했었으나

그럴 필요가 없었고, 딱 내가 사용할 객체들만 생성했다. 

그에 맞게 DAO insert를 수정했어야 했는데, values값을 제대로 확인하지 못해서 생긴 오류이다.

 

DAO- try catch문 안에 e.getMessage();를 통해 정확한 오류를 파악하는 데 큰 도움이 되었다.

 catch (Exception e) {
        System.out.println("회원정보 입력 중 예외 발생: " + e.getMessage());
        e.printStackTrace(); // 예외의 자세한 스택 트레이스를 출력

 

 

 

 

그리고 또 하나 궁금했던 점.

(초큼 늦은 감이 없지않아 있지만)

 

String email 대신 String m_email을 사용하지 않는 이유

내 디비테이블 컬럼명하고 언제 다르게 쓰는 지가 명확하게 궁금했다.

String email = request.getParameter("email");
String password = request.getParameter("password");
String nickname = request.getParameter("nickname");

M_MemberDTO dto = new M_MemberDTO();
dto.setM_email(email);
dto.setM_password(password);
dto.setM_nickname(nickname);

 

Java 변수명

email, password, nickname 등은 사용자가 입력한 데이터를 담고 있는 Java 변수

 

예를 들어, request.getParameter("email")에서 가져온 값을 String email 변수에 저장

 

변수와 DTO 매핑

M_MemberDTO 객체를 생성할 때,

dto.setM_email(email)과 같은 코드로 Java 변수(email)의 값을 DTO의 필드(m_email)에 할당.

여기서 setM_email 메서드는 DTO의 m_email 필드에 값을 저장

DTO 객체가 데이터베이스에 저장될 데이터를 포함

 

= Java 코드에서 변수명과 데이터베이스 컬럼명을 분리하여, 코드의 가독성과 유지보수성 향상

Java 변수 email, password, nickname은 주로 비즈니스 로직이나 사용자 입력 처리에 사용되고,

DTO는 데이터베이스와의 상호작용에 사용되는 구조이다

 

 

 

쫑알쫑알

오늘 읽은 책에서 

백엔드 엔지니어의 실력은 얼마나 많은 오류와 장애를 만나고 이를 해결했는지 여부에 갈린다.

라고 했다. 

백엔드 엔지니어가 되기 위한 여정에서

당연히 오류를 많이 만나고

오류를 해결하는 과정이 중요하다는 걸 다시 한 번 깨닫는다.

오류야 덤벼! 내가 다 해결해볼게! 나만 믿어! 오류를 해결하면 정확한 흐름을 읽기 좋아서

나 같이 수학의 정석을 좋아하는 st 만족스런 공부과정이닷.