꾸준한 개발일기

Vue.js+Spring:: 컴포넌트로 검색 기능 구현, 추가하기(게시판 CRUD, axios.get, 쿼리 parameterType에 따른 변수명 etc.) 본문

JS/VueJs

Vue.js+Spring:: 컴포넌트로 검색 기능 구현, 추가하기(게시판 CRUD, axios.get, 쿼리 parameterType에 따른 변수명 etc.)

꾸개일 2022. 8. 4. 13:04
반응형

 

 

 

Vue.js와 Spring으로 CRUD를 완성하고 추가적인 세부기능을 구현해보자 하였다.

그 중 먼저 검색기능을 컴포넌트로 만들어 재사용성을 높이고 싶었다.

수 많은 블로그를 둘러보며 얻었던 팁들과 함께 작성해보았다.

 

 

 

검색이나 페이징 값을 받을 VO 생성

SearchVo.java

package app.com.model.vo;

public class SearchVO {
	
	private String srhKeyword;

	public String getSrhKeyword() {
		return srhKeyword;
	}
	public void setSrhKeyword(String srhKeyword) {
		this.srhKeyword = srhKeyword;
	}
}

아직 검색어 변수만 선언되어 있지만, 앞으로 페이징 변수도 넣어 사용할 예정이라 VO를 생성하였다.

 

 

 

검색어를 받아 목록 객체를 리턴해줄 read메서드 작성

HomeController.java

package app.com.model;

... 이하 생략 ...

/**
 * Handles requests for the application home page.
 */
@Controller
public class HomeController {
	
	private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
	
	@Autowired 
	HomeService homeService;
	
	/**
	 * Simply selects the home view to render by returning its name.
	 */
	@RequestMapping(value = "/", method = RequestMethod.GET)
	public String home() {
		return "home";
	}
	
	@RequestMapping(value = "/read", method = RequestMethod.GET)
	@ResponseBody
	public List<Users> read(SearchVO searchVO) {
		return homeService.getUsersList(searchVO);
	}
	
... 이하 생략 ...
  • home메서드는 페이지를 로딩해주는 메서드
  • read메서드는 axios 비동기 통신으로 리스트 객체를 리턴(axios.get으로 데이터를 넘겨줄 때는@RequestBody를 사용할 수 없음)

 

 

 

HomeService.java

package app.com.model;

... 이하 생략 ...

@Service
public class HomeService {
	
	@Autowired 
	HomeMapper homeMapper;

	public List<Users> getUsersList(SearchVO searchVO) {
		
		return homeMapper.selectUsersList(searchVO);
	}

... 이하 생략 ...

 

 

 

HomeMapper.java

package app.com.model;

... 이하 생략 ...

@Repository
public class HomeMapper {

	@Autowired
	SqlSessionTemplate session;
	
