반응형

이번에는 CRUD의 마지막 기능인

수정이다. 

 

수정은 데이터를 넘기는 방식이 너무 어려웠다. 

리엑트는 너무 새로운 방식이라 

 

여러가지 방법을 시도해보면 정말 공부를 많이 했다. 

 

우선 리엑트부터 보자

 

    return(
        <>
    <div>
        글번호 : {props.board.id}
    </div>
    <div>
        제목 : {props.board.title}
    </div>
    <div>
        내용 : {props.board.content}
    </div>
    <div>
        <button onClick={()=>{
            axios.get(`/board/delete?id=${props.board.id}`)
            alert('삭제완료');
            window.location.href ="/";
        }}>삭제</button> 
        <button><Link to={`/modify/${props.board.id}`}>수정</Link></button>
    </div>
        </>
    )
}

링크태그를 이용하여 /modify/글번호 로 이동시킨다. 

 

그 후 

 

 <form onSubmit={submitHandler}>
        <div>
            <input name='id' value={props.board.id} readOnly/>
        </div>
        <div>
            <input name='title' value={title} onChange={onChangeTitle}/>
        </div>
        <div>
            <textarea name='content' value={content} onChange={onChangeContent}></textarea>
        </div>
        <div>
        <button type="submit" onClick={()=>{
            alert("수정 완료");
            window.location.href = "/";
        }}>수정</button>
        </div>
    </form>

요론 수정.js를 생성해준다. 

그 후 메인에서 

 

      <Route path='/detail/:id' element={<Detail board={board}/> } />
      <Route path='/modify/:id' element={<Modify board={board}/> } />

이렇게 전달해준다. 

 

그럼 props로 데이터 전달이 가능하다. 

 

한가지 예외상황이 나왔다

 

리엑트에서는 input에 value를 쓰면 수정이 안된다...

수정을 해주려면 onchange속성을 써서 다시 값을 설정해주어야한다. 

 

    const [title, setTitle] = useState(props.board.title);
    const [content, setContent] = useState(props.board.content);

    const onChangeTitle = useCallback(e => {
        setTitle(e.target.value);
    },[])

    const onChangeContent = useCallback(e => {
        setContent(e.target.value);
    },[])

이런식으로 따로 설정을 해주었다. 

JSP나 타임리프에서는 그냥 됬는데 .. 리엑트 너란녀석 참 복잡하다. 

 

그렇게 한 후 원래는 form태그 안에 action 태그를 사용하여 데이터를 보냈지만 이렇게 하면 바로 

url로 타고가서 따로 페이지를 만들어주고 거기서 또 페이지 전환을 시켜줘야하기 떄문에 너무 번거롭다

이번엔 그래서 onsubmit 타입을 이용해서 변경해보자 .

 

    const submitHandler = (e) =>{
        e.preventDefault();
        console.log(props.board.id)
        console.log(title)
        console.log(content)

        const params = new URLSearchParams();

        params.append('id',props.board.id);
        params.append('title',title);
        params.append('content',content)

        axios.post('/board/modify',params)
        
    }

일단 e.preventDefault로 기능을 죽여준다. 

그 후 console.log로 각 데이터가 잘 오는지 확인 꼭 확인 할 필요는 없지만 나는 확인 .,. 

그 후 parmas라는 변수로 URLSearchParams를 객체로 선언해준다. 

 

그 후 위에 데이터를 append시켜 추가해준다. 

 

이것은 axios 공식홈페이지에서 나온 방법이다.

 

그후 post방식으로 url에 태워 보내면 form태그 적용 끝이다.

 

그 후 스프링부트를 보자 

 

    @PostMapping("/board/modify")
    public Integer modify(Board board){
        System.out.println(board.getId());
        System.out.println(board.getContent());
        return boardService.modify(board);
    }

이렇게 선언 해 준뒤 서비스객체를 보자

 

    public Integer modify(Board board){
        return boardRepository.save(board).getId();
    }

