SpringFramework/BASIC

[Mybatis]SqlSessionTemplate/MapperInterface(3.0이전 / 3.0이후) 구현방식 차이

유혁스쿨 2020. 9. 3. 16:49
728x90
반응형

SqlSessionTemplate / MapperInterface

MyBatis에 대한 간단한 설명 : https://u-it.tistory.com/36

 

Mapper xml파일 SqlSessionTemplate, MapperInterface 공통

 

Mapper.xml파일을 생성합니다.

<?xml version="1.0" encoding="UTF-8"?>

 

Mybatis xml파일이라는것을 doc타입 선언을 해줘야합니다. 

<?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">
<!-- mybatis를 다루는 xml이다-->

 

매퍼 xml파일을 시작해주는 태그는 <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>
</mapper>

<mapper>태그 안에서 SQL 쿼리문을 작성과 객체별칭을 등록하는것 등을 작성합니다. 


SqlSessioTemplate

SqlSessionTemplate는 쿼리문을 Mapper xml에서 수행하며 쿼리문을 수행해주는 객체를 DAO클래스에 주입받고 DAO클래스에 오버라이딩 구현된 메서드를 통해 반환타입과 매개변수(key)를 xml에도 동일하게 선언함으로써 일치하는 key값을 기준으로 참조하여 @Autowired로 쿼리문을 수행해주는 객체를 주입받는 DAO클래스와 쿼리문이 선언된 Mapper xml이 서로 맞물려 Mapper xml로부터 쿼리문을 참조하여 DAO클래스에서 의존주입 받은 객체를 통해 쿼리문을 수행하는 방식입니다. 

 

 

[DAO 인터페이스]

public Interface IDataDAO {
	
    public void insert(DataVO d)

    public void edit(DataVO d);

    public void delete(int dNo);
    
    public List<DataVO> getList(DataVO d);

    public DataVO getData(int dNo);
    
}

[DAO 클래스]

쿼리문 수행객체 SqlSession을 reference로 선언하고 @Autowired로 의존성을 주입 어노테이션을 선언합니다.

인터페이스의 추상메서드를 오버라이딩 후 구현합니다.

@Repository
public class DataDAO implements IDataDAO {
	
    @Autowired 
    private SqlSession sqlSession;

    @Override
    public void insert(DataVO d) {
        this.sqlSession.insert("d_in",d);
    }

    @Override
    public void edit(DataVO d) {
        this.sqlSession.update("d_edit",d);
    }

    @Override
    public void delete(int dNo) {
        this.sqlSession.delete("d_del",dNo);
    }
    
    @Override
    public List<DataVO> SelectListD(DataVO d) {
        return this.sqlSession.selectList("Data.d_list",d);
    }

    @Override
    public DataVO selectOneD(int dNo) {
        return this.sqlSession.selectOne("d_Info",dNo);
    }
}

각 메서드에 key이름을 저장합니다. 

key이름을 기준으로 Mapper.xml의 쿼리문에 접근합니다.

key에는 Mapper.xml에 등록된 namespace명을 함께 적어야하지만 생략이 가능합니다.

 

 

[Mapper.xml]

DAO클래스의 메서드가 인자값으로 받은 key값을 통해 Mapper.xml에 등록된 쿼리문을 참조할수 있도록 Mapper.xml 쿼리문에도 동일한 key값을 부여합니다.

