본문 바로가기
💻 뚝딱뚝딱/방통대CBT

[개발일지#003] 기본 부트스트랩 적용 / 기출문제 전체조회 구현

by 뚜루리 2024. 6. 7.
728x90
320x100

 

 

1. 기본 부트스트랩 적용

※ 예전에는 테마 하나를 정해서 그 부트스트랩 테마를 통째로 옮기는 방식으로 사용했다면 이번엔 딱 기본적인 부트스트랩만 가져오고, 간단하게 커스텀해가면서 만들어볼 예정.

 

1-1. 부트스트랩 사이트에서 기본 부트스트랩 파일 다운 받기

  1. https://getbootstrap.kr/docs/5.3/getting-started/introduction/ 접속
  2. 좌측에 [다운로드] 클릭
  3. '컴파일된 CSS와 JS' 하단에 [다운로드] 클릭하면 파일이 다운로드 됨.

 

 

1-2. 다운받은 부트스트랩 폴더를 스프링부트 프로젝트에 적용하기

 

파일 압축 풀기

 

압축 풀면 css, js 두 개의 폴더가 보임. 

 

프로젝트에서 Resources - static 아래의 경로에 폴더 옮기기

 

※ 꼭  Resources - static 아래에 넣어야 하나요?

예! 기본적으로 static 아래에 넣어야 스프링이 자동으로 인식함!

 

그치만 경로를 static 아래로 안하고 싶다면 변경할 수 도 있음. 

ex) 만약에 경로를 src/main/resources 밑으로 변경하고 싶다면?

application.properties  파일에

spring.resources.static-locations=classpath:/resources/

윗 줄을 추가하면 됨.

 
 
 

1-3. html에 부트스트랩 적용하기

<!DOCTYPE html>
<html lang="ko"
      xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
    <meta charset="UTF-8">
    <!-- 아래와 같이 추가 -->
    <link href="/css/bootstrap.min.css" rel="stylesheet">
    <title>Title</title>
</head>
<body>

부트스트랩을 적용하려는 html 상단에 이렇게 추가해주면 된다.

 


 

2. 기출문제 전체조회 구현

ExamInfo.java

package knou.cbt.domain.exam;

import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;

@Getter
@Setter
@RequiredArgsConstructor
public class ExamInfo {

    private String examId;
    private String departmentName;
    private String subjectId;
    private String subjectName;
    private int examYear;
    private int grade;
    private int semester;
    private int examCategory;
    private int questionId;
    private String useYn;

}

기출문제를 목록으로 전체조회하는 화면에는 학과 / 과목 / 시험 테이블을 모두 Join해야 원하는 정보를 가져올 수 있어, 이 정보를 모두 담을 수 있는 examInfo 객체를 하나 생성해 주었다.

 

ExamService.Java

package knou.cbt.domain.exam;


import java.util.List;

public interface ExamService {

    List<ExamInfo> allExamList(int page, int size);

    int countExams();

}

 

ExamServiceImpl.Java

package knou.cbt.domain.exam;

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
@RequiredArgsConstructor
public class ExamServiceImpl implements ExamService{

    private final ExamMapper examMapper;

    @Override
    public List<ExamInfo> allExamList(int page, int size) {
        int offset = (page - 1) * size;
        return examMapper.allExamList(offset, size);
    }

    @Override
    public int countExams() {
        return examMapper.countExams();
    }


}

페이징 처리를 위해 위와 같이 구현함. 

 

ExamMapper.java

package knou.cbt.domain.exam;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.util.List;

@Mapper
public interface ExamMapper {

    List<ExamInfo> allExamList(@Param("offset") int offset, @Param("limit") int limit);

    int countExams();


}

 

ExamMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="knou.cbt.domain.exam.ExamMapper">

    <select id="allExamList" resultType="knou.cbt.domain.exam.ExamInfo">
        SELECT
                   EXAM_ID
                 , (SELECT DEPARTMENT_NAME
                    FROM DEPARTMENT
                    WHERE DEPARTMENT_ID LIKE SUBSTR(EXAM_ID, 1, 1)|| '%') AS departmentName
                 , SUBJECT_ID
                 , (SELECT SUBJECT_NAME
                    FROM SUBJECT
                    WHERE SUBJECT_ID LIKE '%' || SUBSTR(SUBJECT_ID, 1, 1)) AS subjectName
                , SUBJECT_ID
                , EXAM_YEAR
                , GRADE
                , SEMESTER
                , EXAM_CATEGORY
        FROM EXAM
        WHERE USE_YN = 'Y'
        ORDER BY EXAM_ID
            LIMIT #{offset}, #{limit}
    </select>

    <select id="countExams" resultType="int">
        SELECT COUNT(*)
        FROM EXAM
        WHERE USE_YN = 'Y'
        ORDER BY EXAM_ID
    </select>