원래는 변경감지나 머지를 써야한다고 한다. 

나중에 한번 다시 해보자 

 

이렇게 하면 우선 끝이다.

 

작동을 시켜보자 

 

 

 

 

 

이렇게 수정이 완료되었다. 

 

이제는 페이징이랑 검색기능만 남았다 

 

이번주중으로 끝내고 다른거 공부해보자 

 

파이팅!

 

https://github.com/MoonSeokHyun

 

MoonSeokHyun - Overview

http://mls0000.dothome.co.kr/. MoonSeokHyun has 18 repositories available. Follow their code on GitHub.

github.com

 

반응형
반응형

이번에 알아볼건 CRUD에서 정말 간단한 삭제이다.

나는 솔직히 데이터베이스에서 삭제를 하는것을 좋아하지않는다. 

왜냐하면 데이터는 항시 보존되어야한다고 생각한다.

그렇기떄문에 전에 프로젝트를 할 때도 타입을 주던가 y/n 이런식으로 구분을 했다.

하지만 아직 나는 JPA가 익숙하지 않아 그냥 아이디를 이용해 간단하게 삭제 처리를해보자. 

 

import axios from "axios";
import { useEffect, useState } from "react";
import { useParams } from "react-router-dom";
import { Routes, Route, Link } from 'react-router-dom'
function Detail(props){

    let {id} = useParams();


    return(
        <>
    <div>
        글번호 : {props.board.id}
    </div>
    <div>
        제목 : {props.board.title}
    </div>
    <div>
        내용 : {props.board.content}
    </div>
    <div>
        <button onClick={()=>{
            axios.get(`/board/delete?id=${props.board.id}`)
            alert('삭제완료');
            window.location.href ="/";
        }}>삭제</button> 
        <button><Link to={`/modify/${props.board.id}`}>수정</Link></button>
    </div>

detail.js를 보면 

버튼을 클릭했을때 이벤트함수인 onClick을 사용하여 

axios로 넘겨준다.

 

그 후 컨트롤러와 통신한다. 

 

    @GetMapping("/board/delete")
    public void delete(Integer id){
    boardService.delete(id);
        System.out.println("완료");
    }

정말 간단하게 GetMapping으로 해보자 

원래 restful 방식인 Delete를 써야하지만 스프링부트 설정을 해주는 방법은 다음에 알아보도록하자 

설정을 하지않으면 put과 delte를 사용할 수없다 .

 

    public void delete(Integer id){
        boardRepository.deleteById(id);
    }

서비스에서 id를 지목하면 된다. id는 entity에 있는 id로 진행하면된다. 

 

실행화면 

 

글 번호 14번 게시물을 삭제하려고 한다 .

 

삭제 완료 라는 경고창과 함께

2022-05-26 01:52:52.935 DEBUG 908 --- [io-8090-exec-10] org.hibernate.SQL                        : 
    delete 
    from
        board 
    where
        id=?

인텔리제이 콘솔창에도 실행 되었다고 나오는것 같다. 

 

14번 게시물은 삭제되었다. 

 

https://github.com/MoonSeokHyun

 

MoonSeokHyun - Overview

http://mls0000.dothome.co.kr/. MoonSeokHyun has 18 repositories available. Follow their code on GitHub.

github.com

 

반응형
반응형

저번에는 글쓰기를 알아보았다

CRUD를 진행하면서 리엑트는 좀 어려운거같다 

자바스크립트나 제이쿼리의 DOM 방식이 익숙해졌는데 

리엑트의 방식은 나에게 너무 크게 다가왔다.

 

오키 등 다른 곳에 질문을 올려서 꾸역꾸역 해가고 있다.

점점 성장하는거같다 기쁘다.

 

 

먼저 리엑트부분부터 살펴보자 

 

 <Routes>
      <Route path='/' element={
      <div>메인페이지
        <a href='/Write'>글쓰기</a>
        <h1>List</h1>
        <table>
        <tr>
          <th>번호</th>
          <th>제목</th>
        </tr>
      {
        list.map(function(a,i){
          return(
            <>
                <tr>
                  <td>{list[i].id}</td>
                  <td><Link to={`/detail/${list[i].id}`} onClick={
                    () => {
                      axios.get(`/board/detail/${list[i].id}`).then( res =>{   
                        Setboard(res.data)})
                  }
                  }>{list[i].title}</Link></td>
                </tr>
              </>
          )
        })
    }
    </table>
      </div>}>
        
      </Route>
      <Route path="/write" element={ <Write/> } />
      <Route path='/detail/:id' element={<Detail board={board}/> } />
    </Routes>
      
    </div>


  );
}