<?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="Data">
    <insert id="d_in" parameterType="b">
        insert into Data (dNo,id,name,regdate) values (dNo_seq.nextval,#{id},#{name},sysdate)
    </insert>
	 
    <update id="d_edit" parameterType="b">
        update Data set id=#{id},name=#{name} where bno=#{bno}
    </update>
	
    <delete id="d_del" parameterType="int">
        delete from Data where dno=#{dno}
    </delete>
    
    <select id="d_list" resultType="b" parameterType="b">
        select * from Data order by dno desc 
    </select>
	
	
    <select id="d_info" resultType="b">
        select * from Data where dno=#{dno}
    </select>

	

</mapper>

각 쿼리문 태그에 id속성명으로 수행 내용이 일치하는 메서드가 참조할수 있도록 메서드의 인자값과 동일한 key값을 부여합니다.

 

 

[동작 구조]

@Autowired는 root-context.xml에 선언한

<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate" destroy-method="clearCache">
    <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>

 코드로 컨테이너에 등록된 빈을 reference에 객체로 주입 시켜줍니다.

 

DAO의 SqlSession객체가 주입되면 메서드와 Mapper.xml이 함께 맞물려 수행, 쿼리문결과를 반환합니다.

이때 각 메서드에 등록된 key값으로 Mapper xml 파일들로부터 참조하여 일치하는 쿼리문을 수행하게 됩니다.

 

 ↓ 파일을 참조하는 기준은 root-context.xml에 선언한 SqlSessionFactoryBean을 컨테이너에 빈등록할때

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="ds"/>
    <property name="mapperLocations" value="classpath:/폴더명/**/*Mapper.xml" /> 
</bean>

 ↑ SqlSessionFactoryBean의 필드 mappersLocation에 value속성으로 등록된 경로의 모든 폴더 하위의 Mapper라는 이름이 들어간xml파일을 읽어들일수 있도록 선언해줬습니다. 

 

쿼리문 수행 완료 후 수행결과가 반환되며 처음 호출된 컨트롤러의 메서드로 반환됩니다. 


MapperInterface


기존의 Repository계층인 DAO로직을 MyBatis로 대신하게 됩니다.
기존의 방식대로 인터페이스 까지는 설계합니다. - 추상메서드
implements하는 DAOImpl클래스를 따로 만들지 않습니다.
xml설정파일을통해 sql을 선언합니다.
xml파일이 DAO클래스파일이 되면서 빈등록이 되고 그안에 수행될 쿼리문도 함께 작성됩니다.
주입도 자동으로 처리가 됩니다. 어떤 템플릿에 대한 주입..

 

 <mybatis-spring:scan base-package="com.spring.database.mybatis.data.repository"/>

해당 태그로 base-package속성에 등록된 경로의 모든 인터페이스를 컨테이너에 빈 등록해줍니다.

Mybatis의 Mapper xml 파일들을 참조 할수있는 빈으로 등록됩니다.

 

xml파일을 참조하는 기준은 SqlSessionTemple과 동일한 태그인

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="ds"/>
    <property name="mapperLocations" value="classpath:/폴더명/**/*Mapper.xml" /> 
</bean>

SqlSessionFactoryBean을 빈등록하면서 주입한 mapperLocations에 의해 value속성에 적힌 경로에서 조건에 맞는 모든xml파일을 컨테이너에 빈 등록되었으며 등록된 xml빈들에 설정된 namespace속성을 통해 참조하게됩니다

 

이 선언들을 통해 DAO클래스가 생략되며 xml파일에 인터페이스를 직접 연결하여 인터페이스의 추상메서드를 참조하게됩니다.  

 

[DAO 인터페이스]

public Interface IDataMapper {
	
    public void insertD(DataVO d)

    public void editD(DataVO d);

    public void deleteD(int dNo);
    
    public List<DataVO> selectListD(DataVO d);

    public DataVO selectOneD(int dNo);
    
}

[Mapper.xml]

Mapper.xml이 IDataDAO인터페이스의 구현 클래스인 DataDAO가 됩니다.

<mapper>태그의 namespace 속성에 참조할 IDataMapper 인터페이스의 위치와 이름을 작성합니다

패키지경로.IDataMapper 라고 작성하겠습니다.

<?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="패키지경로.IDataMapper">
    <insert id="insertD" parameterType="b">
        insert into Data (dNo,id,name,regdate) values (dNo_seq.nextval,#{id},#{name},sysdate)
    </insert>
	 
    <update id="updateD" parameterType="b">
        update Data set id=#{id},name=#{name} where bno=#{bno}
    </update>
	
    <delete id="deleteD" parameterType="int">
        delete from Data where dno=#{dno}
    </delete>
    
    <select id="selectListD" resultType="b" parameterType="b">
        select * from Data order by dno desc 
    </select>
	
    <select id="selectOneD" resultType="b">
        select * from Data where dno=#{dno}
    </select>


</mapper>

각 쿼리문 태그에 id속성명으로 수행 내용이 일치하는 메서드가 참조할수 있도록 IDataMapper인터페이스에 선언된 추상메서드의 메서드명과 동일한 문자열로 기입합니다.

인터페이스의 메서드이름 선언으로 참조가 가능해 진다는것은 구현받은 클래스에서 오버라이드를 해주는것과 동일한 뜻이기도 합니다.

 

Mapper.xml파일은 DAO인터페이스를 구현받는 DAO클래스의 역할을 대신해줍니다.

<mapper>태그의 namespace 속성을 통해 인터페이스와 연결합니다. 그러므로 이곳이 DAO가 맞습니다.

Mapper파일이 바로 DAO 클래스인 셈이며, 더불어 수행할 SQL쿼리문까지 이곳에 작성합니다.

이렇게되면 DAO 자바메서드 호출과정이 사라지게 되며 코드가 합쳐지지만 구현해야할 내용은 조금 더 줄게 됩니다

 

장점

DAO 클래스파일을 생략 가능하며 SqlSessionTemplate를 사용하지않으니까 SqlSession에 대한 메서드를 몰라도 된다는 이점이 있습니다.
 만약 SqlSessionTemplate을 사용하게 된다면 쿼리문이 반환해주는 반환타입도 맞춰야하고 메서드로 부터 넘겨주는 매개값 순서나 매개값의 형태 같은것들도 각각의 틀에맞춰 써야하기 때문에 그런 불편함이 사라지겠습니다.

따라서 개발속도가 증가하여 생산성에 있어 좋은 방법이되겠다고 볼수 있습니다. 

728x90
반응형