JSP 스터디
JSP 스터디 내용을 요약하여 include 액션 태그, forward, Java Beans, DB 저장, 그리고 Connection Pool에 대해 자세히 알아보겠습니다.
1. include 액션 태그 VS include 페이지 디렉티브
include 액션 태그 : <jsp:include page="example.jsp"></jsp:include>
- example.jsp 를 먼저 컴파일 한 후, 원본 파일에 합쳐 컴파일한다. (컴파일 횟수 2번)
- Rails에서 사용하던 <%= render %> 과 비슷한 형태
- <jsp:param name="id" value="exampleId"></jsp:param> 의 형태로 파라미터를 넘길 수 있다.
include 페이지 디렉티브 : <@include file="example.jsp">
- example.jsp 의 내용을 그대로 원본 파일로 불러들어온 후, 원본 파일을 컴파일한다. (컴파일 횟수 1번)
2. jsp:forward VS request.sendRedirect("example.jsp")
<jsp:forward file="example.jsp"></jsp:forward>
- 원본 페이지에서 유지하고 있던 파라미터를 유지한 상태에서 example.jsp 로 전환할 수 있다.
- 원본 페이지의 URI 를 유지한 채, 내용만 example.jsp 로 전환할 수 있다.
request.sendRedirect("example.jsp");
- JS 의 window.location.href="/url" 과 같이, redirect 를 발생시킨다고 볼 수 있다.
- 원본 페이지에서 유지하고 있던 파라미터를 유지할 수 없다.
3. Java Beans
- DB 에 있던 데이터들을 불러와서, 데이터를 DB의 구조에 맞게 자바 Class로 변환한 후, 가변 자료구조 (ArrayList) 에 저장하여 사용한다.
- Java Resources 디렉토리의 src 에서 생성한 후 작업해야 한다.
package bean;
public class MemberBean {
// getter, setter 생략
// 데이터베이스의 column name 과 변수 이름이 같아야 한다.
private String id;
private String pass1;
private String email;
private String tel;
private String address;
}
<!-- request 로 넘어온 데이터를 자바 빈즈와 매핑시켜주는 useBean -->
<!-- MemberBean mbean = new MemberBean() -->
<jsp:useBean id="mbean" class="bean.MemberBean">
<!-- property 에 하나씩 beans 의 property 를 매칭 시켜 준다 -->
<jsp:setProperty name="mbean" property="id" />
<!-- 자동으로 데이터를 매핑시켜 준다. -->
<jsp:setProperty name="mbean" property="*" />
</jsp:useBean>
<%
// 파라미터로 넘어온 hobby 를 반복문을 돌며 값을 넣어준다.
String[] hobby = request.getParameterValues("hobby");
String textHobby = "";
for(int i = 0 ; i < hobby.length ; i++){
textHobby += hobby[i] + " ";
}
mbean.setHobby(textHobby);
%>
<!-- jsp getProperty -->
<h2><jsp:getProperty property="id" name="mbean"/></h2>
<h2><jsp:getProperty property="pass1" name="mbean"/></h2>
<h2><jsp:getProperty property="email" name="mbean"/></h2>
<!-- class 매소드를 이용한 방법 -->
<%= mbean.getAddress() %>
3. Form 에서 넘어온 데이터를 db 에 저장하기
try {
// 해당 db 를 접속한다고 선언 (드라이버 로드)
Class.forName("oracle.jdbc.driver.OracleDriver");
// 해당 데이터베이스에 접속
Connection con = DriverManager.getConnection(url, id, pass);
// 쿼리를 사용하도록 설정
String sql = "INSERT INTO MEMBER VALUES(?, ?, ?, ?, ?, ?, ?, ?)";
// 쿼리를 사용하도록 설정
PreparedStatement pstmt = con.prepareStatement(sql);
pstmt.setString(1, mbean.getId());
pstmt.setString(2, mbean.getPass1());
pstmt.setString(3, mbean.getEmail());
pstmt.setString(4, mbean.getTel());
pstmt.setString(5, mbean.getHobby());
pstmt.setString(6, mbean.getJob());
pstmt.setString(7, mbean.getAge());
pstmt.setString(8, mbean.getInfo());
System.out.println(mbean.getPass1());
// 쿼리 실행하기
pstmt.executeUpdate(); // CUD 에서 사용함
con.close();
} catch(Exception e) {
e.printStackTrace();
}
4. Connection Pool (DBCP)
- JDBC 를 통하여 DB 에 연결하기 위해서는 드라이버를 로드하고, 커넥션 객체를 받아와야 한다.
- JDBC 를 사용하면 사용자가 요청을 할 대마다 매번 드라이버를 로드하고 커넥션 객체를 생성하여 연결하고 종료하기 때문에, 매우 비효율적이다. (효울성 측면에서)
- 이러한 문제를 해결하기 위해 Connection Pool 이라는 개념이 나타나게 되었다.
- 웹 컨테이너가 실행되면서 Connection 객체를 미리 Pool 에 생성해 둔다.
- DB 와 연결된 Connection 을 미리 생성해 두기 때문에, 서비스에서 필요할 때에 가져다 쓰고 반환한다.
- 미리 생성해두기 때문에, DB에 부하를 줄이고 유동적으로 연결을 관리할 수 있다.
<server.xml>
<Resource name="jdbc/pool" auth="Container" type="javax.sql.DataSource" driverClassName="oracle.jdbc.driver.oracleDriver" loginTimeout="10" maxWait="5000" username="system" password="password" url="jdbc:oracle:thin:@127.0.0.1:1521:xe"/>
<!-- name : pool 의 이름, auth: Container 가 관리한다. (드라이버 로드, 연결에 했던 작업들을 server.xml 에서 수행한다.) -->
<Java Class File>
public void getCon() {
try {
Context initctx = new InitialContext();
Context envctx = (Context)initctx.lookup("java:comp/env");
DataSource ds = (DataSource)envctx.lookup("jdbc/pool");
con = ds.getConnection();
} catch(Exception e) {
e.printStackTrace();
}
// 드라이버를 로드하고, 직접 접속하는 방식
try {
// 해당 db 를 접속한다고 선언 (드라이버 로드)
Class.forName("oracle.jdbc.driver.OracleDriver");
// 해당 데이터베이스에 접속
this.con = DriverManager.getConnection(url, id, pass);
} catch(Exception e) {
e.printStackTrace();
}
}
import java.sql.Connection;
import java.sql.SQLException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
public class DBConnection
{
public static Connection getConnection() throws SQLException, NamingException,
ClassNotFoundException{
Context initCtx = new InitialContext();
//initCtx의 lookup메서드를 이용해서 "java:comp/env" 에 해당하는 객체를 찾아서 evnCtx에 삽입
Context envCtx = (Context) initCtx.lookup("java:comp/env");
//envCtx의 lookup메서드를 이용해서 "jdbc/orcl"에 해당하는 객체를 찾아서 ds에 삽입
DataSource ds = (DataSource) envCtx.lookup("jdbc/orcl");
//getConnection메서드를 이용해서 커넥션 풀로 부터 커넥션 객체를 얻어내어 conn변수에 저장
Connection conn = ds.getConnection();
return conn;
/*
* 위의 코드를 아래와 같이 줄여서 작성 가능하다.
Context context = new InitialContext();
DataSource dataSource = (DataSource) context.lookup("java:comp/env/jdbc/oracle");
Connection con = dataSource.getConnection();
*/
}
}
이것도 읽어보세요