우선 테이블 태그로 리스트를 가볍게 그려주자 

그리고 link태그를 사용하여 list의 글번호를 가게하자 

즉 /detail/1 이런식으로 보내진다. 

 

그 다음 axios로 get요청을 보낸다. 

그 후 데이터베이스에서 받아온 내용을 res라는 함수에 저장하여 

Setboard에 저장한다. 

 

그 후 라우터를 통해 board를 props로 담아서 보내준다.

 

※ 주의사항 ※

 

나는 계속 res를 setboard에다 담고 console찍어 보면

계속 이전 값이 나온다 . 

 

그래서 해결책을 찾았다

 

State의 값 변경은 렌더링을 유발시키는 이유로 변경사항을 모아뒀다가 렌더링 주기마다 한번에 처리하기때문에 값이 바로 변경되지 않습니다.

값변경의 감지는 useEffect 훅을 사용하셔야합니다

 

useEffect(() => {
  console.log(board);
}, [board]);

을 추가하면 된다. 

 

다음으로 

 

디데일.js를 보자

 

import { useEffect, useState } from "react";
import { useParams } from "react-router-dom";

function Detail(props){

    let {id} = useParams();


    return(
        <>
    <div>
        <input name='id' value={props.board.id}/>
    </div>
    <div>
        <input name='title' value={props.board.title}/>
    </div>
    <div>
        <textarea name='content' value={props.board.content}></textarea>
    </div>
        </>
    )
}

export default Detail;

 

그 후 props로 뿌려주면 끝난다. 

 

이제 스프링을 보자 

 

 

    @GetMapping("/board/detail/{id}")
    public Board detail(@PathVariable Integer id){
        return boardService.boardView(id);
    }

 

우선 간단하게 /{id}를 붙였으니

pathvariable로 해준다. 

 

그다음 서비스에서 받은 값을 리턴보내면 컨트롤러의 역활을 끝이다. 

 

서비스를 보면서 이해해보자 

 

    public Board boardView(Integer id){
        return boardRepository.findById(id).get();
    }

id를 보내서 id를 찾는다. 

 

https://github.com/MoonSeokHyun/Vegan-Recipe-WebSite

 

GitHub - MoonSeokHyun/Vegan-Recipe-WebSite

Contribute to MoonSeokHyun/Vegan-Recipe-WebSite development by creating an account on GitHub.

github.com

 

반응형
반응형

간단하게 글쓰기를 구현해보고자 한다. 

 

우선 리엑트에서는

 

import { useEffect, useState } from 'react';
import axios from 'axios';


function Write(){

    const [id, Setid] = useState();
    const [title, SetTitle] = useState("");
    const [content, SetContent] = useState("");

    
    return(
    


    <div>
        <form method='post' action='/board/insert'>
            <div>
                <input name='title'></input>
            </div>
            <div>
                <textarea name='content'></textarea>
            </div>
            <button type='submit'>글 작성a</button>
        </form>
    </div>
        )
    }

export default Write;

이런 간단한 컴포넌트를 하나 만들었다

 

 <a href='/Write'>글쓰기</a>

메인 컴포넌트에서 글쓰기를 누르면 위의 컴포넌트로 이동한다. 

<Route path="/write" element={ <Write/> } />

