코딩 노트

React07 - Book, pocketmon REST API로 생성 / 예외처리 본문

React

React07 - Book, pocketmon REST API로 생성 / 예외처리

newbyeol 2023. 11. 6. 11:17

spring22rest에 

BookDto 생성

@Schema(description = "도서 정보 객체")

@Data @NoArgsConstructor @AllArgsConstructor @Builder

public class BookDto {

private int bookId, bookPageCount;

@Builder.Default

private float bookPrice = -1f; //절대로 들어올 수 없는 값

private String bookTitle, bookAuthor, bookPublicationDate, bookPublisher, bookGenre;

}

mybatis  폴더에 book-mapper.xml 생성

<?xml version="1.0" encoding="UTF-8"?>

 

<!DOCTYPE mapper

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

"https://mybatis.org/dtd/mybatis-3-mapper.dtd">

 

<mapper namespace="book">

 

<!-- 등록, 목록, 검색, 상세, 수정(일부/전체), 삭제 -->

<select id="findAll" resultType="BookDto">

select * from book order by book_id asc

</select>

 

<select id="findByBookId" resultType="BookDto">

select * from book where book_id = #{bookId}

</select>

 

<!-- 도서명 검색 -->

<select id="findByBookTitle" resultType="BookDto">

<!-- select * from book where book_title = #{bookTitle} -->

<!-- select * from book where book_title like = #{bookTitle} || '%' -->

