팀프로젝트 5일차 

 

login

 

jsp

<%@ page contentType="text/html; charset=utf-8" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<!DOCTYPE html>
<html>
<head>
    <title><spring:message code="login.title" /></title>
</head>
<link rel="stylesheet" href="css/login.css?ver=1.3">
<body>

    <div class="wrapper">
    	<div class="container">
    	
    	<div class="login"><strong>LogIn</strong></div>
    
    <div class="login-form">
    <p>
        <label>
        <input type="text" name="mno" placeholder="사번을 입력하세요" class="input" />
        </label>
    </p>
    <p>
        <label>
        <input type="password" name="password" class="input" placeholder="비밀번호를 입력하세요"/>
        </label>
    </p>
    <p>
    <div id="wrongIdPassword" class="errorText"></div>
    </p>

    <button class="btn" id="login"><strong>로그인</strong></button>
    	</div>
    	</div>
    </div>
    <script>   var rootPath = window.location.origin</script>
	<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
	<script src="${rootPath}/js/login.js"></script>
</body>
</html>

 

js

$(document).ready(function() {
	// 페이지 번호 링크를 클릭했을 때의 처리
	$('#login').click(function(event) {
		event.preventDefault(); // 기본 동작 중단
        var mno= $('input[name="mno"]').val();
        var password = $('input[name="password"]').val();
		var pageUrl = 'login'; 
		if(!mno || !password){
			$("#wrongIdPassword").text("아이디 또는 비밀번호를 적어주세요");
			return;
			
		}
		// AJAX 요청
		$.ajax({
			url: pageUrl,
			type: 'POST',
			data:{
				mno:mno,
				password: password
			},
			success: function(data) {
			
				if(data === true){
					window.location.href = 'main';
				}else{
				  $("#wrongIdPassword").text("아이디 또는 비밀번호가 틀립니다.");
				}
				
			},
			error: function() {
				// AJAX 요청이 실패한 경우 처리할 내용
				alert('오류가 발생했습니다.');
			}
		});
	});
});

 

css

* {
  margin: 0;
  padding: 0;
  
}

body {
  background: #292b2c;
  font-family: roboto;
  user-select: none;
}

.container {
  width: 450px;
  margin: 30px auto;
  position: absolute;
    top: 50%;
  left: 50%;
  transform: translate(-50%,-50%);
}

.signup,
.login {
  width: 100%;
  background: #fff;
  float: left;
  height: 60px;
  line-height: 60px;
  text-align: center;
  cursor: pointer;
  text-transform: uppercase;
  
  font-size: 30px;
}

.signup-form,
.login-form {
  background: #fff;
  padding: 40px;
  clear: both;
  width: 100%;
  box-sizing: border-box;
  height: 400px;
}

.input {
  width: 100%;
  padding: 15px;
  box-sizing: border-box;
  margin-bottom: 15px;
  border: 2px solid #e9eaea;
  color: #3e3e40;
  font-size: 14px;
  outline: none;
  transform: all 0.5s ease;
}

.input:focus {
  border: 2px solid #34b3a0;
}

.btn {
  width: 100%;
  background: #292b2c;
  height: 60px;
  text-align: center;
  line-height: 60px;
  text-transform: uppercase;
  color: #fff;
  font-weight: bold;
  letter-spacing: 1px;
  cursor: pointer;
  margin-bottom: 30px;
  margin-top: 50px;
  font-size: 15px;
}

span a {
  text-decoration: none;
  color: #000;
}

::-webkit-input-placeholder {
  /* Chrome/Opera/Safari */
  color: #3e3e40;
  font-family: roboto;
}
::-moz-placeholder {
  /* Firefox 19+ */
  color: #3e3e40;
  font-family: roboto;
}
:-ms-input-placeholder {
  /* IE 10+ */
  color: #3e3e40;
  font-family: roboto;
}
:-moz-placeholder {
  /* Firefox 18- */
  color: #3e3e40;
  font-family: roboto;
}

/* youtube link */
.youtube {
  position: fixed;
  bottom: 10px;
  right: 10px;
  width: 160px;
  text-align: center;
  padding: 15px 10px;
  background: #bb0000;
  border-radius: 5px;
}

.youtube a {
  text-decoration: none;
  color: #fff;
  text-transform: capitalize;
  letter-spacing: 1px;
}
.errorText{
	color: red;
}

 

 

 

사원등록_ null ( 빈 값 ) 체크_ 

JSP

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>사원 등록</title>
</head>
<link rel="stylesheet" href="css/join.css?ver=1.3">
<body>

<div class="infoBar">
<h1>사원 정보 등록</h1>
<hr>
</div>


<form:form action="" method="post" modelAttribute="member" id="joinForm">
<div class="loginForm">

<p>
<label>이름:<br/>
<form:input path="name" />
<div id="messageDivId" class="errorText"></div>
</label>
</p>

<p>
<label>핸드폰 번호:<br/> 
<form:input path="phone" id="phone"/>
<div id="messageDivPass" class="errorText"></div>
</label>
</p>

<p>
<label>비밀번호:<br/>
<form:input style="border:none" path="password" id="password" readonly="true" />
</label>
</p>

