Java파일

ProductBean.java

더보기
더보기
더보기
package myPkg;

public class ProductBean {
	private int id;
    private String name;
    private int price;
    private String company;
    private String regdate;
    
    public ProductBean() {
    	
    }
	public ProductBean(int id, String name, int price, String company, String regdate) {
		super();
		this.id = id;
		this.name = name;
		this.price = price;
		this.company = company;
		this.regdate = regdate;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getPrice() {
		return price;
	}
	public void setPrice(int price) {
		this.price = price;
	}
	public String getCompany() {
		return company;
	}
	public void setCompany(String company) {
		this.company = company;
	}
	public String getRegdate() {
		return regdate;
	}
	public void setRegdate(String regdate) {
		this.regdate = regdate;
	}
    
}

 

ProductDao.java

더보기
더보기
더보기
package myPkg;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

public class ProductDao {

	String driver = "oracle.jdbc.driver.OracleDriver";
	String url = "jdbc:oracle:thin:@localhost:1521:orcl";
	String id = "sqlid";
	String pw = "sqlpw";
	Connection conn = null;
	PreparedStatement ps = null;
	ResultSet rs = null;

	private static ProductDao pdao = new ProductDao();
	public static ProductDao getInstance() {
		return pdao;
	}

	private ProductDao() {
		try {
			Class.forName(driver);
			conn = DriverManager.getConnection(url, id, pw);
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}//
	
	public int insertProduct(ProductBean pb){
		int cnt = -1;
		String sql = "insert into products values(seqprd.nextval,?,?,?,sysdate)";
		try {
			ps = conn.prepareStatement(sql);
			ps.setString(1, pb.getName());
			ps.setInt(2, pb.getPrice());
			ps.setString(3, pb.getCompany());
			
			cnt = ps.executeUpdate();
			
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				if(ps != null)
					ps.close();
				
			}catch(SQLException e) {
				
			}
		}
		return cnt;
		
	}//insertProduct

	public ArrayList<ProductBean> getAllProduct(){
		ArrayList<ProductBean> lists = new ArrayList<ProductBean>();
		String sql = "select * from products order by id";
		try {
			ps = conn.prepareStatement(sql);
			rs = ps.executeQuery();
			while(rs.next()) {
				ProductBean pb = new ProductBean();
				pb.setId(rs.getInt("id"));
				pb.setName(rs.getString("name"));
				pb.setCompany(rs.getString("company"));
				pb.setPrice(rs.getInt("price"));
				pb.setRegdate(String.valueOf(rs.getDate("regdate")));
				lists.add(pb);				
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}finally {
			try {
				if(rs != null)
					rs.close();
				if(ps != null)
					ps.close();
			}catch(SQLException e) {
				
			}
		}
		return lists;
	}//getAllProduct
	
	public ProductBean getOneProduct(String id){
		ProductBean pb = null;
		String sql = "select * from products where id=?";
		try {
			ps = conn.prepareStatement(sql);
			ps.setString(1, id);
			rs = ps.executeQuery();
			while(rs.next()) {
				pb = new ProductBean();
				pb.setId(rs.getInt("id"));
				pb.setName(rs.getString("name"));
				pb.setCompany(rs.getString("company"));
				pb.setPrice(rs.getInt("price"));
				pb.setRegdate(String.valueOf(rs.getDate("regdate")));
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}finally {
			try {
				if(rs != null)
					rs.close();
				if(ps != null)
					ps.close();
			}catch(SQLException e) {
				
			}
		}
		return pb;
	}//getOneProduct
	
	public int updateProduct(ProductBean pb) {
        int cnt = -1;

        try {
            String sql = "update products set name=?, price=?, company=? where id=?";
            ps = conn.prepareStatement(sql);
            ps.setString(1, pb.getName());
            ps.setInt(2, pb.getPrice());
            ps.setString(3, pb.getCompany());
            ps.setInt(4, pb.getId());

            cnt = ps.executeUpdate();

        } catch(SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                if(ps != null) {
                    ps.close();
                }
            } catch(SQLException e) {
                e.printStackTrace();
            }
        }

        System.out.println("update: " + cnt);
        return cnt;
    }//updateProduct
	
	public int deleteProduct(int id) {
        int cnt = -1;

        try {
            String sql = "delete from products where id=?";

            ps = conn.prepareStatement(sql);
            ps.setInt(1, id);

            cnt = ps.executeUpdate();
        } catch(SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                if(ps != null) {
                    ps.close();
                }
            } catch(SQLException e) {
                e.printStackTrace();
            }
        }

        System.out.println("delete: " + cnt);
        return cnt;
    }//eleteProduct
}

 

 

ProductController.java(서블릿 파일)

더보기
더보기
더보기
package myPkg;

import java.io.IOException;
import java.util.ArrayList;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("*.prd") // 주의!!!
public class ProductController extends HttpServlet {
	private static final long serialVersionUID = 1L;
	ServletContext application;   

    public ProductController() {
        super();
    }
    //ServletContext application = new ServletContext() 프로젝트당 1개 생성
    //ServletConfig config = new ServletConfig() : 서블릿당 1개 생성
    public void init(ServletConfig config) throws ServletException {
		System.out.println("init()");
		application = config.getServletContext();	
	}
    
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doAction(request,response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doAction(request,response);
	}

	private void doAction(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		ProductDao pdao = ProductDao.getInstance();
		System.out.println("pdao:" + pdao);
		
		request.setCharacterEncoding("UTF-8");
		
		String uri = request.getRequestURI();
		String contextPath = request.getContextPath();
		int length = contextPath.length();
		String command = uri.substring(length);
		System.out.println("method:"+request.getMethod());
		String page;
//		insert.prd요청은 insertForm.jsp에서 submit클릭했을 때 요청할 수 있고, (DB insert)
//		list.jsp에서 새로고침했을 때 insert.prd요청 할수 있다.(DB insertX)
		
		if(command.equals("/insert.prd")) {
            System.out.println("insert.prd 요청");
            
            System.out.println("flag:"+application.getAttribute("flag"));
            if(application.getAttribute("flag").equals("false")) { // insertForm.jsp submit클릭해서 요청
            	 String name = request.getParameter("name");
                 int price = Integer.parseInt(request.getParameter("price"));
                 String company = request.getParameter("company");
                 ProductBean pb = new ProductBean(0,name,price,company,null);
                 int cnt = pdao.insertProduct(pb);
                 application.setAttribute("flag","true");
                 page = "select.prd";
                 
            }else {
            	 page = "select.prd";
            }
           
        }
        else if (command.equals("/updateForm.prd")) {
            System.out.println("updateForm.prd 요청");
            String id = request.getParameter("id");
            ProductBean pb = pdao.getOneProduct(id);
            request.setAttribute("pb", pb);
            page = "updateForm.jsp";
        }
        else if (command.equals("/update.prd")) {
            System.out.println("update.prd 요청");
            
            //입력3 + hidden1
            int id = Integer.parseInt(request.getParameter("id"));
            String name = request.getParameter("name");
            int price = Integer.parseInt(request.getParameter("price"));
            String company = request.getParameter("company");
            ProductBean pb = new ProductBean(id,name,price,company,null);
            
            int cnt = pdao.updateProduct(pb); 
            page = "/select.prd";
        }
        else if (command.equals("/delete.prd")) {
            System.out.println("delete.prd 요청");
            int id = Integer.parseInt(request.getParameter("id"));
            int cnt = pdao.deleteProduct(id); 
            page = "/select.prd";
        } 
        else { // select.prd 
            System.out.println("select.prd 요청");
            ArrayList<ProductBean> lists = pdao.getAllProduct();
            request.setAttribute("lists", lists);
            page = "list.jsp";
        }

        RequestDispatcher dispatcher = request.getRequestDispatcher(page);
        dispatcher.forward(request, response);
        System.out.println("-----------");
	}

}

insertForm.jsp

더보기
더보기
더보기
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
   
 <%
 	application.setAttribute("flag", "false");
 // 한 프로젝트에서 변수를 설정해서 사용할거라면 그 프로젝트 안에서 flag가 false가 들어있는것을 모든 파일에서 사용
 %>  
    
<form action="insert.prd" method ="post">
<b>상품 정보 입력</b><br>
    상품명 : <input type="text" name="name" value="새우깡"><br>
    가격 : <input type="text" name="price" value="1000"><br>
    제조사 : 
    <select name="company">
        <option value="농심">농심</option>
        <option value="해태">해태</option>
        <option value="오리온">오리온</option>
        <option value="롯데">롯데</option>
    </select>
    <br><br>
    <input type="submit" value="전송">
</form>

list.jsp

더보기
더보기
더보기
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>    
    
list.jsp<br>
<!-- ArrayList<> lists = pdao.selectAll() 
for(x : lists){
}
-->

<table border="1" width="500px">
	<tr>
		<th>아이디</th>
		<th>이름</th>
		<th>제조사</th>
		<th>단가</th>
		<th>입고일자</th>
		<th>수정</th>
		<th>삭제</th>
	</tr>
	<c:forEach var="p" items="${lists}">
		<tr>
			<td>${p.getId()}</td>
	        <td>${p.name }</td>
	        <td>${p['price']}</td>
	        <td>${p.getCompany()}</td>
	        <td>${p.getRegdate()}</td>
			<td><a href="updateForm.prd?id=${p.getId()}">수정</a></td>
			<td><a href="delete.prd?id=${p.getId()}">삭제</a></td>
		</tr>	
	</c:forEach>
</table>
<br>
<a href="insertForm.jsp">삽입</a>

 

updateForm.jsp

더보기
더보기
더보기
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> 
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>

updateForm.jsp<br>    

<form action="update.prd" method ="post">
<input type="hidden" name="id" value="${pb.id}">
<b>상품 정보 수정</b><br>
    상품명 : <input type="text" name="name" value=""><br>
    가격 : <input type="text" name="price" value=""><br>
    제조사 : 
    <select name="company">

    <%
    String[] company = {"농심", "해태", "오리온", "롯데"};     
    %>   
    <c:forEach var="com" items="<%=company %>">
  			<option value="${com}" <c:if test="${pb.company==com}"> selected</c:if>>${com}</option>
    </c:forEach>
    </select>
    <br><br>
    <input type="submit" value="전송">
</form>

Servlet 서블릿이란?

  • 자바 클래스 형태의 웹 어플리케이션
  • 웹 응용프로그램을 만들어내기 위한 자바 클래스 기술
  • 클라이언트(보통 웹 브라우저) 요청을 받아서 처리하고, 그 결과를 응답으로 돌려주는 역할
  • Tomcat과 같은 WAS(Web Application Server)위에서 동작

✅ JSP → Servlet 변환 경로

JSP 파일 (Ex01.jsp)
      ↓   [톰캣 변환]
서블릿 파일 (Ex01_jsp.java)
      ↓   [컴파일]
클래스 파일 (Ex01_jsp.class)
      ↓   [실행 - JVM]
브라우저에 HTML 결과 출력

 

 

C:\JSP_ljr\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\work\Catalina\localhost

 

서블릿 파일 경로 : 

C:\JSP_ljr\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\work\Catalina\localhost\07_EL_JSTL\org\apache\jsp

C:\JSP_ljr\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\
   └─ work\
      └─ Catalina\
         └─ localhost\
            └─ 07_EL_JSTL\        ← 프로젝트(웹 애플리케이션) 컨텍스트 루트
               └─ org\
                  └─ apache\
                     └─ jsp\
                        Ex06_005fresult_jsp.java   ← 변환된 서블릿 파일
                        Ex06_005fresult_jsp.class  ← 컴파일된 클래스 파일

 

 

더보기

서블릿 컴파일

 

JSB ==> JAVA

컴파일이 되어 class확장자(기계언어)로 바뀜

/*
 * Generated by the Jasper component of Apache Tomcat
 * Version: Apache Tomcat/9.0.80
 * Generated at: 2025-09-16 06:17:07 UTC
 * Note: The last modified time of this file was set to
 *       the last modified time of the source file after
 *       generation to assist with modification tracking.
 */
package org.apache.jsp;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;

public final class Ex06_005fform_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent,
                 org.apache.jasper.runtime.JspSourceImports {

  private static final javax.servlet.jsp.JspFactory _jspxFactory =
          javax.servlet.jsp.JspFactory.getDefaultFactory();

  private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;

  private static final java.util.Set<java.lang.String> _jspx_imports_packages;

  private static final java.util.Set<java.lang.String> _jspx_imports_classes;

  static {
    _jspx_imports_packages = new java.util.HashSet<>();
    _jspx_imports_packages.add("javax.servlet");
    _jspx_imports_packages.add("javax.servlet.http");
    _jspx_imports_packages.add("javax.servlet.jsp");
    _jspx_imports_classes = null;
  }

  private volatile javax.el.ExpressionFactory _el_expressionfactory;
  private volatile org.apache.tomcat.InstanceManager _jsp_instancemanager;

  public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
    return _jspx_dependants;
  }

