티스토리 뷰
반응형
- 사용 환경
1) DBMS : MySQL (GUI 프로그램: DBeaver)
2) Framework : Spring boot + Thymeleaf + Bootstrap
3) IDE : Intellij
오늘의 과제
1. Database에 저장한 기안문 정보를 웹페이지에 출력하기
→ 문제점 : JPQL 쿼리문 작성
2. Table을 클릭 시 기안문 세부 내용을 보여주도록 개발
→ 문제점 : Javascript 외에 방법이 있는지 궁금
3. 세부 내용을 가독성있게 디자인하기
→ 문제점 : Bootstrap 템플릿을 수정하지않고 수정해야함
1. Database에 저장한 기안문 정보를 웹페이지에 출력하기
1) DB에 저장된 기안문 정보
2) Spring boot에서 사용할 도메인 작성
* 특이사항
- MySQL의 datatype 중 timestamp를 이용하기 위해선 @Temporal(TemporalType.TIMESTAMP)를 이용
- MySQL의 Auto increment를 사용할 경우 @GeneratedValue(strategy = GenerationType.IDENTITY)를 사용
(MySQL의 기능 그대로 반영함.)
▣ Domain-Board
작성코드
더보기
package com.jun.DowooriVer2.domain;
import lombok.AccessLevel;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import java.util.Date;
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity
@Data
@Table(name = "Board_table")
public class Board {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "Board_id")
private Long id;
private String title;
private String empNum;
private String deptNum;
private String reason;
@Temporal(TemporalType.TIMESTAMP)
private Date startDate;
@Temporal(TemporalType.TIMESTAMP)
private Date endDate;
@Temporal(TemporalType.TIMESTAMP)
private Date writeDate;
private String ampm;
private String status;
}
▣ Repository - JpaBoardRepository
* 문제점
- 로그인시 받아온 empNum을 이용해 DB에 저장된 기안분 데이터를 가져오도록 JPQL 작성하는 과정에서 발생한 에러
Parameter value [1] did not match expected type [java.lang.String (n/a)]; nested exception is java.lang.IllegalArgumentException: Parameter value [1] did not match expected type [java.lang.String (n/a)]
org.springframework.dao.InvalidDataAccessApiUsageException: Parameter value [1] did not match expected type [java.lang.String (n/a)]; nested exception is java.lang.IllegalArgumentException: Parameter value [1] did not match expected type [java.lang.String (n/a)]
- 에러 발생 이유
▶ 받아온 empNum파라미터의 데이터 타입은 Long
@Override public List<Board> findAll(Long empNum) {
TypedQuery<Board> queryResult = em.createQuery("select b from Board b where b.empNum = :number", Board.class).setParameter("number", empNum);
* 해결방법
▶ JPQL setParameter에 필요한 데이터 타입은 String
@Override public List<Board> findAll(Long empNum) {
TypedQuery<Board> queryResult = em.createQuery("select b from Board b where b.empNum = :number", Board.class) .setParameter("number", String.valueOf(empNum)); // Long -> String으로!!
작성코드
더보기
package com.jun.DowooriVer2.repository;
import com.jun.DowooriVer2.domain.Board;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import java.util.List;
@Slf4j
@Repository
@RequiredArgsConstructor
public class JpaBoardRepository implements BoardRepository {
private final EntityManager em;
@Override
public List<Board> findAll(Long empNum) {
TypedQuery<Board> queryResult = em.createQuery("select b from Board b where b.empNum = :number", Board.class)
.setParameter("number", String.valueOf(empNum)); // Long -> String으로!!
List<Board> results = queryResult.getResultList();
return results;
}
}
3) model을 이용해 List<board> 객체를 home.html에 전달
* 특이사항
- model.addAttribute("객체이름", 객체)를 이용해 html로 전달
▣ Controller-HomeController
작성코드
더보기
@GetMapping("/home")
public String homeLogin(HttpServletRequest request, Model model) {
HttpSession session = request.getSession(false); //false : 새로 생성 X
if(session == null){
return "/";
}
Member loginMember = (Member) session.getAttribute(SessionConst.LOGIN_MEMBER);
// 세션에 회원데이터가 없으면 로그인창으로
if(loginMember == null){
return "/";
}
log.info("loginMember.getEmpNum >> "+ loginMember.getEmpNum());
Long empNum = loginMember.getEmpNum();
List<Board> boards = boardService.findAll(empNum);
model.addAttribute("boards", boards);
model.addAttribute("member", loginMember);
return "home";
}
2) thymeleaf 문법 for-each를 이용해 boards=List<board>를 뽑아 출력
* 특이사항
- th:block → 반복문을 사용할 구역을 정의할 때 사용
- th:each="board : ${boards}" → boards에 담긴 객체를 반복문을 이용해 뽑아냄
- th:text="${board.id}" → board에 담긴 id값을 text로 렌더링 후 웹페이지에 출력
▣ home.html
작성코드
더보기
<table class="table table-bordered" id="dataTable" width="100%" cellspacing="0">
<thead>
<tr>
<th>문서번호</th>
<th>문서종류</th>
<th>작성날짜</th>
<th>결재현황</th>
</tr>
</thead>
<tfoot>
<tr>
<th>문서번호</th>
<th>문서종류</th>
<th>작성날짜</th>
<th>결재현황</th>
</tr>
</tfoot>
<tbody>
<th:block th:each="board : ${boards}">
<tr>
<td th:text="${board.id}">문서번호</td>
<td th:text="${board.title}">문서종류</td>
<td th:text="${board.writeDate}"> 작성날짜 </td>
<td>
<span class="text btn btn-primary" th:text="${board.status}">결재현황</span>
</td>
</tr>
</th:block>
</tbody>
</table>
2. Table을 클릭 시 기안문 세부 내용을 보여주도록 개발
* 문제점
- Javascript를 이용하지 않고 table 클릭시 세부내용을 보여줄 수 있는 기능 개발
* 해결방법
- Bootstrap에서 제공하는 accordion 기능 사용하여 구현
1) 클릭시 기준이 될 tr태그(반복문 사용을 위해 board.id를 이용하여 해당 게시글 구분
<tr data-toggle="collapse" th:attr="data-target='#accordion_'+${board.id}" class="clickable" >
2) 클릭시 펼쳐질 td태그 (위에서 구분을 위한 board.id를 이용)
<td colspan="4" class="collapse" th:id="'accordion_'+${board.id}">
▣ home.html
작성코드
더보기
<table class="table table-bordered" id="dataTable" width="100%" cellspacing="0">
<thead>
<tr>
<th>문서번호</th>
<th>문서종류</th>
<th>작성날짜</th>
<th>더보기</th>
</tr>
</thead>
<tfoot>
<tr>
<th>문서번호</th>
<th>문서종류</th>
<th>작성날짜</th>
<th>진행상태</th>
</tr>
</tfoot>
<tbody>
<th:block th:each="board : ${boards}">
<tr data-toggle="collapse" th:attr="data-target='#accordion_'+${board.id}" class="clickable" >
<td th:text="${board.id}">문서번호</td>
<td th:text="${board.title}">문서종류</td>
<td th:text="${board.writeDate}"> 작성날짜 </td>
<td>
<span class="text btn btn-primary" th:text="${board.status}">
결재현황
</span>
</td>
</tr>
<tr>
<td colspan="4" class="collapse" th:id="'accordion_'+${board.id}">
<div>
<div>
<div>
<div>
<div>시작일</div>
<div th:text="${board.startDate}">시작일</div>
</div>
<div>
<div>종료일</div>
<div th:text="${board.endDate}">종료일</div>
</div>
<div>
<div>분류</div>
<div th:text="${board.ampm}">오전오후</div>
</div>
<div>
<div>사유</div>
<div th:text="${board.reason}">사유</div>
</div>
</div>
</div>
</div>
</td>
</tr>
</th:block>
</tbody>
</table>
3. 세부 내용을 가독성있게 디자인하기
* 문제점
- Bootstrap template을 customizing에 어려움
* 해결방법
<div style="display:flex">
<div style="width:50%">구분할 태그1</div>
<div style="width:50%">구분할 태그2</div>
</div>
▶참고사항
Flex는 수평이 될 요소들의 Container(box-container)에 display: flex;를 적용
(세부 속성이 필요하지 않은 경우도 많기 때문에 상당히 쉽고 빠르게 수평 요소를 구성할 수 있습니다.)
- 출처 https://heropy.blog/2018/11/24/css-flexible-box/
▣ home.html
작성코드
더보기
<table class="table table-bordered" id="dataTable" width="100%" cellspacing="0">
<thead>
<tr>
<th>문서번호</th>
<th>문서종류</th>
<th>작성날짜</th>
<th>더보기</th>
</tr>
</thead>
<tfoot>
<tr>
<th>문서번호</th>
<th>문서종류</th>
<th>작성날짜</th>
<th>진행상태</th>
</tr>
</tfoot>
<tbody>
<th:block th:each="board : ${boards}">
<tr data-toggle="collapse" th:attr="data-target='#accordion_'+${board.id}" class="clickable" >
<td th:text="${board.id}">문서번호</td>
<td th:text="${board.title}">문서종류</td>
<td th:text="${board.writeDate}"> 작성날짜 </td>
<td>
<span class="text btn btn-primary" th:text="${board.status}">
결재현황
</span>
</td>
</tr>
<tr>
<td colspan="4" class="collapse" th:id="'accordion_'+${board.id}">
<!-- card example 1-->
<div class="row">
<div class="col-xl-12 col-md-12 mb-4">
<div class="card border-left-primary shadow h-100 py-2">
<div class="card-body" style="display: flex;">
<div style="width: 50%;">
<div class="row no-gutters align-items-center">
<div class="col mr-2">
<div class="text-xs font-weight-bold text-primary text-uppercase mb-1">시작일</div>
<div th:text="${board.startDate}" class="h5 mb-0 font-weight-bold text-gray-800">시작일</div>
</div>
</div>
<div class="row no-gutters align-items-center">
<div class="col mr-2">
<div class="text-xs font-weight-bold text-primary text-uppercase mb-1">종료일</div>
<div th:text="${board.endDate}" class="h5 mb-0 font-weight-bold text-gray-800">종료일</div>
</div>
</div>
</div>
<div style="width: 50%;">
<div class="row no-gutters align-items-center">
<div class="col mr-2">
<div class="text-xs font-weight-bold text-primary text-uppercase mb-1">분류</div>
<div th:text="${board.ampm}" class="h5 mb-0 font-weight-bold text-gray-800">오전오후</div>
</div>
</div>
<div class="row no-gutters align-items-center">
<div class="col mr-2">
<div class="text-xs font-weight-bold text-primary text-uppercase mb-1">사유</div>
<div th:text="${board.reason}" class="h5 mb-0 font-weight-bold text-gray-800">사유</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- card example 1-->
</div>
</td>
</tr>
</th:block>
</tbody>
</table>
이상 개인프로젝트 사항 정리내용입니다.
긴 글 읽어주셔서 감사하고, 즐거운 연말연시 보내시길 바랍니다.!!!
반응형
'프로젝트 > 개인프로젝트' 카테고리의 다른 글
AWS EC2와 RDS로 SpringBoot 프로젝트 배포하기(1/3) (0) | 2023.03.05 |
---|---|
JPA(Hibernate)를 이용한 페이징(Pagination) 개발하기 (0) | 2023.02.16 |
Fullcalendar 출력하기 (0) | 2023.02.01 |
Fullcalendar 랜더링 에러 해결방법 (0) | 2023.01.30 |
Spring boot + Thymeleaf + ajax 이용 중복 이메일 체크 (0) | 2022.12.04 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- Java
- 항해99
- 회고록
- 개발자취준
- NLU
- 재기동
- 자바
- thymeleaf
- 코드트리
- Comparable
- BFS
- 유데미
- 취업리부트코스
- 객체정렬
- 챗봇
- Comparator
- dxdy
- 글또
- BufferedWriter
- 취리코
- RASA
- BufferedReader
- springboot
- script
- Spring
- JWT
- 코딩테스트
- 전자정부프레임워크
- 나만의챗봇
- 백준
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
글 보관함
반응형