</mapper>

 

별 다를 것이 없는 Xml이지만, 이전 사이드 프로젝트를 할 당시와 다른 점이 하나 있다면!

    <select id="findByLoginId" parameterType="java.lang.String" resultType="seulgi.bookRentalSystem.domain.member.Member">
        SELECT
               MEMBER_ID AS mermberId
             , MEMBER_NAME AS memberName
             , PASSWORD
             , JOIN_DATE AS joinDate
            FROM MEMBER_TB WHERE MEMBER_ID = #{loginId}
    </select>

예전의 Xml에서는 데이터베이스의 MEMBER_ID 컬럼이고 Java의 Dto 변수명이 memberd일 경우, 자동으로 카멜변환을 해주지 못해서 급한대로 alias를 따로 줬었음. 그리 번거로운 일은 아니지만, 컬럼이 많아질수록 alias를 매번 줘야하는 번거로움이 있었음. 근데 이번에는 자동으로 카멜표기법으로 변환할 수 있도록 설정을 변경함

 

※ 카멜표기법이 되게끔 하는 방법은 아래의 URL에 따로 포스팅했음

 

[Spring boot(스프링부트)/Mybatis] Xml에 카멜표기법 설정하기

Mybatis를 사용하여 xml을 사용할 때 예를들어 데이터베이스의 MEMBER_ID 컬럼이고 Java의 Dto 변수명이 memberd일 경우, 자동으로 카멜변환을 해주지 못해서 급한대로 아래처럼 alias를 따로 줬었음. 그리

ddururiiiiiii.tistory.com

 

 

allExamList.html

<!DOCTYPE html>
<html lang="ko"
      xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
    <meta charset="UTF-8">
    <link href="/css/bootstrap.min.css" rel="stylesheet">
    <title>Title</title>
</head>
<body>
<div class="container" id="content">
    <div class="py-5 text-center">
        <h2>기출문제 리스트</h2> </div>
    <div class="row">
    </div>
    <hr class="my-4">
    <div>
        <table class="table">
            <thead>
            <tr>
                <th scope="col" style="text-align: center;">학과</th>
                <th scope="col" style="text-align: center;">과목</th>
                <th scope="col" style="text-align: center;">시험년도</th>
                <th scope="col" style="text-align: center;">학년</th>
                <th scope="col" style="text-align: center;">학기</th>
                <th scope="col" style="text-align: center;">구분</th>
                <th scope="col"></th>
            </tr>
            </thead>
            <tbody class="table-group-divider">
            <tr th:each="exam : ${exams}" style="text-align: center;">
                <td style="text-align: center;"><a th:text="${exam.departmentName}">학과</a></td>
                <td style="text-align: center;"><a th:text="${exam.subjectName}">과목</a></td>
                <td style="text-align: center;"><a th:text="|${exam.examYear} 년도|">시험년도</a></td>
                <td style="text-align: center;"><a th:text="|${exam.grade} 학년|">학년</a></td>
                <td style="text-align: center;"><a th:text="|${exam.semester} 학기|">학기</a></td>
                <td style="text-align: center;">
                    <a th:if="${exam.examCategory == 1}" th:text="'기말'">구분</a>
                    <a th:if="${exam.examCategory == 2}" th:text="'계절학기(동계)'">구분</a>
                    <a th:if="${exam.examCategory == 3}" th:text="'계절학기(하계)'">구분</a>
                </td>
                <td style="text-align: center;"><button type="button" class="btn btn-primary">풀기</button></td>
            </tr>
            </tbody>
        </table>
    </div>
    <hr class="my-4">
</div> <!-- /container -->
</body>

별다를 것 없는 For문 돌리기지만 몇 가지 설명을 덧 붙이자면

 

 

<td style="text-align: center;"><a th:text="|${exam.semester} 학기|">학기</a></td>

값이 1이면 '1학기' 로 보이게끔 하려면 || 안에 가둬주면 됨.

 

<td style="text-align: center;">
    <a th:if="${exam.examCategory == 1}" th:text="'기말'">구분</a>
    <a th:if="${exam.examCategory == 2}" th:text="'계절학기(동계)'">구분</a>
    <a th:if="${exam.examCategory == 3}" th:text="'계절학기(하계)'">구분</a>
</td>

값이 1이면 기말, 2면 계절학기(동계), 3이면 계절학기(하계) 로 보이게 하기 위해서 If문을 활용하였음.

 

<a th:if="${exam.examCategory == '1'}" th:text="'기말'">구분</a>

처음에 위와 같이 if문을 작성했는데 값이 나오지 않음. 알고보니 exam.examCategory는 정수값인데 1이 아니라 '1'인 문자로 비교를 하니까 그런거였음. 그래서 '1'에서 1로 변경해 줌!

 


 

[구현화면]

 

728x90
320x100