  public java.util.Set<java.lang.String> getPackageImports() {
    return _jspx_imports_packages;
  }

  public java.util.Set<java.lang.String> getClassImports() {
    return _jspx_imports_classes;
  }

  public javax.el.ExpressionFactory _jsp_getExpressionFactory() {
    if (_el_expressionfactory == null) {
      synchronized (this) {
        if (_el_expressionfactory == null) {
          _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
        }
      }
    }
    return _el_expressionfactory;
  }

  public org.apache.tomcat.InstanceManager _jsp_getInstanceManager() {
    if (_jsp_instancemanager == null) {
      synchronized (this) {
        if (_jsp_instancemanager == null) {
          _jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
        }
      }
    }
    return _jsp_instancemanager;
  }

  public void _jspInit() {
  }

  public void _jspDestroy() {
  }

  public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
      throws java.io.IOException, javax.servlet.ServletException {

    if (!javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
      final java.lang.String _jspx_method = request.getMethod();
      if ("OPTIONS".equals(_jspx_method)) {
        response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
        return;
      }
      if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method)) {
        response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
        response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSP들은 오직 GET, POST 또는 HEAD 메소드만을 허용합니다. Jasper는 OPTIONS 메소드 또한 허용합니다.");
        return;
      }
    }

    final javax.servlet.jsp.PageContext pageContext;
    javax.servlet.http.HttpSession session = null;
    final javax.servlet.ServletContext application;
    final javax.servlet.ServletConfig config;
    javax.servlet.jsp.JspWriter out = null;
    final java.lang.Object page = this;
    javax.servlet.jsp.JspWriter _jspx_out = null;
    javax.servlet.jsp.PageContext _jspx_page_context = null;


    try {
      response.setContentType("text/html; charset=UTF-8");
      pageContext = _jspxFactory.getPageContext(this, request, response,
      			null, true, 8192, true);
      _jspx_page_context = pageContext;
      application = pageContext.getServletContext();
      config = pageContext.getServletConfig();
      session = pageContext.getSession();
      out = pageContext.getOut();
      _jspx_out = out;

      out.write("\r\n");
      out.write("    \r\n");
      out.write("    \r\n");
      out.write("<form action=\"Ex06_result.jsp\">\r\n");
      out.write("    <input type=\"checkbox\" name=\"fruit\" value=\"포도\" checked=\"checked\">포도\r\n");
      out.write("    <input type=\"checkbox\" name=\"fruit\" value=\"사과\" checked=\"checked\">사과\r\n");
      out.write("    <input type=\"checkbox\" name=\"fruit\" value=\"수박\">수박\r\n");
      out.write("    <input type=\"submit\" value=\"전송\">\r\n");
      out.write("</form>");
    } catch (java.lang.Throwable t) {
      if (!(t instanceof javax.servlet.jsp.SkipPageException)){
        out = _jspx_out;
        if (out != null && out.getBufferSize() != 0)
          try {
            if (response.isCommitted()) {
              out.flush();
            } else {
              out.clearBuffer();
            }
          } catch (java.io.IOException e) {}
        if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
        else throw new ServletException(t);
      }
    } finally {
      _jspxFactory.releasePageContext(_jspx_page_context);
    }
  }
}

 

1. Servlet파일 생성하기

 

 

 

2. Servlet파일 실행

Servlet은 Run As로 실행해야한다.

 

 

2. Servlet파일 실행 - url mapping

 

Servlet 생명주기 전체 그림 (생성자 → init → doGet/doPost → destroy)

최초 요청:   생성자 → init() → doGet()/doPost()
이후 요청:   doGet()/doPost()만 실행
코드 변경:   destroy() 호출 → 객체 소멸
다시 요청:   새 객체 생성 → init() 실행 → doGet()/doPost()
package myPkg;

import java.io.IOException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class HelloServlet
 */
@WebServlet("/hi") // 요청명 (url mapping)
public class HelloServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

    /**
     * Default constructor. 
     */
    public HelloServlet() {
        System.out.println("HelloServlet() 생성자");
    }

	/**
	 * @see Servlet#init(ServletConfig)
	 */
	public void init(ServletConfig config) throws ServletException {
		 System.out.println("init 메서드");
	}

	/**
	 * @see Servlet#destroy()
	 */
	public void destroy() {
		 System.out.println("destroy 메서드");
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		 System.out.println("doGet() 메서드");
		response.getWriter().append("Served at: ").append(request.getContextPath());
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("doPost() 메서드");
	}

}

 


 

서블릿 파일

Test.java

@WebServlet("/test.do")

 

package myPkg;

import java.io.IOException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class Test
 */

// @:annotaion
@WebServlet("/test.do")
public class Test extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public Test() {
        super();
        System.out.println("Test");
    }

	/**
	 * @see Servlet#init(ServletConfig)
	 */
	public void init(ServletConfig config) throws ServletException {
		 System.out.println("init");
	}

	/**
	 * @see Servlet#destroy()
	 */
	public void destroy() {
		 System.out.println("destroy");
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		 System.out.println("doGet");
		response.getWriter().append("Served at: ").append(request.getContextPath());
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("doPost");
		doGet(request, response);
	}

}

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<script type="text/javascript">
	function movePage(){
		location.href = "test.do";
	}
</script>

<a href="test.do">링크</a><br>
<br><hr>

<input type="button" value="요청" onClick="movePage()">

<form method="get" action="test.do">
	<input type="submit" value="호출1">
</form>

<form method="post" action="test.do">
	<input type="submit" value="호출2">
</form>

 

Servlet get방식 목록 📌 Servlet GET 방식 요청 방법
1. 1. <a> 태그 (HTML 하이퍼링크) :  a태그 <a href="helloServlet?name=iu&age=30">링크 클릭</a>
2. 주소창에 요청명 직접 쓰기 http://localhost:8080/myweb/helloServlet?name=iu&age=30
3. location 객체를 통한 요청  location.href = "helloServlet?name=iu&age=30";
4. form method = "get" <form method="get">

 

 


🌈 Servlet 예제: insertServlet (데이터 전달 → JSP 출력) - 예제1

insertform.jsp (입력폼)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

    <form action="insert.per" method="post"> 
    	이름 : <input type="text" name="name"><br>
    	<input type="submit" value="전송">
    </form>
    
   <!--  servlet으로 넘어갔다 => 응답형태로 console로 출력 -->

insertForm에서 정보를 입력하면 ==> servalet 으로 이동 ==> p 변수를 통해  result.jsp에 출력

insertServlet.java  (서블릿파일)

@WebServlet("/insert.per")
public class insertServlet extends HttpServlet {

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		
		// 1) 한글 인코딩 처리
		request.setCharacterEncoding("UTF-8");

		// 2) 파라미터 가져오기
		String name = request.getParameter("name");
		System.out.println("name : " + name);

		// 3) 브라우저로 직접 출력 (PrintWriter)
		response.setContentType("text/html; charset=UTF-8");
		PrintWriter pw = response.getWriter();
		pw.print("이름 : " + name);

		// 4) 자바 객체 생성 → request에 저장
		Person per = new Person("태연", 30, 178.3);
		request.setAttribute("p", per);

		// 5) result.jsp로 포워딩
		RequestDispatcher dispatcher = request.getRequestDispatcher("result.jsp");
		dispatcher.forward(request, response);
	}
}

 

 

⚫  request.setCharacterEncoding("UTF-8") → 서블릿 파일에서 POST 한글 처리 필수

⚫  request.getParameter("name") → form에서 넘어온 값 읽기

⚫  request.setAttribute("p", per) → JSP로 객체 전달

⚫  dispatcher.forward(request, response) → 같은 request 객체를 공유하며 이동


result.jsp

<%@page import="myPkg.Person"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
result.jsp<br>
insertForm.jsp => InsertServlet => result.jsp<br>

<!-- Servlet에서 사용한 request객체를 공유한다. == forward Action태그와 같다.  -->  

<!-- 1) 파라미터 직접 읽기 -->
result.jsp name1 : <%=request.getParameter("name") %> <p>   

<%
    // 2) Servlet에서 setAttribute("p", per)로 전달한 객체 꺼내기
    Person obj = (Person)request.getAttribute("p");
    System.out.println("obj.getName : " + obj.getName());
%>

<!-- 3) Person 객체 출력 -->
Person name : <%= obj.getName() %> <p>
Person age : <%= obj.getAge() %><p>
Person height : <%= obj.getHeight() %><p>

 

⚫ request.getParameter("name")
→ form에서 넘어온 단일 입력값을 그대로 읽음

→ 단, forward 된 경우에도 유지됨

 

⚫ request.getAttribute("p")

→ Servlet이 만든 Person 객체를 JSP에서 받음
→ EL 문법을 쓰면 더 간단하게 출력 가능:

 

 

⚫  forward
→ request와 response를 그대로 넘기기 때문에 파라미터와 속성을 둘 다 사용할 수 있음

 

 

🌈 RequestDispatcher vs sendRedirect

  • dispatcher.forward()
    • 서버 내부 이동 (URL 안 바뀜)
    • request / response 객체 그대로 전달
    • equest를 result.jsp와 공유한다. ==>  result.jsp 그대로 전달
    •  "p" 속성도 그대로 살아있음
  • response.sendRedirect()
    • 클라이언트에게 새 요청 보내도록 지시 (URL 바뀜)
    • request 초기화됨 → 데이터 유지 불가

 


 

결과출력

✅예제1 정리

  1. Servlet에서 DB 조회나 로직 처리 → 결과를 per 객체에 담음
  2. request.setAttribute("p", per); 로 JSP에 보낼 데이터 저장
  3. dispatcher.forward(request, response); 로 result.jsp에 포워드
  4. result.jsp에서 ${p} EL로 데이터 출력

 


🌈 Servlet 예제: insertServlet (데이터 전달 → JSP 출력) - 예제2

요청 흐름 : form에 입력한 값 insertServlet → result.jsp

 

 

1. form.jsp (입력 폼 method="post")

프로젝트 파일 Run As --> 주소창에 요청명 입력 --> http://localhost:8080/09_Servlet/form 

 

🔽전체코드

더보기
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
form.jsp<br>


<form method="post" action="insertProc">
	<table border="1">
        <tr>
            <td>이름</td>
            <td><input type="text" name="name"></td>
        </tr>
        <tr>
            <td>나이</td>
            <td><input type="text" name="age">
        </tr>
        <tr>
            <td>성별</td>
            <td><input type="radio" name="gender" value="남자">남자 <input
                type="radio" name="gender" value="여자">여자</td>
        </tr>
        <tr>
            <td>취미</td>
            <td><input type="checkbox" name="hobby" value="독서">독서 
            <input type="checkbox" name="hobby" value="등산">등산 
            <input type="checkbox" name="hobby" value="운동">운동 
            <input type="checkbox" name="hobby" value="낚시">낚시</td>
        </tr>
        <tr>
            <td colspan="2" align="center">
                <input type="submit" value="전송">
                <input type="reset" value="취소">
            </td>
        </tr>
    </table>