<p>
<label>사번<br/> 
<form:input style="border:none" path="mno" readonly="true"/> <!-- 다음 사번 자동으로 가져오기 -->
</label>
</p>

<p>
        <label for="job">직위 선택:</label>
        <form:select path="job" id="job">
       		<option selected value="">---직위 선택---</option>
            <form:option value="사원">사원</form:option>
            <form:option value="주임">주임</form:option>
            <form:option value="대리">대리</form:option>
            <form:option value="과장">과장</form:option>
            <form:option value="부장">부장</form:option>
        </form:select>
        <div id="joberror" class="errorText"></div>
</p>

<p>
        <label for="deptno">부서 선택:</label>
        <form:select path="deptno" id="deptno">
        	<option selected value="">---부서 선택---</option>
            <form:option value="1">전산팀</form:option>
            <form:option value="2">인사팀</form:option>
            <form:option value="3">영업팀</form:option>
            <form:option value="4">경영기획팀</form:option>
        </form:select>
        <div id="deptnoerror" class="errorText"></div>
</p>

<input type="submit" value="등록" id="buttonS">
</div>
</form:form>


	<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
	<script src="js/join.js"></script>




</body>
</html>

 

CSS






  /* 폼 요소 스타일 */
  label {
    display: block;
    
    
  }
  
.errorText{
	color: red;
}
  
  hr {
  border: none;
  border-top: 2px solid #333; /* 수평선 색상 및 두께 지정 */
  margin: 10px 0; /* 수평선 위아래 여백 지정 */
  width : 270px;
}



  input[type="text"], select {
    
    
    
    border: 1px solid #ccc;
    border-radius: 3px;
    box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
  }
	
  input[type="submit"] {
    background-color: #333;
    color: #fff;
    padding: 10px 20px;
    border: none;
    border-radius: 3px;
    cursor: pointer;
  }
  
  input[type="submit"]:hover {
	  
	background-color: #5f5e5e; /* 호버 시 배경색 변경 */
    
	  
  }

 

JS


    
    
    
    // 회원 가입 null 빈칸 체크
$(document).ready(function() {
    $("#buttonS").click(function(event) { // 버튼의 id인 "buttonS"를 사용
        event.preventDefault(); // 기본 동작 중단

        // 입력값 확인
        var name = $("input[name='name']").val();
        var phone = $("input[name='phone']").val(); // 'phone'으로 수정
        var job = $("#job").val(); // 'job'은 select 요소의 id
        var deptno = $("#deptno").val(); // 'deptno'은 select 요소의 id

        if (!name) {
             $("#messageDivId").text("이름을 입력하세요.");
            return;
        }else {
			$("#messageDivId").text("");
		}
		
		if (!phone) {
             $("#messageDivPass").text("핸드폰번호를 입력하세요.");
            return;
        }else {
			$("#messageDivPass").text("");
		}
		
		if (!job) {
             $("#joberror").text("직위를 선택하세요.");
            return;
        }else {
			$("#joberror").text("");
		}
		
		if (!deptno) {
             $("#deptnoerror").text("부서를 선택하세요.");
            return;
        }else {
			$("#deptnoerror").text("");
		}
        
  
        $.ajax({
            type: "POST", // GET에서 POST로 변경
            url: "/joinForm", // GET에서 POST로 변경
            data: $("form").serialize(),
            success: function(response) {
                // 회원가입 완료 후 알림 표시
                alert("사원 등록 완료");
                // 로그인 페이지로 이동
               	 $('.mainView').html(response);
            },
            error: function(xhr, status, error) {
                alert("회원가입 중 오류가 발생했습니다. 다시 시도해주세요.");
            }
        });
    });
});


$(document).ready(function() {
    // 핸드폰 번호 입력 필드와 비밀번호 입력 필드의 ID 설정
    var phoneField = document.getElementById("phone");
    var passwordField = document.getElementById("password");

    // 핸드폰 번호 입력 필드의 'input' 이벤트 핸들러 등록
    phoneField.addEventListener("input", function() {
        var phoneNumber = phoneField.value;
        
        // 입력 값을 숫자만 남기고 나머지는 제거
        var cleanedPhoneNumber = phoneNumber.replace(/\D/g, "");

        // 특정 패턴에 맞게 번호를 다시 포맷
        if (cleanedPhoneNumber.length >= 3 && cleanedPhoneNumber.length <= 6) {
            cleanedPhoneNumber = cleanedPhoneNumber.substring(0, 3) + "-" + cleanedPhoneNumber.substring(3);
        }
        else if (cleanedPhoneNumber.length >= 7) {
            cleanedPhoneNumber = cleanedPhoneNumber.substring(0, 3) + "-" + cleanedPhoneNumber.substring(3, 7) + "-" + cleanedPhoneNumber.substring(7);
        }

        // 변경된 번호를 입력 필드에 설정
        phoneField.value = cleanedPhoneNumber;

        // 비밀번호 필드에 마지막 4자리를 설정
        var last4Digits = cleanedPhoneNumber.replace(/\D/g, "").slice(-4);
        passwordField.value = last4Digits;
    });
});

 

Controller

package com.study.springboot.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import com.study.springboot.member.dao.MemberDao;
import com.study.springboot.member.model.Member;

import lombok.extern.slf4j.Slf4j;