<!-- select * from book where book_title like concat(#{bookTitle} || '%') -->

select * from book where instr(book_title, #{bookTitle}) > 0

</select>

 

<insert id="save">

insert into book(

book_id, book_title, book_author, book_publication_date,

book_price, book_publisher, book_page_count, book_genre

)

values(

book_seq.nextval, #{bookTitle}, #{bookAuthor}, #{bookPublicationDate},

#{bookPrice}, #{bookPublisher}, #{bookPageCount}, #{bookGenre}

)

</insert>

 

<delete id="deleteByBookId">

delete book where book_id = #{bookId}

</delete>

 

<!--

(참고) JPA에서는 등록과 수정 명령이 같다 - 둘다 save

- 변경 시 변경할 PK와 변경할 정보(DTO)가 전달

- PK는 bookId, DTO는 bookDto

-->

<update id="change">

update book

<set>

<if test="bookDto.bookTitle != null">

book_title = #{bookDto.bookTitle},

</if>

<if test="bookDto.bookAuthor != null">

book_author = #{bookDto.bookAuthor},

</if>

<if test="bookDto.bookPublicationDate != null">

book_publication_date = #{bookDto.bookPublicationDate},

</if>

<if test="bookDto.bookPrice >= 0">

book_price = #{bookDto.bookPrice},

</if>

<if test="bookDto.bookPublisher != null">

book_publisher = #{bookDto.bookPublisher},

</if>

<if test="bookDto.bookPageCount > 0">

book_page_count = #{bookDto.bookPageCount},

</if>

<if test="bookDto.bookGenre != null">

book_genre = #{bookDto.bookGenre},

</if>

</set>

where book_id = #{bookId}

</update>

 

</mapper>

BookDao 인터페이스 생성

public interface BookDao {

List<BookDto> selectList();

BookDto selectOne(int bookId);

List<BookDto> searchList(String bookTitle);

void insert(BookDto bookDto);

void edit(int bookId, BookDto bookDto);

void delete(int bookId);

 

}

BookDaoImpl 생성

@Slf4j

@Repository

public class BookDaoImpl implements BookDao{

@Autowired

private SqlSession sqlSession;

 

@Override

public List<BookDto> selectList() {

return sqlSession.selectList("book.findAll");

}

@Override

public BookDto selectOne(int bookId) {

return sqlSession.selectOne("book.findByBookId", bookId);

}

@Override

public List<BookDto> searchList(String bookTitle) {

return sqlSession.selectList("book.findByBookTitle", bookTitle);

}

@Override

public void insert(BookDto bookDto) {

sqlSession.insert("book.save", bookDto);

}

@Override

public void edit(int bookId, BookDto bookDto) {

Map<String, Object> param = Map.of("bookId", bookId, "bookDto", bookDto);

sqlSession.update("book.change", param);

}

@Override

public void delete(int bookId) {

sqlSession.delete("book.deleteByBookId", bookId);

}

}

BookRestController 생성

@Tag(name = "도서 관리", description = "도서 정보 관리를 위한 컨트롤러")

@CrossOrigin

@RestController

@RequestMapping("/book") //주소는 반드시 테이블명(테이블명을 노출시키고 싶지 않다면 그와 비슷한 유사 이름)

public class BookRestController {

 

@Autowired

private BookDao bookDao;

 

@GetMapping("/") //자원 설계 방식이 기능이 아니라서 주소 이름이 list가 아님

public List<BookDto> list(){

return bookDao.selectList();

}

 

@GetMapping("/bookId/{bookId}")

public BookDto find(@PathVariable int bookId) {

return bookDao.selectOne(bookId);

}

 

@GetMapping("/bookTitle/{bookTitle}")

public List<BookDto> search(@PathVariable String bookTitle) {

return bookDao.searchList(bookTitle);

}

 

@PostMapping("/")

public void insert(@RequestBody BookDto bookDto) {

bookDao.insert(bookDto);

}

 

@PutMapping("/{bookId}")

public void update(@RequestBody BookDto bookDto, @PathVariable int bookId) {

//bookDto에 모든 항목이 있는지 검사해야함

bookDao.edit(bookId, bookDto);

}

@PatchMapping("/{bookId}")

public void update2(@RequestBody BookDto bookDto, @PathVariable int bookId) {

//bookDto에 항목이 하나라도 있는지 검사해야함

bookDao.edit(bookId, bookDto);

}

@DeleteMapping("/{bookId}")

public void delete(@PathVariable int bookId) {

bookDao.delete(bookId);

}

}

RequestBody와 ModelAttribute의 차이점은 받는 데이터가 다르다는 것

controller와 restController 차이?

rest가 붙으면 데이터를 반환하는 것이다.

 

error 패키지 생성 후 ExceptionControllerAdvice 생성

@Slf4j

@RestControllerAdvice(basePackages = {"com.kh.spring22.restcontroller"})

//@RestControllerAdvice(annotations = {RestController.class})

public class ExceptionControllerAdvice {

 

//[1] NoTargetException이 발생하면 사용자에게 404를 반환

@ExceptionHandler(NoTargetException.class)

public ResponseEntity<?> error404(Exception e) {

log.warn("404 발생", e);

return ResponseEntity.notFound().build();

}

 

//[2] 그 외 예외가 발생하면 사용자에게 500을 반환

@ExceptionHandler(Exception.class)

public ResponseEntity<String> error500(Exception e) {

log.error("오류 발생", e);

return ResponseEntity.internalServerError().body("server error");

}

 

}

BookDaoImpl 구문 수정

@Override

public BookDto selectOne(int bookId) {

BookDto bookDto = sqlSession.selectOne("book.findByBookId", bookId);

if(bookDto == null) throw new NoTargetException();

return bookDto;

}

Map<String, Object> param = Map.of("bookId", bookId, "bookDto", bookDto);

int result = sqlSession.update("book.change",param);

if(result == 0) throw new NoTargetException();

@Override

public void delete(int bookId) {

int result = sqlSession.delete("book.deleteByBookId",bookId);

if(result == 0) throw new NoTargetException();

}

React와 백엔드 연결 시키기

demo05 프로젝트 생성

npx create-react-app demo05 --skip-git

부트스트랩, 부츠워치 다운

npm i bootstrap
npm i bootswatch
설치 후 import

 

프로젝트에 Ctrl + shiht + c = 외부 터미널 열기'

react-router 다운

npm install react-router

npm install react-router-dom

npm install react-router npm install react-router-dom : 한 번에 다운로드 하기

 

npm list : 설치 목록 보기

index.js 구문 수정

import React from 'react';
import ReactDOM from 'react-dom/client';

//link 대신 import를 통해 설치한 라이브러리 CSS를 불러오도록 처리
//- node_modules에 설치한 요소들은 바로 이름을 사용하여 접근 가능
import 'bootstrap/dist/css/bootstrap.min.css';
//이곳에 bootswatch css파일을 불러오는 구문을 작성
import 'bootswatch/dist/lumen/bootstrap.min.css';

import App from './App';
import reportWebVitals from './reportWebVitals';

//Router는 React 앱을 여러 페이지로 분할하여 사용하도록 만드는 기술
//- HashRouter는 주소에 해시(#)가 포함된다.
//- BrowserRouter는 주소에 해시(#)가 포함되지 않는다.
import {BrowserRouter, HashRouter} from 'react-router-dom';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <HashRouter>
    <App />
  </HashRouter>
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

App.js 구문 수정

import { NavLink, Route, Routes } from "react-router-dom";
import Pocketmon from "./components/Pocketmon";
import Book from "./components/Book";
import Home from "./components/Home";

function App() {
  return (
    <div className="container-fluid">
      {/* 상단 메뉴 영역 */}
      <div>
        {/* a링크 쓸 수 없음 화면이 동기화 되어서 */}
        <NavLink to="/"></NavLink>
        <NavLink to="/pocketmon">포켓몬스터</NavLink>
        <NavLink to="/book">도서</NavLink>
      </div>

      {/* 본문 영역 */}
      <div>
        <Routes>
          <Route exact path="/" element={<Home/>}></Route>
          <Route path="/pocketmon" element={<Pocketmon/>}></Route>
          <Route path="/book" element={<Book/>}></Route>
        </Routes>
      </div>

    </div>
  );
}

export default App;

Home.js 생성

const Home = (props) => {
    return(
        <>
            <h1>메인 페이지</h1>
        </>
    );
};

export default Home;

Pocketmon.js 생성

const Pocketmon = (props)=>{
    return (
        <>
            <h1>포켓몬 관리화면</h1>
        </>
    );
};

export default Pocketmon;

Book.js 생성

const Book = (props)=>{
    return(
        <>
            <h1>도서 관리 화면</h1>
        </>
    );
};

export default Book;

index.js 구문 추가

import React from 'react';
import ReactDOM from 'react-dom/client';

//link 대신 import를 통해 설치한 라이브러리 CSS를 불러오도록 처리
//- node_modules에 설치한 요소들은 바로 이름을 사용하여 접근 가능
import "bootstrap/dist/css/bootstrap.min.css";
//이곳에 bootswatch css파일을 불러오는 구문을 작성
import "bootswatch/dist/lumen/bootstrap.min.css";
import "bootstrap";

import App from './App';
import reportWebVitals from './reportWebVitals';

//Router는 React 앱을 여러 페이지로 분할하여 사용하도록 만드는 기술
//- HashRouter는 주소에 해시(#)가 포함된다.
//- BrowserRouter는 주소에 해시(#)가 포함되지 않는다.
import {HashRouter} from 'react-router-dom';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <HashRouter>
    <App />
  </HashRouter>
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

App.js 구문 수정

import { NavLink, Route, Routes } from "react-router-dom";
import Pocketmon from "./components/Pocketmon";
import Book from "./components/Book";
import Home from "./components/Home";
import Menu from "./components/Menu.js";


function App() {
  return (
    <div className="container-fluid">
      {/* 상단 메뉴 영역 */}
      <Menu/>

      {/* 본문 영역 */}
      <div>
        <Routes>
          <Route exact path="/" element={<Home/>}></Route>
          <Route path="/pocketmon" element={<Pocketmon/>}></Route>
          <Route path="/book" element={<Book/>}></Route>
        </Routes>
      </div>

    </div>
  );
}

export default App;

Menu.js 생성

import { NavLink, useLocation } from "react-router-dom";
import "bootstrap/dist/js/bootstrap.js";

const Menu = props => {
    const location = useLocation();
    //console.log(location.pathname);

    return (
        <>
            <nav className="navbar navbar-expand-lg bg-dark" data-bs-theme="dark">
                <div className="container-fluid">
                    <NavLink className="navbar-brand" to="/">KH정보교육원</NavLink>
                    <button className="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarColor02" aria-controls="navbarColor02" aria-expanded="false" aria-label="Toggle navigation">
                        <span className="navbar-toggler-icon"></span>
                    </button>
                    <div className="collapse navbar-collapse" id="navbarColor02">
                        <ul className="navbar-nav me-auto">
                            <li className="nav-item">
                                <NavLink className={`nav-link ${location.pathname === '/pocketmon' ? 'active' : ''}`} to="/pocketmon">포켓몬</NavLink>
                            </li>
                            <li className="nav-item">
                                <NavLink className={`nav-link ${location.pathname === '/book' ? 'active' : ''}`} to="/book">도서</NavLink>
                            </li>
                        </ul>
                    </div>
                </div>
            </nav>
        </>
    );
};

export default Menu;

이런 식으로

npm install axios : axios 라이브러리 다운

Pocketmon.js 구문 수정

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

const Pocketmon = (props)=>{
    const [pocketmonList, setPocketmonList] = useState([]);

    useEffect(()=>{
        //서버에서 pocketmon list를 불러와서 state에 설정하는 코드
        axios({
            url:"http://localhost:8080/pocketmon/",
            method:"get"
        })
        .then(response=>{
            // console.log(response);
            setPocketmonList(response.data);
        })
        .catch(err=>{});
    }, []);

    return (
        <>

            <div className="row">
                <div className="col">
                    <h1>포켓몬 관리</h1>
                    <p>React CRUD 연습 예제</p>
                </div>
            </div>

            <div className="row mt-4">
                <div className="col">
                    <table className="table">
                        <thead>
                            <tr>
                                <th>번호</th>
                                <th>이름</th>
                                <th>속성</th>
                                <th></th>
                            </tr>
                        </thead>
                        <tbody>
                            {pocketmonList.map(pocketmon=>(
                                <tr key={pocketmon.no}>
                                    <td>{pocketmon.no}</td>
                                    <td>{pocketmon.name}</td>
                                    <td>{pocketmon.type}</td>
                                </tr>
                            ))}
                        </tbody>
                    </table>
                </div>
            </div>
           
        </>
    );
};

export default Pocketmon;

Book.js 구문 수정

import axios from "axios";
import { useEffect, useState } from "react";
import { FaXmark } from "react-icons/fa6";
import { FaRegEdit } from "react-icons/fa";

import "./Book.css";

const Book = (props) => {
    const [bookList, setBookList] = useState([]);

    useEffect(() => {
        //서버에 있는 도서 정보를 불러와서 state에 반영하는 코드
        axios({
            url: "http://localhost:8080/book/",
            method: "get"
        })
        .then(response => {
            setBookList(response.data);
        })
        .catch(err => {
            window.alert("통신 오류 발생!")
        });
    }, []);

    return (
        <>
            <div className="row">
                <div className="col">
                    <h1>도서 관리</h1>
                    <p>React CRUD 연습 예제</p>
                </div>
            </div>

            <div class="row mt-4">
                <div className="col">
                    <table className="table">
                        <thead className="table-info">
                            <tr>
                                <th className="pc-only">번호</th>
                                <th>제목</th>
                                <th>저자</th>
                                <th className="pc-only">출간일</th>
                                <th>가격</th>
                                <th>출판사</th>
                                <th className="pc-only">페이지수</th>
                                <th className="pc-only">장르</th>
                                <th>관리</th>
                            </tr>
                        </thead>
                        <tbody>
                            {bookList.map(book=>(
                                <tr key={book.bookId}>
                                    <td className="pc-only">{book.bookId}</td>
                                    <td>{book.bookTitle}</td>
                                    <td>{book.bookAuthor}</td>
                                    <td className="pc-only">{book.bookPublicationDate}</td>
                                    <td>{book.bookPrice}</td>
                                    <td>{book.bookPublisher}</td>
                                    <td className="pc-only">{book.bookPageCount}</td>
                                    <td className="pc-only">{book.bookGenre}</td>
                                    <td>
                                        {/* 수정버튼 */}
                                        <FaRegEdit
                                        className="text-warning ms-1"
                                        />
                                        {/* 삭제버튼 */}
                                        <FaXmark
                                        className="text-danger"
                                        />
                                    </td>
                                </tr>
                            ))}
                        </tbody>
                    </table>
                </div>
            </div>
        </>
    );
};

export default Book;

Book.css 생성

@media screen and (max-width:768px) {
    .pc-only {
        display: none;
    }
}

화면이 작아지면 항목이 줄어든다.

App.js 수정

import { NavLink, Route, Routes } from "react-router-dom";
import Pocketmon from "./components/Pocketmon";
import Book from "./components/Book";
import Home from "./components/Home";
import Menu from "./components/Menu.js";


function App() {
  return (
    <div className="container-fluid my-5 py-5">
      {/* 상단 메뉴 영역 */}
      <Menu/>

      {/* 본문 영역 */}
      <div className="row">
          <div className="col-sm-10 offset-sm-1">
            <Routes>
              <Route exact path="/" element={<Home/>}></Route>
              <Route path="/pocketmon" element={<Pocketmon/>}></Route>
              <Route path="/book" element={<Book/>}></Route>
            </Routes>
          </div>
      </div>

    </div>
  );
}

export default App;

Pocketmon.js 삭제 구문 추가

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

import {LiaEdit} from "react-icons/lia";
import {AiFillDelete} from "react-icons/ai";

const Pocketmon = (props)=>{
    const [pocketmonList, setPocketmonList] = useState([]);

    //서버에서 pocketmon list를 불러와서 state에 설정하는 코드
    const loadPocketmon = ()=>{
        axios({
            url:"http://localhost:8080/pocketmon/",
            method:"get"
        })
        .then(response=>{
            //console.log(response);
            setPocketmonList(response.data);
        })
        .catch(err=>{});
    };

    useEffect(()=>{
        loadPocketmon();
    }, []);

    //포켓몬스터 삭제
    //- 이제는 state에서 삭제하는 것이 아니라 서버에 통신을 보낸 뒤 목록을 갱신하면 된다
    const deletePocketmon = (pocketmon) => {
        const choice = window.confirm("정말 삭제하시겠습니까?");
        if(choice === false) return;

        //axios({옵션}).then(성공시 실행할 함수).catch(실패시 실행할 함수);
        axios({
            url:`http://localhost:8080/pocketmon/${pocketmon.no}`,
            method:"delete"
        })
        .then(response=>{
            loadPocketmon();//목록 갱신
        })
        .catch(err=>{});
    };

    return (
        <>
           
            <div className="row">
                <div className="col">
                    <h1>포켓몬스터 관리</h1>
                    <p>React CRUD 연습 예제</p>
                </div>
            </div>

            <div className="row mt-4">
                <div className="col">
                    <table className="table">
                        <thead>
                            <tr>
                                <th>번호</th>
                                <th>이름</th>
                                <th>속성</th>
                                <th></th>
                            </tr>
                        </thead>
                        <tbody>
                            {pocketmonList.map(pocketmon=>(
                                <tr key={pocketmon.no}>
                                    <td>{pocketmon.no}</td>
                                    <td>{pocketmon.name}</td>
                                    <td>{pocketmon.type}</td>
                                    <td>
                                        {/* 아이콘 자리 */}
                                        <LiaEdit className="text-warning"/>
                                        <AiFillDelete className="text-danger"
                                            onClick={e=>deletePocketmon(pocketmon)}/>                                        
                                    </td>
                                </tr>
                            ))}
                        </tbody>
                    </table>
                </div>
            </div>

        </>
    );
};

export default Pocketmon;

Pocketmon.js 등록 구문 모달로 추가 (구현중)

import {useState, useEffect, useRef} from "react";
import axios from "axios";

import {LiaEdit} from "react-icons/lia";
import {AiFillDelete, AiOutlinePlus} from "react-icons/ai";
import { Modal } from "bootstrap";

const Pocketmon = (props)=>{
    const [pocketmonList, setPocketmonList] = useState([]);

    //서버에서 pocketmon list를 불러와서 state에 설정하는 코드
    const loadPocketmon = ()=>{
        axios({
            url:"http://localhost:8080/pocketmon/",
            method:"get"
        })
        .then(response=>{
            //console.log(response);
            setPocketmonList(response.data);
        })
        .catch(err=>{});
    };

    useEffect(()=>{
        loadPocketmon();
    }, []);

    //포켓몬스터 삭제
    //- 이제는 state에서 삭제하는 것이 아니라 서버에 통신을 보낸 뒤 목록을 갱신하면 된다
    const deletePocketmon = (pocketmon) => {
        const choice = window.confirm("정말 삭제하시겠습니까?");
        if(choice === false) return;

        //axios({옵션}).then(성공시 실행할 함수).catch(실패시 실행할 함수);
        axios({
            url:`http://localhost:8080/pocketmon/${pocketmon.no}`,
            method:"delete"
        })
        .then(response=>{
            loadPocketmon();//목록 갱신
        })
        .catch(err=>{});
    };

    //modal 관련된 처리
    const bsModal = useRef();
    const openModal = ()=>{
        const modal = new Modal(bsModal.current);
        modal.show();
    };
    const closeModal = ()=>{
        const modal = Modal.getInstance(bsModal.current);
        modal.hide();
    };

    //등록과 관련된 state
    const [pocketmon, setPocketmon] = useState({name:"" , type:""});
    const changePocketmon = (e)=>{
        setPocketmon({
            ...pocketmon,
            [e.target.name] : e.target.value
        });
    };

    return (
        <>
           
            <div className="row">
                <div className="col">
                    <h1>포켓몬스터 관리</h1>
                    <p>React CRUD 연습 예제</p>
                </div>
            </div>

            {/* 추가 버튼 */}
            <div className="row mt-4">
                <div className="col text-end">
                    <button className="btn btn-success" onClick={openModal}>
                        <AiOutlinePlus/>
                        추가
                    </button>
                </div>
            </div>
           
            {/* 출력 위치 */}
            <div className="row mt-4">
                <div className="col">
                    <table className="table">
                        <thead>
                            <tr>
                                <th>번호</th>
                                <th>이름</th>
                                <th>속성</th>
                                <th></th>
                            </tr>
                        </thead>
                        <tbody>
                            {pocketmonList.map(pocketmon=>(
                                <tr key={pocketmon.no}>
                                    <td>{pocketmon.no}</td>
                                    <td>{pocketmon.name}</td>
                                    <td>{pocketmon.type}</td>
                                    <td>
                                        {/* 아이콘 자리 */}
                                        <LiaEdit className="text-warning"/>
                                        <AiFillDelete className="text-danger"
                                            onClick={e=>deletePocketmon(pocketmon)}/>                                        
                                    </td>
                                </tr>
                            ))}
                        </tbody>
                    </table>
                </div>
            </div>

            {/* Modal */}
            <div className="modal fade" ref={bsModal}
                        data-bs-backdrop="static" tabIndex="-1" role="dialog" aria-hidden="true">
                <div className="modal-dialog" role="document">
                    <div className="modal-content">
                    <div className="modal-header">
                        <h5 className="modal-title" >제목</h5>
                        <button type="button" className="close" data-dismiss="modal" aria-label="Close">
                            <span aria-hidden="true">&times;</span>
                        </button>
                    </div>
                    <div className="modal-body">

                        <div className="row">
                            <div className="col">
                                <label className="form-label">이름</label>
                                <input type="text" name="name" className="form-control"
                                        value={pocketmon.name} onChange={changePocketmon}/>
                            </div>
                        </div>

                        <div className="row mt-4">
                            <div className="col">
                                <label className="form-label">속성</label>
                                <input type="text" name="type" className="form-control"
                                        value={pocketmon.type} onChange={changePocketmon}/>
                            </div>
                        </div>

                    </div>
                    <div className="modal-footer">
                        <button className="btn btn-secondary" onClick={closeModal}>닫기</button>
                        <button className="btn btn-success">저장</button>
                    </div>
                    </div>
                </div>
            </div>

        </>
    );
};

export default Pocketmon;

pocketmon-mapper.xml

<?xml version="1.0" encoding="UTF-8"?>

 

<!DOCTYPE mapper

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

"https://mybatis.org/dtd/mybatis-3-mapper.dtd">

 

<mapper namespace="pocketmon">

<select id="list" resultType="PocketmonDto">

select * from pocketmon order by no asc

</select>

 

<insert id="save">

insert into pocketmon(no, name, type) values(pocketmon_seq.nextval, #{name}, #{type})

</insert>

 

<delete id="remove">

delete pocketmon where no = #{no}

</delete>

 

<select id="find" resultType="PocketmonDto">

select * from pocketmon where no = #{no}

</select>

 

<update id ="edit">

update pocketmon

set

<if test="dto.no > 0">

no=#{dto.no},

</if>

name=#{dto.name}, type=#{dto.type}

where no = #{no}

</update>

 

<update id="editUnit">

update pocketmon

<set>

<if test="dto.no > 0">no = #{dto.no},</if>

<if test="dto.name != null">name = #{dto.name},</if>

<if test="dto.type != null">type = #{dto.type},</if>

</set>

where no = #{no}

</update>

</mapper>