[Java/Spring] Project 구성

Hyeri Park·2022년 8월 10일
0

JAVA/Spring 기초

목록 보기
18/22
post-thumbnail

프로젝트 구성



1. Dendencies

  • Spring Boot DevTools : 개발에 편리한 기능들을 제공
  • Lombok : @annotation 사용으로 코드가 심플해짐
  • Mybatis Framework : db framework
  • MySQL Driver
  • Spring Web


2. MVC(Model,View,Controller) 구조


1) View/Controller

jsp, html, ModelAndView 작업이 핵심

2) Model

데이터 Access, select 하는 작업
Mybatis가 DBCP를 이용해 싱글톤 적용



우선 웹 서버의 구조에서 각 클라이언트당 스레드의 개념으로 접근하게 된다.
위 그림을 살펴보면 3명의 유저가 동시에 서버에 접속을 해서 자원을 사용한다고 하였을 때

1) 일반적인 구조에서는 각 스레드 당 객체들이 생성되게 된다. 따라서 스레드의 개수만큼 객체가 생성되게 되고 그 객체의 메모리가 서버의 힙 메모리 공간에 저장되게 된다.

2) 반면 스프링에서 권장하고 있는 사항은 일반적인 구조처럼 각 스레드당 new를 해서 객체를 만드는 것이 아닌 beans파일 즉 xml에 한번만 정의해 놓고 각 스레드가 해당 자원을 공유하며 결론적으론 서버 힙 공간에는 초기셋팅시 딱 하나만 생성되게 만든다.

 스프링은 기본적으로 이러한 구조 즉 싱글톤 패턴을 권장한다. 

각 스레드당 객체를 관리하는 것 보다 객체를 하나만 보유하고 있으면서 그걸 공유하는 방법이 더 효율적이다.
따라서 스프링에서는 이러한 것을 지원하기 위해 어노테이션으로 @Autowired를 지원한다.


3. Package/class 구성


- src/main/java

    * com.example.client

        * service : 비지니스 로직을 수행, 서비스 레이어 영역 

            Service의 역할은 Dao/Mapper가 DB에서 받아온 데이터를 전달 받아 가공, 
            즉 데이터베이스에 접근하는 DAO를 이용해 결과값을 받아옴


        * config : 설정파일

            @Configuration : 설정 파일이라는것을 알려주는 어노테이션        
            @Bean 사용자가 직접 제어하지 못하는 외부 라이브러리를 빈으로 등록할때 사용
            @Component : 사용자가 직접 제어할 수 있는 Class를 빈으로 등록할때 사용


        * controller 

            웹 브라우저 요청을 전담하여 처리, Controller가 Service 호출 


        * mapper/dao 

           1) DAO(Data Access Object)란? 

              Database의 데이터에 접근하는 트랜잭션 객체
              즉, DB에 접근하여 데이터를 조회, 조작하는 기능을 전담. 
              사용하는 이유는 효율적인 커넥션 관리와 보안성, 저수준의 로직과 고급 비즈니스 로직을 분리하고, 
              Domain 로직으로부터 DB관련 mechanism을 숨기기 위해 사용한다. 

           2) Mapper 인터페이스란? 

              MyBatis 매핑xml에 기재된 sql을 호출하기 위한 인터페이스이다.
              DB 처리 용도, 인터페이스로 구성 → SampleMapper.xml 파일 읽기, 스키마 총 3개 


           ✓ 1) 클라이언트 - Controller - Service - DAO - mapper.xml 의 구조를 사용하는 것보다  
             2) 클라이언트 - Controller - Service - Mapper.java - mapper.xml 의 구조를 사용하는 것이 더 편리하다.
             단, DB에 접근하는 Layer명을 Mapper로 할지 DAO로 할지는 개발자의 기호에 맞게 구조를 잡으면 된다.


        * model : DTO(Data Transfer Object)

            각 계층이 데이터를 주고 받을 때 사용하는 객체

    	

- src/main/resources

- static 

	 html, css, js, img 등 정적 resource directory
     
     
     

* JRE System Libray : 현재 사용하는 JDK 의 라이브러리

* Project dependencies : gradle 의존성 주입

* 그외 폴더는 자동으로 생성 (gradle 관련 파일들, help.md)

4. 흐름파악

1) DTO

(1) dto.java

데이터를 주고받을때 사용하는 객체

package board.board.dto;

import lombok.Data;

@Data
public class BoardDto {
	
	private int boardIdx;
	
	private String title;
	
	private String contents;
	
	private int hitCnt;
	
	private String creatorId;
	
	private String createdDatetime;
	
	private String updaterId;
	
	private String updatedDatetime;
}

2) Controller

(2) Controller.java

웹 브라우저 요청 전담하여 처리하는 컨트롤러
서비스와 뷰의 중재자 역할

@Controller   //해당 클래스를 컨트롤러로 동작하게 한다.
public class BoardController {
	
	@Autowired
	private BoardService boardService;
	