@Controller
@RequestMapping("/joinForm")
@Slf4j
public class JoinController {
	
    @Autowired
    private MemberDao memberDao;
    
    
    
    @GetMapping
    public String showRegisterForm(Model model) {
    	
    	Member member = new Member();
    	
    	Long nextMno = (long) memberDao.getNextMno();
    	member.setMno(nextMno);
    	
    	
        model.addAttribute("member", member);
        return "/member/joinForm"; // 회원 등록 폼을 표시할 뷰 페이지의 이름
    
    
    }

    @PostMapping
    public String registerMember(Member member) {
        memberDao.insertMember(member);
        return "/member/joinForm";
    }
	
}

 

 

 

'프로젝트 기반 자바(JAVA) 응용 SW개발자 취업과정' 카테고리의 다른 글

2023-09-13 82일차  (0) 2023.09.13
2023-09-12 81일차  (0) 2023.09.12
2023-09-08 79일차  (0) 2023.09.08
2023-09-07 78일차  (0) 2023.09.07
2023-09-06 77일차  (0) 2023.09.06

스프링 부트_MyBatis 사용해서_ 게시판 ( 답변, 페이징 )

 


DTO

 

package com.study.springboot.mvjsp.model;

import java.util.Date;

import lombok.Builder;
import lombok.ToString;

@Builder
@ToString
public class Article {

	private int id;
	private int groupId;
	private String sequenceNumber;
	private Date postingDate;
	private int readCount;
	private String writerName;
	private String password;
	private String title;
	private String content;
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public int getGroupId() {
		return groupId;
	}
	public void setGroupId(int groupId) {
		this.groupId = groupId;
	}
	public String getSequenceNumber() {
		return sequenceNumber;
	}
	public void setSequenceNumber(String sequenceNumber) {
		this.sequenceNumber = sequenceNumber;
	}
	public Date getPostingDate() {
		return postingDate;
	}
	public void setPostingDate(Date postingDate) {
		this.postingDate = postingDate;
	}
	public int getReadCount() {
		return readCount;
	}
	public void setReadCount(int readCount) {
		this.readCount = readCount;
	}
	public String getWriterName() {
		return writerName;
	}
	public void setWriterName(String writerName) {
		this.writerName = writerName;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public String getContent() {
		return content;
	}
	public void setContent(String content) {
		this.content = content;
	}

	public int getLevel() {
		if (sequenceNumber == null) {
			return -1;
		}
		if (sequenceNumber.length() != 16) {
			return -1;
		}
		if (sequenceNumber.endsWith("999999")) {
			return 0;
		}
		if (sequenceNumber.endsWith("9999")) {
			return 1;
		}
		if (sequenceNumber.endsWith("99")) {
			return 2;
		}
		return 3;
	}
	
}

 

페이징 커맨드객체

package com.study.springboot.mvjsp.model;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class ArticleListModel {
	
	private List<Article> articleList;
	private int requestPage;
	private int totalPageCount;
	private int startRow;
	private int endRow;

	public ArticleListModel() {
		this(Collections.<Article>emptyList(), 0, 0, 0, 0);
	}
	
	public ArticleListModel(List<Article> articleList, int requestPageNumber,
			int totalPageCount, int startRow, int endRow) {
		this.articleList = articleList;
		this.requestPage = requestPageNumber;
		this.totalPageCount = totalPageCount;
		this.startRow = startRow;
		this.endRow = endRow;
	}

	public List<Article> getArticleList() {
		return articleList;
	}
	
	public boolean isHasArticle() {
		return ! articleList.isEmpty();
	}

	public int getRequestPage() {
		return requestPage;
	}

	public int getTotalPageCount() {
		return totalPageCount;
	}

	public int getStartRow() {
		return startRow;
	}

	public int getEndRow() {
		return endRow;
	}
	
}

 

DAO( 인터페이스 )

package com.study.springboot.mvjsp.dao;

import java.util.List;

import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import com.study.springboot.mvjsp.model.Article;

@Mapper
public interface ArticleDao {
	
	@Select("select count(*) from article")
	int selectCount();
	
	@Select("select article_id, group_id, sequence_no, posting_date, "
			+ "read_count, writer_name, password, title, content from article "
			+ "order by sequence_no desc limit ${firstRow-1}, ${endRow - firstRow + 1}")
	 @Results(id="myResultId", value = {
	          @Result(property = "id", column = "article_id"),
	          @Result(property = "groupId", column = "group_id"),
	          @Result(property = "sequenceNumber", column = "sequence_no"),
	          @Result(property = "postingDate", column = "posting_date"),
	          @Result(property = "readCount", column = "read_count"),
	          @Result(property = "writerName", column = "writer_name")
	  }) //필드명과 컬럼명이 같으면 @Results 는 필요없다.
	List<Article> select(@Param("firstRow") int firstRow, @Param("endRow") int endRow);

	@Insert("insert into article "
			+ "(group_id, sequence_no, posting_date, read_count, "
			+ "writer_name, password, title, content) "
			+ "values (#{article.groupId}, #{article.sequenceNumber},"
			+ " now(), 0, #{article.writerName}, #{article.password},"
			+ " #{article.title}, #{article.content})")
	@Options(useGeneratedKeys = true, keyProperty = "id", keyColumn="article_id")
	int insert(@Param("article") Article article);
	
