상세 컨텐츠

본문 제목

게시판 만들기 3(주민번호 입력하고 검색하기)

spring 기초

by jjrroo 2024. 5. 7. 00:33

본문

도출해내야하는 결과

1. 이름과 성별, 주민등록번호, 거주시/도를 입력했을때 DB 에 성공적으로 insert 됐을시 '데이터를 성공적으로 추가하였습니다'라는 화면창에 띄우기 

2. 카테고리에서 이름, 성별, 주민등록 번호, 거주 시/도를 검색했을때 그 검색값에 맞게 게시글이 나와야한다.

3. 주민등록 번호 같은경우는 앞자리만 검색해도 뒷자리까지 같이 검색결과 게시글로 나와야한다. 

 


1. `test0426`.`personals`테이블 만들기 

```
CREATE SCHEMA `test0426`;
CREATE TABLE `test0426`.`personals`
(
    `name`      VARCHAR(10) NOT NULL, //이름
    `gender`    VARCHAR(1)  NOT NULL, //성별
    `ssn_birth` VARCHAR(6)  NOT NULL, //첫번째 칸 주민번호 
    `ssn_key`   VARCHAR(7)  NOT NULL, //두번째 칸 주민번호
    `region`    VARCHAR(10) NOT NULL, //지역 이름 
    CONSTRAINT PRIMARY KEY (`ssn_birth`, `ssn_key`)//주민번호 칸 프라이머리키 해보기
);
```

2. html 만들어주기 
```
<form method="post"> <!--form 메서드에서 post 를 지정해줘야함-->
    <h2 class="title">주민관리</h2>
    <div class="horizontal">
        <label class="label">
            <span class="text">이름</span>
            <input maxlength="10" minlength="2" name="name" spellcheck="false" type="text" placeholder="성/이름(공백없이)">
        </label>
        <br>
        <label class="label" content>
            <span class="text">성별</span>
            <select nam e="gender">
                <option value="M">남</option>
                <option value="F">여</option>
            </select>
        </label>
        <br>
        <label class="label" content>
            <span class="text">주민등록번호</span>
            <input maxlength="6" minlength="6" name="ssnBirth" spellcheck="true" type="text" placeholder="앞자리(숫자 여섯자리)">
        </label>
        <label class="label" content>
            <span class="text"></span>
            <input maxlength="7" minlength="7" name="ssnKey" spellcheck="true" type="text"  placeholder="뒷자리(숫자 일곱 자리)">
        </label>
        <br>
        <label class="label" content>
            <span class="text">거주 시/도</span>
            <select name="region"> //option value 값으로 DB에 들어감
                <option  value="서울특별시">서울특별시</option>
                <option  value="부산광역시">부산광역시</option>
                <option  value="대구광역시">대구광역시</option>
                <option  value="인천광역시">인천광역시</option>
                <option  value="광주광역시">광주광역시</option>
                <option  value="대전광역시">대전광역시</option>
                <option  value="울산광역시">울산광역시</option>
                <option  value="세종특별자치시">세종특별자치시</option>
                <option  value="경기도">경기도</option>
                <option  value="강원특별자치도">강원특별자치도</option>
                <option  value="충청북도">충청북도</option>
                <option  value="충청남도">충청남도</option>
                <option  value="전북특별자치도">전북특별자치도</option>
                <option  value="전라남도">전라남도</option>
                <option  value="경상북도">경상북도</option>
                <option  value="경상남도">경상남도</option>
                <option  value="제주특별자치도">제주특별자치도</option>
            </select>
        </label>
        <br>
        <input class="button" type="submit" value="추가">
        <!--버튼을 누르면 post 로 요청이 들어간다.-->
    </div>
    <div class="true" th:if="${result != null && result.equals('SUCCESS')}" th:text="${'메모를 성공적으로 작성하였습니다.'}"></div>
    <div class="false" th:if="${result != null && result.equals('FAILURE')}" th:text="${'메모 작성을 실패하였습니다. '}"></div>
</form>

```
```


<td colspan="5"> <!--4칸을 합쳐서 페이지를 보여주겠다.-->
    <a th:each="page:${#numbers.sequence(dto?.getMinPage(), dto?.getMaxPage())}"
       th:href="@{/personal/(page=${page})}" // personal은 맵핑할 주소를 적어줘야한다.
       th:text="${page}" style="display: inline-block; margin-right: 10px;"></a>
    <!-- page 는 반복문 돌릴때 사용되는 변수이름이다.
    th:href="@{/personal/(page=${page})}" 맵핑 주소 적어줘야함 -->
</td>

```
- <th:href="@{/personal/(page=${page})}" > 

 