</form>

 

2. insertServlet.java (서블릿 파일)

@WebServlet("/insertProc")   // url-pattern 지정
public class insertServlet extends HttpServlet {

    // 기본 생성자
    public insertServlet() {
        super();
    }

    // init() : 최초 요청 시 1번 실행 (초기화 작업)
    public void init(ServletConfig config) throws ServletException {
    }

    // destroy() : 서버 종료 시 실행 (자원 해제)
    public void destroy() {
    }

    // doGet() : GET 방식 요청 처리
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        response.getWriter().append("Served at: ").append(request.getContextPath());
    }

    // doPost() : POST 방식 요청 처리
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        
        // 1) 한글 인코딩 처리
        request.setCharacterEncoding("UTF-8");

        // 2) 클라이언트가 보낸 데이터 받기
        String name = request.getParameter("name");
        int age = Integer.parseInt(request.getParameter("age"));
        String gender = request.getParameter("gender");
        String[] hobby = request.getParameterValues("hobby"); // 체크박스 여러 값

        // 3) MemberBean 객체 생성
        MemberBean mb = new MemberBean(name, age, gender, hobby);

        // 4) request 객체에 저장 (공유)
        request.setAttribute("mb", mb);

        // 5) JSP로 포워딩
        RequestDispatcher dispatcher = request.getRequestDispatcher("result.jsp");
        dispatcher.forward(request, response);
    }
}

 

2. result.jsp

⚫ Servlet에서 전달된 데이터

  • insertServlet → MemberBean 객체(mb)를 request.setAttribute("mb", mb) 로 전달
  • result.jsp에서 request.getAttribute로 객체 꺼내기
  • 또한 form 파라미터(name, hobby)도 함께 넘어옴
<%@page import="myPkg.MemberBean"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>  
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

result.jsp<br>

<%
    // form에서 넘어온 파라미터 배열 (체크박스 같은 경우)
    String[] hobby = request.getParameterValues("hobby");

    // Servlet에서 setAttribute 한 객체 꺼내기
    MemberBean member = (MemberBean)request.getAttribute("mb");

    // JSP의 pageContext에 저장 → EL에서 ${member} 로 접근 가능
    pageContext.setAttribute("member", member);
%>

 

출력방식

✅ 스크립트릿 방식 (Java 코드 직접 사용)

name1: <%= member.getName() %> <br>
name2: <%= request.getParameter("name") %> <br>

✅ EL(Expression Language) 방식

name3: ${param.name} <br>        <!-- 파라미터 바로 출력 -->
name4: ${param['name']} <br>    <!-- 파라미터 대괄호 방식 -->
name5: ${member.name} <br>      <!-- MemberBean getter 호출 -->
name6: ${member['name']} <br>   <!-- Bean 프로퍼티 대괄호 방식 -->

 

✅ hobby 출력 비교 (체크박스)

<!-- 1) 스크립트릿 for문 -->
hobby1 :
<%
    for(String h : hobby){
        out.print(h + " ");
    }
%>

<!-- 2) EL (배열 자체 출력: 주소값 느낌) -->
hobby2 : ${paramValues.hobby} <br>

<!-- 3) JSTL forEach -->
hobby3 :
<c:forEach var="h" items="${paramValues.hobby}" varStatus="ss">
    ${h}
    <c:if test="${not ss.last}">,</c:if>   <!-- 마지막이 아니면 , 출력 -->
</c:forEach>

 

✅핵심 정리

  • 스크립트릿 방식: Java 코드 직접 작성 → 오래된 방식, 지양
  • EL 방식: request 파라미터, 속성, Bean 프로퍼티 접근 가능 → 간결
  • JSTL forEach: 배열·List 반복 처리할 때 가장 깔끔

 

 

✅ 1. EL(Expression Language)이란?

  1. 자바언어를 사용하지 않고 JSP 페이지 작성
  2. JSP 기본문법을 보완하는 스크립트 언어
  3. 간결한 소스 작성
  4. 자바스크립트와 Xpath를 베이스로 설계
  5. Xpath : XML 문서의 정보에 접근하기위해 사용되는 언어

EL의 표현 방법 - 출력

${expr}
<% request.setCharacterEncoding("UTF-8"); %>
<jsp:useBean id="pb" class="myPkg.PersonBean"/>
<jsp:setProperty property="*" name="pb"/>

아이디1: <%=request.getParameter("id") %> <br>
아이디2: ${param.id} <br>
아이디3: <%=pb.getId()%> <br>
아이디4: <jsp:getProperty property="id" name="pb"/> <br>
아이디5: ${pb.id} <br>
아이디6: ${pb['id']} <br>
아이디7: ${param["id"]} <br>

이름: ${param.name} <br>
비밀번호: ${pb.password} <br>
나이: ${param["age"]} <br>

 

 

EL의 표현 방법 - 문자열 연결과 숫자연산

${param.kor} + ${param.eng} + ${param.math} → 문자열 연결

${param.kor + param.eng + param.math} → 숫자 덧셈

 

 

EL의 - 조건문 if

 

JSTL Core 라이브러리 선언

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

 

  • taglib 지시어 → JSP에서 외부 태그 라이브러리(JSTL Core)를 사용 가능하게 선언
  • prefix="c" → c: 라는 별칭으로 JSTL Core 태그를 쓰겠다는 뜻
  • uri="http://java.sun.com/jsp/jstl/core" → JSTL Core 라이브러리의 식별자

🌈정리

  • c:는 반복, 조건, 변수 설정 등 로직 제어용 태그 모음.
  • EL과 함께 쓰면 JSP 스크립트릿(<% %>)을 거의 안 써도 됨.

 

<c:if test="${avg>=90}">
    A학점
</c:if>
<c:if test="${avg>=80 and avg<90}">
    B학점
</c:if>
<c:if test="${avg>=70 and avg<80}">
    C학점
</c:if>
<c:if test="${avg>=60 and avg<70}">
    D학점
</c:if>
<c:if test="${avg<60}">
    F학점
</c:if>

 

  • c:if : 조건이 참일 때만 출력
  • EL 연산자
    • and, or, not → 논리연산
    • eq, ne, lt, gt, le, ge → 비교연산

 

EL의 - 조건문 when

<form action="Ex04_result.jsp" method="post">
    좋아하는 음식 선택 <br>
    <select name="food">
        <option value="피자">피자</option>
        <option value="짜장면">짜장면</option>
        <option value="떡볶이">떡볶이</option>
        <option value="치킨">치킨</option>
    </select><br><br>
    <input type="submit" value="전송">
</form>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>    
<%request.setCharacterEncoding("UTF-8");%>
	Ex04_result.jsp<br>
	<%
		request.setCharacterEncoding("UTF-8");
	%>
	
	food : ${param.food}<br>
	<c:choose>
		<c:when test="${param.food == '피자'}">
			피자는 맛있다
		</c:when>
		<c:when test="${param.food == '떡볶이'}">
			떡볶이는 맵다
		</c:when>
		<c:when test="${param.food == '짜장면'}">
			짜장면은 달다
		</c:when>
		<c:otherwise>
			치킨입니다.
		</c:otherwise>
	</c:choose>

 

 

EL의 - for문

 

JSTL 함수(function) 라이브러리 선언

<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>

 

  • taglib 지시어
    → JSP에서 JSTL 라이브러리(JAR 파일 안 TLD) 연결할 때 사용
  • prefix="fn"
    → fn: 이라는 별칭으로 JSTL 함수들을 사용하겠다는 뜻
  • uri="http://java.sun.com/jsp/jstl/functions"
    → JSTL 함수 라이브러리의 고유 식별자

 

 

 

 

1) 인덱스 방식 (일반 for문과 유사)

<c:forEach var="i" begin="0" end="${fn:length(paramValues.fruit)-1}">
 ${paramValues.fruit[i]}
</c:forEach>

 

  • begin ~ end로 범위를 지정 → 0부터 마지막 인덱스까지
  • ${paramValues.fruit[i]} → 인덱스로 접근

 

 

 

2) items 방식 (향상된 for문과 유사)

<c:forEach var="m" items="${paramValues.fruit}">
 ${m}
</c:forEach>

 

  • items에 배열/리스트를 통째로 넘김
  • 한 요소씩 m에 바인딩

 

 


✅ JSTL Core 주요 태그

태그 설명 예시
<c:out> EL 결과 출력 (<%= %> 대신) <c:out value="${param.id}"/>
<c:set> 변수 저장 <c:set var="sum" value="${10+20}"/>
<c:remove> 변수 제거 <c:remove var="sum"/>
<c:if> 조건문 (if) <c:if test="${avg >= 90}">A학점</c:if>
<c:choose> 조건문 (switch) <c:choose><c:when test="${avg>=90}">A</c:when><c:otherwise>F</c:otherwise></c:choose>
<c:forEach> 반복문 <c:forEach var="i" begin="1" end="5">${i}</c:forEach>
<c:forTokens> 구분자로 문자열 분리 후 반복 <c:forTokens var="word" items="a,b,c" delims=",">${word}</c:forTokens>

 

 

 

✅ JSTL Functions (fn:)  함수

함수 설명 예시 결과
fn:length() 문자열/배열/리스트 길이 ${fn:length("Hello")} 5
fn:toUpperCase() 대문자로 변환 ${fn:toUpperCase("abc")} ABC
fn:toLowerCase() 소문자로 변환 ${fn:toLowerCase("ABC")} abc
fn:substring() 문자열 자르기 ${fn:substring("Hello",0,3)} Hel
fn:contains() 포함 여부 ${fn:contains("Hello","el")} true
fn:replace() 문자열 치환 ${fn:replace("Hello","l","x")} Hexxo
fn:trim() 공백 제거 ${fn:trim(" HI ")} HI

'▶ Java&JSP' 카테고리의 다른 글

28. EL JSTL  (0) 2025.09.17
27. Servlet  (0) 2025.09.16
25. JSP_게시판  (0) 2025.09.16
24 JSP + JDBC 다중 삭제 (multiDelete) 구현  (0) 2025.09.15
23. JSP + JDBC delete예제 정리3 _ Movie  (0) 2025.09.15

✅ 작성순서

  1. DB 테이블/시퀀스 설계 (board 테이블, seq)
  2. DAO 클래스 작성 (insertBoard, getArticles, getArticle, updateBoard, deleteBoard 등)
  3. 화면 JSP 작성 (insertForm.jsp, list.jsp, detail.jsp 등)
  4. Proc JSP 작성 (insertProc.jsp, updateProc.jsp, deleteProc.jsp)
  5. 흐름 연결 & 테스트

글목록 조회 결과화면

 

 

🌈게시글 IP란에 나의 IP를 넣는방법 

상단메뉴 Run > Run Configuration > Tomcat Server선택 > Aguments > VM aguments 맨 아래칸에 작성

 

-Djava.net.preferIPv4Stack=true

 

 

 

 

(1) SQL Table 생성 

더보기
drop table board;

create table board( 
	num number not null primary key,
	writer varchar2(10) not null,
	email varchar2(10),
	subject varchar2(20) not null,
	passwd varchar2(12) not null,
	reg_date date not null,
	readcount int default 0,
	ref number not null,
	re_step number not null,
	re_level number not null,
	content varchar2(20) not null,
	ip varchar2(15) not null
);

drop sequence board_seq;
create sequence board_seq
  increment by 1
  start with 1
  minvalue 1
  maxvalue 10000
  nocache;
  

	
insert into board(num,writer,email,subject,passwd,reg_date,ref,re_step,re_level,content,ip)
values(board_seq.nextval,'a1','a1','a1','1234','2023-1-1',1,0,0,'내용1','127.0.0.1');


insert into board(num,writer,email,subject,passwd,reg_date,ref,re_step,re_level,content,ip)
values(board_seq.nextval,'a2','a2','a2','1234','2023-1-1',2,0,0,'내용2','127.0.0.1');