라우터를 사용하였다. 

라우터쓰는 방법은 많이 나와있으니 참고바란다. 

 

리엑트에서도 form을 써도 되나 싶긴하지만 아직은 리린이라 그냥 진행해보자 

 

스프링부트로 넘어가보자

 

    @PostMapping("/board/insert")
    public void boardinsert(Board board){
        boardService.insert(board);
    }

우선 컨트롤러를 보자면 리엑트에서 폼으로 데이터를 넘긴다 

이때 board 형식으로 받아준다. 

board는 enfity에 있다 즉 vo와 비슷함 

 

@Entity
@Data
public class Board {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY) //

    private Integer id;
    private String title;
    private String content;


}

단 3줄짜리 entity이다 나중에 id로 페이징도 할것이다. 

내용과 제목 끝 정말 간단하다.

 

그리고 레포지토리를 등록하자

 

@Repository
public interface BoardRepository extends JpaRepository<Board,Integer> {
}

이부분은 jpa 시간에도 많이 했던거라 생략한다. 

 

그리고 서비스를 작성하자

 

   public void insert(Board board){
        boardRepository.save(board);
    }

jpa의 함수 save(객체)를 써서 간단하게 글 등록을 마칠 수 있엇다. 

 

글 등록을 해보자 

 

글쓰기를 누르면 

 

 

블로그 테스트용~ 으로 글을 남겼다. 글 작성을 누르면 

아래와 같이 등록이된다. 

 

 

 

https://github.com/MoonSeokHyun

 

MoonSeokHyun - Overview

http://mls0000.dothome.co.kr/. MoonSeokHyun has 18 repositories available. Follow their code on GitHub.

github.com

 

반응형
반응형

 

저번시간에는 디비로부터 데이터를 끌어와 리엑트로 보여주는 것을 해봤다

오늘은 뷰에서 직접 파라미터를 받아 서버로 데이터를 보내보자 

 

별거 없었다 또 괜히 2일동안 고민한거 같다. 

 

 

시작해보자 

 

const [id, Setid] = useState();
const [title, SetTitle] = useState("");

우선 아이디와 콘텐트 이 2개를 usestate에 빈값으로 남겨 놓자 

그리고 메인컴포넌트에서 

 

    <input  onChange={(e)=>{
      Setid(e.target.value);
    }}/>
       <input onChange={(e)=>{
      SetTitle(e.target.value);
    }}/>

이렇게 인풋값을 2개를 만들어준다.

하나는 숫자가 들어갈 인풋 다른 하나는 숫자든 상관없다.

 

이제 전송버튼을 살펴보자

 

    <button
      onClick={
        ()=>{
          axios.get('/board/insert',{
            params:{
              id : id,
              title : title
            }
          }).catch(function(){
            console.log('실패함')
          })
        }}
    >전송</button>

우선 온클릭이벤트로 값을 만들어 준다. 

그 후로 axios로 보낼 url값 즉 파라미터에 getMapping값을 적어준뒤 뒤에 params에는

오브젝트형식으로 위에 변수를 적어준다. 

 

 

    @GetMapping("/board/insert")
    public void boardinsert(@RequestParam Integer id, @RequestParam String title){
        System.out.println(id);
        System.out.println(title);
    }
    }

 

그리고 GetMapping으로 위에 파라미터를 받아준다.

 

이제 테스트를 해보자

위에 처럼 적고 전송버튼을 누르면

 

스프링부트로 전달이 아주 잘됬다.

이제 이걸로 간단한 회원가입페이지를 만들어보자

 

반응형
반응형

한 2일을 고민했다. 

블로그도 찾아보고 리엑트랑 스프링부트랑 연결도 하고 이제 데이터베이스에서 뿌려주는 것만 하면 

프로젝트  준비는 거의 끝낫다. 

 

리엑트에서 axios를 활용하여 컨트롤러에 접근하여 가져온 디비의 내용을 출력하면 된다. 

 