	@Select("select * from article where article_id = #{param1}")
	Article selectById(int articleId);
	
	@Update("update article set read_count = read_count + 1 where article_id = #{arg0}")
	void increaseReadCount(int articleId);
	
	@Select("select min(sequence_no) from article where sequence_no < #{param1} and sequence_no >= #{param2}")
	String selectLastSequenceNumber(String searchMaxSeqNum, String searchMinSeqNum);
	
	@Update("update article set title = #{article.title}, content = #{article.content} where article_id = #{article.id}")
	int update(@Param("article") Article article);
	
	@Delete("delete from article where article_id = #{param1}")
	void delete(int articleId);
}

 

Controller ( DAO만들고 테스트 해보기 ) 

package com.study.springboot.mvjsp.controller;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

import com.study.springboot.mvjsp.model.Article;
import com.study.springboot.mvjsp.model.ArticleListModel;
import com.study.springboot.mvjsp.service.ArticleNotFoundException;
import com.study.springboot.mvjsp.service.ListArticleService;
import com.study.springboot.mvjsp.service.ReadArticleService;

@Controller
public class MvController {
	
	@Autowired
	ListArticleService listSerivce;
	
	@Autowired
	ReadArticleService readArticleService;
	
	@GetMapping("/list")
	public String list(HttpServletRequest request, Model model) {
		String pageNumberString = request.getParameter("p");
		int pageNumber = 1;
		if (pageNumberString != null && pageNumberString.length() > 0) {
			pageNumber = Integer.parseInt(pageNumberString);
		}
		ArticleListModel articleListModel = listSerivce.getArticleList(pageNumber);
		request.setAttribute("listModel", articleListModel);
		
		if (articleListModel.getTotalPageCount() > 0) {
			int beginPageNumber = 
				(articleListModel.getRequestPage() - 1) / 10 * 10 + 1;
			int endPageNumber = beginPageNumber + 9;
			if (endPageNumber > articleListModel.getTotalPageCount()) {
				endPageNumber = articleListModel.getTotalPageCount();
			}
			model.addAttribute("beginPage", beginPageNumber);
			model.addAttribute("endPage", endPageNumber);
		}
		return "/list_view";
	}
	
	@GetMapping("/read")
	public String read(HttpServletRequest request, Model model) {
		int articleId = Integer.parseInt(request.getParameter("articleId"));
		String viewPage = null;
		try {
			Article article = readArticleService.readArticle(articleId);
			request.setAttribute("article", article);
			viewPage = "/read_view";
		} catch(ArticleNotFoundException ex) {
			viewPage = "/article_not_found";
		}
		return viewPage;
	}

}

 

Service

package com.study.springboot.mvjsp.service;

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

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.study.springboot.mvjsp.dao.ArticleDao;
import com.study.springboot.mvjsp.model.Article;

@Service
public class ArticleCheckHelper {
	
	@Autowired
	ArticleDao articleDao;

	public Article checkExistsAndPassword(int articleId, String password) 
			        throws ArticleNotFoundException, InvalidPasswordException{

		Article article = articleDao.selectById(articleId);
		if (article == null) {
			throw new ArticleNotFoundException(
					"게시 글이 존재하지 않음: " + articleId);
		}
		if (!checkPassword(article.getPassword(), password)) {
			throw new InvalidPasswordException("패스워드 오류");
		}
		return article;
	}

	private boolean checkPassword(String realPassword, String userInputPassword) {
		if (realPassword == null) {
			return false;
		}
		if (realPassword.length() == 0) {
			return false;
		}
		return realPassword.equals(userInputPassword);
	}

}
package com.study.springboot.mvjsp.service;

public class ArticleNotFoundException extends Exception {

	public ArticleNotFoundException(String msg) {
		super(msg);
	}

}
package com.study.springboot.mvjsp.service;

public class CannotReplyArticleException extends Exception {

	public CannotReplyArticleException(String message) {
		super(message);
	}

}
package com.study.springboot.mvjsp.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.study.springboot.mvjsp.dao.ArticleDao;

@Service
public class DeleteArticleService {

	@Autowired
	ArticleDao articleDao;
	
	public void deleteArticle(DeleteRequest deleteRequest)
			throws ArticleNotFoundException, InvalidPasswordException {

			ArticleCheckHelper checkHelper = new ArticleCheckHelper();
			checkHelper.checkExistsAndPassword(deleteRequest.getArticleId(),
					                             deleteRequest.getPassword());
			
			articleDao.delete(deleteRequest.getArticleId());

	}
}
package com.study.springboot.mvjsp.service;

public class DeleteRequest {
	
	private int articleId;
	private String password;
	
	public int getArticleId() {
		return articleId;
	}
	public void setArticleId(int articleId) {
		this.articleId = articleId;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	
}
package com.study.springboot.mvjsp.service;

public class IdGenerationFailedException extends Exception {

