데일리 공부 기록

hands on vue3 - vue3 & spring boot & Mysql로 restApi를 통해 조건에 맞는 값 가져오기(간단예제)

탐훈 2023. 3. 29. 00:48
728x90

[목표]

vue를 이용하여

spring boot에 단순 데이터 조회를 요청했다.

 

이제는

조건의 parameter를 보내어

 

해당 조건에 맞는 데이터를 불러오자

 

포스팅 목차는 다음과 같다

  1. DB 테이블 생성 및 데이터 추가
  2. Vue에서 간단한 게시판 조회 Form 만들기
  3. Spring-boot의 Controller, Service, DAO, DTO, xml 셋팅하기 
  4. 폼에서 조건을 들고 api 쏘고 결과 값 화면에 나타내기

DB테이블 생성 및 데이터 추가
CREATE TABLE Notice (
 nid        INT NOT NULL AUTO_INCREMENT,
 target     VARCHAR(20),
 gubun    VARCHAR(20),
 title    VARCHAR(50),  
 hit VARCHAR(50),
  PRIMARY KEY(nid)
)
INSERT INTO Notice(target, gubun, title, hit)
VALUES
('전체','공지', '2023년이 밝았습니다', '210'),
('전체','안내', '1층 경비실에서 안내드립니다.', '502'),
('전체','안내', '추석을 맞아 대행사 안내문', '1005'),
('일반회원','안내', '흡연부스에서 안내 드립니다', '5124'),
('전체','공지', '출입증 전체 변경', '10244'),
('특별회원','프로모션', '올리브영에서 프로모션을 합니다.', '10241'),
('개인회원','안내', '주기적인 암호 변경 안내문', '5123214')
;


Vue에서 간단한 게시판 조회 Form 만들기

위 그림과 같은 폼을 만든다.

먼저 키워드는 조건을 추가하지 않고

 

등록대상과 공지구분만을 가지고서 

조건에 맞는 조회를 해볼 예정이다.

 

 

[App.vue]

<template>
  <div>
    <h2>공지사항</h2>
    <div id="notice">
      <div>
        <label for="등록대상">등록대상</label>
        <section>
          <select v-model="memberType">
            <option value="전체">전체</option>
            <option value="일반회원">일반회원</option>
            <option value="특별회원">특별회원</option>
          </select>
        </section>
      </div>
      
      <div>
        <label for="공지구분">공지구분</label>
        <section>
          <select v-model="gubun">
            <option value="전체">전체</option>
            <option value="공지">공지</option>
            <option value="프로모션">프로모션</option>
          </select>
        </section>
      </div>

      <div>
        <label for="키워드">키워드</label>
        <section>
          <input type="text">
        </section>
      </div>
      <button @click="search">검색하기</button>
    </div>
  </div>
</template>

<script>

export default {
  data(){
    return{
      dataList: '',
      memberType: '',
      gubun: '',
    }
  },
  methods: {
    search(){
      let param = {
        "target" : this.memberType,
        "gubun" : this.gubun
      };

      fetch('/getNotice', {
        method: 'POST', // 또는 'PUT'
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(param),
      })
      .then((response) => response.json())
      .then((data) => {
        //데이터를 성공적으로 받았을 때
        console.log('성공:', data);
        this.dataList = data;
        console.log(JSON.stringify(this.dataList));
      })
      .catch((error) => {
        //데이터를 못 받았을 때
        console.error('실패:', error);
      });
    }
  }
}
</script>

<style scoped>
#notice{
  border: 1px solid black;
}

div{
  padding:10px;
}
</style>

 

간단하게 코드에 대해 설명하자면

 

 

등록대상의

option 값을 선택하면

memberType에 자동으로 데이터가 삽입된다.

 

공지구분은

gubun이라는 변수에 자동으로 데이터가 삽입된다.

 

왜냐하면

v-model은

v-bind와 @input 이 합쳐진 속성을 갖고 있기 때문이다. 

등록대상이 전체와

공지구분이 공지에 대한 것만 검색하게 되면

 

클릭했을 때 

파라미터로 api를 쏘게 된다. 

 

결과값을 

dataList에 담는다.

 


Spring-boot의 Controller, Service, DAO, DTO, xml 셋팅하기 

폴더 경로는 다음과 같다.

 

 

[NoticeController.java]

package com.example.demo.controller;

import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.example.demo.DTO.NoticeDTO;
import com.example.demo.service.NoticeService;

@RestController
public class NoticeController {
	
	private final Logger log = LoggerFactory.getLogger(this.getClass().getSimpleName());
	
	@Autowired
	NoticeService nService;
	
	@RequestMapping(value="/getNotice", method=RequestMethod.POST)
	public List<NoticeDTO> getNotice(@RequestBody Map<String,Object> param){
		log.info("param : " + param);
		List<NoticeDTO> list = nService.getNotice(param);
		
		return list;
	}
}

 

 

