[SeSACX코딩온] Spring(1)

JUHEE·2024년 5월 28일
0

SeSACX코딩온

목록 보기
25/26

Spring

  • java기반 백엔드 웹 프레임 워크
  • 엔터프라이즈용 java 애플리케이션 개발을 편하게 할 수 있게 해주는 오픈소스 경량급 애플리케이션 프레임워크
  • 스프링 프레임 워크의 4가지 특징, IoC, DI, AOP, POJO

IoC, 제어의 역전

  • Java에서 객체를 갱성할 때 의존성을 역전시켜 제어권을 직접갖지 않는 것을 의미한다
  • 스프링 컨테이너가 객체를 관리해준다
  • 이해가 안가...

DI, 의존성 주입

  • Field Injection, Setter Injection, Constructor Injection
  • 어노테이션 @Autowired 사용

AOP, 관점 지향 프로그래밍

  • 어떤 로직을 기준으로 "핵심관점", "부가관점"으로 나누어 각각 모듈화, 기능을 비즈니스 로직과 공통 모듈로 구분하고 코드 밖에서 필요한 시점에 비즈니스 로직을 삽입하여 실행되도록 함
  • 여러 객체에 공통으로 적용할 수 있는 기능을 구분함으로써 재사용성을 높여주는 기법
  • 공통 관심을 따로 빼내어 외부에서 접근해 사용하도록 함으로써 개발자는 핵심관점 코드에만 집중하도록 할 수 있다

POJO, 단순한 자바 오브젝트

  • 다른 기술 사용없이 순수 java만을 통해 생성된 객체
  • 외부 라이브러리 import해서 사용할 경우 변경 시 코드를 모두 변경하거나 재사용이 어려울 수 있음
  • 객체 지향적인 원리에 충실하면서 환경과 기술에 종속되지 않고 필요에 따라 재활용될 수 있는 방식으로 설계된 오브젝트를 의미

Spring Boot

  • 쉽고 빠르게 Spring 프레임워크 사용가능
  • was 내장, 독립적 실행가능
  • 스프링 부트 스타터 제공
  • 애플리케이션 설정을 xml이 아닌 java코드로 직관적 작성가능
  • jar을 이용해 자바 옵션만으로 배포가능, 실행환경에서 별도의 설정이 필요 없음

시작하기

  • https://start.spring.io/ : 스프링 프로젝트 만들어주는 사이트, 원하는 라이브러리 선택하고 생성가능
  • 기본적인 수업 프로젝트 세팅, 디펜던시는 이후 build 파일에서 따로 추가할 수도 있으니 걱정 ㄴㄴ
  • 생성 후 zip파일이 다운되는데 해당 파일의 압축을 풀고 내가 작업하려는 공간에 압축 해제된 파일을 넣는다. 내 경우 바탕화면의 36_spring 폴더 안에 넣음
  • 해당 파일을 intelliJ에서 open하면 자동으로 build가 시작된다
  • 실행은 src/main/java/내가만든파일명/SpringBootMybatisApplication.java 파일의 main함수를 실행하고 localhost:8080으로 접속해보면 된다
  • Spring도 MVC 패턴을 사용하여 프로젝트를 구성

정적파일

  • src/main/resources/templates에 html파일을 생성하여 controller에서 연결하여 사용할 수 있다
  • controller에서 return시 기본적으로 해당위치의 폴더들로 연결됨

Thymeleaf

  • 템플릿 엔진
  • html 태그에 속성을 추가해 페이지에 동적으로 값을 추가하거나 처리할 수 있게 도와주는 것
  • 이전의 ejs와 비슷한 느낌? html문서에 키워드로 변수 사용할 수 있도록 해줌
  • 표현식: ${형태}를 가장 많이 쓴 듯

    1) html태그에 코드 추가해야 사용가능
<!doctype html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">

2) 사용문법

  • 기본적인 형태는 태그안에 th:~~ 형태로 작성
  • 페이지 렌더 시 서버에서 받아 온 값을 보여줄 때 사용함
  • th:text = innerText와 유사
<td th:text="${board.no}"></td>
  • th:utext = innerHtml과 유사, html 태그 문자열도 인식
  • th:value = html요소의 value값을 지정가능 button, input 등
  • th:with = 변수값을 지정해서 사용 가능, 서버에서 보낸 hello 변수의 값을 temp라는 내가 생성한 변수에 넣어서 html파일에서 temp라는 변수명으로 사용가능