	public IdGenerationFailedException(Throwable cause) {
		super(cause);
	}
}
package com.study.springboot.mvjsp.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class IdGenerator {

	@Autowired
	JdbcTemplate jdbcTemplate;
	
	@Transactional
	public int generateNextId(String sequenceName) {

		String sql = "select next_value from id_sequence " +
				     "where sequence_name = ? for update";
		int id = this.jdbcTemplate.queryForObject(sql, 
				(rs, n)-> rs.getInt(1), sequenceName);
		id++;
		sql = "update id_sequence set next_value = ? " +
				  "where sequence_name = ?";
		this.jdbcTemplate.update(sql, id, sequenceName);
		return id;
	}

}
package com.study.springboot.mvjsp.service;

public class InvalidPasswordException extends Exception {

	public InvalidPasswordException(String message) {
		super(message);
	}
	
}
package com.study.springboot.mvjsp.service;

public class LastChildAleadyExistsException extends Exception {

	public LastChildAleadyExistsException(String message) {
		super(message);
	}

}
package com.study.springboot.mvjsp.service;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.study.springboot.mvjsp.dao.ArticleDao;
import com.study.springboot.mvjsp.model.Article;
import com.study.springboot.mvjsp.model.ArticleListModel;

@Service
public class ListArticleService {

	@Autowired
	ArticleDao articleDao;

	public static final int COUNT_PER_PAGE = 10;

	public ArticleListModel getArticleList(int requestPageNumber) {
		if (requestPageNumber < 0) {
			throw new IllegalArgumentException("page number < 0 : " + requestPageNumber);
		}

		int totalArticleCount = articleDao.selectCount();

		if (totalArticleCount == 0) {
			return new ArticleListModel();
		}

		int totalPageCount = calculateTotalPageCount(totalArticleCount);

		int firstRow = (requestPageNumber - 1) * COUNT_PER_PAGE + 1;
		int endRow = firstRow + COUNT_PER_PAGE - 1;

		if (endRow > totalArticleCount) {
			endRow = totalArticleCount;
		}
		List<Article> articleList = articleDao.select(firstRow, endRow);

		ArticleListModel articleListView = new ArticleListModel(articleList, requestPageNumber, totalPageCount,
				firstRow, endRow);
		return articleListView;

	}

	private int calculateTotalPageCount(int totalArticleCount) {
		if (totalArticleCount == 0) {
			return 0;
		}
		int pageCount = totalArticleCount / COUNT_PER_PAGE;
		if (totalArticleCount % COUNT_PER_PAGE > 0) {
			pageCount++;
		}
		return pageCount;
	}
}
package com.study.springboot.mvjsp.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.study.springboot.mvjsp.dao.ArticleDao;
import com.study.springboot.mvjsp.model.Article;

@Service
public class ReadArticleService {
	
	@Autowired
	ArticleDao articleDao;

	public Article readArticle(int articleId) throws ArticleNotFoundException {
		return selectArticle(articleId, true);
	}

	private Article selectArticle(int articleId, boolean increaseCount) throws ArticleNotFoundException {

			Article article = articleDao.selectById(articleId);
			if (article == null) {
				throw new ArticleNotFoundException(
						"게시글이 없음: " + articleId);
			}
			if (increaseCount) {
				articleDao.increaseReadCount( articleId);
				article.setReadCount(article.getReadCount() + 1);
			}
			return article;

	}

	public Article getArticle(int articleId) throws ArticleNotFoundException {
		return selectArticle(articleId, false);
	}
}

JSPList

<%@ page contentType="text/html; charset=euc-kr" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
	response.setHeader("Pragma", "No-cache");
	response.setHeader("Cache-Control", "no-cache");
	response.addHeader("Cache-Control", "no-store");
	response.setDateHeader("Expires", 1L);
%>
<html>
<head><title>게시글 목록</title></head>
<body>
<table border="1">
	<c:if test="${listModel.totalPageCount > 0}">
	<tr>
		<td colspan="5">
		${listModel.startRow}-${listModel.endRow}
		[${listModel.requestPage}/${listModel.totalPageCount}]
		</td>
	</tr>
	</c:if>
	
	<tr>
		<td>글 번호</td>
		<td>제목</td>
		<td>작성자</td>
		<td>작성일</td>
		<td>조회수</td>
	</tr>
	
<c:choose>
	<c:when test="${listModel.hasArticle == false}">
	<tr>
		<td colspan="5">
			게시글이 없습니다.
		</td>
	</tr>
	</c:when>
	<c:otherwise>
	<c:forEach var="article" items="${listModel.articleList}">
	<tr>
		<td>${article.id}</td>
		<td>
			<c:if test="${article.level > 0}">
			<c:forEach begin="1" end="${article.level}">-</c:forEach>&gt;
			</c:if>
			<c:set var="query" 
				value="articleId=${article.id}&p=${listModel.requestPage}"/>
			<a href="<c:url value="/read?${query}"/>">
			${article.title}
			</a>
		</td>
		<td>${article.writerName}</td>
		<td>${article.postingDate}</td>
		<td>${article.readCount}</td>
	</tr>
	</c:forEach>
	<tr>
		<td colspan="5">
		
		<c:if test="${beginPage > 10}">
			<a href="<c:url value="/list?p=${beginPage-1}"/>">이전</a>
		</c:if>
		<c:forEach var="pno" begin="${beginPage}" end="${endPage}">
		<a href="<c:url value="/list?p=${pno}" />">[${pno}]</a>
		</c:forEach>
		<c:if test="${endPage < listModel.totalPageCount}">
			<a href="<c:url value="/list?p=${endPage + 1}"/>">다음</a>
		</c:if>
		</td>
	</tr>
	</c:otherwise>
</c:choose>
	
