본문 바로가기

웹 개발/Spring

[Web_Spring] 09

3-tier

- 스프링 프로젝트는 3-tier 방식으로 구성한다.

- 각 영역은 독립적으로 설계되어 나중에 특정한 기술이 변하더라도 필요한 부분을 부품처럼 쉽게 교환할 수 있는 방식

- 각 연결 부위는 인터페이스를 이용해서 설계하는 것이 일반적인 구성 방식이다.

 

 

 

● Presentation Tier(화면 계층)

- 화면에 보여주는 기술을 사용하는 영역

- 컨트롤러에서 사용자의 요청에 맞는 응답처리를 진행하며, HTML엔진(thymeleaf), HTML 등이 담당하는 영역이다.

 

 

 

● Business Tier(비지니스 계층)

- 순수한 비지니스 로직을 담고 있는 영역

- 고객이 원하는 요구사항을 반영하는 계층이기 때문에 중요한 영역이다.

- 이 영역의 설계는 고객의 요구사항과 정확히 일치해야 한다.

 

 

 

● Persistence Tier(영속 혹은 데이터 계층)

- DBMS 설계가 들어가는 계층

 

 


 

실습

- board

 

 

1. src/main/resource/application.properties

#server port
server.port=10003

#JDBC spy datasource
log4jdbc.spylogdelegator.name=net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator
spring.datasource.hikari.driver-class-name=net.sf.log4jdbc.sql.jdbcapi.DriverSpy
spring.datasource.hikari.jdbc-url=jdbc:log4jdbc:oracle:thin:@localhost:1521:XE
spring.datasource.hikari.username=hr
spring.datasource.hikari.password=hr

#log level
logging.level.root=info

2. src/main/java/com.example.board/domain.vo/BoardVO.java​

package com.example.board.domain.vo;

import lombok.Data;
import org.springframework.stereotype.Component;

@Component
@Data
public class BoardVO {
    private Long boardNumber;
    private String boardTitle;
    private String boardContent;
    private String boardWriter;
    private String boardRegisterDate;
    private String boardUpdateDate;
}

 

 

3. src/main/java/com.example.board/mybatis/MyBatisConfig.java

package com.example.board.mybatis;

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import lombok.RequiredArgsConstructor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
 
import java.io.IOException;

@Configuration //설정 관련 클래스에 작성한다.
@MapperScan("com.example.board.mapper") //작성한 경로부터 하위 경로까지 모두 @Mapper를 스캔한다.
@RequiredArgsConstructor
public class MyBatisConfig {
    //    커넥션 풀 및 MyBatis에 필요한 요소를 메모리에 할당 및 관리, xml과 java연동에 필요한 경로 관리
    private final ApplicationContext applicationContext;

    //    @Bean : 메소드의 리턴 객체를 스프링 컨테이너에 등록, 객체명은 메소드의 이름으로 자동 설정되며,
//            직접 설정하고자 할 때에는 @Bean(name="객체명")으로 사용
    @Bean //@Configuration 또는 @Component가 작성된 클래스의 메소드에만 사용이 가능하다.
    @ConfigurationProperties(prefix = "spring.datasource.hikari") //properties 파일에서 prefix인 설정 모두 가져오기
    public HikariConfig hikariConfig() {
        return new HikariConfig(); //properties파일에서 가져온 설정들과 필드가 매핑되어 자동으로 주입된다.
    }

    @Bean
    public HikariDataSource hikariDataSource(){
//        DataSource 객체에 DBMS 정보 설정
        return new HikariDataSource(hikariConfig());
    }