<div th:with="temp=${hello}" th:text="${temp}"></div>
  • th:switch = switch-case문, th:case로 각 case를 구분한다, default의 경우 case = "*" 을 마지막에 사용해서 표현한다
  • th:if = if문, else if는 사용이 불가능, else문은 unless라는 키워드로 대신 사용 = 뒤에 "안에 조건문을 적어 사용함" if와 unless의 조건은 동일해야함(unless는 조건이 아닌 경우를 인식하기 때문에)
  • th:each = 반복문, each="지정변수:${서버에서보낸배열}" 형태를 반복하려는 태그에 넣고 그 안에서 배열 객체를 지정한 변수 이름으로 한 개씩 접근할 수 있음, for each문과 비슷한 사용 방식

Controller

  • controller폴더를 만들고 그 안에 클래스를 생성한다
  • 기본적으로 대문자로 시작하는 것이 관례
  • 생성된 클래스에 어노테이션 @Controller를 사용하여 지정해준다
  • 클래스 내부에 메소드를 생성하는데, @GetMapping 등의 어노테이션을 통해 method와 주소를 지정해서 사용할 수 있다. String으로 html 파일명을 리턴할 경우 해당 파일이 렌더링된다.(경로는 기본적으로 templates라 생략 가능, .html도 생략가능)

API

  • GET
  • GetMapping, parameter나 query로 데이터를 받을 수 있다
    1) ?key=value받기
  • @RequestParam 어노테이션 사용
  • 사용예시
@GetMapping(url)
public String getMethod(@RequestParam(value="key") String key) {
	//?key=value 형식의 데이터에서 value를 key라는 이름의 변수에 담아 사용가능
    return "view";
}

2) /{value받기}

  • @PathVariable 사용
  • url주소에 받을 변수 명시
  • 사용예시
@GetMapping(url/{value})
public String getMethod(@PathVariable String value) {
	//?value를 key라는 이름의 변수에 담아 사용가능
    return "view";
}
  • POST: @PostMapping(url) 사용
  • Model model: import하여 사용가능, model.addAttribute 메소드로 렌더링할 페이지에 데이터 함께 전송가능
// 페이지 로드
@GetMapping("")
public String getBoard(Model model) {
	List<BoardDTO> boards = boardService.getBoardList();
	model.addAttribute("boards", boards);
	return "board";
}
  • view를 리턴하지 않고, 데이터만 전달할 때는?
  • @ResponseBody 사용하기, res.send()와 유사한 개념

Axios

  • html코드에 axios cdn 추가하고 axios.get or post 등의 요청 전송
  • form으로 데이터 받을 경우 controller에서 @RequestBody로 변수 받기 필수!!
  • 메소드 위에 @ResponseBody 어노테이션 사용하고 전달하려는 데이터 return, html에서 타임리프로 사용가능
  • 예시코드
@PatchMapping("/{id}")
@ResponseBody
public Map<String, Boolean> patchBoard(@RequestBody BoardCreateDTO board, @PathVariable int id) {
	Map<String, Boolean> result = new HashMap<String, Boolean>();
	try{
		boardService.updateBoard(id, board);
		result.put("result", true);
	} catch(Exception e){
		log.error("patch error {}",e.getMessage());
		result.put("result", false);
	}
	return result;
}

Controller - Rest

  • Representational State Transfer
  • 서버와 클라이언트 통신 방법 중 하나로, http URI를 통해 자원을 명시하고 http method를 이용해 자원을 교환하는 통신 방법
  • 특징: Server-Client 구조, Stateless(무상태), Cacheable(캐시처리가능), Layered System(계층화), Uniform Interface(인터페이스 일관성)
  • 장점: http 프로토콜 인프라를 그래도 사용하여 별도의 인프라 구축 필요X, http표준 프로토콜을 따르는 모든 플랫폼에서 사용 가능, 서버와 클라이언트 역할을 명확하게 분리
  • 단점: http method 형태가 제한적, 구형 브라우저에서는 호환이 되지 않아 지원못해주는 동작이 많다
  • dto와 vo를 컨트롤러 메소드에서 전달받는 인자의 타입으로 지정하여 사용

DTO

  • Data Transfer Object
  • 계층 간 데이터 교환을 위해 사용하는 객체
  • 데이터를 옮기기 위한 전달자
  • 다른 로직을 가지지 않는 순수한 데이터 객체
  • DTO 예시(Setter필수)
@Getter
@Setter
public class UserDTO {
    private int id;
    private String name;
    private String nickname;
    private int no;
}

VO

  • Value Object
  • DTO와 유사하지만 read-Only속성을 가짐(setter불가)
  • model.addAttribute와 사용 불가능
  • DTO vs VO

Spring Database