	<tr>
		<td colspan="5">
			<a href="writeForm.jsp">글쓰기</a>
		</td>
	</tr>	
</table>
</body>
</html>

read_view

<%@ page contentType="text/html; charset=euc-kr" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%
	response.setHeader("Pragma", "No-cache");
	response.setHeader("Cache-Control", "no-cache");
	response.addHeader("Cache-Control", "no-store");
	response.setDateHeader("Expires", 1L);
%>
<html>
<head><title>글 읽기</title></head>
<body>
<table>
<tr>
	<td>제목</td>
	<td>${article.title}</td>
</tr>
<tr>
	<td>작성자</td>
	<td>${article.writerName}</td>
</tr>
<tr>
	<td>작성일</td>
	<td><fmt:formatDate value="${article.postingDate}" 
		pattern="yyyy-MM-dd" /></td>
</tr>
<tr>
	<td>내용</td>
	<td>
		<pre><c:out value="${article.content}" /></pre>
	</td>
</tr>
<tr>
	<td colspan="2">
	<a href="list?p=${param.p}">목록보기</a>
	<a href="reply_form.jsp?parentId=${article.id}&p=${param.p}">답변쓰기</a>
	<a href="update_form.jsp?articleId=${article.id}&p=${param.p}">수정하기</a>
	<a href="delete_form.jsp?articleId=${article.id}">삭제하기</a>
	</td>
</tr>
</table>
</body>
</html>

 

 

결과

'프로젝트 기반 자바(JAVA) 응용 SW개발자 취업과정' 카테고리의 다른 글

2023-09-12 81일차  (0) 2023.09.12
2023-09-11 80일차  (0) 2023.09.11
2023-09-07 78일차  (0) 2023.09.07
2023-09-06 77일차  (0) 2023.09.06
2023-09-05 76일차  (0) 2023.09.05

팀프로젝트 4일차 스프링부트_사원목록 조회, 검색, 페이징 기능 

 

DTO

package com.study.springboot.member.model;

import java.time.LocalDateTime;

import com.study.springboot.member.service.WrongIdPasswordException;

import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;


@Getter
@NoArgsConstructor
@Setter
public class Member {
    private Long mno;
    private String name;
    private String password;
    private String phone;
    private LocalDateTime hiredate;
    private String job;
    private Integer deptno;
    private String dname;
    private String loc;
    
    // 검색 필터
    private String type;
    private String keyword;
    
    public Member(Long mno, String name, String password, String phone, LocalDateTime hiredate, String job, Integer deptno) {
        this.mno = mno;
        this.name = name;
        this.password = password;
        this.phone = phone;
        this.hiredate = hiredate;
        this.job = job;
        this.deptno = deptno;

        		
    }
    
    
    
    
    

    // setHiredate 메소드를 수정
    public void setHiredate(LocalDateTime hiredate) {
        this.hiredate = hiredate;
    }

    // setDepartment 메소드를 수정
    public void setDepartment(Department department) {
        this.deptno = department.getDeptno();
    }
    


    public void changePassword(String oldPassword, String newPassword) {
        if (!password.equals(oldPassword)) {
            throw new WrongIdPasswordException();
        }
        this.password = newPassword;
    }

    public boolean matchPassword(String password) {
        return this.password.equals(password);
    }

    public void setMno(Long mno) {
        this.mno = mno;
    }
}

 

페이징

package com.study.springboot.member.model;

import java.util.List;



public class MemberPage {

	@Override
	public String toString() {
		return "BoardPage [total=" + total + ", currentPage=" + currentPage + ", content=" + content + ", totalPages="
				+ totalPages + ", startPage=" + startPage + ", endPage=" + endPage + "]";
	}

	private int total;
	private int currentPage;
	private List<Member> content;
	private int totalPages;
	private int startPage;
	private int endPage;

	public MemberPage(int total, int currentPage, int size, List<Member> content) {
		this.total = total;
		this.currentPage = currentPage;
		this.content = content;
		if (total == 0) {
			totalPages = 0;
			startPage = 0;
			endPage = 0;
		} else {
			totalPages = total / size;
			if (total % size > 0) {
				totalPages++;
			}
			int modVal = currentPage % 5;
			startPage = currentPage / 5 * 5 + 1;
			if (modVal == 0) startPage -= 5;
			
			endPage = startPage + 4;
			if (endPage > totalPages) endPage = totalPages;
		}
	}

	public int getTotal() {
		return total;
	}

	public boolean hasNoArticles() {
		return total == 0;
	}

	public boolean hasArticles() {
		return total > 0;
	}
	
	public int getCurrentPage() {
		return currentPage;
	}

	public int getTotalPages() {
		return totalPages;
	}

	public List<Member> getContent() {
		return content;
	}

	public int getStartPage() {
		return startPage;
	}
	
	public int getEndPage() {
		return endPage;
	}
}

 

DAO

