📝 TIL

[TIL] JSP로 CRUD 구현

오늘 ONEUL 2022. 6. 14. 21:33

✍ Today I Learned

 

[Log 템플릿 설정]

  • SLF4J로 로깅하기 위해 다음의 코드를 템플릿으로 설정한다.
    Window → Prdferences → Java → Code Style → Code Templates → Code
    New Java files → Edit
${filecomment}
${package_declaration}
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
${typecomment}
${type_declaration}
  • Class body → Edit
private static Logger log = LoggerFactory.getLogger(${type_name}.class);
  • Java 파일을 생성하면 다음과 같이 템플릿이 적용되어 생성된다.
package action.emp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Test {
	private static Logger log = LoggerFactory.getLogger(Test.class);
}

 

[JNDI]

  • JNDI(Java Naming and Directory Interface API)란? 디렉터리 서비스에서 제공하는 데이터 및 객체를 발견(discover)하고 참고(lookup) 하기 위한 자바 API다. 간단히 말하면, 연결하고 싶은 데이터베이스의 DB Pool을 미리 Naming 시켜주는 방법 중 하나이다. (참고자료)
  • src > main > webapp > WEB-INF > web.xml 파일을 다음과 같이 작성한다.
... web.xml
<resource-ref>
	  <description>DBCP Config</description>
	  <res-ref-name>jdbc/mysql</res-ref-name>
	  <res-type>javax.sql.DataSource</res-type>
	  <res-auth>Container</res-auth>
</resource-ref>
  • DB와 연결하는 DBConnector.java 파일을 다음과 같이 작성한다.
package repository;

import java.sql.Connection;
import java.sql.SQLException;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class DBConnector {
	private static Logger log = LoggerFactory.getLogger(DBConnector.class);
	
	public static Connection getConnection() {
		Connection cn = null;
		try {
			Context initContext = new InitialContext();
			Context envContext = (Context) initContext.lookup("java:/comp/env"); // 기본 설정값
			DataSource ds = (DataSource) envContext.lookup("jdbc/mysql"); // 직접 설정한 name
			
			try { // 한번 더 try-catch 해준다
				cn = ds.getConnection();
			} catch (SQLException e) {
				log.info(">>> DB 연결정보 오류");
				e.printStackTrace();
				return null;
			}
		} catch (NamingException e) {
			log.info(">>> DBCP 설정 오류");
			e.printStackTrace();
			return null;
		}
		return cn;
	}
}

 

[데이터베이스 생성]

  • DBeaver에서 jspdb와 jspuser를 생성 후 jspuser에 전체 권한을 부여한다.
  • src > main > webapp에 schema.sql 파일을 생성하고 DBeaver에서 가져온 DDL 정보를 기록해둔다.
  • EMP 테이블을 가져와 jspdb에 생성한다.

 

[VO 객체 생성]

  • 물리적 데이터를 만들었으니 VO 객체를 생성한다.
  • VO(Value Object)는 데이터베이스의 데이터 테이블 기준으로 같은 명칭을 사용하여 변수를 정의함으로써 데이터의 정확성을 높이는 작업이다. 서비스에 필요한 데이터를 통일된 형식으로 관리한다.
  • Register, List, Modify, Detail 상황별 생성자를 만들고 Getter, Setter를 생성한다.

 

[부트스트랩 설정]

  • 반응형을 위해 meta 태그를 추가한다.
  • header.jsp에 부트스트랩 소스를 임포트 한다. 이때, 로케이터가 설정되어있지 않기 때문에 폴더 내의 부트스트랩 소스를 이용하면 오류가 난다. cdn을 이용하도록 하자.
<meta name="viewport" content="width=device-width, inital-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.2/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.2/dist/js/bootstrap.bundle.min.js"></script>

 

[테스트해보기]

  • 톰캣 포트를 8088로 설정한다.
  • Project 우클릭 → Run as → Run On Server를 클릭하여 테스트를 진행한다.

 

[Register(Insert)]

  • 부트스트랩의 nav 템플릿을 가져와 nav bar를 만들고, forms 템플릿을 가져와 register.jsp를 작성한다. 이때, form태그 내 aciton의 주소 값은 "./insert.em"으로, method 값은 "post"로 설정한다.
  • EmpController에서 switch문을 이용하여 분기 처리를 해준다. Controller는 분기 처리만 담당할 수 있도록 그 외의 일은 Action객체를 생성하여 처리한다.
  • register.jsp에서 입력받은 데이터를 다음과 같은 순서로 전달한다.
    Controller → Action(여기서 데이터를 EmpVO 객체로 만듦) → Service → DAO → 데이터베이스에 Insert 후 성공 여부(0 or 1)를 로그에 출력하고, list.jsp로 이동한다.

 

  • EmpDAOImpl를 static으로 올리지 않아도 되는 이유는? DatabaseConnector 연결을 DBCP가 처리해주기 때문이다. JDBC는 사용자가 직접 연결해야 했다면 지금은 사용자가 DBCP의 주소만 확보하고 있으면 된다.

 

[List(SelectList)]

  • Insert 후에 List를 볼 수 있도록 destPage를 "list.em"으로 설정하고, 다음과 같은 순서로 요청한다.
    Controller → Action→ Service → DAO → 데이터베이스에서 Select 후 EmpVO 객체의 리스트를 다시 list.jsp까지 전달한다.
  • list.jsp에서 기존에 쓰던 스크립틀릿 대신 JSTL EL 태그를 이용한다. EL태그로 VO 객체를 사용할 때, VO객체의 변수명만 작성해도 Getter 메서드를 호출하도록 매핑되어있다.
<c:forEach items="${list}" var="evo">
<tr>
  <td>${evo.empno}</td>
  <td><a href="./detail.em?empno=${evo.empno }">${evo.ename}</a></td>
  <td>${evo.hiredate}</td>
  <td>${evo.deptno}</td>
</tr>
</c:forEach>