JDBC

  • java Database Connectivity
  • 자바와 db를 연결해주는 통로, 자바에서 db에 접근할 수 있도록 해주는 자바 API
  • Spring JDBC: 스프링 프레임 워크의 일부, db작업 단순화, 코드 양을 줄여줌

SQL mapper와 orm

  • spring의 두가지 유형의 데이터베이스 상호작용 방식, 두 방식 모두 java 객체와 데이터베이스 간의 상호작용
  • 차이점
    1) SQL mapper
  • 개발자는 sql쿼리 직접 작성, 퀴리 결과를 java 객체에 매핑함
  • 동적 sql생성, 조건문, 반복문 등 sql작성에 있어서 유연
  • sql쿼리의 세밀한 튜닝이 필요할 때 주로 사용
  • ex) MyBatis, JDBCTemplate
    2) ORM
  • java객체가 데이터베이스와 어떻게 매핑 될지를 정의함
  • 대부분의 crud 연산에 대한 sql을 자동으로 생성, 객체 지향적으로 데이터를 다룰 수 있게 됨
  • ex) Hibernate, JPA

MyBatis

  • SQL Mapper로써, JDBC로 처리하는 상당 부분의 코드와 파라미터 설정 및 결과 매핑을 대신해준다.
  • JDBC의 모든 기능을 사용가능, 쉬운 접근서오가 코드의 간결함
  • sql문과 프로그래밍 코드 분리
  • 다양한 프로그래밍 언어로 구현 가능
    1) myBatis를 사용하기 위해 dependency 추가
  • build gradle 파일 수정
implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:3.0.3'
  • 수정 후 아이콘 클릭하여 빌드(필수!) 후 실행
    2) application.properties 수정
  • 예시코드
spring.application.name=spring-boot-mybatis
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=yes&characterEncoding=UTF-8&allowMultiQueries=true&serverTimezone=Asia/Seoul
spring.datasource.username=root
spring.datasource.password=1234

mybatis.type.aliases-package=com.spring.boot.mapper
mybatis.mapper-locations=mybatis-mapper/*.xml
  • 바꿔야 하는 부분: db username과 password, mapper-location 자기 설정대로 수정해야함
  • mybatis-mapper 이하의 모든 xml 파일에 접근 가능하도록 함

프로젝트 구조와 흐름

  • 실습 문제 폴더 구조, 자세한 내용은 git참고
  • https://github.com/hjh3933/SeSAC_Dobong1_Web/tree/main/35_spring/spring-boot-mybatis
  • 혼자 설명해보기(select)
    -> sql문으로 테이블 생성하고 코드 작성 시작
    -> domain폴더에 테이블과 동일한 구조의 클래스작성(Getter, Setter)
    -> dto폴더에 실제로 view와 controller에서 주고 받을 형식의 클래스 작성(예를 들어 비밀번호 값은 보여주지 않는다거나, 회원가입시 인덱스 값은 전송받을 필요가 없기 때문에 domain과 달라질 수 있는 거임)
    -> mapper 폴더에 사용할 테이블에 대해 인터페이스 생성, 이후 sql명령 별 메솓를 작성하고 xml파일과 매칭해서 사용함
    -> controller 생성 후 메소드 작성 시작 service의 메소드를 통해 사용할 dto데이터 받음
    -> service는 mapper 폴더의 인터페이스에서 추상메소드를 불러와서 sql결과를 domain형태로 받고, 해당 데이터를 dto형태로 set하는 작업을 진행, 이후 해당 dto 데이터를 return함
    -> 컨트롤러는 해당 데이터를 받아 axios나 페이지를 렌더하면서 데이터를 전송함
    -> sql문은 resources하위의 xml파일에 작성하는데 기본형태는 아래와 같고, id는 interface의 메소드와 동일해야함, 태그 사이에 sql문을 작성함
<?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="lecture.spring_boot_mybatis.mapper.BoardMapper">
   <select id="retrieveAll" resultType="lecture.spring_boot_mybatis.domain.Board">
        SELECT board.* FROM board
   </select>
</mapper>

-> 값을 불러오는게 아니라 전달하는 insert, update, delete 등의 경우 로직은 비슷함 컨트롤러에서 dto 타입 전달 -> service -> interface를 거쳐 -> .xml에서 sql 작성 후 결과에 따라 값 리턴
-> xml에서 값을 받아서 sql문에 사용할 경우 parameterType 작성필요, 보통 dto나 domain은 map으로 받음, 이외에 String이나 Integer 등 참조 타입으로도 전달가능

<update id="updateBoard" parameterType="map">
	UPDATE board SET title = #{title}, content = #{content}, writer = #{writer} WHERE id = #{id}
</update>
profile
초보개발자

0개의 댓글