	// 사원 목록 출력
	public List<Member> listAll(int page, int size) {
	    int offset = (page - 1) * size;
	    String sql = "SELECT m.mno, m.name, m.phone, m.hiredate, m.job, d.dname, d.loc " +
	                 "FROM member m " +
	                 "LEFT JOIN department d ON m.deptno = d.deptno " +
	                 "LIMIT ?, ?";

	    return jdbcTemplate.query(
	        new PreparedStatementCreator() {
	            @Override
	            public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
	                PreparedStatement ps = con.prepareStatement(sql);
	                ps.setInt(1, offset);
	                ps.setInt(2, size);
	                return ps;
	            }
	        },
	        new RowMapper<Member>() {
	            @Override
	            public Member mapRow(ResultSet rs, int rowNum) throws SQLException {
	                Member member = new Member();
	                member.setMno((long) rs.getInt("mno"));
	                member.setName(rs.getString("name"));
	                member.setPhone(rs.getString("phone"));

	                // hiredate 컬럼을 LocalDateTime으로 변환
	                Timestamp hiredateTimestamp = rs.getTimestamp("hiredate");
	                member.setHiredate(hiredateTimestamp != null ? hiredateTimestamp.toLocalDateTime() : null);

	                member.setJob(rs.getString("job"));

	                member.setDname(rs.getString("dname"));
	                member.setLoc(rs.getString("loc"));

	                return member;
	            }
	        });
	}
	// 페이징 기능에 사용
	public int getTotalMemberCount() {
	    String sql = "SELECT COUNT(*) FROM member";
	    return jdbcTemplate.queryForObject(sql, Integer.class);
	}
	


	// 검색
	public List<Member> searchMembers(String type, String keyword) {
	    // 검색 쿼리 작성 (예: 이름으로 검색)
	    String sql = "SELECT m.mno, m.name, m.phone, m.hiredate, m.job, d.dname, d.loc " +
	                 "FROM member m " +
	                 "LEFT JOIN department d ON m.deptno = d.deptno " +
	                 "WHERE " + type + " LIKE ?";

	    String likeKeyword = "%" + keyword + "%";

	    return jdbcTemplate.query(
	        new PreparedStatementCreator() {
	            @Override
	            public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
	                PreparedStatement ps = con.prepareStatement(sql);
	                ps.setString(1, likeKeyword);
	                return ps;
	            }
	        },
	        new RowMapper<Member>() {
	            @Override
	            public Member mapRow(ResultSet rs, int rowNum) throws SQLException {
	                Member member = new Member();
	                member.setMno((long) rs.getInt("mno"));
	                member.setName(rs.getString("name"));
	                member.setPhone(rs.getString("phone"));

	                // hiredate 컬럼을 LocalDateTime으로 변환
	                Timestamp hiredateTimestamp = rs.getTimestamp("hiredate");
	                member.setHiredate(hiredateTimestamp != null ? hiredateTimestamp.toLocalDateTime() : null);

	                member.setJob(rs.getString("job"));

	                member.setDname(rs.getString("dname"));
	                member.setLoc(rs.getString("loc"));

	                return member;
	            }
	        });
	}

 

Service

package com.study.springboot.member.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.study.springboot.member.dao.MemberDao;
import com.study.springboot.member.model.Member;

@Service
public class MemberService {

	@Autowired
	private MemberDao memberDao;


	public MemberInfo authenticate(Long mno, String password) {
		Member member = memberDao.selectByMno(mno);
		if (member == null) {
			throw new WrongIdPasswordException();
		}
		if (!member.matchPassword(password)) {
			throw new WrongIdPasswordException();
		}
		return new MemberInfo(member.getMno(),

				member.getName(), member.getPhone(), member.getJob(), member.getDeptno());
	}
	
    public List<Member> searchMembers(String type, String keyword) {
        return memberDao.searchMembers(type, keyword);
    }

}

 

Controller

package com.study.springboot.controller;



import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

import com.study.springboot.member.dao.MemberDao;
import com.study.springboot.member.model.Member;
import com.study.springboot.member.service.MemberService;

import lombok.extern.slf4j.Slf4j;



@Controller
@Slf4j
public class MemberListController {
    @Autowired
	private MemberDao memberDao;

    @Autowired
    private MemberService memberService;
   
    
    @GetMapping("/memberList")
    public String listMembers(Model model,
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(defaultValue = "10") int size) {
        int totalMemberCount = memberDao.getTotalMemberCount();
        int totalPages = (int) Math.ceil((double) totalMemberCount / size);

        List<Member> members = memberDao.listAll(page, size);
        model.addAttribute("members", members);
        model.addAttribute("page", page);
        model.addAttribute("size", size);
        model.addAttribute("totalPages", totalPages);

        log.info("Listing members: {}", members);
        System.out.println(members);
        return "/login/memberList"; 
    }
    
    @GetMapping("/getSearchList")
    public String getSearchList(@RequestParam("type") String type,
    								   @RequestParam("keyword") String keyword, 
    								   Model model){
    	List<Member> members = memberService.searchMembers(type, keyword);
    	model.addAttribute("members", members);
    	return "/login/memberList";
    }

    
    

    


    
    
    

}

 

JS

