본문 바로가기
학원수업/3월

03/24 국비 개발자 과정 - Spring - React - Oralce 연결, 회원가입구현

by 코딩마스터^^ 2023. 3. 24.

회원제로 운영되는 서비스라고 가정해본다

 

게시판 유형이 여러가지 필요하다고 상상해보자

(예를 들면, 리뷰게시판, Qnz)

요구사항 QNA게시판인데 양도, 매매, 등으로 검색조건이 꼭 필요하다

게시판의 유형에 따라 첨부파일이 필요한 경우도 있고 필요없는 경우도 있다.

게시판 유형에 따라 댓글 처리 테이블을 별도로 설계한다

리뷰게시판-(예:Review_Comment게시판)-댓글테이블

QnA게시판-QnA댓글(예:qna_comment)

예매게시판-예매댓글테이블(예:reserve_comment)등

 

첨부파일은 통합 테이블로 관리하기로 결정되었다.

mlog_file

 

댓글형 게시판 구현하기

ERWin으로 테이블을 설계해준다.

블로그에 필요한 데이터들을 만들어 준다. 

 

오라클 계정 만들기-MBLOG계정

create user mblog identified by mblog;

--권한부여하기
grant connect, resource TO mblog;
grant create session to mblog  with admin option;
grant create table to mblog  with admin option;
grant create view to mblog;

--사용자 정보의 확인
SELECT * FROM DBA_USERS;

 

mblog계정에 export해준다.

 

 

 

 

프론트로 넘어가자.

 

 

자바스크립트 타입

원시형

export const jsonMemberListDB = (member) => {
  return new Promise((resolve, reject) => {
    try {
      const response = axios({
        method: "get",
        url: process.env.React_APP_SPRING_IP+ "member/jsonMemberList",
        params: member,
      });
      resolve(response);
    } catch (error) {
      reject(error);
    }
  });
};

 

댓글형 게시판 구현하기

mem_status 디폴트 0

1이면 일반 

블랙리스트 등등 생각할수있다.

 

MEM_AUTH

회원관리테이블을 다 따로 할 필요없다...

권한을 설정하고 허가된 사람만 접근할수 있도록 할 수 있다.

 

사업자라면 사업번호같은 권한을 넣어야 접근권한이 인정되는거지

그래서 사용자가 입력하는 것이 아니다.

 

MEM_PW는 비밀번호를 확인하는 화면이 필요하다.

실제 디비에는 없지만 MEM_PW2가 필요하다.

 

 

 

 

 

 

 

 

//POST로 처리, @RequestBody, {} 객체 리터럴로 넘겼을때 Map or VO로 받을 수 있는지...->비동기처리(순서대로 처리X) 오래걸리는것부터 먼저..뒤죽박죽
 
비동기 처리할때 자바스크립트에서는 promise를 생각해야한다.
//->Promise(resolve, reject)
//async-await 비동기로 처리할때 꼭 사용
 

 

JSon형식인데도 로그에 찍혔다. 들어갔다.

 

화면에서 디비에 회원을 넣어보자.

import React, { useCallback, useState } from 'react'
import { Button } from 'react-bootstrap'
import { Navigate, useNavigate } from 'react-router-dom'
import { memberInsertDB } from '../../service/dbLogic'
import { BButton, ContainerDiv, FormDiv, HeaderDiv } from '../styles/FromStyle'

