스프링부트를 대략 알았으닝, 부트롱 RestFul CRUD를 한번 해보장!(흐름에 집중!)
File -> New -> Spring Starter Project를 눌러 아래와 같이 세팅한당.(jdk21기준)
Dependency는 아래와 같이 선택하도록 하장(오라클에 MyBatis를 쓸거당!)
Lombok은 요기서 다운받아서 실행시키는 요상한 설치법을 추가로 해주공
STS를 재 실행시켜줘야 한당.
요상태에서 바로 실행시켜보면 console에 아래와 같은 에러가 발생한당.
오라클 데이터베이스 연결과 MyBatis 설정이 필요하당.
application.properties 파일에 아래처럼 설정하장.(#은 주석 표시당당)
# 아래 2개는 참공 logging.level.com.e7e.merong=debug #server.port=9004 spring.datasource.url=jdbc:oracle:thin:@localhost:1521/xe spring.datasource.username=java spring.datasource.password=oracle mybatis.configuration.map-underscore-to-camel-case=true mybatis.configuration.jdbc-type-for-null=varchar mybatis.type-aliases-package=com.e7e.merong.vo mybatis.mapper-locations=classpath:mybatis/mapper/*-Mapper.xml # 아래도 파일업로드 용량설정이당 그냥 참고하장 # default 128K #spring.servlet.multipart.max-file-size=10MB #spring.servlet.multipart.max-request-size=12MB #spring.servlet.multipart.file-size-threshold=12MB
위 설정대로 하기 위해 src/main/resources 아래에 mybatis/mapper 폴더를 맹글도록 하장.
다시 실행시켜보면 에러가 없어진 걸 알 수 있당.~~
본질을 흐리지 않고, 길에서 벗어나지 않도록 아래처럼 초 간단 테이블을 맹글장.
편의상 시퀀스도 1개 맹글장.
create SEQUENCE seq_sujin;
VO를 아래처럼 맹글장.(기본은 테이블 1개당 VO 1개로 추후 확장은 본인 선택이당!)
SujinVO.java
package com.e7e.merong.vo; import lombok.Getter; import lombok.Setter; import lombok.ToString; @Setter @Getter @ToString public class SujinVO { private int sujinNum; private String sujinName; private String sujinContent; private String sujinFile; }
맵퍼 인터페이스를 아래 처럼 맹글장!
SujinMapper.java
package com.e7e.merong.mapper; import java.util.List; import org.apache.ibatis.annotations.Mapper; import com.e7e.merong.vo.SujinVO; @Mapper public interface SujinMapper { // Get List List<SujinVO> listSujin(); // Get One SujinVO getSujin(SujinVO sujinVO); // insert int insertSujin(SujinVO sujinVO); // update int updateSujin(SujinVO sujinVO); // delete int deleteSujin(SujinVO sujinVO); }
맵퍼 인퍼페이스와 매칭시킬 SQL문을 가진 맵퍼xml을 아래처럼 맹글장.
문제가 있당. sts4에 mybatis xml 틀을 만들어 주는 게 안 들어있당.(짜증)
메뉴 Help -> Eclipse Marketplace 에서 mybatis로 검색후 아래 플러그인을 설치하장
좋은 기능이 정말 많이 들어있엉, 생산성 차이가 극과 극이당.
Sujin-Mappr.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="com.e7e.merong.mapper.SujinMapper"> <select id="listSujin" resultType="SujinVO"> select * from sujin </select> <select id="getSujin" parameterType="SujinVO" resultType="SujinVO"> select * from sujin where sujin_num=#{sujinNum} </select> <insert id="insertSujin" parameterType="SujinVO"> insert into sujin(sujin_num,sujin_name,sujin_content,sujin_file) values(seq_sujin.nextval,#{sujinName},#{sujinContent},#{sujinFile}) </insert> <update id="updateSujin" parameterType="SujinVO"> UPDATE sujin SET sujin_name=#{sujinName}, sujin_content=#{sujinContent} sujin_file=#{sujinFile} WHERE sujin_num=#{sujinNum} </update> <delete id="deleteSujin" parameterType="SujinVO"> delete from sujin where sujin_num=#{sujinNum} </delete> </mapper>
맵퍼는 서버를 돌려서 테스트하는 것 보다는 Spring 테스트에서 지원하는
Junit 테스트 프레임워크를 이용하는 것이 빠르고, 활용성도 좋아 정신 건강에 좋당.
src/test/java 패키지에 아래 파일을 맹글고, 마우스 오른쪽을 누르면 Run As에 Junit Test가 보인당.
SujinMapperTest.java
package com.e7e.merong; import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import com.e7e.merong.mapper.SujinMapper; import com.e7e.merong.vo.SujinVO; @SpringBootTest public class SujinMapperTest { @Autowired private SujinMapper sujinMapper; @Test @DisplayName("수진맵퍼테스통") public void insertTest() { SujinVO sujinVO = new SujinVO(); sujinVO.setSujinName("수진"); sujinVO.setSujinContent("그냥 웃지용"); sujinVO.setSujinFile("sujin.jpg"); assertEquals(1, sujinMapper.insertSujin(sujinVO)); } }
실행시 아래와 같은 warin이 보일 수 있당.(무시해도 된당)
WARNING: A Java agent has been loaded dynamically (C:\Users\chlee\.m2\repository\net\bytebuddy\byte-buddy-agent\1.14.10\byte-buddy-agent-1.14.10.jar)WARNING: If a serviceability tool is in use, please run with -XX:+EnableDynamicAgentLoading to hide this warningWARNING: If a serviceability tool is not in use, please run with -Djdk.instrument.traceUsage for more informationWARNING: Dynamic loading of agents will be disallowed by default in a future releaseOpenJDK 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended
무시하시 싫다면 마우스 오른쪽 버튼 Run as -> Run Configuration에서 아래와 같이 해주면 눈에 가시가 빠진당
서비스 인터페이스를 맹글장.(여기애 @Service를 절대 붙이면 안된당!)
SujinService.java
package com.e7e.merong.service; import java.util.List; import com.e7e.merong.vo.SujinVO; public interface SujinService { // Get List List<SujinVO> listSujin(); // Get One SujinVO getSujin(SujinVO sujinVO); // insert int insertSujin(SujinVO sujinVO); // update int updateSujin(SujinVO sujinVO); // delete int deleteSujin(SujinVO sujinVO); }
서비스 인터페이스틀 구현한 클래스를 맹글장.(여기에 @service를 붙여야 한당)
SujinServiceImple.java
package com.e7e.merong.service; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.e7e.merong.mapper.SujinMapper; import com.e7e.merong.vo.SujinVO; @Service public class SujinServiceImpl implements SujinService{ @Autowired private SujinMapper sujinMapper; @Override public List<SujinVO> listSujin() { return sujinMapper.listSujin(); } @Override public SujinVO getSujin(SujinVO sujinVO) { return sujinMapper.getSujin(sujinVO); } @Override public int insertSujin(SujinVO sujinVO) { return sujinMapper.insertSujin(sujinVO); } @Override public int updateSujin(SujinVO sujinVO) { return sujinMapper.updateSujin(sujinVO); } @Override public int deleteSujin(SujinVO sujinVO) { return sujinMapper.deleteSujin(sujinVO); } }
마지막으로 컨트롤러를 맹글고, Rest Client(부메랑, Postman등등...)를 이용 테스트한당.
SujinController.java
package com.e7e.merong.controller; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.e7e.merong.service.SujinService; import com.e7e.merong.vo.SujinVO; import lombok.extern.slf4j.Slf4j; @Slf4j @RestController @RequestMapping("/api") public class SujinController { @Autowired private SujinService sujinService; @GetMapping(value = "/sujins",produces = "application/json;charset=utf-8") public List<SujinVO> listSujin(){ return sujinService.listSujin(); } @GetMapping(value = "/sujin/{num}",produces = "application/json;charset=utf-8") public SujinVO getSujin(@PathVariable int num){ SujinVO sujinVO = new SujinVO(); sujinVO.setSujinNum(num); return sujinService.getSujin(sujinVO); } @PostMapping(value = "/sujin",produces = "application/json;charset=utf-8") public int insertSujin(@RequestBody SujinVO sujinVO){ log.debug("" +sujinVO); return sujinService.insertSujin(sujinVO); } @PutMapping(value = "/sujin",produces ="application/json;charset=utf-8") public int updateSujin(@RequestBody SujinVO sujinVO){ return sujinService.updateSujin(sujinVO); } @DeleteMapping(value = "/sujin/{num}",produces ="application/json;charset=utf-8") public int deleteSujin(@PathVariable int num){ SujinVO sujinVO = new SujinVO(); sujinVO.setSujinNum(num); return sujinService.deleteSujin(sujinVO); } }
나는 잘된당.
백엔드는 대략 끝났으닝, 이제 프론트엔드만 맹글면 되겠당.~~
식사를 하시고 집으로 가는 길에 사진을 찍자고 하신당.
의식하지 못했당. 꾸미고 나오신 걸
머릿속이 하얗게 변했당. 영정사진!
배에 단단히 힘을 주고, 티 내지 않고 웃으며 같이 사진을 찍었당.
다시 일상으로 돌아갔당. 잊고 말았당.
얼마뒤 조용히 가시었당. 비가 온당.
엄마가 되어 보아야겠당.~~
https://www.youtube.com/watch?v=5C1OnNsEvKg
스프링 부트 war 패키징 (4) | 2025.02.10 |
---|---|
spring boot3 security jwt 적용 1 (B/E) (0) | 2025.01.08 |
Spring boot WebSocket(스프링 부트 웹소켓 사용) (8) | 2024.11.11 |
sts4 spring boot 세번쨍 (0) | 2023.07.10 |
sts4 spring boot 첫번쨍 (0) | 2023.07.03 |