[NoticeService.java] 인터페이스로 생성해야함. class로 생성하면 안됨

package com.example.demo.service;

import java.util.List;
import java.util.Map;

import com.example.demo.DTO.NoticeDTO;

public interface NoticeService {
	public List<NoticeDTO> getNotice(Map<String,Object> param);
}

 

 

[NoticeServiceImpl.java]

package com.example.demo.service;

import java.util.List;
import java.util.Map;

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

import com.example.demo.DTO.NoticeDTO;
import com.example.demo.dao.NoticeDAO;

@Service
public class NoticeServiceImpl implements NoticeService{
	
	@Autowired
	NoticeDAO nDao;
	
	@Override
	public List<NoticeDTO> getNotice(Map<String, Object> param) {
		List<NoticeDTO> list = nDao.getNotice(param);
		return list;
	}

}

 

 

[NoticeDAO.java] 인터페이스 파일로 생성해야함. 클래스파일 아님

package com.example.demo.dao;

import java.util.List;
import java.util.Map;

import org.apache.ibatis.annotations.Mapper;

import com.example.demo.DTO.NoticeDTO;

@Mapper
public interface NoticeDAO {
	public List<NoticeDTO> getNotice(Map<String,Object> param);
}

 

[Notice.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="com.example.demo.dao.NoticeDAO">
 
    <select id="getNotice" resultType="NoticeDTO" parameterType="Map">
        SELECT * FROM Notice
        WHERE target = #{target}
        AND gubun = #{gubun}
    </select>
    
</mapper>

 

[DatabaseConfig.java]

package com.example.demo.config; 

import javax.sql.DataSource;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration
@MapperScan(basePackages="com.example.demo.dao")
@EnableTransactionManagement
public class DatabaseConfig {
	
    @Bean
    public  SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
        final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSource);
        sessionFactory.setTypeAliasesPackage("com.example.demo.DTO");
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        sessionFactory.setMapperLocations(resolver.getResources("classpath:com/example/demo/mapper/*.xml"));
        return sessionFactory.getObject();
    }
    
    @Bean
    public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) throws Exception {
      final SqlSessionTemplate sqlSessionTemplate = new SqlSessionTemplate(sqlSessionFactory);
      return sqlSessionTemplate;
    }
}

 

여기까지 기본 셋팅은 끝났다.


폼에서 조건을 들고 api 쏘고 결과 값 화면에 나타내기

위와 같이 셋팅이 모두 마쳤으면

등록대상과 공지구분을 

셋팅한 후 검색하기를 클릭하면

결과 값이 테이블 형식으로 나온다.

 

<template>
  <div>
    <h2>공지사항</h2>
    <div id="notice">
      <div>
        <label for="등록대상">등록대상</label>
        <section>
          <select v-model="memberType">
            <option value="전체">전체</option>
            <option value="일반회원">일반회원</option>
            <option value="특별회원">특별회원</option>
          </select>
        </section>
      </div>
      
      <div>
        <label for="공지구분">공지구분</label>
        <section>
          <select v-model="gubun">
            <option value="전체">전체</option>
            <option value="공지">공지</option>
            <option value="프로모션">프로모션</option>
          </select>
        </section>
      </div>

      <div>
        <label for="키워드">키워드</label>
        <section>
          <input type="text">
        </section>
      </div>
      <button @click="search">검색하기</button>
    </div>
  </div>
  <div v-if="dataList.length != 0 ">
    <table id="tbl">
      <tr>
        <td>id</td>
        <td>등록대상</td>
        <td>공지구분</td>
        <td>제목</td>
        <td>조회수</td>
      </tr>
      <tr v-for="item in dataList" :key="item.nid">
        <td>{{item.nid}}</td>
        <td>{{item.target}}</td>
        <td>{{item.gubun}}</td>
        <td>{{item.title}}</td>
        <td>{{item.hit}}</td>
      </tr>
    </table>
  </div>
</template>

<script>

export default {
  data(){
    return{
      dataList: '',
      memberType: '',
      gubun: '',
    }
  },
  methods: {
    search(){
      let param = {
        "target" : this.memberType,
        "gubun" : this.gubun
      };

      fetch('/getNotice', {
        method: 'POST', // 또는 'PUT'
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(param),
      })
      .then((response) => response.json())
      .then((data) => {
        //데이터를 성공적으로 받았을 때
        console.log('성공:', data);
        this.dataList = data;
        console.log(JSON.stringify(this.dataList));
      })
      .catch((error) => {
        //데이터를 못 받았을 때
        console.error('실패:', error);
      });
    }
  }
}
</script>

<style scoped>
#notice{
  border: 1px solid black;
}

div{
  padding:10px;
}
#tbl{
  border: 1px solid black;

}
#tbl td{
  border: 1px solid black;
}
</style>

 

 

 

 


 

오류, 수정해야될 부분이 있거나

질문이 있으시면 댓글로 작성하시면 빠르게 답변 드립니다!