insert into board(num,writer,email,subject,passwd,reg_date,ref,re_step,re_level,content,ip)
values(board_seq.nextval,'a21','a21','a21','1234','2023-1-1',2,4,1,'내용21','127.0.0.1');

insert into board(num,writer,email,subject,passwd,reg_date,ref,re_step,re_level,content,ip)
values(board_seq.nextval,'a22','a22','a22','1234','2023-1-1',2,1,1,'내용22','127.0.0.1');

insert into board(num,writer,email,subject,passwd,reg_date,ref,re_step,re_level,content,ip)
values(board_seq.nextval,'a221','a221','a221','1234','2023-1-1',2,3,2,'내용221','127.0.0.1');

insert into board(num,writer,email,subject,passwd,reg_date,ref,re_step,re_level,content,ip)
values(board_seq.nextval,'a222','a222','a222','1234','2023-1-1',2,2,2,'내용222','127.0.0.1');



insert into board(num,writer,email,subject,passwd,reg_date,ref,re_step,re_level,content,ip)
values(board_seq.nextval,'a3','a3','a3','1234','2023-1-1',7,0,0,'내용3','127.0.0.1');

insert into board(num,writer,email,subject,passwd,reg_date,ref,re_step,re_level,content,ip)
values(board_seq.nextval,'a31','a31','a31','1234','2023-1-1',7,6,1,'내용31','127.0.0.1');

insert into board(num,writer,email,subject,passwd,reg_date,ref,re_step,re_level,content,ip)
values(board_seq.nextval,'a311','a311','a311','1234','2023-1-1',7,7,2,'내용311','127.0.0.1');

insert into board(num,writer,email,subject,passwd,reg_date,ref,re_step,re_level,content,ip)
values(board_seq.nextval,'a32','a32','a32','1234','2023-1-1',7,2,1,'내용32','127.0.0.1');

insert into board(num,writer,email,subject,passwd,reg_date,ref,re_step,re_level,content,ip)
values(board_seq.nextval,'a321','a321','a321','1234','2023-1-1',7,5,2,'내용321','127.0.0.1');

insert into board(num,writer,email,subject,passwd,reg_date,ref,re_step,re_level,content,ip)
values(board_seq.nextval,'a322','a322','a322','1234','2023-1-1',7,3,2,'내용322','127.0.0.1');

insert into board(num,writer,email,subject,passwd,reg_date,ref,re_step,re_level,content,ip)
values(board_seq.nextval,'a3221','a3221','a3221','1234','2023-1-1',7,4,3,'내용3221','127.0.0.1');

insert into board(num,writer,email,subject,passwd,reg_date,ref,re_step,re_level,content,ip)
values(board_seq.nextval,'a33','a33','a33','1234','2023-1-1',7,1,1,'내용33','127.0.0.1');


commit;

(2). BoardDao 계정연결 및 싱글톤패턴 생성코드 보기

더보기
public class BoardDao {
	String driver = "oracle.jdbc.driver.OracleDriver";
    String url = "jdbc:oracle:thin:@localhost:1521:orcl";
    String id = "sqlid";
    String pw = "sqlpw";
    Connection conn = null;
    PreparedStatement ps = null;
    ResultSet rs = null;
    
    // 🌈싱글톤패턴으로 객체생성(객체를 한번만 생성하기)
    private static BoardDao instance = new BoardDao();
    
    public static BoardDao getInstance() {
    	return instance;
    }// getInstance
    
    // 드라이버 접속
    private BoardDao() {
    	try {
			Class.forName(driver);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
    }
    
    // 계정연결
    public void getConnection() {
    	try {
			conn = DriverManager.getConnection(url, id, pw);
		} catch (SQLException e) {
			e.printStackTrace();
		}
    }

 

 

🌈 싱글톤패턴

// 싱글톤패턴으로 객체생성(객체를 한번만 생성하기)
private static BoardDao instance = new BoardDao();
  • 싱글톤 패턴: 프로그램 전체에서 BoardDao 객체를 딱 하나만 만들고 공유.
  • new BoardDao()를 private static으로 선언 → 클래스가 로딩될 때 단 한 번 객체를 생성해둔다.

👉 리소스 절약 + 일관성 + 유지보수성 때문에 DAO에서 싱글톤을 많이 씀.

 

 

📌 <jsp:useBean>이랑 뭐가 다르냐?

더보기
  • JSP 페이지가 실행될 때마다 필요할 때 new 해서 객체 생성
  • JSP가 다르면 DAO 객체도 새로 만들어질 수 있음
  • 기본적으로 싱글톤 보장 안 됨

👉  Bean (BoardBean, MovieBean 등 데이터 담는 클래스): <jsp:useBean>으로 사용


1. 🌈게시판 만들기 - list.jsp 글목록 조회

 

1-1. BoardDao.getArticles (글 목록조회)

더보기
public ArrayList<BoardBean> getArticles(int start, int end) {
    ArrayList<BoardBean> list = new ArrayList<BoardBean>();
    getConnection();
    String sql = "select num, writer, email, subject, passwd, reg_date, readcount, ref, re_step, re_level, content, ip " ;
    sql += "from (select rownum as rank, num, writer, email, subject, passwd, reg_date, readcount, ref, re_step, re_level, content, ip ";
    sql += "from (select num, writer, email, subject, passwd, reg_date, readcount, ref, re_step, re_level, content, ip ";
    sql += "from board  ";
    sql += "order by ref desc, re_step asc )) ";
    sql += "where rank between ? and ? ";

    try {
        ps = conn.prepareStatement(sql);
        ps.setInt(1, start);
        ps.setInt(2, end);
        rs = ps.executeQuery();

        while(rs.next()) {
            int num = rs.getInt("num");
            String writer = rs.getString("writer");
            String email = rs.getString("email");
            String subject = rs.getString("subject");
            String passwd = rs.getString("passwd");
            Timestamp reg_date = rs.getTimestamp("reg_date");
            int readcount = rs.getInt("readcount");
            int ref = rs.getInt("ref");
            int re_step = rs.getInt("re_step");
            int re_level = rs.getInt("re_level");
            String content = rs.getString("content");
            String ip = rs.getString("ip");

            BoardBean bb = new BoardBean(num, writer, email, subject, passwd, 
                    reg_date, readcount, ref, re_step, re_level, content, ip);

            list.add(bb);

        }
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        try {
            if(rs != null)
                rs.close();
            if(ps != null)
                ps.close();
            if(conn != null)
                conn.close();
        } catch(SQLException e) {
            e.printStackTrace();
        }
    }
    System.out.println("list: " + list.size());
    return list;
}// getArticles

1-2. BoardDao.getArticlesCount()  (글 개수 조회)

 

 

조회 메서드 작성 순서 & 설명

더보기

1. 기본 조회 (정렬까지)

SELECT num, writer, email, subject, passwd, reg_date, readcount, ref, re_step, re_level, content, ip
FROM board
ORDER BY ref DESC, re_step ASC;
  • 게시글 전체 조회
  • ORDER BY ref DESC, re_step ASC
    → ref(원글 기준 그룹번호) → 최신 글이 위로 오도록 내림차순
    → re_step(답글 순서) → 나중에 단 답글(re_step이 큰 값)이 아래로 보이도록 오름차순 

2. ROWNUM 붙이기

SELECT ROWNUM AS rank, num, writer, email, subject, passwd, reg_date, readcount, ref, re_step, re_level, content, ip
FROM ( ...정렬된 select... )​

 

  • Oracle에서 페이징 처리를 위해 ROWNUM 붙임
  • 단, ROWNUM은 ORDER BY보다 먼저 적용되므로 정렬된 결과를 서브쿼리로 감싸야 원하는 순서대로 번호(rank)를 매길 수 있음

3. 바깥쪽에서 원하는 구간만 자르기

SELECT num, writer, email, subject, passwd, reg_date, readcount, ref, re_step, re_level, content, ip
FROM ( ...ROWNUM 붙인 select... )
WHERE rank BETWEEN ? AND ?;

 

  • ? 바인딩 변수 사용 (JDBC PreparedStatement에서 값 넣음)
    • ? 첫 번째: 시작 글 번호 (예: 1, 11, 21 …)
    • ? 두 번째: 끝 글 번호 (예: 10, 20, 30 …)
  • 예: BETWEEN 11 AND 20 → 11번째부터 20번째까지 게시글 가져오기

✅ 요약 흐름

  1. 게시글 가져오기 + 정렬
    → 최신 글 순서대로 정렬
  2. ROWNUM 붙이기
    → 행 번호(rank)를 생성
  3. WHERE rank BETWEEN ? AND ?
    → 특정 페이지 범위(시작~끝)만 잘라서 가져오기

🔑 정리

  • 안쪽 SELECT: 실제 데이터 정렬
  • 중간 SELECT: ROWNUM 붙여서 순번 매김
  • 바깥 SELECT: 페이지 범위 추출 (페이징)

 

🔑 한 줄 정리

  • rownum =  "넣은순서"가 아니라 "조회 순서"
  • num = "글 고유번호"

🔍 예시

1. 정렬 안 한 경우

select rownum, num, subject from board;

ROWNUM | NUM | SUBJECT
-------+-----+----------
1      | 1   | 첫 번째 글
2      | 2   | 두 번째 글
3      | 3   | 세 번째 글
4      | 4   | 네 번째 글

👉 이 경우에는 rownum이 insert된 순서대로 보이는 것처럼 보임.
왜냐면 기본적으로 Oracle이 클러스터 인덱스 순으로 읽어오기 때

 

2. 정렬을 바꾼 경우

select rownum, num, subject 
from (select * from board order by num desc);

ROWNUM | NUM | SUBJECT
-------+-----+----------
1      | 4   | 네 번째 글
2      | 3   | 세 번째 글
3      | 2   | 두 번째 글
4      | 1   | 첫 번째 글

👉 이번엔 rownum이 num 컬럼 내림차순 정렬된 순서대로 다시 매겨짐.

 

✅ 차이 요약

  • num
    • 우리가 시퀀스로 넣은 글번호 (테이블에 저장된 실제 값)
    • 절대 변하지 않음
  • rownum
    • SELECT 실행 시점에 결과 집합에 붙는 "임시 순번"
    • 정렬 결과에 따라 계속 달라질 수 있음

 


2. list.form 전체코드

더보기
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ page import="java.util.*"%>
<%@ page import="myPkg.*"%>
<%
	BoardDao bdao= BoardDao.getInstance();
%>

<%@ page import="java.text.SimpleDateFormat"%>
	<%
		// static 이므로 클래스이름으로 접근한다.
		// 객체가 한번만 만들어질 수 있도록 static으로 설정
		
	
		// 날짜 포맷 지정 (작성일 출력용)
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");	
	
		int pageSize = 10; // 1페이지당 10개
		
		String pageNum = request.getParameter("pageNum");
		if(pageNum == null){ // 현재화면에서 실행 1페이지 시작
			pageNum = "1";
		}
		int currentPage = Integer.parseInt(pageNum);
		
		// 현재 페이지에서 가져올 레코드의 시작행/끝행 계산
		int startRow = (currentPage - 1) * pageSize + 1;
		int endRow = (currentPage * pageSize);
		
		// 전체 레코드 개수 구하기
		int count = bdao.getArticleCount();
		ArrayList<BoardBean> list = bdao.getArticles(startRow, endRow);
		// 현재 페이지에 처음 시작되는 번호
		int number = count - (currentPage - 1) * pageSize;
	%>

<style>
    table {
        border-collapse: collapse;
        margin: 10px auto;
    }
    td, th {
        border: 1px solid #232323;
        padding: 5px;
    }
    th{
    	background-color: cyan;
    }
    a {
        text-decoration: none;
        color: blue;
    }
   
    #page{
    	text-align: center;
    }
    
    #titlelist{
    	text-align:center;
    }
</style>