https://devofroad.tistory.com/84?category=972234 

 

JPA를 사용한 게시판 만들기(2) 리스트작업 {타임리프,스프링부트}

저번에는 글쓰기에 대해서 알아보았다. 이제 쓴 글을 리스트화 시키는 방법에 대해서 스프링 부트와 jpa 방법으로 알아보고자 한다. 이렇게 됬다 공부중이라 디자인은 생략한다. 자 이제 시작해

devofroad.tistory.com

데이터는 이것을 썻다.

 

const [list , SetList] = useState([]);

useEffect(()=> {
  axios.get('/board/list').then((res)=>{
    SetList(res.data)
    console.log(list)
  })
},[])

우선 useState로 리스트에 받아올 값을 넣어주기 위해 변수로 선언해 준다.

그다음 페이지가 로딩된 다음에 use이펙트를 통해 axios로 컨트롤러에 접근을 한다. 

 

이떄 뒤에 [] (빈 배열)을 넣어주지 않으면 무한로딩이 되기 떄문에 조심하자. 

 

    public List<Board> boardList(Model model){
        return boardService.boardList();
    }

컨트롤러는 다음과 같다. 

service에서 리턴한 값을 그대로 리엑트로 쏴준다. 

 

그럼 console.log로 res를 확인 해 보았을때 data가 약 120개 정도 나온다.

 

이 떄 이것을 이제 화면에다 뿌려주면된다. 

 

function App() {

const [list , SetList] = useState([]);

useEffect(()=> {
  axios.get('/board/list').then((res)=>{
    SetList(res.data)
    console.log(res)
  })
},[])
  
  return (
    <div className="App">

      <h1>List</h1>
      {
        list.map(function(a,i){
          return(
            <div>
            <div>{list[i].id}</div>
            <div>{list[i].title}</div>
            <div>{list[i].content}</div>
            </div>
          )
        })
      }

      
    </div>


  );
}

이제 컴포넌트 안에 {}를 선언해주고 map을 써주면 된다. 

 

jsp에 el태그와 비슷하다.

즉 파라미터 문법으로 

a를 i만큼 반복한다는 뜻이다.

즉 반복문 같은 거라 

list[i].id는 

res.data[0~120].id 라는 소리 이것을 120번 반복한다. 

 

이렇게 뿌려주면

 

이렇게 나온다. 

 

테이블 태그를 쓰지않아서 .. 한줄로 나오지만 a태그를 넣고 하면 간단한 게시판 형식이 나올 것 같다. 

 

https://github.com/MoonSeokHyun

 

MoonSeokHyun - Overview

http://mls0000.dothome.co.kr/. MoonSeokHyun has 17 repositories available. Follow their code on GitHub.

github.com

 

반응형
반응형

이전에는 리엑트를 연습했엇다.

이제 본격적으로 리엑트 + 스프링 부트를 한번 연결 시켜 보자 

 

인텔리 제이로했음 .

 

JSX로 함

 

우선 컨트롤러를 보자 

 

@RestController
public class boardController {

    @GetMapping("/board")
    public String board() {
        System.out.println("연결 잘됨?");
        return "연결테스트";
    }

    }

 

이렇게 /board라는 것을 use이펙터로 

ajax를 사용 하여 컨트롤러와 통신한다. 

 

import logo from './logo.svg';
import './App.css';
import { useEffect, useState } from 'react';
import axios from 'axios';

function App() {
  // message 초기값 설정 (""로 설정)
  const [message, setMessage] = useState("");

  // useEffect(함수, 배열) : 컴포넌트가 화면에 나타났을 때 자동 실행
  useEffect(() => {
    // fetch(url, options) : Http 요청 함수
    fetch("/board")
      .then(response => response.text())
      .then(message => {
        setMessage(message);
      });
  }, [])

  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          board : {message}
        </p>
      </header>
    </div>
  );
}

export default App;

 

 성공이다.

반응형

+ Recent posts