<오류 떴던 이유>
  - 여기에서 주소창에 맵핑한 주소 /personal/을 적어줘야하는데 memos 를 적어줘서 페이지 눌렀을때 404가 떴던거였음 .


3. 검색창에 쳤을때 나오는 html

- 여기서 form method는 get 으로 맞춰줘야한다. 
- select name과 value 값을 xml에서 매개변수를 쓸때 똑같이 잘 써주지 않으면 검색했을때 결과값이 나오지 않으므로 주의

 



- 여기서 parameterType으로 countPerPage랑 offset을 사용해주고 있기때문에 MemoDto를 연결해주고  resultType으로 PersonEntity를 꼭 연결시켜줘여한다.
- resultType 은 xml에서 자바로 반환되는 결과타입을 적어줘야함 
  - resultType 속성에는 기본 데이터 타입(int, long, double, boolean 등)과 자바 클래스(String, Date, User 등)를 모두 사용할 수 있습니다.

- parameterType 은 어떤 곳에서 매개변수를 쓸것인가 주소를 적어줘야함 
  - 기본 데이터 타입(int, long, double, boolean 등)과 자바 클래스(String, Date, User 등)를 모두 사용할 수 있습니다.


4. interface 에 추가해주기 
```
   int insertPerson(PersonEntity person);//화면창에 기입한정보를 DB에 넣어줄 인터페이스
   PersonEntity[] allSelect (MemoDto dto);//페이지 가져오는 메서드 

```


4. MemoMapper.xml
`<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC
        "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cohttp://m.jjrr.study.mappers.MemoMapper" >

    <select id="selectPage" resultType="_int" parameterType="cohttp://m.jjrr.study.dto.MemoDto">
        SELECT COUNT(0) AS `count`
        FROM `test0426`.`personals`
        <if test="by != null and by.equals('name') and keyword != null">
            WHERE REPLACE(`name`, ' ', '') LIKE CONCAT('%', REPLACE(#{keyword}, ' ', ''), '%')
        </if>
        <if test="by != null and by.equals('gender') and keyword != null">
            WHERE REPLACE(`gender`, ' ', '') LIKE CONCAT('%', REPLACE(#{keyword}, ' ', ''), '%')
        </if>
        <if test="by != null and by.equals('person') and keyword != null">
            WHERE CONCAT(REPLACE(`ssn_birth`, ' ', ''), REPLACE(`ssn_key`, ' ', '')) LIKE CONCAT('%', REPLACE(#{keyword}, ' ', ''), '%')
        </if>
        <if test="by != null and by.equals('region') and keyword != null">
            WHERE REPLACE(`region`, ' ', '') LIKE CONCAT('%', REPLACE(#{keyword}, ' ', ''), '%')
        </if>
    </select>
---
    <insert id="insertPerson" parameterType="cohttp://m.jjrr.study.entity.PersonEntity">
        INSERT INTO test0426.personals(`name`, `gender`, `ssn_birth`, `ssn_key`, `region`)
        VALUES (`#{name},#`{gender},`#{ssnBirth},#`{ssnKey},#{region})
    </insert>