<div id="titlelist">
<b>글목록(전체 글: <%=count %>)</b>
</div>
<table width="700">
	<tr>
		<td><a href="writeForm.jsp">글쓰기</a></td>
	</tr>
</table>
<table width="700">
	<tr height="30">
		<td align="center" width="50">번 호</td>
		<td align="center" width="250">제 목</td>
		<td align="center" width="100">작성자</td>
		<td align="center" width="150">작성일</td>
		<td align="center" width="50">조 회</td>
		<td align="center" width="100">IP</td>
	</tr>
	<% 
    	for(int i=0; i<list.size(); i+=1){
    		BoardBean bb = list.get(i);
    %>
	<tr>
		<td><%=number-- %></td>
		<%-- <td><%=bb.getNum() %></td> --%>
		<td id="title">
				<%
					if(bb.getRe_level()>0){//답글:1 답답:2 답답답:3
						int wid = bb.getRe_level() * 15;
				%>
					<img src="./images/level.gif" width="<%=wid%>"> 
					<img src="./images/re.gif">
				
				<%				
					} //if				
				%>				
					<a href="content.jsp?num=<%=bb.getNum()%>&pageNum=<%=currentPage%>"><%=bb.getSubject()%></a> 
				
				<%
					if(bb.getReadcount() >= 10){
				%>
					<img src="./images/hot.gif" height="14"/>
				<%
					}
				%>
				
		</td>
		<td><%=bb.getWriter() %></td>
		<td><%=sdf.format(bb.getReg_date()) %></td>
		<td><%=bb.getReadcount() %></td>
		<td><%=bb.getIp() %></td>
	</tr>
	<% 
    	}
    %>
</table>
<div id="page">
<%
	if(count > 0){
		// 전체 페이지 수 = 전체글수 / 페이지크기 (+나머지 있으면 +1)
		int pageCount = count / pageSize + (count % pageSize ==0 ? 0 : 1);
		
		int pageBlock = 10;  // 한번에 보여줄 페이지 블록 수
		int startPage = ((currentPage-1) / pageBlock * pageBlock) + 1;
		int endPage = startPage + pageBlock - 1; // 끝 페이지
		
		if(endPage > pageCount){
			endPage = pageCount;  // 마지막 페이지 번호를 초과하지 않도록 보정
		}
		
		if(startPage>10){
		%>
		<a href="list.jsp?pageNum=<%=startPage-10%>">[이전]</a>
		<% 			
		}
		%>
		<%
		for(int i=startPage; i<=endPage; i+=1){
		%>
		<a href="list.jsp?pageNum=<%=i %>">[<%=i %>]</a>
		<%			
		}// for
		
		if(endPage < pageCount){
		%>
		<a href="list.jsp?pageNum=<%=startPage+10%>">[다음]</a>
		<%			
				}
			}
		%>
</div>

📌 전체 흐름

1. DAO 불러오기

<%
	BoardDao bdao= BoardDao.getInstance();
%>
  • DAO를 싱글톤 패턴으로 생성해서 가져옴.
  • 이제 이 페이지에서 DB 접근은 bdao가 맡음.

2. 페이지 번호 및 시작(startRow)·끝(endRow) 행 구하기

int pageSize = 10; // 1페이지당 10개
String pageNum = request.getParameter("pageNum");
if(pageNum == null) {
	pageNum = "1";
}
int currentPage = Integer.parseInt(pageNum);

int startRow = (currentPage - 1) * pageSize + 1;
int endRow = currentPage * pageSize;

 

⚫pageSize: 한 페이지당 글 개수 (10개).

 

⚫ pageNum: 현재 몇 번째 페이지인지 파라미터로 받음 (없으면 1페이지).

===> 처음 창을 열었을때는 null 이므로

===> pageNum =  1

===> int currentPage = 1

 

  • startRow: 이 페이지에서 가져올 첫 번째 글 번호
  • endRow: 이 페이지에서 가져올 마지막 글 번호
startRow = (선택한 페이지 번호 - 1) * 페이지당 글 개수 + 1
endRow = (선택한 페이지 번호) * 페이지당 글 개수

3. 게시판 글 개수 · 글 목록 조회 & 화면 번호 계산

// 게시판 글 개수
int count = bdao.getArticleCount();

//  글 목록 조회
ArrayList<BoardBean> list = bdao.getArticles(startRow, endRow);

// 화면에 출력할 페이지 번호
int number = count - (currentPage - 1) * pageSize;
  1. count: 전체 글 수 (DB에서 select count(*)).
  2. list: 현재 페이지 범위(startRow~endRow)의 글 목록.
  3. number: 화면에 출력할 글 번호

✅ number 예시:

  • 전체 글 수 = 95, 페이지 크기 = 10
  • 1페이지 → 95 - (1-1)*10 = 95 (맨 위 글 번호 95)
  • 2페이지 → 95 - (2-1)*10 = 85 (맨 위 글 번호 85)
  • 3페이지 → 95 - (3-1)*10 = 75

 


4. 게시판 목록을 <table>에 출력하는 부분 (글 목록 테이블) 

<tr>
	<td align="center" width="50">번 호</td>
	<td align="center" width="250">제 목</td>
	<td align="center" width="100">작성자</td>
	<td align="center" width="150">작성일</td>
	<td align="center" width="50">조 회</td>
	<td align="center" width="100">IP</td>
</tr>
<%
	for(int i=0; i<list.size(); i++){
		BoardBean bb = list.get(i);
%>
<tr>
	<td><%=number-- %></td>
	<td id="title">
		<% if(bb.getRe_level()>0){ %>
			<img src="./images/level.gif" width="<%=bb.getRe_level()*15%>">
			<img src="./images/re.gif">
		<% } %>
		<a href="content.jsp?num=<%=bb.getNum()%>&pageNum=<%=currentPage%>"><%=bb.getSubject()%></a>
		<% if(bb.getReadcount() >= 10){ %>
			<img src="./images/hot.gif" height="14"/>
		<% } %>
	</td>
	<td><%=bb.getWriter() %></td>
	<td><%=sdf.format(bb.getReg_date()) %></td>
	<td><%=bb.getReadcount() %></td>
	<td><%=bb.getIp() %></td>
</tr>
<%
	}
%>
    🌈 제목 처리
  • number--: 번호를 순차적으로 줄여나감.
  • re_level: 답글 들여쓰기 (답글일수록 왼쪽 여백 wid ↑).
  • hot.gif: 조회수 10 이상이면 🔥 표시.
  • sdf.format: 작성일 yyyy-MM-dd HH:mm 형태로 출력.

5. 페이지 블록 출력 (하단 페이지 번호)

int pageCount = count / pageSize + (count % pageSize == 0 ? 0 : 1);
int pageBlock = 10;
int startPage = ((currentPage-1) / pageBlock * pageBlock) + 1;
int endPage = startPage + pageBlock - 1;
if(endPage > pageCount) endPage = pageCount;
  • count: 전체 글 수
  • pageSize: 한 페이지에 보여줄 글 개수

👉 count / pageSize 로 몫 계산 → 기본 페이지 수
👉 나머지가 있으면 +1 페이지 더 추가

더보기
int startPage = ((currentPage-1) / pageBlock * pageBlock) + 1;

 

👉 현재 페이지(currentPage)가 속한 페이지 블록의 시작 번호를 구하는 공식

 

📌 블록 개념 먼저

  • pageBlock = 10 이라고 하면
    • [1][2][3]...[10] → 첫 번째 블록
    • [11][12]...[20] → 두 번째 블록
    • [21][22]...[30] → 세 번째 블록

즉, 10개씩 묶어서 페이지 번호를 보여주는 것 


예시:

currentPage = 7, pageBlock = 10

(currentPage - 1) = 6

6 / 10 = 0 (정수 나눗셈)

0 * 10 = 0

+ 1 → startPage = 1👉 즉, 7번 페이지는 1~10 블록에 속하므로 시작 번호는 1


6. 페이지 번호링크 출력

if(startPage > 10){
	<a href="list.jsp?pageNum=<%=startPage-10%>">[이전]</a>
}
for(int i=startPage; i<=endPage; i++){
	<a href="list.jsp?pageNum=<%=i %>">[<%=i %>]</a>
}
if(endPage < pageCount){
	<a href="list.jsp?pageNum=<%=startPage+10%>">[다음]</a>
}

 

👉 페이지 번호 링크 출력

 

  • [이전], [다음] 버튼으로 앞/뒤 블록 이동.
  • 현재 블록 내 페이지 번호를 반복문으로 출력

📌 정리

  • 이 페이지 역할: list.jsp = 게시판의 글 목록 + 페이징 처리.
  • 데이터 흐름:
    DB → DAO (getArticles) → ArrayList<BoardBean> → JSP에서 for문으로 테이블 출력.
  • 주요 기능:
    • 글 번호 출력
    • 답글 들여쓰기 (re_level)
    • 조회수 10 이상 시 hot 아이콘
    • 작성일 포맷팅
    • 페이지 번호 블록 표시

 

🎬 JSP + JDBC 다중 삭제 (multiDelete) 구현

 

🔎 전체 흐름도

[select.jsp] 체크박스 선택 후 "삭제" 버튼 클릭
        │
        ▼
[multiDelete.jsp] 선택된 값들 request.getParameterValues()
        │
        ▼
[MovieDao.multiDelete()] DB에서 선택된 PK 전부 삭제
        │
        ▼
[select.jsp] 목록 새로고침

 

1️⃣ select.jsp (체크박스 + 삭제 버튼)

<form name="myform" action="multiDelete.jsp" method="post">
    <input type="button" value="추가" onClick="location.href='insertForm.jsp'">
    <input type="button" value="삭제" onClick="selectDelete()">

    <table border="1">
        <tr>
            <th><input type="checkbox" name="allcheck" onClick="allDelete(this)"></th>
            <th>번호</th><th>아이디</th><th>이름</th>...
        </tr>
        <% for(MovieBean mb : lists) { %>
        <tr>
            <td><input type="checkbox" name="rowcheck" value="<%=mb.getNum()%>"></td>
            <td><%=mb.getNum()%></td>
            <td><%=mb.getId()%></td>
            ...
        </tr>
        <% } %>
    </table>
</form>

 

✔️ rowcheck라는 이름으로 여러 개 체크박스를 생성
✔️ 삭제 버튼 클릭 시 → 선택된 값들을 multiDelete.jsp로 전송


2️⃣ multiDelete.jsp (삭제 처리)

<jsp:useBean id="mdao" class="myPkg.MovieDao"/>

<%
    String[] num = request.getParameterValues("rowcheck"); // 여러 개 값
    int cnt = mdao.multiDelete(num);
%>

<jsp:forward page="select.jsp"/>

 

✔️ request.getParameterValues("rowcheck") → String[] 형태로 모든 체크된 번호를 받음
✔️ DAO 호출해서 실제 DB 삭제 수행
✔️ 삭제 후 다시 목록으로 이동


3️⃣ MovieDao.multiDelete (DAO)

public int multiDelete(String[] num) {

    getConnection();
    String sql = "delete from movie where num=?";
    for(int i=0; i<num.length-1; i++) {
        sql += " or num=?";
    }
    int cnt = 0;

    try {
        ps = conn.prepareStatement(sql);

        for(int i=0; i<num.length; i++) {
            ps.setInt(i+1, Integer.parseInt(num[i]));
        }
        cnt += ps.executeUpdate();

    } catch (SQLException e) {
        System.out.println(e);
    }finally {
        try {
            if(ps != null) ps.close();
            if(conn != null) conn.close();

        } catch (SQLException e) {
            System.out.println(e);
        }
    }    // finally

    return cnt;
}    // multiDeleteMovie

 

✔️ delete from movie where num=? or num=? or num=? ... 형태로 SQL을 조립
✔️ 선택된 개수만큼 ? 바인딩
✔️ executeUpdate() 실행 → 삭제된 행 개수 반환

 


