ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 학원 day85. mybatis-spring 연동시키기
    기록 2023. 1. 3. 13:03

    mybatis의 주요 API

     

      * 개발자가 직접 mybatis의 주요 API를 사용해서 코딩하는 경우는 없다.

     

      * SqlSessionFactoryBuilder

          - mybatis 환경설정 파일을 읽어서 SqlSessionFactory 객체를 생성한다.

      * SqlSessionFactory

          - SqlSession 객체를 제공한다.

          - 애플리케이션이 실행되는동안 싱글턴 객체로 관리되어야 한다.

          - 주요메소드

                 Sqlsession openSession() : 새로운 SqlSession 객체를 반환한다.

      * SqlSession

           - SQL를 실행하는 메소드를 제공하는 객체다.

           - Sql를 실행할 때마다 SqlSessionFactory의 openSession() 메소드를 실행해서 새로운 SqlSession객체를 획득해서 사용하고, Sql실행이 완료되면 close() 메소드를 호출해서 폐기한다. (일회용객체)

           - 주요메소드

               <T> T selection(String id, Object parameter)

                       결과값이 하나 조회되는 SELECT문을 실행시키고, 값을 반환한다.

               <E> List<E> selectList(String id, Object parameter)

                       결과값이 여러개 조회되는 SELECT문을 실행시키고, 값을 반환한다.

                int insert(String id, Object parameter)

                        INSERT문을 실행시키고, 추가된 행의 갯수를 반환한다.

                int update(String id, Object parameter)

                        UPDATE문을 실행시키고, 변경된 행의 갯수를 반환한다.

                int delete(String id, Object parameter)

                        delete문을 실행시키고, 삭제된 행의 갯수를 반환한다.

                void commit()

                        INSERT, UPDATE, DELETE 문의 실행결과를 테이블에 영구적으로 반영시킨다.

                void rollback()

                        INSERT, UPDATE, DELETE 문의 실행의 테이블 반영을 취소시킨다.

                void close()

                        sqlSession 객체를 폐기시킨다.

               <T> T getMapper(Class<T> type)

                        type에서 지정한 Mapper 인터페이스를 구현한 Mapper 인스턴스를 반환한다.

    Mapper 인스턴스 획득하기
    SqlSession session = sqlSessionFactory.openSession();
    UserMapper instance = session.getMapper(UserMapper.class);
    * instance변수에는 UserMapper 인터페이스를 구현한 객체가 대입된다.
    * mybatis-spring 라이브러리는 모든 Mapper인터페이스를 스캔해서 Mapper 인스턴스를 생성하고, 스프링 컨테이너의 빈으로 등록시키는 기능이 있기 때문에 UserMapper instance = session.getMapper(UserMapper.class); 이런코드를 하나씩 적지는 않는다.


    spring-mybatis 연동하기


    1. 필요한 라이브러리 의존성 추가


    * jdbc 드라이버 라이브러리 의존성 추가
    <dependency>
         <groupId>com.oracle.database.jdbc</groupId>
         <artifactId>ojdbc11</artifactId>
         <version>21.8.0.0</version>
    </dependency>


    * spring-jdbc 라이브러리 의존성 추가
    <dependency>
         <groupId>org.springframework</groupId>
         <artifactId>spring-jdbc</artifactId>
         <version>5.3.24</version>
    </dependency>


    * mybatis 라이브러리 의존성 추가
    <dependency>
       <groupId>org.mybatis</groupId>
       <artifactId>mybatis</artifactId>
       <version>3.5.11</version>
    </dependency>


    * mybatis-spring 라이브러리 의존성 추가
    <dependency>
       <groupId>org.mybatis</groupId>
       <artifactId>mybatis-spring</artifactId>
       <version>3.0.1</version>
    </dependency>


    2. 스프링 빈 설정 파일에 Connection Pool 객체를 스프링 컨테이너에 등록하기 

    context.xml (스프링 빈 설정파일) 만드는 방법
    : spring폴더에서 오른쪽 버튼 눌러서 new - Spring Bean Configuration File 선택하기
      Namespace에서 beans하고 context하고 mybatis-spring 체크하기

    3. Mapper 인터페이스와 Mapper 파일을 작성한다.

    Mapper파일 작성

    더보기

    <?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.sample.mapper.UserMapper">
    <insert id="insertUser" parameterType="com.sample.vo.User">
      insert into web_users 
         (user_id, user_password, user_name, user_email)
      values
         (#{id}, #{password}, #{name}, #{email})
    </insert>

    <update id="updateUser" parameterType="User">
      update
         web_users
      set
         user_password         =  #{password},
         user_enabled            =  #{enabled},
         user_updated_date  = sysdate
      where
         user_id            = #{id}
    </update>

    <select id="getUsers" parameterType="map" resultType="User">
      select
         user_id           as id,
         user_password     as password,
         user_name         as name,
         user_email        as email,
         user_enabled      as enabled,
         user_updated_date as updatedDate,
         user_created_date as createdDate
     from
         web_users

    <where>
      <if test="enabled != null">
           user_enabled = #{enabled}
      </if>
    </where>    
      order by
           user_created_date desc    
    </select>

    <select id="getUserById" parameterType="string" resultType="User">
      select
         user_id           as id,
         user_password     as password,
         user_name         as name,
         user_email        as email,
         user_enabled      as enabled,
         user_updated_date as updatedDate,
    user_created_date as createdDate
    from
         web_users
    where
         user_id = #{value} 
    </select>

    <select id="getUserByEmail" parameterType="string" resultType="User">
      select
         user_id           as id,
         user_password     as password,
         user_name         as name,
         user_email        as email,
         user_enabled      as enabled,
         user_updated_date as updatedDate,
         user_created_date as createdDate
     from
        web_users
     where
        user_email = #{value} 
    </select>
    </mapper>

    4. mybatis-config.xml로 mybatis 환경설정 파일을 작성한다.


    5. 스프링 빈 설정파일에  SqlSessionFactory(mybatis 핵심 객체) 객체를 스프링 컨테이너에 등록하기

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
       <property name="dataSource"  ref="dataSource"></property>
       <property name="configLocation" value="mybatis/mybatis-config.xml"></property>
       <property name="mapperLocations" value="classpath:mybatis/mappers/*.xml"></property>
       <property name="typeAliasesPackage"  value="com.sample.vo,  com.sample.dto"></property>
    </bean>


    * SqlSessionFactoryBean 객체는 의존성 주입으로 전달은  dataSource, configLocation, mapperLications, typeAliasesPackage 등의 값을 이용해서 SqlSessionFactory객체를 생성하고, 스프링 컨테이너에 등록시킨다.


    * dataSource는 mybatis가 데이터베이스 엑세스할 때  데이터베이스와 연결된 Connection객체를 제공하는 Connection Pool객체를 의존성 주입받는다.


    * configLocation은 mybatis 환경설정파일의 경로 및 이름을 의존성 주입받는다.
    * mapperLocations는 mybatis의 SQL 매퍼파일의 경로 및 이름을 의존성 주입받는다.
    * typeAliasesPackage는 SQL 매퍼파일에서 parameterType과 resultType으로 사용되는 VO, DTO 클래스가 정의된 패키지명을 의존성 주입받는다. 
    * SqlSessionFactory는 애플리케이션이 실행되는 싱글턴 객체로 관리되어야 한다.(스프링 컨테이너는 객체를 싱글턴 객체로 관리한다.)
    * SqlSessionFactory는 SqlSession객체를 제공하는 객체다.
    * SqlSession객체는 INSERT, UPDATE, DELETE, SELECT 쿼리문을 실행시키는 메소드, 커밋/롤백을 실행시키는 메소드, Mapper 인터페이스를 구현한 Mapper 인스턴스를 반환하는 메소드를 가지고 있는 객체다.


    6. 스프링 빈 설정파일에 MapperScannerConfigurer 객체를 스프링 컨테이너에 등록하기

    <mybatis-spring:scan base-package="com.sample.mapper" factory-ref="sqlSessionFactory"/>
    * <mybatis-spring:scan /> 태그는 MapperScannerConfigurer 객체를 스프링 컨테이너의 객체로 등록한다.
    * MapperScannerConfigurer은 base-package 속성으로 지정된 패키지에서 Mapper 인터페이스를 전부 스캔해서, 
                     Mapper 인터페이스를 구현한  Mapper 인스턴스를 생성하고 스프링 컨테이너의 객체로 전부 등록한다.
    * 예시
    interface UserMapper, interface PostMapper, interface CommentMapper 등의 Mapper 인터페이스와 Mapper 파일이 각각 정의되어 있다면,
    UserMapper의 구현객체, PostMapper의 구현객체, CommentMapper의 구현객체를 생성한다.
    각각의 구현객체에서는 메소드 이름과 일치하는 SQL 구문을 실행시키는 코드가 생성되어 있다.

    - 초록색 박스로 되어있는것이 스프링 Bean으로 등록된다. (얇은 초록색박스는 한번만 설정)

    - UserMapper 구현객체와 UserService의 등록을 제일 기대하고 있었던 것이다. 

    - UserMapper구현객체는 UserMapper타입인 것은 확실하니까 UserMapper타입이 필요하다고 어노테이션을 붙여준다.

    - UserMapper인터페이스가 UserService에 자동 의존성 주입되고, insertUser메소드를 호출하면, 재정의된 UserMapper 구현객체의  insertUser메소드가 실행된다.  

    - 주황색 박스는 DB 엑세스 작업을 하기 위해서 내가 정의해야 하는 것이다.

    - JDBC에서는 DAO를 생성하는게 목적이었다면, MyBatis는 Mapper 인스턴스를 생성하는게 목적이다.

     

    - MapperScannerConfigurer은 SqlSession객체를 이용해서 Mapper 인스턴스를 생성한다.
    MapperScannerConfigurer가 Mapper 인스턴스를 생성한다. 마이바티스와 스프링 연동의 핵심객체이다.
    * 스프링연동 의미 : 스프링 컨테이너에서 그 객체를 갖게 한다는 것이다. 
    스프링이 그 객체를 갖고 있어야 다른 객체가 필요하면 주입해줄 수 있다. 
    스프링하고 연동했다고 하면 스프링컨테이너에서 그 객체를 갖고 놀 수 있다는 뜻임. 

     

     

    @Param을 통해서 값을 두개 전달할 수 있다.

     

    UserMapper가 주입된다.

    서비스에서 코딩을 하면 재정의 되어 있는게 실행된다.

    서비스는 Mapper가 필요하고

    컨트롤러는 서비스가 필요하다.

    PostMapper를 꺼내 쓸 일이 없다. 조립되려고 쓰는 거다.

    Service가 가장 마지막에 구현했으니까 Service를 getBean으로 꺼내 쓰는 것이다.

    Controller를 마지막에 구현하면 Controller를 가져다 쓴다.

     

    @Param은 xml에서 parameterType을 안적어줘도 된다.  

    open="(" close=")" separator="," 뜻은 forEach문 전에는 (를 넣고 forEach문이 끝나면 )를 넣고 값들 사이에 , 를 넣으라는 의미이다. 

    쿼리문을 아래와 같이 적은 것이다.

    delete from web_posts

    where post_no in (?,?,?)

     

    => Service에서 for문으로 실행하는 것보다 쿼리에서 처리하는게 더 경제적인 방법이다.


     

    댓글

Designed by Tistory.