본문 바로가기
CLASS/REACT

#2-3 / React - 회원가입 리스트 및 페이징,검색 (data select)

by hingu 2024. 9. 13.

  👀 oracle임  

- App.js ()

import {List} from './List';		

<Route path='/List' element={<List />}></Route>

//요거 추가

 

 

- List.js

import React,{ useEffect, useRef, useState } from 'react';

//API에서 보내준 회원전체 리스트 출력 파트
export let List = function (){
	var [colno,colnumber] = useState('6');
	var [pgno,pgnonum] = useState('1');
	var [total,totalno] = useState('');
	var [listdata,listarray] = useState('');
	
	var [sp, spno] = useState(false); //검색 활성화 및 비활성화
	var uri = "";
	var methods = "";
	
	//useEffect 안에 useRef, userState 사용 불가
	var [shword,shw] = useState("");
	
	//useEffect : 즉시실행 및 useState값이 변경 되었을 경우 재실행 
	 //단, useState가 동일한 값일 경우 실행하지 안음
	useEffect(function(){ //여러개의 uri를 가진 api 형태를 구성하는 코드
		//var sdata = document.getElementById("search").value;
		if(sp == false){ //검색어가 없을 경우
			uri = "/api/memberlist/"+pgno;
			methods="get";
		}else{ //검색어가 있을 경우
			uri = "/api/searchlist/"+shword;
			methods="post";
			console.log(uri)
		}
		
		fetch(uri,{
			method:methods,
			headers:{
				"content-type":"application/json"
			}
		})
		.then(api_req=>api_req.json())
		.then(api_res=>{
			listarray(api_res);
			totalno(Math.ceil(api_res[0]['total']/[10]));	//한페이지당 10개씩 출력 리스트
		})
		.catch(error=>console.log(error))
	},[pgno,sp,shword]) 
	//pgno : 페이지번호를 반영하여 데이터 변경사항을 backend에 전달
	//useEffect : 가독성을 높이기 위한 함수이므로 데이터 변경에 대한 즉각 반응을 하는 함수
	// ,[] : 해당 useEffect가 데이터가 다를 경우 재호출 해서 무한 재호출됨
	
	//data view
	var all_list = function(){
		var html = [];
		if(total == 0){
			html.push(<tr align="center" key={colno}><td colSpan={colno}>등록된 회원이 없습니다.</td></tr>);
		}else {
			listdata.forEach(function(a,b,c){
				html.push(
					<tr key={a['c_idx']}>
						<td>NO</td>
						<td>{a['c_id']}</td>
						<td>{a['c_name']}</td>
						<td>{a['c_email']}</td>
						<td>{a['c_hp']}</td>
						<td>
							<input type='button' value="수정" onClick={member_modify} />
							<input type='button' value="삭제"onClick={member_delete} />  
						</td>
					</tr>
				)
			})
		}
		
		return html;
	}

	function page_num(pg){
		pgnonum(pg.target.innerText);
	}
	
	//page를 생성하는 함수
	var page_for = function(){
		var html=[];
		for(var a=1;a<=total;a++){
			html.push(<td onClick={page_num} key={a}>{a}</td>);
		}
		return html;
	}
	
	function searchBtn(){ //list - 검색
		var shword2 = document.getElementById("search").value;
		/* useState, useRef를 직접 value로 핸들링 하게되면 null로 인하여 오류 발생함 */
		if(shword2 == ""){
			shw(false); //useState값 인식	
		}else{
			shw(shword2);
			if(sp!=true){ //false일 경우
				spno(!sp);  // !는 기존의 true,false 반대로 변경
			}
		}
	}
	
	
	function member_modify(){	//회원수정
		
	}
	function member_delete(){	//회원삭제
		
	}
	
	return (
	<section>
	<p> [ {pgno} 번 페이지 ] </p>
	검색 : <input type="text" id="search" />
	<input type="button" value="검색" onClick={searchBtn}/>
	<br /><br />
	<table border="1" cellPadding="0">
	<thead>
		<tr>
			<th>NO</th>
			<th>아이디</th>
			<th>고객명</th>
			<th>이메일</th>
			<th>휴대폰</th>
			<th>수정 및 삭제</th>
		</tr>
	</thead>
	<tbody>
		{all_list()}
	</tbody>
	</table>
	
	<table border={"1"}>
	<thead>
	<tr>
		{page_for()}
	</tr>
	</thead>
	</table>
	
	</section>	
	)
}

 

 