    @Bean
    public SqlSessionFactory sqlSessionFactory() throws IOException {
//        세션 팩토리 설정 객체
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
//        DBMS 정보를 담고 있는 DataSource를 세션 팩토리 설정 객체에 전달
        sqlSessionFactoryBean.setDataSource(hikariDataSource());
//        SQL 쿼리를 작성할 mapper.xml 경로 설정
        sqlSessionFactoryBean.setMapperLocations(applicationContext.getResources("classpath*:/mapper/**/*.xml"));
        sqlSessionFactoryBean.setConfigLocation(applicationContext.getResource("classpath:/config/config.xml"));
        try {
//            위에서 설정한 세션 팩토리 빈을 통해 세션 팩토리 생성
            SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBean.getObject();
//            팟홀(언더바) 표기법을 카멜 표기법으로 자동 변경 설정
            sqlSessionFactory.getConfiguration().setMapUnderscoreToCamelCase(true);
            return sqlSessionFactory;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

 

 

 

4. src/main/resource/config/config.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0/EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <typeAliases>
        <typeAlias type="com.example.board.domain.vo.BoardVO" alias="boardVO"/>
    </typeAliases>
</configuration>

 

 

 

5. src/main/resource/mapper/BoardMapper.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.example.board.mapper.BoardMapper">
    <select id="getList" resultType="boardVO">
        SELECT BOARD_NUMBER, BOARD_TITLE, BOARD_CONTENT, BOARD_WRITER, BOARD_REGISTER_DATE, BOARD_UPDATE_DATE
        FROM TBL_BOARD
    </select>

    <insert id="insert">
        INSERT INTO TBL_BOARD (BOARD_NUMBER, BOARD_TITLE, BOARD_CONTENT, BOARD_WRITER)
        VALUES (SEQ_BOARD.NEXTVAL, #{boardTitle}, #{boardContent}, #{boardWriter})
    </insert>
</mapper>

 

 

 

6. src/test/java/com.example.board/mapper/BoardMapperTests.java​

package com.example.board.mapper;

import com.example.board.domain.vo.BoardVO;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
@Slf4j
public class BoardMapperTests {
    @Autowired
    private BoardMapper boardMapper; 

//    @Test
//    public void getListTest(){
//        boardMapper.getList().stream().map(BoardVO::toString).forEach(log::info);
//    }

    @Test
    public void insertTest(){
        BoardVO boardVO = new BoardVO();
        boardVO.setBoardTitle("새롭게 추가된 게시글 제목1");
        boardVO.setBoardContent("새롭게 추가된 게시글 내용1");
        boardVO.setBoardWriter("new1");

        boardMapper.insert(boardVO);
    }
}

 

 

 

7. src/test/java/com.example.board/mybatis/MyBatisConfigTests.java​

package com.example.board.mybatis;

import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import javax.sql.DataSource;
import java.sql.Connection;  

@SpringBootTest
@Slf4j
public class MyBatisConfigTests {
    @Autowired
    private DataSource dataSource;

    @Autowired
    private SqlSessionFactory sqlSessionFactory;

//    @Test
//    public void dataSourceTest(){
////        try statement 문법
////        try(외부 드라이버 요청 문법 작성){}
////        try문에 있는 소괄호에 연결객체를 요청하면, 사용종료 후 자동으로 close()된다.
//        try
//                (
//                        Connection conn = dataSource.getConnection();
//                )
//        {
//            log.info("---------------------------------");
//            log.info("datasource connection : " + conn);
//            log.info("---------------------------------");
//
//        } catch (Exception e){
//            e.printStackTrace();
//        }
//    }

    @Test
    public void sqlSessionTest(){
        log.info("-------------------------------");
        log.info("sql session factory : " + sqlSessionFactory);
        log.info("-------------------------------");

        try
                (
                        SqlSession sqlSession = sqlSessionFactory.openSession(true);
                        Connection conn = sqlSession.getConnection();
                )
        {
            log.info("sql session : " + sqlSession);
            log.info("-------------------------------");
            log.info("sql session connection " + conn);
            log.info("-------------------------------");

        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

 

 

 

 

'웹 개발 > Spring' 카테고리의 다른 글

[Web_Spring] 11  (0) 2022.06.23
[Web_Spring] 10  (0) 2022.06.22
[Web_Spring] 08  (0) 2022.06.20
[Web_Spring] 07  (0) 2022.06.19
[Web_Spring] 06  (0) 2022.06.18