✅ 정리

  • select.jsp : 여러 개 체크박스 생성
  • multiDelete.jsp : 선택된 값들을 String[]으로 받아 DAO 호출
  • DAO.multiDelete : SQL 동적으로 만들어 여러 PK 삭제

1. MovieDao.deleteMovie()

public int deleteMovie(String num) {
    getConnection();
    String sql = "DELETE FROM movie WHERE num=" + num;
    int cnt = -1;

    try {
        ps = conn.prepareStatement(sql);
        cnt = ps.executeUpdate();

    } catch (SQLException e) {
        e.printStackTrace();
    }finally {
        try {
            if(ps != null) ps.close();
            if(conn != null) conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

 

 

2. deleteProc.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
deleteProc.jsp<br>
<%
    request.setCharacterEncoding("UTF-8");

    String num = request.getParameter("num");
%>

<jsp:useBean id="mdao" class="myPkg.MovieDao"/>
<%
    int cnt = mdao.deleteMovie(num); 
    if(cnt != -1){    // 삽입 성공
        System.out.println("삭제 성공");
    }else{
        System.out.println("삭제 실패");
    }
    response.sendRedirect("select.jsp");
%>

 

 

✅ 흐름 설명

  1. 파라미터 받기
    • request.getParameter("num") → 삭제할 대상의 번호 (PK)
    • 여기서도 문자열로 받아오기 때문에 DAO에서 정수 변환을 처리하거나,
      JSP에서 Integer.parseInt() 후 넘겨도 됨
  2. DAO 호출
    • deleteMovie(num) 실행
    • DAO 내부에서 SQL 실행
  3. 결과 확인
    • cnt : 삭제된 행 수
    • 성공 → cnt 1 이상
    • 실패 → cnt == -1 (DAO에서 초기화값)
  4. 리다이렉트
    • 삭제가 끝나면 무조건 select.jsp로 이동 (목록 재조회)
    • 성공/실패 여부는 콘솔 로그에서만 확인 가능

 

구현하기구현하기

🔎 전체 흐름도

[select.jsp] 수정 버튼 클릭 (num 전달)
        │
        ▼
[updateForm.jsp] num 기반으로 기존 값 불러오기
        │
        ▼
사용자가 수정 후 "수정하기" 클릭
        │
        ▼
[updateProc.jsp] 수정 데이터 MovieBean에 담아 DAO 전달
        │
        ▼
[MovieDao.updateMovie()] DB update 실행
        │
        ▼
성공 → select.jsp 리다이렉트
실패 → updateForm.jsp 재호출

1️⃣ updateForm.jsp (수정 화면)

<%@page import="myPkg.MovieBean"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>

select.jsp(num)=>updateForm.jsp<br>
<jsp:useBean id="mdao" class="myPkg.MovieDao" />
<% 
	String[] genre = {"공포", "다큐", "액션", "애니메이션"};
	String[] time = {"08~10","10~12","12~14","14~16","16~18","18~20"};
	int num = Integer.parseInt(request.getParameter("num"));
	MovieBean movie = mdao.getMovieByNum(num);  
	System.out.println(movie.getNum());
	System.out.println(movie.getGenre()); // 공포 액션 
%>

	<h2>영화 선호도 조사 수정폼</h2>
	<form action="updateProc.jsp" method="post">
		<input type="hidden" name="num" value="<%=num%>">
		<table border="1">
		<tr>
			<td>아이디</td>
			<td><input type="text" name="id" value="<%=movie.getId()%>"></td>  
		</tr>
		<tr>
			<td>이름</td><td> 
			<input type="text" name="name" value="<%=movie.getName()%>"></td> 
		</tr> 
		<tr>
			<td>나이</td>
			<td><input type="text" name="age" value="<%=movie.getAge()%>"></td> 
		</tr>
		<tr>
			<td>좋아하는 장르</td>
			<td>
				<!-- 
				<input type="checkbox" name="genre" value="공포">공포
				<input type="checkbox" name="genre" value="다큐">다큐 
				<input type="checkbox" name="genre" value="액션">액션 
				<input type="checkbox" name="genre" value="애니메이션">애니메이션 
				-->
				
                <%for(String g : genre) { %>
                    <input type="checkbox" name="genre" value="<%= g %>" <%if(movie.getGenre().contains(g)){ %> checked <%}%> ><%= g %>         
                <%} %>
	
			</td> 
		</tr>

		<tr>
			<td>즐겨보는 시간대</td>
			<td>
		
				<select name="time">
					<!-- <option value="08~10">08~10</option>
					<option value="10~12">10~12</option>
					<option value="12~14">12~14</option>
					<option value="14~16">14~16</option>
					<option value="16~18">16~18</option>
					<option value="18~20">18~20</option> -->
					
					<%for(int i = 0; i < time.length; i++){ %>
					    <option value="<%=time[i] %>" <%if(movie.getTime().equals(time[i])){%> selected <%} %>><%=time[i] %></option>
					<%} %>
				</select>
		<tr>
			<td>동반 관객수</td>
			<td>
				<%
				for(int i=1;i<=5;i++){
				%>
					<input type="radio" name="partner" value="<%=i%>" <%if(movie.getPartner()==i){ %> checked <%}%>><%=i%>
				<%} %>
			</td>
		</tr>
		
		<tr>
			<td>영화관 개선사항</td>
			<td>
				<textarea name="memo" cols="40" rows="3"><%=movie.getMemo() %></textarea> 
			</td>
		</tr>
		<tr align="center">
			<td colspan="2">
				<input type="submit" value="수정하기">
			</td>
		</tr>
		</table>
	</form>

 

 

<jsp:useBean id="mdao" class="myPkg.MovieDao" />

int num = Integer.parseInt(request.getParameter("num"));
MovieBean movie = mdao.getMovieByNum(num);

 

✔️ Dao 호출 하여 getMovieByNum(num) 으로 DB 값 불러와서

폼에 기본값으로 표시 (체크박스, 라디오, select 포함)

 

 

  • URL: updateForm.jsp?num=10
  • getParameter("num") → "10" (문자열)
  • 정수로 쓰려면 Integer.parseInt("10") 해야 int로 변환됨

 


2️⃣ updateProc.jsp (수정 처리)

<%
    request.setCharacterEncoding("UTF-8");
%>
<jsp:useBean id="mdao" class="myPkg.MovieDao"/>
<jsp:useBean id="mBean" class="myPkg.MovieBean"/>
<jsp:setProperty property="*" name="mBean"/>

<%
    // 체크박스 다중 값 처리
    String[] genre = request.getParameterValues("genre");
    String temp = "";
    if(genre != null){
        for(int i=0; i<genre.length; i++){
            temp += genre[i] + " ";
        }
    }
    mBean.setGenre(temp);

    int cnt = mdao.updateMovie(mBean); 
    if(cnt > 0){
        response.sendRedirect("select.jsp");
    }else{
        response.sendRedirect("updateForm.jsp?num="+mBean.getNum());
    }
%>

 

✔️ 폼 데이터를 MovieBean에 자동 매핑 (jsp:setProperty property="*")
✔️ 장르는 여러 개 선택될 수 있어서 수동으로 문자열 합쳐서 저장
✔️ DAO 호출 후 성공/실패에 따라 이동

 


 

3️⃣ MovieDao (DB 처리)

// 특정 번호 데이터 가져오기
public MovieBean getMovieByNum(int num) {
    getConnection();
    MovieBean mb = null;
    try {
        String sql = "select * from movie where num = ?";
        ps = conn.prepareStatement(sql);
        ps.setInt(1, num);
        rs = ps.executeQuery();
        if(rs.next()) {
            mb = new MovieBean(
                rs.getInt("num"),
                rs.getString("id"),
                rs.getString("name"),
                rs.getInt("age"),
                rs.getString("genre"),
                rs.getString("time"),
                rs.getInt("partner"),
                rs.getString("memo")
            );
        }
    } finally { /* 리소스 정리 */ }
    return mb;
}

// 데이터 수정
public int updateMovie(MovieBean mb) {
    getConnection();
    int cnt = -1;
    try {
        String sql = "update movie set id=?, name=?, age=?, genre=?, time=?, partner=?, memo=? where num=?";
        ps = conn.prepareStatement(sql);
        ps.setString(1, mb.getId());
        ps.setString(2, mb.getName());
        ps.setInt(3, mb.getAge());
        ps.setString(4, mb.getGenre());
        ps.setString(5, mb.getTime());
        ps.setInt(6, mb.getPartner());
        ps.setString(7, mb.getMemo());
        ps.setInt(8, mb.getNum());
        cnt = ps.executeUpdate();
    } finally { /* 리소스 정리 */ }
    return cnt;
}

 

✔️ getMovieByNum() → 수정폼에 기존 데이터 표시
✔️ updateMovie() → 변경된 데이터 DB에 반영

 


✅ 정리

  • updateForm.jsp
    • num 받아서 해당 데이터 불러오기
    • 기존 값들을 폼에 표시 (체크박스, 라디오, select 포함)
  • updateProc.jsp
    • 수정된 값들을 MovieBean에 묶어서 DAO로 전달
    • 다중 선택값(장르)은 별도 처리
  • MovieDao
    • getMovieByNum() : 수정폼에 보여줄 데이터 조회
    • updateMovie() : DB에 업데이트 실행

 

  • Form.jsp → 화면만 담당 (Bean 필요 없음)
  • Proc.jsp → 입력값을 Bean에 담아 DAO로 전달 (Bean 필수)
  • Select.jsp → DAO가 반환한 Bean 리스트를 출력 (Bean 직접 생성 ❌, DAO가 만들어줌)

Proc.jsp에서만 Bean을 직접 호출하는 이유는 "사용자가 입력한 값(request 파라미터)"를 Bean에 묶어서 DAO로 보내는 역할이 있기 때문이에요.

 

🎬 JSP + JDBC 예제 (Movie 데이터 입력하기)

사용자가 입력한 데이터를 DB에 저장하는 insertForm.jsp → inputProc.jsp 과정을 정리

 


1. insertForm.jsp (입력 폼)

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<script type="text/javascript" src="./js/jquery.js"></script>
<script type="text/javascript">
$(document).ready(function(){
    //alert('ready');

    var isCheck = false;
    var isChange = false;
    var use = "";
    var isBlank = false;

    $('#id_check').click(function(){ // 중복체크 버튼을 클릭했을 때
        //alert('id_check');
        isCheck = true;
        isChange = false;

        if($('input[name=id]').val() == ""){
            alert("아이디를 입력하세요");
            isBlank = true;
            return;
        }
        isBlank = false;

        $.ajax({
            url : "id_check_proc.jsp", // 사용가능:YES , 사용불가능:NO
            data : ({
                userid : $('input[name=id]').val() // userid = kim
            }),
            success : function(data){
                //alert(data);
                if($.trim(data) == 'YES'){
                    $('#idmessage').html("<font color=blue>사용가능합니다.</font>");
                    $('#idmessage').show();
                    use = "possible";
                }else{
                    $('#idmessage').html("<font color=red>이미 사용중인 아이디입니다.</font>");
                    $('#idmessage').show();
                    use = "impossible";

                }
            } //success
        });// ajax
    });// 중복체크 버튼 click

    $('input[name=id]').keydown(function(){
        //alert('keydown');
        $('#idmessage').css('display','none');
        use ="";
        isChange = true;
        isCheck=false;
        return; 
    });//keydown

    $('#sub').click(function(){ // 가입하기(type=submit) 클릭했을 때
        //alert('submit');
        if(use == "impossible"){
            alert("이미 사용중인 아이디입니다.");
            return false; // 무슨 의미??

        }else if(isCheck == false || isChange== true){ // 중복체크 버튼 클릭하지 않았으면
            alert('중복체크 클릭하세요');
            return false; 

        }else if(isBlank == true){
            alert("아이디를 입력하세요 submit");
            return false;
        }
    });//submit click
}); // ready
</script>

insertForm.jsp<br>

<%
String[] genre = {"공포", "다큐", "액션", "애니메이션"};
String[] time = {"08~10","10~12","12~14","14~16","16~18","18~20"};
%>

<h2>영화 선호도 조사 </h2>
<form action="inputProc.jsp" method="post">
    <table border="1" width="700px">
    <tr>
        <td>아이디</td>
        <td>
            <input type="text" name="id" value="IU">
            <!-- <button id="id_check">중복체크</button> -->
            <input type="button" id="id_check" value="중복체크">
            <span id="idmessage" style="display:none"></span>
        </td>  
    </tr>
    <tr>
        <td>이름</td><td> 
        <input type="text" name="name" value="아이유"></td> 
    </tr> 
    <tr>
        <td>나이</td>
        <td><input type="text" name="age" value="23"></td> 
    </tr>
    <tr>
        <td>좋아하는 장르</td>
        <td>
            <!-- 
            <input type="checkbox" name="genre" value="공포">공포
            <input type="checkbox" name="genre" value="다큐">다큐 
            <input type="checkbox" name="genre" value="액션">액션 
            <input type="checkbox" name="genre" value="애니메이션">애니메이션 
            -->

            <%for(String g : genre) { %>
                <input type="checkbox" name="genre" value="<%= g %>"><%= g %>
            <%} %>

        </td> 
    </tr>

    <tr>
        <td>즐겨보는 시간대</td>
        <td>

            <select name="time">
                <!-- <option value="08~10">08~10</option>
                <option value="10~12">10~12</option>
                <option value="12~14">12~14</option>
                <option value="14~16">14~16</option>
                <option value="16~18">16~18</option>
                <option value="18~20">18~20</option> -->

                <%for(int i = 0; i < time.length; i++){ %>
                    <option value="<%=time[i] %>"><%=time[i] %></option>
                <%} %>
            </select>
    <tr>
        <td>동반 관객수</td>
        <td>
            <%
            for(int i=1;i<=5;i++){
            %>
                <input type="radio" name="partner" value="<%=i%>"><%=i%>
            <%} %>
        </td>
    </tr>

    <tr>
        <td>영화관 개선사항</td>
        <td>
            <textarea name="memo" cols="40" rows="3">value는 여기에 넣기</textarea> 
        </td>
    </tr>
    <tr align="center">
        <td colspan="2">
            <input type="submit" value="가입하기" id="sub">
        </td>
    </tr>
    </table>
</form>

 

👉 여기서 핵심

  • 아이디 중복체크 (AJAX)
  • 체크박스(장르), 셀렉트(시간), 라디오(관객수), textarea(개선사항)
  • 유효성 검사 후 inputProc.jsp로 이동

 


2. inputProc.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
insertForm.jsp(7) => inputProc.jsp<br>
<%
	request.setCharacterEncoding("UTF-8");
%>
<jsp:useBean id="mdao" class="myPkg.MovieDao"/>
<jsp:useBean id="mBean" class="myPkg.MovieBean"/>
<jsp:setProperty property="*" name="mBean"/>

<%
String[] genre = request.getParameterValues("genre");

String temp = ""; 
if (genre == null){
	out.println("널입니다.");
	temp="선택사항없음"; 
    // 이 줄 없으면 수정 form에서 선택해놓은 취미가 없을 때 에러가 나므로(null과 비교하므로) 이 줄 넣어준다.
	// 아니면 위의 String temp=" " 이렇게 스페이스 하나 temp에 넣어주면 temp="선택사항없음" 넣어주지 않아도 된다.
}
else {
	//out.println("선택한 항목의 갯수 : " + hobby.length);
	//out.println("<br>");
	for (int i = 0; i < genre.length; i++) {
		//out.println("<b>" + hobby[i] + "</b>");
		if(i == genre.length-1)
			temp += genre[i] ;
		else
			temp += genre[i] + ","  ;
	}
	//out.println("<br>");
}
mBean.setGenre(temp); 

    mBean.setGenre(temp);
    int cnt = mdao.insertMovie(mBean);
    if(cnt > 0){
        response.sendRedirect("select.jsp");
    }else{
        response.sendRedirect("insertForm.jsp");
    }
%>

 

👉 주의할 점:
체크박스를 선택하지 않으면 null이 넘어오기 때문에 "선택사항없음" 같은 기본값을 넣어야 에러가 안 납니다.

 


3. MovieDao.insertMovie()

public int insertMovie(MovieBean mb) {
    getConnection();
    int cnt = -1;
    String sql = "insert into movie values(mv_seq.nextval, ?, ?, ?, ?, ?, ?, ?)";
    try {
        ps = conn.prepareStatement(sql);
        ps.setString(1, mb.getId());
        ps.setString(2, mb.getName());
        ps.setInt(3, mb.getAge());
        ps.setString(4, mb.getGenre());
        ps.setString(5, mb.getTime());
        ps.setInt(6, mb.getPartner());
        ps.setString(7, mb.getMemo());

        cnt = ps.executeUpdate();
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        try {
            if(ps != null)
                ps.close();
            if(conn != null)
                conn.close();
        } catch(SQLException e) {
            e.printStackTrace();
        }
    }
    return cnt;
}// insertMovie

1️⃣ insertForm.jsp (폼 입력)

  • 사용자가 id, name, age, genre[], time, partner, memo를 입력합니다.
  • form이 inputProc.jsp로 전송됩니다.

 

2️⃣ inputProc.jsp (데이터 수집 → Bean에 담기)

<jsp:useBean id="mBean" class="myPkg.MovieBean"/>
<jsp:setProperty property="*" name="mBean"/>

 

  • 여기서 setProperty property="*" 덕분에
    폼 input의 name과 MovieBean의 필드명이 동일하다면 자동으로 매핑됩니다.
    예:
    • <input name="id"> → mBean.setId(...)
    • <input name="name"> → mBean.setName(...)
    • <input name="age"> → mBean.setAge(...)
    • <textarea name="memo"> → mBean.setMemo(...)
  • 다만 genre는 체크박스 다중 선택이어서 String[] 형태로 넘어오므로,
    이건 수동으로 temp 문자열로 합쳐서 mBean.setGenre(temp)로 넣어줬습니다.

즉, 최종적으로 mBean 안에 한 명의 영화 선호도 데이터가 전부 들어가게 됩니다.

 

 

3️⃣ inputProc에서 insertMovie(mBean) 호출

int cnt = mdao.insertMovie(mBean);

 

  • 이제 DAO의 insertMovie(MovieBean mb) 메서드에 mBean 하나를 통째로 전달합니다.
  • DAO에서는 getter로 각 값을 꺼내서 SQL에 바인딩합니다.
ps.setString(1, mb.getId());
ps.setString(2, mb.getName());
ps.setInt(3, mb.getAge());
ps.setString(4, mb.getGenre());
ps.setString(5, mb.getTime());
ps.setInt(6, mb.getPartner());
ps.setString(7, mb.getMemo());

 


✅ 요약:

  1. insertForm.jsp → 입력
  2. inputProc.jsp → MovieBean에 자동 매핑 (jsp:setProperty property="*")
  3. mdao.insertMovie(mBean) → DAO에 Bean 객체 통째로 전달
  4. DAO에서 Bean의 getter로 값 꺼내서 SQL 실행

 


🌈 AJAX 아이디 중복체크 흐름

 (insertForm.jsp → AJAX → id_check_proc.jsp → MovieDao → DB)

[사용자 입력] insertForm.jsp
        │
        ▼
[AJAX 요청] id_check_proc.jsp?userid=OOO
        │
        ▼
[DAO 호출] MovieDao.searchId(userid)
        │
        ▼
[DB 조회] select * from movie where id=?
        │
        ▼
[응답 반환] YES / NO
        │
        ▼
[AJAX success 콜백 → 메시지 표시]

 

 

1️⃣ insertForm.jsp (클라이언트)

사용자가 아이디를 입력하고 "중복체크" 버튼을 누르면, AJAX가 실행돼 서버에 아이디를 전달합니다.

$(document).ready(function(){
//alert('ready');

var isCheck = false;
var isChange = false;
var use = "";
var isBlank = false;

$('#id_check').click(function(){ // 중복체크 버튼을 클릭했을 때
    //alert('id_check');
    isCheck = true;
    isChange = false;

    if($('input[name=id]').val() == ""){
        alert("아이디를 입력하세요");
        isBlank = true;
        return;
    }
    isBlank = false;

    $.ajax({
        url : "id_check_proc.jsp", // 사용가능:YES , 사용불가능:NO
        data : ({
            userid : $('input[name=id]').val() // userid = kim  // 전달할 데이터
        }),
        success : function(data){  // 서버 응답 받음
            //alert(data);
            if($.trim(data) == 'YES'){
                $('#idmessage').html("<font color=blue>사용가능합니다.</font>");
                $('#idmessage').show();
                use = "possible";
            }else{
                $('#idmessage').html("<font color=red>이미 사용중인 아이디입니다.</font>");
                $('#idmessage').show();
                use = "impossible";

            }
        } //success
    });// ajax
});// 중복체크 버튼 click

$('input[name=id]').keydown(function(){
    //alert('keydown');
    $('#idmessage').css('display','none');
    use ="";
    isChange = true;
    isCheck=false;
    return; 
});//keydown

$('#sub').click(function(){ // 가입하기(type=submit) 클릭했을 때
    //alert('submit');
    if(use == "impossible"){
        alert("이미 사용중인 아이디입니다.");
        return false; // 무슨 의미??

    }else if(isCheck == false || isChange== true){ // 중복체크 버튼 클릭하지 않았으면
        alert('중복체크 클릭하세요');
        return false; 

    }else if(isBlank == true){
        alert("아이디를 입력하세요 submit");
        return false;
    }
});//submit click
}); // ready
</script>

 

 

✅ 정리

  • url: 서버에 요청할 JSP (id_check_proc.jsp)
  • data: 서버로 보낼 파라미터 (userid=입력값)
  • success: 서버에서 응답(YES/NO)을 받으면 실행

 

 

2️⃣ id_check_proc.jsp (서버 JSP)

AJAX 요청을 받아 DB에서 해당 아이디가 존재하는지 확인하고, 결과를 YES/NO 문자열로 응답

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<jsp:useBean id="mdao" class="myPkg.MovieDao"/>
<%
	String userid = request.getParameter("userid");
	System.out.println("id_check_proc.jsp userid : " + userid);
	boolean isExist = mdao.searchId(userid); 
	// true; 있다. 이미 존재함, 사용하면 안됨
	// false;  없다. 존재하지 않는다, 사용해도 된다.
	String str;
	if(isExist){
		str = "NO";
		out.print(str);
		System.out.println("out 이전 문장"); 
	}else{
		str = "YES";
		out.print(str);
		System.out.println("out 이전 문장"); 
	}
%>

✅ 정리

  • request.getParameter("userid") → 클라이언트에서 보낸 값 받음
  • DAO 호출 (mdao.searchId(userid))
  • 결과 true/false에 따라 "NO" 또는 "YES" 출력

 

3️⃣ MovieDao.searchId (DAO)

DB에 접근해서 실제로 아이디가 있는지 확인하는 역할입니다.

public boolean searchId(String userid){

    getConnection();
    String sql = "select * from movie where id=?";
    // select * from movie where id='kim';
    boolean flag = false;
    try {
        ps = conn.prepareStatement(sql);
        ps.setString(1, userid);
        rs = ps.executeQuery();
        while(rs.next()) {
            flag = true; // 있다. 이미 존재함, 사용하면 안됨
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }finally {
        try {
            if(rs != null)
                rs.close();
            if(ps != null)
                ps.close();
            if(conn != null)
                conn.close();
        } catch(SQLException e) {
            e.printStackTrace();
        }
    }
    return flag;
}//searchId

✅ 정리

  • SQL 실행: select * from movie where id=?
  • 결과가 있으면 true (이미 사용중), 없으면 false (사용 가능) 반환

4️⃣ 전체 흐름 요약

  1. 사용자 → insertForm.jsp에서 "중복체크" 버튼 클릭
  2. AJAX 실행 → id_check_proc.jsp?userid=입력값 요청
  3. id_check_proc.jsp → MovieDao.searchId() 호출
  4. DAO → DB 조회 → true/false 반환
  5. JSP에서 "YES" 또는 "NO" 출력
  6. AJAX success 콜백 → 응답 값에 따라 메시지 출력

 

결과

  • DB에 존재하지 않으면 → "사용가능합니다" (YES)
  • DB에 존재하면 → "이미 사용중입니다" (NO)

 

 

🎬 JSP + JDBC 예제 (Movie 테이블 조회)

이번 글에서는 JSP + JDBC를 활용하여 movie 테이블의 데이터를 조회


1. 사용한 sql문

drop table movie;
create table movie(
	num number not null  primary key,
	id varchar2(10) not null,
	name varchar2(10) not null,
	age number not null,
	genre varchar2(40),
	time varchar2(20),
	partner number default 1,
	memo varchar2(50)
);

drop sequence mv_seq;
create sequence mv_seq
	increment by 1
	start with 1 
	minvalue 1
	maxvalue 10000
	nocache;

insert into movie(num,id,name,age,genre,time,partner,memo)
values(mv_seq.nextval,'m1','김길동',30,'다큐','10~12',2,'좌석을 넓혀주세요.');

commit;
col num for 99
col id for a5
col name for a8
col age for 999
col genre for a16
col time for a10
col partner for 99
col memo for a30

select * from movie;

 

 

2. select.jsp (조회 목록 작성)

<%@page import="myPkg.MovieBean"%>
<%@page import="java.util.ArrayList"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<jsp:useBean id="mdao" class="myPkg.MovieDao" />
<% 
    ArrayList<MovieBean> lists = mdao.getAllMovie();
%>
<form name="myform" action="multiDelete.jsp" method="post">
<input type="button" value="추가" onClick="location.href='insertForm.jsp'">
<input type="button" value="삭제" onClick="selectDelete()">

<table border="1">
	<tr>	
		<th><input type="checkbox" name="allcheck" onClick="allDelete(this)"></th>
	    <th>번호</th>
	    <th>아이디</th>
	    <th>이름</th>
	    <th>나이</th>
	    <th>좋아하는 장르</th>
	    <th>즐겨보는 시간대</th>
	    <th>동반 관객수</th>
	    <th>개선사항</th>
	    <th>수정</th>
	    <th>삭제</th>
	</tr>


    <% for(MovieBean mb : lists) {%>
        <tr>
        	<td><input type="checkbox" name="rowcheck" value="<%=mb.getNum() %>"></td>
            <td><%=mb.getNum() %></td>
            <td><%=mb.getId() %></td>
            <td><%=mb.getName() %></td>
            <td><%=mb.getAge() %></td>
            <td><%=mb.getGenre() %></td>
            <td><%=mb.getTime() %></td>
            <td><%=mb.getPartner()%></td>
            <td><%=mb.getMemo() %></td>
            <td><a href="updateForm.jsp?num=<%=mb.getNum()%>">수정</a></td>
            <td><a href="deleteProc.jsp?num=<%=mb.getNum()%>">삭제</a></td>
        </tr>

    <%} %>
</table>

</form>

 

 

3. MovieDao.jsp 작성

public ArrayList<MovieBean> getAllMovie(){
    getConnection();
    ArrayList<MovieBean> list = new ArrayList<MovieBean>();

    String sql = "select * from movie order by num";
    try {
        ps = conn.prepareStatement(sql);
        rs = ps.executeQuery();
        while(rs.next()) {
            int num = rs.getInt("num");
            String id  = rs.getString("id");
            String name  = rs.getString("name");
            int age = rs.getInt("age");
            String genre  = rs.getString("genre");
            String time  = rs.getString("time");
            int partner = rs.getInt("partner");
            String memo  = rs.getString("memo");

            MovieBean mb = new MovieBean(num,id,name,age,genre,time,partner,memo);
            list.add(mb);
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }finally {
        try {
            if(rs != null) rs.close();
            if(ps != null) ps.close();
            if(conn != null) conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    System.out.println("list.size():" + list.size());
    return list;
}//getAllMovie

 

4. MovieBean.jsp

package myPkg;

public class MovieBean {
	private int num;
    private String id;
    private String name;
    private int age;
    private String genre;
    private String time;
    private int partner;
    private String memo;
    
    public MovieBean() {
    	
    }
	public MovieBean(int num, String id, String name, int age, String genre, String time, int partner, String memo) {
		super();
		this.num = num;
		this.id = id;
		this.name = name;
		this.age = age;
		this.genre = genre;
		this.time = time;
		this.partner = partner;
		this.memo = memo;
	}
	public int getNum() {
		return num;
	}
	public void setNum(int num) {
		this.num = num;
	}
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getGenre() {
		return genre;
	}
	public void setGenre(String genre) {
		this.genre = genre;
	}
	public String getTime() {
		return time;
	}
	public void setTime(String time) {
		this.time = time;
	}
	public int getPartner() {
		return partner;
	}
	public void setPartner(int partner) {
		this.partner = partner;
	}
	public String getMemo() {
		return memo;
	}
	public void setMemo(String memo) {
		this.memo = memo;
	}
}

작성 순서

 

1. BookDao 에 multidelete 메서드 작성

public int multiDeleteBook(String[] no) {

    getConnection();
    int cnt = -1;
    String sql = "delete from book where no= ? ";
    System.out.println(11);
    for(int i=0; i<no.length-1; i++) {
        sql +=" or no=?";
    }	
    // delete from book where no or? or no? +...+ or no?

    try {
        ps=conn.prepareStatement(sql);
        for(int i=0; i<no.length; i++) {
            ps.setInt(i+1, Integer.parseInt(no[i]));
        }
        System.out.println(33);
        cnt = ps.executeUpdate();
    } catch (SQLException e) {
        e.printStackTrace();
    }finally {
        try {
            if(ps != null)
                ps.close();
            if(conn != null)
                conn.close();
        } catch(SQLException e) {
            e.printStackTrace();
        }
    }

return cnt;		
}

 

 

2. Proc 작성 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
  
  내가 선택한 번호 rowcheck에 담아 출력하기
  
<jsp:useBean id="bdao" class="myPkg.BookDao"/> 
  
    <%
    String[] no = request.getParameterValues("rowCheck");

    for(String str : no) {
        System.out.println(str);
    }
    int cnt = bdao.multiDeleteBook(no);
%>

<jsp:forward page ="select.jsp"/>

 

 

3. 화면 jsp작성

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import ="myPkg.*" %>
<%@ page import ="java.util.*" %>

select.jsp

<style type="text/css">
    table {
    width: 800px;
    margin: auto;
    border-collapse: collapse;   /* 테두리 겹침 제거 */
    text-align: center;
	}
	
	table th, table td {
	    border: 1px solid #999;      /* 기본 회색 테두리 */
	    padding: 8px;                /* 여백 */
	}
	
	table th {
	    background-color: #F6EAC2;   /* 헤더 배경색 */
	}
</style>

<script type="text/javascript">
    function insert(){
        location.href="insertForm.jsp"
    }
    function selectDelete(){
        flag = false;
        rowObj = document.getElementsByName("rowCheck");
        for(i=0;i<rowObj.length;i+=1){
            if(rowObj[i].checked){
                flag = true;
            }
        }
        if(!flag){
            alert('체크박스를 하나라도 선택하세요')
            return; // 아래코드를 만나지 않기 위함.
        }
        
        document.myform.submit(); 
        /* myform에서 submit을 누른것처럼 행동 ==> action으로 넘어간다. 
        선택한 체크박스 번호를 rowCheck에 담아 multiDelete로 넘어감
        */
        
        
    }
    function allDelete(obj){
        rowObj = document.getElementsByName("rowCheck");
        // obj.cheked: 체크했으면 true / 체크 안했으면 false
        if (obj.checked){
            // rowCheck 모두 체크 상태
            for(i=0;i<rowObj.length;i+=1){
                rowObj[i].checked = true;
            }

        } else{
            // rowCheck 모두 체크 해제상태
            for(i=0;i<rowObj.length;i+=1){
                rowObj[i].checked = false;
            }
        }
    }
</script>

<jsp:useBean id="bdao" class="myPkg.BookDao"/>

<%
    ArrayList<BookBean> lists = bdao.getAllbook();
%>
<form name="myform" action="multiDelete.jsp" > <!-- sumbit 클릭 -->
<input type= "button" value ="추가" onClick="insert()">
<input type= "button" value ="삭제" onClick="selectDelete()">

<table border="1">
    <tr>
    	<th><input type="checkbox" name="allcheck" onClick="allDelete(this)"></th>
		<th>번호</th>
        <th>제목</th>
        <th>저자</th>
        <th>출판사</th>
        <th>가격</th>
        <th>입고일</th>
        <th>배송비</th>
        <th>구매 가능 서점</th>
        <th>보유 수량</th>
        <th>수정</th>
        <th>삭제</th>
    </tr>
    
    
    <%for(BookBean bb : lists){%>
    <tr>
    	<td><input type="checkbox" name="rowCheck" value="<%=bb.getNo() %>"></td>
        <td><%=bb.getNo()%></td>
        <td><%=bb.getTitle()%> </td>
        <td><%=bb.getAuthor() %></td>
        <td><%=bb.getPublisher() %></td>
        <td><%=bb.getPrice() %></td>
        <td><%=bb.getDay() %></td>
        <td><%=bb.getKind() %></td>
        <td><%=bb.getBookstore() %></td>
        <td><%=bb.getCount()%></td>
        <td><a href = "updateForm.jsp?no=<%= bb.getNo() %>">수정</a></td>
        <td><a href = "deleteProc.jsp?no=<%= bb.getNo() %>">삭제</a></td>
    </tr>
    <%}    %> 
</table>


<a href ="insertForm.jsp">삽입폼</a>

</form>

 

 


📌 select.jsp 순서 정리 (다중삭제용)

1. <form> 시작 (action=multiDelete.jsp)

<form name="myform" action="multiDelete.jsp" method="post">

👉 체크박스들이 모두 <form> 안에 있어야 전송 가능

 

2. 버튼(추가, 삭제)

<input type="button" value="추가" onClick="insert()">
<input type="button" value="삭제" onClick="selectDelete()">
  • 추가 : insertForm.jsp 이동
  • 삭제 : 자바스크립트 selectDelete() 실행 → 체크박스 선택 여부 검사 후 document.myform.submit() 호출

 

3. 전체선택 체크박스

<th><input type="checkbox" name="allcheck" onClick="allDelete(this)"></th>

 

반복문으로 데이터 출력 (rowCheck 체크박스 포함)

</form> 닫기

JS 함수 (selectDelete(), allDelete())

 

 

4. 반복문으로 데이터 출력 + 개별 체크박스

<% for(BookBean bb : lists){ %>
<tr>
  <td><input type="checkbox" name="rowCheck" value="<%=bb.getNo()%>"></td>
  <td><%=bb.getNo()%></td>
  <td><%=bb.getTitle()%></td>
  ...
</tr>
<% } %>
  • rowCheck 라는 이름으로 체크된 값들(no)이 배열 형태로 넘어감

 

5. <form> 닫기

</form>

 

 

6. 자바스크립트 함수 작성

function selectDelete(){
    var flag = false;
    var rowObj = document.getElementsByName("rowCheck");

    for(var i=0; i<rowObj.length; i++){
        if(rowObj[i].checked){
            flag = true;
            break;
        }
    }
    if(!flag){
        alert("체크박스를 하나라도 선택하세요");
        return;
    }
    document.myform.submit(); 
}

function allDelete(obj){
    var rowObj = document.getElementsByName("rowCheck");
    for(var i=0; i<rowObj.length; i++){
        rowObj[i].checked = obj.checked;
    }
}

+ Recent posts