- mapper.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="kr.co.sen.api_member_repo">

    <!-- 
    parameterType으로 셋팅하여 Map 키배열에 해당되는 키 값을 DDL에 적용한 형태 
    => Oracle에는 limit이 없음
    -->
    <select id="listdata" resultType="kr.co.sen.customer_dto" parameterType="Map">
        select * from (select ROW_NUMBER() OVER (order by C_IDX desc) num,CUSTOMER.* from CUSTOMER order by C_IDX desc) where num between #{startpg} and #{endpg}
    </select>

    <select id="ctndata" resultType="Integer" parameterType="String">
        select count(*) ctn from ${tablename}
    </select>
    
    <select id="search_data" resultType="kr.co.sen.customer_dto" parameterType="String">
    select * from CUSTOMER where c_name like '%'||#{word}||'%' order by c_idx desc;
    </select>

</mapper>

 


- api_member_repo.java (interface)

package kr.co.sen;

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

import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface api_member_repo {	
	List<customer_dto> listdata(Map<String, String> mp);
	
	//데이터 총 갯수
	Integer ctndata(String tablename);
    
        //회원 검색
	List<customer_dto> search_data(String word);
}



- api_member_service (interface)

package kr.co.sen;

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

public interface api_member_service {	
	//회원 전체 리스트 interface
	List<customer_dto> listdata(Map<String, String> mp);
	
        //전체 데이터 갯수
	Integer ctndata(String tablename);
    
        //회원 검색
	List<customer_dto> search_data(String word);
}

 


- api_member_impl.java

package kr.co.sen;

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

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

@Service
public class api_member_impl implements api_member_service{
	@Autowired
	private api_member_repo apirepo; 
	
	@Override
	public List<customer_dto> listdata(Map<String, String> mp) {
		List<customer_dto> result = apirepo.listdata(mp);
		
		return result;
	}
	
	@Override
	public Integer ctndata(String tablename) {
		Integer result = apirepo.ctndata(tablename);
		return result;
	}
    
    	//검색
    	@Override
	public List<customer_dto> search_data(String word) {
		List<customer_dto> result = apirepo.search_data(word);
		
		return result;
	}
	
}

 


- restapi.java (Controller)

package kr.co.sen;
//import 생략

@RestController //api 전용 controller
public class restapi {
	//api는 무조건 결과값을 전달해줘야함 - 해당 값을 받을 변수 미리 선언
	private String result = null;
	private JSONObject jo = null;
	
	//Dto
	@Resource(name="customer_dto")
	customer_dto customer_dto;
	
	//Service Interface
	@Autowired
	api_member_service api_member_service;
	
        //검색
	@PostMapping("/api/searchlist/{search}")
	public String membersearch(@PathVariable(name="search") String search) {
		List<customer_dto> sdata = api_member_service.search_data(search);
		
		JSONArray ja  = new JSONArray(); //[] 원시배열
		
		//회원 리스트 정보 및 데이더 전체 갯수를 배열화(JSON)
		for(customer_dto dto : sdata) {
			JSONObject jo = new JSONObject(); //{} key배열
			jo.put("total", sdata.size()); //전체 갯수
			jo.put("c_idx", dto.getC_idx()); //고유값
			jo.put("c_id", dto.getC_id());
			jo.put("c_name", dto.getC_name());
			jo.put("c_email", dto.getC_email());
			jo.put("c_hp", dto.getC_hp());
			
			ja.put(jo);
		}
		
		this.result=ja.toString();
		return this.result;
	}
	
	//회원 전체 리스트 API
	//{page} => Pageing에 해당되는 값을 받아서 limit(between)으로 Data를 핸들링
	@CrossOrigin(origins = "*",allowedHeaders = "*")
	@GetMapping("/api/memberlist/{page}")
	public String memberlist(@PathVariable(name = "page") int page) {
		int ea= 10;
		//between에서 사용하는 값을 생성
		int startpg = ((page-1)*ea)+1;
		int endpg = page*ea;
		
		Map<String, String> page_setting=new HashMap<>();
		page_setting.put("startpg", String.valueOf(startpg) );
		page_setting.put("endpg",String.valueOf(endpg));
		
		//생성된 Map interface로 전달 후 Mapper.xml에 적용하여 10개 최상위 데이터를 가져옴 
		List<customer_dto> alldata= api_member_service.listdata(page_setting);
		
		Integer ctn= api_member_service.ctndata("CUSTOMER");
		JSONArray ja  = new JSONArray(); //[] 원시배열
		
		//회원 리스트 정보 및 데이더 전체 갯수를 배열화(JSON)
		for(customer_dto dto : alldata) {
			JSONObject jo = new JSONObject(); //{} key배열
			jo.put("total", ctn); //전체 갯수
			jo.put("c_idx", dto.getC_idx()); //고유값
			jo.put("c_id", dto.getC_id());
			jo.put("c_name", dto.getC_name());
			jo.put("c_email", dto.getC_email());
			jo.put("c_hp", dto.getC_hp());
			
			ja.put(jo);
		}
		
		this.result=ja.toString();
		return this.result;
	}

}

 

잘나옴 뿌엥 ㅠ

 

 

 

npm install crypto-js