--- 
    <select id="allSelect" parameterType="cohttp://m.jjrr.study.dto.MemoDto" resultType="cohttp://m.jjrr.study.entity.PersonEntity">
        SELECT
        `personals`.`name` AS `name`,
        `personals`.`gender` AS `gender`,
        `personals`.`ssn_birth` AS `ssnBirth`,
        `personals`.`ssn_key` AS `ssnKey`,
        `personals`.`region` AS `region`
        FROM `test0426`.`personals`
        <if test="by != null and by.equals('name') and keyword != null">
            WHERE REPLACE(`name`, ' ', '') LIKE CONCAT('%', REPLACE(#{keyword}, ' ', ''), '%')
        </if>
        <if test="by != null and by.equals('gender') and keyword != null">
            WHERE REPLACE(`gender`, ' ', '') LIKE CONCAT('%', REPLACE(#{keyword}, ' ', ''), '%')
        </if>
        <if test="by != null and by.equals('person') and keyword != null">
            WHERE CONCAT(REPLACE(`ssn_birth`, ' ', ''), REPLACE(`ssn_key`, ' ', '')) LIKE CONCAT('%', REPLACE(#{keyword}, ' ', ''), '%')
        </if>
        <if test="by != null and by.equals('region') and keyword != null">
            WHERE REPLACE(`region`, ' ', '') LIKE CONCAT('%', REPLACE(#{keyword}, ' ', ''), '%')
        </if>
        LIMIT #{countPerPage} OFFSET #{offset}
    </select>
</mapper>


`



- 이 쿼리에서 if문을 쓸때 주민번호는 앞자리만 나 뒷자리만 쳐도 검색 결과가 나와야하기 떄문에  if문을 따로 쓰면 안되고 한번에 써줘야 같이 나온다. 
- CONCAT :이 함수는 여러 개의 문자열을 하나의 문자열로 결합하는 기능 
- REPLACE : 이 함수는 문자열 내에서 특정 문자열을 다른 문자열로 대체하는 기능을 합니다.
- WHERE : WHERE 절을 사용하면 테이블에서 특정 조건에 맞는 데이터만 선택할 수 있습니다.

- **WHERE REPLACE(****region****, ' ', '') LIKE CONCAT('%', REPLACE(#{keyword}, ' ', ''), '%')**
  region 컬럼의 값에서 공백을 제거한 후, 사용자 입력 키워드(공백 제거 후)를 포함하고 있는지 확인합니다.
  이를 통해 region 컬럼의 값과 사용자 입력 키워드 간의 부분 일치 검색을 수행할 수 있습니다




서비스 로직
```
@Service
public class MemoService {
    public final MemoMapper memomapper;

    public MemoService(MemoMapper mapper) { //서비스 메퍼랑 의존성 추가해주기
        this.memomapper = mapper;
    }

    /* 주민번호 DB에 insert 하는 메서드 */

    public AddResult add(PersonEntity person){

        if (person == null || person.getGender() == null || person.getRegion()==null||person.getSsnKey().length() != 7 || person.getSsnBirth().length() != 6 || person.getName().length() >10||person.getName().length() < 2){

          return AddResult.FAILURE;
        }

    int db = this.memomapper.insertPerson(person);
        return db > 0 ? AddResult.SUCCESS: AddResult.FAILURE;

    }

    public PersonEntity[] getMemo(MemoDto dto) { // 전체게시물을 보여줘야하기때문에 꼭 배열로 가져와줘야함 

        dto.setCountPerPage(5);//한페이지당 몇개 게시글 보여줄것인지
        dto.setTotalCount(this.memomapper.selectPage(dto)); // 전체 게시글 숫자 넣어주기
        dto.setMaxPage(dto.getTotalCount() / dto.getCountPerPage() + (dto.getTotalCount() % dto.getCountPerPage() == 0 ? 0 : 1));

        if (dto.getMaxPage()<1){
            dto.setMaxPage(1); //최대페이지수가 1보다 작을때 0이라고 뜨는걸 방지하기 위해 기입함
        }
        dto.setOffset(dto.getCountPerPage() * (dto.getRequestPage()-1));
        //거를 게시글 갯수
        //한페이지당 보여줄 게시글수 X 요청페이지-1
        // 이렇게 해야 1페이지에 있는 5개 게시글 빼고 노출되기 때문이다.

        dto.setMinPage(1); //젤 작은 페이지수는 1페이지로 지정
        System.out.println(dto.getKeyword());
        return memomapper.allSelect(dto);

    }
}

'spring 기초' 카테고리의 다른 글

게시판 만들기 2(검색기능 추가하기)  (0) 2024.05.07
게시판 만들기1 (기초)  (0) 2024.05.07

관련글 더보기