//회원가입 페이지
const Signup = () => {//컴포넌트 함수
//useXXXX은 훅이라고 한다. - 16.8버전- 그 전까지는 클래스(this이슈. 변함) 지원되던것을
//함수형 프로그래밍에 대한 이점으로 훅을 지원하게 되었다.
  const navigate=useNavigate();
  const [mem_uid,setMemuid]=useState('')
  const [mem_pw,setMempw]=useState('')
  const [mem_name,setMemname]=useState('')
  const [mem_nickname,setMemnickname]=useState('')
  const [mem_email,setMememail]=useState('')
  const [mem_tel,setMemtel]=useState('')
  const [mem_gender,setMemgender]=useState('')
  const [mem_birthday,setMembirthday]=useState('')
//POST로 처리, @RequestBody, {} 객체 리터럴로 넘겼을때 Map or VO로 받을 수 있는지...->비동기처리(순서대로 처리X) 오래걸리는것부터 먼저..뒤죽박죽
//->Promise(resolve, reject)
//async-await 비동기로 처리할때 꼭 사용
const memberInsert= async ()=>{
  const member={
    mem_uid:mem_uid,
    mem_pw:mem_pw,
    mem_name: mem_name,
    mem_nickname:mem_nickname,
    mem_email:mem_email,
    mem_tel:mem_tel,
    mem_gender:mem_gender,
    mem_birthday:mem_birthday
  }
  const res= await memberInsertDB(member)
  console.log(res+","+res.data);
  if(!res.data){
    console.log('회원가입실패');
  }else{
    console.log('회원가입성공');
    navigate("/login");
  }

}

  const handleID=useCallback((e)=>{
    setMemuid(e)
  },[])

  const handlePW=useCallback((e)=>{
    setMempw(e)
  },[])

  const handleName=useCallback((e)=>{
    setMemname(e)
  },[])

  const handleNickname=useCallback((e)=>{
    setMemnickname(e)
  },[])

  const handleEmail=useCallback((e)=>{
    setMememail(e)
  },[])

  const handleTel=useCallback((e)=>{
    setMemtel(e)
  },[])

  const handleGender=useCallback((e)=>{
    setMemgender(e)
  },[])

  const handleBirthday=useCallback((e)=>{
    setMembirthday(e)
  },[])


  return (
    <div>
      <ContainerDiv>
        <HeaderDiv>
          <h3 style={{marginLeft:"10px"}}>회원가입</h3>
        </HeaderDiv>
        <FormDiv>
          <div style={{width:"100%", maxWidth:"2000px"}}>

            <div style={{display: 'flex', justifyContent: 'space-between', marginBottom:'5px'}}>
              <h4>아이디</h4> 
            </div>
            <input id="mem_uid" type="text" maxLength="50" placeholder="아이디를 입력하세요."
              style={{width:"200px",height:'40px' , border:'1px solid lightGray', marginBottom:'5px'}} onChange={(e) => {handleID(e.target.value)}}/>

            <div style={{display: 'flex', justifyContent: 'space-between', marginBottom:'5px'}} >
              <h4>비밀번호</h4> 
            </div>
            <input id="mem_pw" type="text" maxLength="50" placeholder="PW를 입력하세요."
              style={{width:"200px",height:'40px' , border:'1px solid lightGray', marginBottom:'5px'}} onChange={(e) => {handlePW(e.target.value)}} />
           
            
            <div style={{display: 'flex', justifyContent: 'space-between', marginBottom:'5px'}}>
              <h4>비밀번호확인</h4> 
            </div>
            <input id="mem_pw2" type="text" maxLength="50" placeholder="PW를 확인하세요."
              style={{width:"200px",height:'40px' , border:'1px solid lightGray', marginBottom:'5px'}}/>

            <div style={{display: 'flex', justifyContent: 'space-between', marginBottom:'5px'}}>
              <h4>이름</h4> 
            </div>
            <input id="mem_nickname" type="text" maxLength="50" placeholder="이름을 확인하세요."
              style={{width:"200px",height:'40px' , border:'1px solid lightGray', marginBottom:'5px'}} onChange={(e) => {handleName(e.target.value)}} />
            
            <div style={{display: 'flex', justifyContent: 'space-between', marginBottom:'5px'}}>
              <h4>닉네임</h4> 
            </div>
            <input id="mem_nickname" type="text" maxLength="50" placeholder="닉네임을 확인하세요."
              style={{width:"200px",height:'40px' , border:'1px solid lightGray', marginBottom:'5px'}} onChange={(e) => {handleNickname(e.target.value)}} />
            
            <div style={{display: 'flex', justifyContent: 'space-between', marginBottom:'5px'}}>
              <h4>이메일</h4> 
            </div>              
            <input id="mem_email" type="text" maxLength="50" placeholder="이메일을 입력하세요."
              style={{width:"200px",height:'40px' , border:'1px solid lightGray', marginBottom:'5px'}} onChange={(e) => {handleEmail(e.target.value)}} />
            
            <div style={{display: 'flex', justifyContent: 'space-between', marginBottom:'5px'}}>
              <h4>전화번호</h4> 
            </div>              
            <input id="mem_tel" type="text" maxLength="50" placeholder="전화번호를 입력하세요."
              style={{width:"200px",height:'40px' , border:'1px solid lightGray', marginBottom:'5px'}} onChange={(e) => {handleTel(e.target.value)}} />

            
            <div style={{display: 'flex', justifyContent: 'space-between', marginBottom:'5px'}}>
              <h4>성별</h4> 
            </div>              
            <input id="mem_gender" type="text" maxLength="50" placeholder="성별을 입력하세요."
              style={{width:"200px",height:'40px' , border:'1px solid lightGray', marginBottom:'5px'}} onChange={(e) => {handleGender(e.target.value)}} />
            
            
            <div style={{display: 'flex', justifyContent: 'space-between', marginBottom:'5px'}}>
              <h4>생일</h4> 
            </div>              
            <input id="mem_birthday" type="text" maxLength="50" placeholder="생일을 입력하세요."
              style={{width:"200px",height:'40px' , border:'1px solid lightGray', marginBottom:'5px'}} onChange={(e) => {handleBirthday(e.target.value)}} />
            <div style={{display: 'flex', justifyContent: 'space-between', marginBottom:'5px'}}>
            <Button onClick={memberInsert} >회원가입</Button>
            </div>
          </div>
        </FormDiv>
      </ContainerDiv>
    </div>
  )
}

export default Signup

xml에 memberInsert쿼리문을 추가해주었다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

dd

댓글