	public List<Users> selectUsersList(SearchVO searchVO) {

		return session.selectList("app.com.model.HomeMapper.selectUsersList", searchVO);
	}

... 이하 생략 ...

 

 

 

HomeMapper.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="app.com.model.HomeMapper">
	<select id="selectUsersList" parameterType="app.com.model.vo.SearchVO" resultType="app.com.model.Users">
		SELECT 
			id as id,
			first_name as firstName,
			last_name as lastName,
			email as email,
			gender as gender,
			ip_address as ipAddress,
			last_update as lastUpdate
		FROM users
		WHERE 1=1
		<if test='srhKeyword != null and srhKeyword != ""'>
			AND email LIKE CONCAT('%', #{srhKeyword}, '%')
		</if>
		ORDER BY id desc
	</select>
	
... 이하 생략 ...
</mapper>
  • Postgesql을 사용해주었는데 WHERE 절에서 1=1AND를 꼭 넣어줘야한다.
  • parameterType에 VO 객체를 넣어줬으니 srhKeyword 변수를 사용할 수 있다. (parameterType이 String이라면 변수는 value 하나만 사용할 수 있다.)

 

 

 

search.js

export default {
	template : `
		<div>
			<label>검색 : </label>
			<input type="text" v-model="srhKeyword" @keyup.enter="search(srhKeyword)" style="height: 25px;" />
			<button class="btn btn-outline-primary" @click="search(srhKeyword)">Search</button>
		</div>
	`,
	methods : {
		search : function(srhKeyword) {
			this.$parent.loadPage(srhKeyword);
		}
	}
}
  • 엔터를 치거나 버튼을 눌렀을 때 search 메서드가 실행되도록 구현
  • search메서드에서 리스트 화면을 로딩하는 부모 컴포넌트의 loadPage를 실행

 

 

 

read.js

import { eventBus } from './instance.js';
import SearchComponent from './search.js';

export default {
	template : `
		<div class="col-md-6 themed-grid-col" v-show="$parent.isShow == 'read'">
			<h1>Users List</h1>
		
			<button class="btn btn-outline-primary"><a @click="showCreatePage">Add</a></button>
			<SearchComponent />
			<table class="table">
				<thead>
					<tr>
						<th scope="col">id</th>
						<th scope="col">first_name</th>
						<th scope="col">last_name</th>
						<th scope="col">email</th>
					</tr>
				</thead>
				<tbody>
					<tr v-for="item in users">
						<td scope="row"><a @click="showUpdatePage(item)">{{ item.id }}</a></td>
						<td><a @click="showUpdatePage(item)">{{ item.firstName }}</a></td>
						<td><a @click="showUpdatePage(item)">{{ item.lastName }}</a></td>
						<td><a @click="showUpdatePage(item)">{{ item.email }}</a></td>
					</tr>
				</tbody>
			</table>
		</div>
	`,
	components: {
		SearchComponent
	},
	data() {
		return { 
			users: []
		}
	},
	mounted(){
		this.loadPage('');
	},
	methods : {
		... 이하 생략 ...,
		loadPage : function(srhKeyword) {
			axios.get('/model/read',{
				params : {
					srhKeyword : srhKeyword
				}
			}).then((response)=>{
				this.users = response.data;
			}).catch((error)=>{
				console.log(error);
			})
		}
	}
}
  • SearchComponent 선언
  • loadPage 메서드에서 axios.get을 사용할 때 파라미터는 {params: {name: value}} 형식으로만 넣어줘야 컨트롤러에서 인식 가능
  • 받아온 srhKeyword를 파라미터로 넘겨줌

 

 

 

instance.js

import readComponent from './read.js';
... 이하 생략 ...

export const eventBus = new Vue();

const read_component = readComponent;
... 이하 생략 ...

new Vue({
	el: '#app',
	components: {
		'read-component': read_component,
		... 이하 생략 ...
	},
	data : {
		isShow: 'read'
	}
})
  • read-component를 선언

 

 

 

결과 화면:

email을 단어로 검색할 수 있게되었다.

 

 

 

단순한 기능이지만 axios.get에 파라미터를 넣어주는 기능을 처음 써 보느라 시행착오가 많았지만, Vue.js에 대해 더 공부할 수 있는 시간이었다. 개발을 할 때 보통 전에 만들어 놨던 것을 많이 참고하게 되는데 이 코드들도 현업 프로젝트에서 많이 참고될 수 있었으면 좋겠다.

 

 

 

전체코드:

https://github.com/seoh2k/spring-project/commit/4113ff62e4ed2e26bc215632a8949eb1dcffa6d7

 

Vue.js 컴포넌트로 만든 검색 기능 구현 · seoh2k/spring-project@4113ff6

1. SearchVO 추가 - 페이징에도 이용할 예정 - String으로 파라미터를 넘겨줄 시 쿼리에서 변수명 대신 value만 사용 가능 2. 쿼리 작성시, WHERE절에서 AND 꼭 넣어주기 3. SearchComponent를 만들어 재사용성

github.com

 

 

 

반응형
Comments