$(document).ready(function () {
    // 검색 버튼을 클릭했을 때
    $('.search').click(function (event) {
        event.preventDefault(); // 기본 동작 중단

        // 입력한 데이터 가져오기
        var type = $('.type').val();
        var keyword = $('.keyword').val();
        if (keyword == null) {
            alert("검색내용을 입력하세요.");
            return; // 함수 종료
        }
        // AJAX 요청
        $.ajax({
            url: '/getSearchList', // 적절한 URL로 수정
            type: 'Get',
            data: {
                type: type,
                keyword: keyword,
                page: 1 // 검색 결과를 첫 번째 페이지로 설정
            },
            success: function (res) {
                $('.mainView').html(res);
            },
            error: function () {
                // AJAX 요청이 실패한 경우 처리할 내용
                alert('오류가 발생했습니다.');
            }
        });
    });

    // 페이지 번호 링크를 클릭했을 때의 처리
    $(document).on('click', '.search_page', function (event) {
        event.preventDefault(); // 기본 동작 중단

        var pageUrl = $(this).attr('href');

        // AJAX 요청
        $.ajax({
            url: pageUrl,
            type: 'GET',
            success: function (data) {
                // AJAX 요청이 성공하면 data를 적절한 방식으로 처리하여 페이지 업데이트
                $('.mainView').html(data);
            },
            error: function () {
                // AJAX 요청이 실패한 경우 처리할 내용
                alert('오류가 발생했습니다.');
            }
        });
    });
});

 

JSP

<%@ page contentType="text/html; charset=utf-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>사원 목록</title>
    
        <style>

        .pagination {
            display: inline-block;
            padding: 0;
        }

        .pagination li {
            display: inline;
            margin-right: 5px;
        }



    	</style>

</head>
<body>
    <h2>사원 목록</h2>
    <table border="1">
        <thead>
            <tr>
                <th>사번</th>
                <th>이름</th>
                <th>핸드폰</th>
                <th>입사일</th>
                <th>직급</th>
                <th>부서명</th>
                <th>부서 위치</th>
            </tr>
        </thead>
        <tbody id ="usertable">
            <c:forEach items="${members}" var="member">
                <tr>
                    <td>${member.mno}</td>
                    <td>${member.name}</td>
                    <td>${member.phone}</td>
                    <td>${member.hiredate}</td>
                    <td>${member.job}</td>
                    <td>${member.dname}</td>
                    <td>${member.loc}</td>
                </tr>
            </c:forEach>
            
        </tbody>
    </table>
<!-- 페이지 번호 표시 부분 -->
<div class="page-box">
    <c:if test="${totalPages > 1}">
        <ul class="pagination">
            <li class="<c:if test="${page == 1}">disabled</c:if>">
                <a class="search_page" href="/memberList?page=${page - 1}" aria-label="Previous">
                    <span aria-hidden="true">&laquo;</span>
                </a>
            </li>
            <c:forEach begin="1" end="${totalPages}" var="pageNumber">
                <li class="<c:if test="${page == pageNumber}">active</c:if>">
                    <a class="search_page" href="/memberList?page=${pageNumber}">${pageNumber}</a>
                </li>
            </c:forEach>
            <li class="<c:if test="${page == totalPages}">disabled</c:if>">
                <a class="search_page" href="/memberList?page=${page + 1}" aria-label="Next">
                    <span aria-hidden="true">&raquo;</span>
                </a>
            </li>
        </ul>
    </c:if>
</div>

<div>
    <select name="type" class="type">
        <option selected value="">검색 내용 선택</option>
        <option value="mno">사번 검색</option>
        <option value="name">이름 검색</option>
        <option value="dname">부서명 검색</option>
    </select>
    <input type="text" class="keyword" name="keyword" value="" />
    <button class="search">검색</button>
</div>

<!-- <script>
function getSearchList() {
    $.ajax({
        type: 'GET',
        url: "/getSearchList",
        data: $("form[name=search-form]").serialize(),
        success: function (result) {
        	
        	$(#usertable).html(result);

        }
    });
    return false; // 페이지 새로고침 방지
}
</script> -->

	<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
	<script src="js/memberList.js"></script>
    
</body>
</html>

 

 

결과

 

사번, 이름, 부서 검색 기능 

'프로젝트 기반 자바(JAVA) 응용 SW개발자 취업과정' 카테고리의 다른 글

2023-09-11 80일차  (0) 2023.09.11
2023-09-08 79일차  (0) 2023.09.08
2023-09-06 77일차  (0) 2023.09.06
2023-09-05 76일차  (0) 2023.09.05
2023-09-04 75일차  (0) 2023.09.04

sdsd

'프로젝트 기반 자바(JAVA) 응용 SW개발자 취업과정' 카테고리의 다른 글

2023-09-08 79일차  (0) 2023.09.08
2023-09-07 78일차  (0) 2023.09.07
2023-09-05 76일차  (0) 2023.09.05
2023-09-04 75일차  (0) 2023.09.04
2023-09-01 74일차  (0) 2023.09.01

asdsad

'프로젝트 기반 자바(JAVA) 응용 SW개발자 취업과정' 카테고리의 다른 글

2023-09-07 78일차  (0) 2023.09.07
2023-09-06 77일차  (0) 2023.09.06
2023-09-04 75일차  (0) 2023.09.04
2023-09-01 74일차  (0) 2023.09.01
2023-08-31 73일차  (0) 2023.08.31

+ Recent posts