Dev/Spring

Spring (main 파일 추가, Test 설정, SampleDAO 주입, 인터페이스 활용, 웹프로젝트를 위한 준비, 데이터 소스 구성, MariaDB, HikariCP, MyBatis, MyBatis 연동, 스프링 설정, Mapper 인터페이스, SqlSessionFactory)

Walker_ 2024. 4. 19. 12:57

1. 파일 추가

 

 

 - 각 폴더에 해당 이름에 파일들 추가 sample에 자바 파일 두개

 - root-context.xml 추가

 

 - 파란 텍스트 클릭

 

 - OK 클릭

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean class="com.example.spring_project_02.sample.SampleDAO"></bean>
    <bean class="com.example.spring_project_02.sample.SampleService"></bean>
</beans>

 

 - root-context.xml에 bean 2줄 추가

 - (각자 프로젝트 마다 경로 차이 있음)

 

2. Test 설정

 

 - SampleService > 우클릭 > go to > test > create test > OK

 

 - 한 번에 원인 찾을 시 상당히 어려워서 중간 중간 테스트 하면서 진행 할 수 있도록 도와주는 테스트 기능

 

// SampleServiceTest

package com.example.spring_project_02.sample;

import lombok.extern.log4j.Log4j2;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;

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

@Log4j2
@ExtendWith(SpringExtension.class)
@ContextConfiguration(locations = "file:src/main/webapp/WEB-INF/root-context.xml")
class SampleServiceTest {
    @Autowired
    private SampleService sampleService;

    @Test
    public void testService1() {
        log.info(sampleService);
        Assertions.assertNotNull(sampleService);
    }

}

 

 - 생성된 SampleServiceTest 파일에 위 코드 추가

 

 - 테스트 코드는 메서드 단위로 실행 가능

 

 

 - 옆에 플레이버튼 누르면 테스트 됨

 - INFO ~ 줄이 Log INFO 관련. 

 - INFO [해당 파일 경로] ~줄이 테스트 결과

 

3. SampleDAO 주입하기

 - SampleDAO에 아래 코드 작성

package com.example.spring_project_02.sample;

import lombok.ToString;
import org.springframework.beans.factory.annotation.Autowired;

@ToString
public class SampleService {
    @Autowired
    private SampleDAO sampleDAO;
}

 

 - 다시 Test를 실행하면 sampleDAO 객체가 주입된 것을 확인

 

4. @Repository, @Service

 - @Controller : MVC의 컨트롤러를 위한 어노테이션

 - @Service : 서비스 계층의 객체를 위한 어노테이션

 - @Repository : DAO와 같은 객체를 위한 어노테이션

 - @Component : 일반 객체나 유틸리티 객체를 위한 어노테이션

 

 - root-context.xml을 아래 코드로 수정

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans.xsd 
       http://www.springframework.org/schema/context
       https://www.springframework.org/schema/context/spring-context.xsd">
    
    <context:component-scan base-package="com.example.spring_project_02.sample"/>
<!--    <bean class="com.example.spring_project_02.sample.SampleDAO"></bean>-->
<!--    <bean class="com.example.spring_project_02.sample.SampleService"></bean>-->
</beans>

 

 - SampleDAO에 @Repository 추가

package com.example.spring_project_02.sample;

import org.springframework.stereotype.Repository;

@Repository
public class SampleDAO {
}

 

 - SampleService에 어노테이션 추가

package com.example.spring_project_02.sample;

import lombok.ToString;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@ToString
@Log4j2
@Service
public class SampleService {
    @Autowired
    private SampleDAO sampleDAO;
}

 

 - TEST 실행 > 정상 작동 확인

 

 - 생성자 주입을 편리하게 하기 위해 SampleService 아래 코드로 변경

package com.example.spring_project_02.sample;

import lombok.RequiredArgsConstructor;
import lombok.ToString;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@ToString
@Log4j2
@Service
@RequiredArgsConstructor
public class SampleService {
    @Autowired
    private final SampleDAO sampleDAO;
}

 

5. 인터페이스를 이용한 느슨한 결합

 - 인터페이스를 이용하면 실제 객체를 모르고 타입만을 이용해서 코드를 작성하는 일이 가능해 짐

 

 - 1) SampleDAO를 인터페이스로 변경하기

package com.example.spring_project_02.sample;

public interface SampleDAO {
}

 

 - 2) SampleDAOImpl 파일 추가 하고, 코드 작성

package com.example.spring_project_02.sample;

import org.springframework.stereotype.Repository;

@Repository
public class SampleDAOImpl implements SampleDAO {
}

 

 - 3) 다른 SampleDAO 객체로 변경해 보기

 - 파일 생성 후 코드 추가

package com.example.spring_project_02.sample;

import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Repository;

@Repository
@Primary
public class EventSampleDAOImpl implements SampleDAO {
}

 

6. 웹프로젝트를 위한 스프링 준비

 - 아래 코드를 build.gradle > 디펜덴시에 추가 후 코끼리 버튼 클릭

implementation 'org.springframework:spring-webmvc:5.3.30'

 

 - main > java > webapp > WEB-INF > web.xml을 아래 코드로 변경

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/root-context.xml</param-value>
    </context-param>
    
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
</web-app>

 

 - 톰캣으로 실행 후 정상작동 확인

 

 - 아래 2줄이 나온다면 정상 

 

7. 데이터 소스 구성하기

 - maven Repository > MariaDB

https://mvnrepository.com/artifact/org.mariadb.jdbc/mariadb-java-client/3.1.4

 - 접속 

 - build.gradle에 추가

// https://mvnrepository.com/artifact/org.mariadb.jdbc/mariadb-java-client
implementation 'org.mariadb.jdbc:mariadb-java-client:3.1.4'

 