	@RequestMapping("/apple")    // 이 주소로 접속하면 이 메소드를 호출한다.(매핑한다.), 기존 web.xml이 했던 역할 수행
    @RequestParam() : view에 <form> 태그에서 POST 방식으로 넘어온 파라미터들을 제어 할 수 있음.
    
	public ModelAndView openBoardList() throws Exception{
    
	//Model and View 는 컨트롤러에서 뷰의 중재역할 
        ModelAndView mv = new ModelAndView("/apple/boardList");
		
		List<BoardDto> list = boardService.selectBoardList();
        
    // addObject() : 뷰 내부의 변수와 매핑
		mv.addObject("list",list);
        
    // setViewName() : 출력할 뷰 선택 , 서비스 호출의 시작점
		mv.setViewName("view/sample/index");
		return mv;
	}
}



@Controller 어노테이션

: @Controller 어노테이션을 붙여 이 클래스가 컨트롤러 클래스 라는 것을 알려준다.

사용자 요청이 들어오면 이 컨트롤러가 호출된다.


@RequestMappring("/apple") 어노테이션

: baseurl/apple 로 접속하게 되면 이 어노테이션을 가진 메소드로 매핑이 된다.


List<BoardDto> list = boardService.selectBoardList();

이 부분이 Service를 호출하는 부분.

Service의 반환값을 list 에 저장하고 있음.


3) Service

Service는 (1) service interface, (2) service interface를 구현한 class (service interface 구현체) 두 가지를 설계방식을 사용 했으나
최근 들어 같은 인터페이스를 만들어서 사용하기 때문에 한 가지만 만드는 설계방식을 사용 하기도 한다.

  • service는 mapper/dao를 호출한다.

(1) 두 가지 설계방식

(1-1) BoardService.java
  • 인터페이스를 만들고
package board.board.service;
import board.board.dto.BoardDto;
import java.util.List;

public interface BoardService {
	List<BoardDto> selectBoardList() throws Exception;
	
}

(1-2) BoardServicempl.java

  • service interface를 구현한 클래스
package board.board.service;
import board.board.dto.BoardDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import board.board.mapper.BoardMapper;

import java.util.List;

// @Service 어노테이션을 붙여 서비스 클래스라는 것을 명시
@Service
public class BoardServicelmpl implements BoardService {
	
	@Autowired
	private BoardMapper boardMapper;
	
	@Override
	public List<BoardDto> selectBoardList() throws Exception {
    	//Service가 mapper를 호출하는 부분 
		return boardMapper.selectBoardList();
	}

}

(2) 한 가지 설계방식

package board.board.business;

import org.springframework.stereotype.Service;

import board.board.mapper.SampleMapper;
import board.board.model.SampleDto;

@Service
public class SampleService {
	
    // final : 상수, 생성자를 생성해서 사용해야 한다. 
	private final SampleMapper sampleMapper;
    
	// 생성자
	public SampleService(SampleMapper sampleMapper) {
		this.sampleMapper = sampleMapper;
	}

	public SampleDto getMemberInfo(Integer userId) {
		return this.sampleMapper.selectMemberInfo(userId);
	}
}

4) Mapper

Mybatis는 Mapper를 제공한다.
DAO대신 Mapper를 사용하면 되는데, Mapper를 사용하면 일일이 DAO를 만들지 않고 인터페이스만 이용해서 좀 더 편하게 개발 할 수 있다.
Mabatis는 자바코드와 SQL문을 분리하여 편리하게 관리하도록 한다.
SQL문음 *.xml 형식으로 저장한다.

(1) BoardMapper.java

package board.board.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import board.board.dto.BoardDto;

// @Mapper 어노테이션을 붙이면 Mapper 인터페이스로 인식
@Mapper
public interface BoardMapper {
	List<BoardDto> selectBoardList() throws Exception;
    // 한가지 Service 사용할 때 예시 
    // SampleDto selectMemberInfo(Integer userId); 
}
 

(2) sql.xml

*.xml 형식으로 원하는 SQL문을 작성한다.
xml 파일에서 중요한 것은 'namespace, id, resultType' 이다.

  • namespace : Mapper의 전체 경로
  • id : Mapper 인터페이스와, xml 파일을 매칭 시키기 위해 Mapper 인터페이스의 메소드의 명과 xml 파일의 id를 동일하게 작성 해 줘야함
  • resultType : SQL문을 실행하고 결과값을 어떤 형식으로 반환할지 나타냄, 여기서는 BoardDto 객체로 반환
<?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="board.board.mapper.BoardMapper">
  <select id="selectBoardList" resultType="board.board.dto.BoardDto">
     <![CDATA[
     	SELECT
     		board_idx,
     		title,
     		hit_cnt,
     		created_datetime
     	FROM
     		t_board
     	WHERE
     		deleted_yn = 'N'
     	ORDER BY board_idx DESC
     ]]>
  </select>
</mapper>

Reference
1) https://dalpaeng00.tistory.com/83
2) https://blog.naver.com/PostView.nhn?blogId=scw0531&logNo=220988401816&parentCategoryNo=&categoryNo=28&viewDate=&isShowPopularPosts=false&from=postView

profile
Backend Developer

0개의 댓글