본문 바로가기
Spring/Spring 기초

e7e샘의 sts4 spring boot 두번째

by 미눅스[멘토] 2023. 8. 24.
728x90

https://e-7-e.tistory.com/159

 

sts4 spring boot 두번쨍

스프링부트를 대략 알았으닝, 부트롱 RestFul CRUD를 한번 해보장!(흐름에 집중!) File -> New -> Spring Starter Project를 눌러 아래와 같이 세팅한당.(난 jdk1.8이당) Dependency는 아래와 같이 선택하도록 하장(

e-7-e.tistory.com

참고하자

 

 

 

 

 

File -> New Spring Starter Project 로 새로 만듬

여기서 Group은 회사 도메인을 거꾸로 쓴다

 

 

 

 

부트는 처음부터 톰켓을 새로 실행시킨다.

jsp만 고쳐도 새로 시작해야되는 편하게 시작해주는것이

프로그램 상태가 괜찮은지 모니터링해주는 것이

 

이렇게 두 개를 꼭 깔고감

 

 

DB와 연동시킬, Oracle드라이버등  체크해준다

 

다 체크했으면 넥스트

 

피니쉬

 

 

 

실행시켜봄

 

 

 

DB설정을 해달라고 에러가 나옴

그래서 설정하기로함

 

 

 

스프링부트는

 

여기서 설정을 다함

 

이거 복사해서

# 아래 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

갖다 붙히고

 

로깅 내패키지로 바꿔주고

서버 포트 변경해줌

 

 

그리고 database 내거로 설정

 


#mybatis도 설정 해주는데 여기서

mybatis.configuration.map-underscore-to-camel-case=true

ㄴ//카멜케이스를 사용하겠다
mybatis.configuration.jdbc-type-for-null=varchar

ㄴ//자바와 오라클의 언어가 달라서 sql에 자바의 null이 들어오면 어떻게 할것이냐 = varchar로 처리 하겠다. 라는뜻

여기까지 설정한 두가지는 필수이다

 

mybatis.type-aliases-package=com.suji.merong.vo

ㄴ 경로에 맞는 파일을 만들어줌 vo

 

//mybatis.mapper-locations=classpath:mybatis/**/*-Mapper.xml 로 지어도됨

mybatis.mapper-locations=classpath:mybatis/mapper/*-Mapper.xml

클래스 패스 : 에 폴더도 만들어줌

 

 

이렇게 해놓고 서버 다시 스타트 그럼 오류 안나고 잘나옴

 

DB에러가 사라짐

 

 

맨밑에 파일업로드도 열어준다 여기까지하고 설정하고

이제 테이블을 만들어주자

 

만든후

시퀀스도 만들자

create SEQUENCE seq_suji;
select seq_suji.nextval from dual; --이거 한번해야
select seq_suji.currval from dual; --이게 나옴 위에거 안되면 오류

하고 실행

 

 

 

그리고 나서 vo만듬

여기서 롬복이 안먹는데 안먹으면

프로그램 자체를 껏다가 킨다

 

그럼 오른쪽에 롬복 설정이 잘 된것을 볼 수 있음

toString을 쓰는 이유는 디버그 할때 좋아서 쓴다.

 

 

이제 Mapper를 만들자

Mapper.Interface 생성하고 @Mapper꼭 붙여줌

package com.suji.merong.mapper;

import java.util.List;

import org.apache.ibatis.annotations.Mapper;

import com.suji.merong.vo.SujiVO;

@Mapper
public interface SujiMapper {
	  // Get List
	  List<SujiVO> listSuji();
	  // Get One
	  SujiVO getSujin(SujiVO sujinVO);
	  // insert
	   int  insertSujin(SujiVO sujinVO);
	   // update
	   int  updateSujin(SujiVO sujinVO);
	   // delete
	   int  deleteSujin(SujiVO sujinVO);
}

 

이제 이것을 사용할 mybatis 작성해야함

data-jpa =자바에서 vo객체지향을 하면 sql테이블을 안만들어도됨

객체와 관계형 DB에 대해서 경험치가 충분히있어야

data-jpa를 잘 쓸 수 있음

뭔소린지 모르겠다..

 

마이바티스 설정파일

플러그인 넣어야함

 

https://harawata.jfrog.io/ui/native/eclipse-local/plugins/

 

JFrog

 

harawata.jfrog.io

https://harawata.jfrog.io/ui/native/eclipse-local/features/

 

JFrog

 

harawata.jfrog.io

 

두개 사이트 다들어가서  1.2.4버전을 다운로드 받는다

 

다운 받았으면

 

뒤에 feature붙은 파일을 

D:\MyTool\sts-472 폴더 안에 feature 에 넣는다

그리고 나머지 mybatips로 끝나는 파일을 plugins에 넣는다

 

 

그리고 STS껏다 킴

 

 

그리고 다시 mapper에서 

 

새로은 파일 생성 클릭하고

 

my만 쳐도 mybatis XML이 나옴

 선택 후 넥스트

 

이름 정해주고 피니쉬

 

 

그럼 여기서 namespace는 mapper로 사용할 패키지 안에 인터페이스 경로를 설정해준다

클래스 안에 컴파일된 파일의 경로를 복사 Qualified Name을 복사

 

 

Mapper에 namespace에 붙여넣는다

 

 

 

Ctrl + 마우스로 클릭해서 설정하려했던 Inteface가 들어가지면 잘 된것

 

 

그럼이제 Suji-Mapper를 작성하자

여기서 parameterType은 마이바티스에서 설정해서 그냥 SujiVO로 설정해줘도 된단다.

 

<?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.suji.merong.mapper.SujiMapper">


	<select id="listSuji" parameterType="SujiVO">
		select * from suji
	</select>

	<select id="getSuji" parameterType="SujiVO" resultType="SujiVO">
		select * from suji where suji_num=#{sujiNum}
	</select>
	
	<insert id="insertSuji" parameterType="SujiVO">
		insert into suji(suji_num,suji_name,suji_content,suji_file)
		values(seq_suji.nextval,#{sujiName},#{sujiContent},#{sujiFile})
	</insert>
	
	<update id="updateSuji" parameterType="SujiVO">
		UPDATE suji
	 	SET 
	 	suji_Name=#{sujiName},
	 	suji_Content=#{sujiContent},
	 	suji_File=#{sujifile}
		WHERE
		suji_num=#{sujiNum}
	</update>
	
	<delete id="deleteSuji" parameterType="SujiVO">
		delete from suji where suji_num=#{sujiNum}
	</delete>
</mapper>

 

무테이션 메소드란??

데이터를 변경하는 메소드

 

 

이렇게 해두고 이제

테스트를 한다

우리는 수지 메퍼를 테스트 할것이라 src/test/java 안에

똑같은 패키지를 만들고 test클래스를 만든다.

 

@SpringBootTest를 꼭 달아준다.

이것이 해주는것은

@BootstrapWith(value=SpringBootTestContextBootstrapper.class)
@ExtendWith(value={SpringExtension.class})
@Target(value={TYPE})
@Retention(value=RUNTIME)
@Documented
@Inherited

이 여섯가지 어노테이션이 하는 역할 을 해준다

 

그리고 테스트는 리턴값이 필요가 없어서

void를 많이 쓴다.

 

 

 

package com.suji.merong.mapper;

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.suji.merong.vo.SujiVO;

@SpringBootTest
public class SujiMapperTest {
	
	@Autowired
	private SujiMapper sujiMapper;
	
	@Test
	@DisplayName("예린Insert테스통")
	public void insertTest() {
		SujiVO sujiVO = new SujiVO(); //현재는 이렇게 하는 게 좋은뎅
		// 항상 좋은 것은 아님, 고객이 성능을 원하느냐? 가독성(유지보수)를 원하느냐?
		for (int i = 1; i <= 10; i++) {
			sujiVO.setSujiContent("내용이얌");
			sujiVO.setSujiFile("/merong/aaa.jpg");
			sujiVO.setSujiName("소연님등장");
			//테스트할 때는 이거 메소드 하나만씀
			assertEquals(1, sujiMapper.insertSuji(sujiVO));
		}
	}
}

   

여기서 1은 예상값(기대값), sujiMapper.insertSuji(sujiVO) = 실제값

 

이제 실행해보면

 

 

 

이렇게 잘 되었다.

 

 

딜리트 해보자

package com.suji.merong.mapper;

import static org.junit.jupiter.api.Assertions.assertEquals;

import org.junit.jupiter.api.Disabled;
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.suji.merong.vo.SujiVO;

@SpringBootTest
public class SujiMapperTest {
	
	@Autowired
	private SujiMapper sujiMapper;
	
	@Test
	@DisplayName("예린Insert테스통")
	@Disabled // 이미 테스트가 끝나서 더 안할 꺼임!
	public void insertTest() {
		SujiVO sujiVO = new SujiVO(); //현재는 이렇게 하는 게 좋은뎅
		// 항상 좋은 것은 아님, 고객이 성능을 원하느냐? 가독성(유지보수)를 원하느냐?
		for (int i = 1; i <= 10; i++) {
			sujiVO.setSujiContent("내용이얌"+i);
			sujiVO.setSujiFile("/merong/aaa.jpg"+i);
			sujiVO.setSujiName("소연님등장"+i);
			//테스트할 때는 이거 메소드 하나만씀
			assertEquals(1, sujiMapper.insertSuji(sujiVO));
		}
	}
	
	@Test
	@DisplayName("안예린Delete")
	public void deleteTest() {
		SujiVO sujiVO = new SujiVO();
		sujiVO.setSujiNum(6);
		assertEquals(1,sujiMapper.deleteSuji(sujiVO));
	}
}

잘된다

 

 

 

 

테스트 잘 통과됬으니 이제 서비스를 만들어보자

서비스 인터페이스 를 만들고

 

 

 

Mapper Interface에 있는 메소드들 복사해서 가져오자

 

그리고 ServiceImpl 클래스 를 만들어준다

서비스 인터페이스를 상속받고

@Service라고 명시해주고

Mapper를 사용할거기 때문에 SujiMapper에다 @Autowired 의존성 주입을 해준다.

 

SujiServiceImpl 클래스

package com.suji.merong.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.suji.merong.mapper.SujiMapper;
import com.suji.merong.vo.SujiVO;

@Service
public class SujiServiceImpl implements SujiService{

	@Autowired //수지 매퍼를 불러야 함!!
	private SujiMapper sujiMapper;
	
	@Override
	public List<SujiVO> listSuji() {
		return sujiMapper.listSuji();
	}

	@Override
	public SujiVO getSuji(SujiVO sujiVO) {
		return sujiMapper.getSuji(sujiVO);
	}

	@Override
	public int insertSuji(SujiVO sujiVO) {
		return sujiMapper.insertSuji(sujiVO);
	}

	@Override
	public int updateSuji(SujiVO sujiVO) {
		return sujiMapper.updateSuji(sujiVO);
	}

	@Override
	public int deleteSuji(SujiVO sujiVO) {
		return sujiMapper.deleteSuji(sujiVO);
	}

}

 

 

이제 컨트롤러 만들자

@RestConroller = @ResponseBody와 @Controller에 합작임

그래서 @RestController를 쓰면 편한것이 @ResponseBody를 메서드에서 생략 가능함

만약에 메소드중에 하나라도 @ResponseBody쓴다면 그냥 @Controller로 사용한다.

 

 

SujiController

package com.suji.merong.controller;

import java.util.List;

import org.apache.ibatis.annotations.Delete;
import org.springframework.beans.factory.annotation.Autowired;
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.RestController;

import com.suji.merong.service.SujiService;
import com.suji.merong.vo.SujiVO;

@RestController
public class SujiController {

	@Autowired	//서비스를 호출하기 위함
	private SujiService sujiService;
	
	@GetMapping("/rest/suji")
	public List<SujiVO> getList() {
		return sujiService.listSuji();
	}
	
	//{num} = pathVariable로 받음!!
	@GetMapping("/rest/suji/{num}")
	public SujiVO getList(@PathVariable int num) {
		SujiVO sujiVO = new SujiVO();
		sujiVO.setSujiNum(num);
		return sujiService.getSuji(sujiVO);
	}
	
	@PostMapping("/rest/suji")
	public String insertSuji(@RequestBody SujiVO sujiVO) {//제이슨 형태로 넘어오기때문에 @RequestBody를 사용해줘야함
		//문자열로 리턴해줘야 하기때문에 결과값 정수형을 문자열로 바꿔줌
		return Integer.toString(sujiService.insertSuji(sujiVO));
	}
	
	@PutMapping("/rest/suji")
	public String updateSuji(@RequestBody SujiVO sujiVO) {//제이슨 형태로 넘어오기때문에 @RequestBody를 사용해줘야함
		//문자열로 리턴해줘야 하기때문에 결과값 정수형을 문자열로 바꿔줌
		return Integer.toString(sujiService.updateSuji(sujiVO));
	}
	
	@Delete("/rest/suji/{num}")
	public String deleteSuji(@PathVariable int num) {//제이슨 형태로 넘어오기때문에 @RequestBody를 사용해줘야함
		//문자열로 리턴해줘야 하기때문에 결과값 정수형을 문자열로 바꿔줌
		SujiVO sujiVO = new SujiVO();
		sujiVO.setSujiNum(num);
		return Integer.toString(sujiService.deleteSuji(sujiVO));
	}
	
}

 

그럼 백앤드 끝

이제 잘 했는지 확인할 시간

서버를 실행시키고

부매랑으로 확인해 본다..

잘 동작하면 문제 없음

POST방식의 업데이트도 문제 없음

나머지 들도 확인