- HikariCP 추가

- https://mvnrepository.com/artifact/com.zaxxer/HikariCP/5.0.1

- 접속 

 

 - build.gradle에 추가

// https://mvnrepository.com/artifact/com.zaxxer/HikariCP
implementation 'com.zaxxer:HikariCP:5.0.1'

 

- root-context.xml 에 아래 코드 추가

- 각 PC DB 설정마다 설정 값 다름

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans.xsd 
       http://www.springframework.org/schema/context
       https://www.springframework.org/schema/context/spring-context.xsd">
    
    <context:component-scan base-package="com.example.spring_project_02.sample"/>

    <bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
        <property name="driverClassName" value="org.mariadb.jdbc.Driver"/>
        <property name="jdbcUrl" value="jdbc:mariadb://localhost:3308/sample_spring_todo"/>
        <property name="username" value="root"/>
        <property name="password" value="5046"/>
        <property name="dataSourceProperties">
            <props>
                <prop key="cachePreStmts">true</prop>
                <prop key="prepStmtCacheSize">250</prop>
                <prop key="prepStmtCacheSqlLimit">2040</prop>
            </props>
        </property>
    </bean>

    <bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
        <constructor-arg ref="hikariConfig"/>
    </bean>

<!--    <bean class="com.example.spring_project_02.sample.SampleDAO"></bean>-->
<!--    <bean class="com.example.spring_project_02.sample.SampleService"></bean>-->
</beans>

 

- Test 파일에 아래 코드 추가

@Autowired
private DataSource dataSource;

@Test
public void testConncetion() throws Exception {
    Connection connection = dataSource.getConnection();
    log.info(connection);
    Assertions.assertNotNull(connection);

    connection.close();
}

 

 - Test 실행해서 정상 작동 확인

 - 아래 줄이 나오면 정상 작동

 

8. MyBatis와 스프링 연동

JDBC > MyBatis > JPA

 - MyBatis : 쿼리는 XML에 작업, 메서드 자동 완성

 - JPA : 쿼리, 메서드 자동 완성

 

 - MyBatis는 'Sql Mapping Framework'라고 표현

 - SQL의 분리 : MyBatis를 이용하면 별도의 파일이나 어노테이션 등을 이용해서 SQL 가능

 - 단독으로 실행 가능

 

 - build.gradle에 아래 코드 추가 후 코끼리 클릭

implementation 'org.springframework:spring-jdbc:5.3.30'
implementation 'org.springframework:spring-tx:5.3.30'

 

 - maven repository에 mybatis 검색

 - https://mvnrepository.com/artifact/org.mybatis/mybatis/3.5.9           

 - 접속 

 

 - mybais-spring

https://mvnrepository.com/artifact/org.mybatis/mybatis-spring

 - 접속

 

 

 - build.gradle 아래 코드 추가

// https://mvnrepository.com/artifact/org.mybatis/mybatis
implementation 'org.mybatis:mybatis:3.5.9'

// https://mvnrepository.com/artifact/org.mybatis/mybatis-spring
implementation 'org.mybatis:mybatis-spring:2.0.7'

 

9. MyBatis를 위한 스프링 설정 - SqlSessionFactory

 

MyBatis를 이용하기 위해서는 스프링에 설정해둔  HikariDataSource를 이용해서

SqlSeesionFactory라는 빈을 설정

 

 - root-context.xml에 아래 코드 추가

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
</bean>

 

 - 톰캣으로 변경 후 실행해서 정상 작동 확인

 

10. Mapper 인터페이스 활용하기

 - mapper > TimeMapper 추가

 

 - root-context.xml 에 아래 코드 추가

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mybatis="http://mybatis.org/schema/mybatis-spring"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans.xsd 
       http://www.springframework.org/schema/context
       https://www.springframework.org/schema/context/spring-context.xsd
       http://mybatis.org/schema/mybatis-spring
       http://mybatis.org/schema/mybatis-spring.xsd">
    
    <context:component-scan base-package="com.example.spring_project_02.sample"/>

    <bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
        <property name="driverClassName" value="org.mariadb.jdbc.Driver"/>
        <property name="jdbcUrl" value="jdbc:mariadb://localhost:3308/sample_spring_todo"/>
        <property name="username" value="root"/>
        <property name="password" value="5046"/>
        <property name="dataSourceProperties">
            <props>
                <prop key="cachePreStmts">true</prop>
                <prop key="prepStmtCacheSize">250</prop>
                <prop key="prepStmtCacheSqlLimit">2040</prop>
            </props>
        </property>
    </bean>

    <bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
        <constructor-arg ref="hikariConfig"/>
    </bean>

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <mybatis:scan base-package="com.example.spring_project_02.mapper"/>

<!--    <bean class="com.example.spring_project_02.sample.SampleDAO"></bean>-->
<!--    <bean class="com.example.spring_project_02.sample.SampleService"></bean>-->
</beans>

 

 - TimeMapper에서 go to > test 눌러서 test 파일 생성

 - 생성된 TimeMapperTest 파일에 아래 코드 작성

package com.example.spring_project_02.mapper;

import lombok.extern.log4j.Log4j2;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;

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

@Log4j2
@ExtendWith(SpringExtension.class)
@ContextConfiguration(locations = "file:src/main/webapp/WEB-INF/root-context.xml")
public class TimeMapperTest {
    @Autowired(required = false)
    private TimeMapper timeMapper;

    @Test
    public void testGetTimer() {
        log.info(timeMapper.getTime());
    }
}

 

 - 테스트 실행하여 정상 작동 확인

 

 


공부 과정을 정리한 것이라 내용이 부족할 수 있습니다.

부족한 내용은 추가 자료들로 보충해주시면 좋을 것 같습니다.

읽어주셔서 감사합니다 :)