hands on vue3 - vue3 & spring boot & Mysql로 restApi를 통해 조건에 맞는 값 가져오기(간단예제)
[목표]
vue를 이용하여
spring boot에 단순 데이터 조회를 요청했다.
이제는
조건의 parameter를 보내어
해당 조건에 맞는 데이터를 불러오자
포스팅 목차는 다음과 같다
- DB 테이블 생성 및 데이터 추가
- Vue에서 간단한 게시판 조회 Form 만들기
- Spring-boot의 Controller, Service, DAO, DTO, xml 셋팅하기
- 폼에서 조건을 들고 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>
오류, 수정해야될 부분이 있거나
질문이 있으시면 댓글로 작성하시면 빠르게 답변 드립니다!