반응형

저번에 해보았던 회원 등록에 이어서 삭제까지 해보고자 한다.

드디어 처음 DeleteMapping 이다. 

 

우선 서비스 클래스를 보면 

 

Iterator로 저번에 만들어둔 list 타입을 불러와보자 

user 객체로 iterator.next()로 한개 씩 불러보자 

 

그다음 while hasNext로 for문과 같은 경우이다. 

그다음 if문을 통해 불러온 아이디와 발견한 id가 같다면 

유저를 리턴한다. 

 

@DeleteMapping("/users/{id}")
public void deleteUser(@PathVariable int id){
    User user = service.deleteById(id);

    if(user ==  null){
        throw new UserNotFoundExeception(String.format(id + " not pound"));
    }

}

DelMapping 으로 User/{id}로 pathVariavble을 해준다. 

user를 불러와서 service객체에 접근한다. 

 

그리고 서비스에서 불러온 값을 다시 리턴해준다. 

 

여기서 1번 데이터를 지워보자

 

딜리트로 신호를 보내보자 

 

삭제가 잘 되었다!

반응형
반응형

저번에 회원관리중 회원 선택 후 에 셀렉트 하는 것과 회원 전체 리스트를 json으로 받는 방법에 대해 서술하였다. 

이번에는 회원 추가 즉 insert를 할 것이다. 

아직 데이터베이스 즉 JPA를 하지 않아 메모리상의 데이터를 이용하려고 한다. 

 

시작해보자 

 

저번에 user라는 data객체와 service 그리고 controller를 만들었다. 

 

private static int usersCount = 3;

    public User save(User user){
        if(user.getId()== null){
            user.setId(++usersCount);
        }
        users.add(user);
        return user;
    }

우선 데이터가 3건이 기 떄문에 

userCount라는 변수를 만들어 데이터가 추가 될때마다 

++연산자로 한개씩 올려주려고 한다. 

그 후 users를 insert(add)를 하려고 한다. 

 

    @PostMapping("/users")
    public ResponseEntity<User> createUser(@RequestBody User user){
        User savedUser = service.save(user);

        URI location =  ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}")
                .buildAndExpand(savedUser.getId()).toUri();

        return ResponseEntity.created(location).build();
    }

createUser를 만들어 주고 

savedUser라는 변수를 만들어 서비스와 연결해준다. 

 

그 후 URI 를 사용하여 데이터를 전달해주면 

리턴값으로 

/users/{id} 값이 나오게 된다. 

 

즉 URI 값으로 바로 이용이 가능하다.

 

포스트맨 으로 한번 해보자 

 

 new_User 라고 name값을 추가해주고

즉 JSON으로 데이터를 전달해준다. 

post로 던져준다.

 

 

아까 만들어둔 location 값이 url로 만들어 진 것을 볼 수 있다. 

 

저 url로 접속을 해보면 

 

GET으로 접속을 해보면 아까 추가한 데이터가 추가 되었다!

 

 

반응형
반응형

다음에는 회원번호를 사용하여 PathVariable을 사용하여 

/users/{id} 이런식으로 데이터를 받아

2번이면 

id : 2

name : seok

 

이런식으로 데이터를 받아와보자 

우선 서비스 객체를 보자 

    public User findOne(int id){
        for(User user : users){
            if(user.getId() == id){
                return user;
            }
        }
        return null;
    }

 

save라는 메소드를 사용했다. 

우선 id를 비교하여 데이가 있다면 해당 user를 비교하여 데이터가 있다면

user를 리턴해준다.

만약 데이터가 없다면 null을 반영한다. 

 

@GetMapping("/users/{id}")
public User retrieveUser(@PathVariable int id){
    return service.findOne(id);
}

 

그 후 pathvariable을 사용하여 int를 서비스로 넘겨 비교한 후 클라이언트에게 

가져온 아이디를 리턴한다. 

 

2번 데이터를 리턴해보자 

 

 

이렇게 포스트맨으로  2번 데이터를 받아올 수 있다. 

만약 없는 데이터가 오면 null이 올것이다. 

 

다음에는 글 등록을 해보자

반응형
반응형

Rest API을 연습해보고자 한다

현재는 Get + POST만 사용했는데

Put과 Delete를 쓰려고 한다. 

 

 한번 사용해보자 

 

우선 데이터베이스를 쓰지 않고 메모리에 저장하는 형식으로 사용해보고자 한다. 

import java.util.Date;

@Data
@AllArgsConstructor
public class User {
    private Integer id;
    private String name;
    private Date joinDate;
}

우선 모델객체를 생성해주고 Lombok을 사용하려고 한다. 

 

그 후 service 객체를 생성해보자 

 

그 후 데이터 베이스를 사용하지 않기 떄문에 

실행과 동시에 반영이 가능한 static 변수를 사용하여 

List 타입을 만들고 id 1,2,3을 만들어서 기본 데이터 모델을 사용하려고 한다. 

public class UserDAOService {
    private static List<User> users = new ArrayList<>();
    private static int usersCount = 3;

    static {
        users.add(new User(1,"Moon", new Date()));
        users.add(new User(2,"Seok", new Date()));
        users.add(new User(3,"Huyn", new Date()));
    }

먼저 findAll 이라는 생성하여 위 데이터를 Rest api 방식을 사용하여 출력을 하여보자 

 

    public List<User> findAll(){
        return users;
    }

그 다음 컨트롤러를 사용해보자 

 

@RestController
public class userController {
    @Autowired
    private UserDAOService service;

    @GetMapping("/users")
    public List<User> retrieveAllusers(){
        return service.findAll();
    }

리스트 타입으로 GET방식으로 받아보자 

 

다음은 포스트 맨으로 

locallhost:8989/users 로 접속을 해보자

 

이런식으로 데이터를 잘 받아 오는 것을 알 수 있다. 

 

반응형
반응형

이번에는 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

 

반응형

+ Recent posts