SpringFramework/BASIC

Jdbc-Template 과 mybatis의 SqlSessionTemplate의 각각의 개념과 차이점

유혁스쿨 2020. 9. 2. 01:32
728x90
반응형

Jdbc-Template 과 mybatis 의 SqlSessionTemplate

 

Jdbc-Template란?

 전통방식으로 구현하는 JDBC로직을 단 두,세줄로 처리해버릴수 있는 Spring API입니다.

update문 같은 경우에는 쿼리문을 포함하여 단 두줄로도 구현하여 처리할수도 있습니다.

 

자원을 내부적으로 생성하고 해제함으로써 전통방식의 JDBC의 코드구현을 단순화시킵니다.

Connection, PrepareStatement, ResultSet - 각각 연결, 수행, 결과를 수행해주는 객체들 을 사용 한 후 이것을 닫아줘야 하는데 Jdbc-Template에서는 수행객체 사용을 마친 후 닫아주는 처리 또한 내부적으로 해줍니다.

 

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
	<property name="dataSource" ref="ds"/>	
</bean>

우리가 Jdbc-Template를 사용하기위해 컨테이너에 jdbcTemplate라는 id로 bean등록을 해줬습니다.

이때 등록된 패키지명을 보시면 jdbc.core패키지라고 되어있습니다.

jdbc.core패키지의 가장 핵심이되는 기능이라고 말할 수 있습니다.

 

 

아주 간단히 예시코드를 보여드리면서 설명하겠습니다.

userName 하나의 필드만 가지고 있는 UserVO 클래스 입니다.

public class UserVO {
	
	private String userName;

	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
}

 

DataBase에 입력을 통한 정보 추가를 하겠습니다.

전통JDBC 방식의 로직 구현으로 insert 쿼리문을 수행하도록 메서드를 구현하겠습니다.

@Repository 
public class UserDAO implements IUserDAO {

	private String driver = "oracle.jdbc.OracleDriver";
	private String url = "jdbc:oracle:thin:@127.0.0.1:1521:xe";
	private String user = "week";
	private String pw = "week";

	@Override
	public void insertScore(UserVO user) {

		Connection con = null;
		PreparedStatement pstmt = null;
		String sql = "insert into scores (user_name) values (?)";
        
		try{
		    Class.forName(driver);
		    con = DriverManager.getConnection(url,user,pw);
		    pstmt = con.prepareStatement(sql);			
		    pstmt.setString(1, user.getUsername());
		    pstmt.executeUpdate();
		    System.out.println("등록 성공!");
		} catch (SQLException | ClassNotFoundException e) {
			e.printStackTrace();
		}finally {
			try {
				pstmt.close();
				con.close();
			} catch (Exception e2) {
				e2.printStackTrace();
			}
		}
	}
}

 

Spring방식의 JdbcTemplate을 사용하여 코드를 변경해보겠습니다.

@Repository 
public class UserDAO implements IUserDAO {

	@Override
	public void insertScore(UserVO user) {
    
	@Autowired
	private JdbcTemplate template;
		
	String sql = "insert into scores (user_name) values (?)";
    		template.update(sql,scores.getuserName());
	}
}

Jdbc-Template 객체 template가 제공하는 update메서드를 통해 메서드 인자값으로 sql쿼리문과 바인딩값을 받아 쿼리문을 수행합니다

JDBC 구현 코드가 눈에 띌 정도로 많이 줄어들었죠?

 

 

여기서 핵심은 첫번째로 우리가 그동안 배워왔던 @Autowired로 인한 의존성 주입 입니다.

	template.update(sql,scores.getUserName());

template객체의 update() 메서드에 sql쿼리문과 받아 바인드변수에 담을 객체필드정보를 넣어줍니다.

update()메서드는 template객체로부터 나오는데 이 객체는 @Autowired로 선언한 JdbcTemplate클래스의 객체입니다.

 

template객체를 사용하여 쿼리문을 수행하기위해서 UserDAO클래스는 JdbcTemplate에 의존적이게 되는것입니다.

 

 

두번째로 JDBC로직 코드 단순화 입니다.

앞서말했듯 전통적인 JDBC로직코드를 템플릿을 통해 스프링 내부에서 대부분의 작업들을 수행해줍니다.

앞서 말했듯 Connection, PrepareStatement, ResultSet 등의 객체들은, 들어온 쿼리문이 수행되기 위한 과정인 연결, 수행, 결과 를 작업해 주는데 이 코드들이 모두 생략되었습니다. 스프링 내부적으로 수행되고 있다는것입니다.

또한 이 객체들을 사용 한 후 이것을 따로 닫아줘야 하는데 이것또한 Jdbc-Template에서 수행객체 사용을 마친 후 닫아주는 처리로서 스프링 내부적으로 닫아줍니다.

 

우선은 이게 어떤원리로 돌아가는지에 대해서 '프레임워크'를 완벽하게 뜯어보기는 힘듭니다.
프레임워크라는 것은 어떤원리로 돌아가는지에 대해서는 관심을 배제하고 먼저 사용법을 익혀서 쓰는것이 바로 프레임워크입니다.

 

mybatis의 SqlSessionTemplate은 Jdbc-Template보다 코드를 더 단순화합니다.

 

앞서 제가 Jdbc-Template에서 update만 예시를 보여드렸지 select기능은 보여드리지 않았습니다.

select는 update에 비해 더 많은 작업이 필요합니다.

 

Jdbc-Template를통한 select구문 수행 예시코드를 현재로서는 직접 구현하여 보여 드릴수는 없지만,

만약 mybatis의 SqlSessionTemplate를 사용하신다면 굳이 보여드릴 필요 없이 아래의 개념정리와 설명을 듣고 따라하시면 될것 입니다. - (추후에 Jdbc-Template를 직접 사용하게 된다거나 공부가 필요할때 select문이나 다른 부가적인 기능을 추가작성하도록 하겠습니다.)


mybatis의 SqlSessionTemplate

mybatis는 JDBC에서 개발자가 직접 처리하는 PreparedStatement의 ?에 대한 설정이나 ResultSet을 이용한 처리가 JdbcTemplate와 같이 내부적으로 이루어지기 때문에 기존 JDBC방식에 비해 개발의 생산성이 좋아집니다.

국내의 대부분의 프로젝트는 XML만을 이용해서 SQL문을 작성하고, 별도의 DAOImpl을 만드는 방식을 선호합니다.

이처럼 mybatis는 JdbcTemplate에서 조금 더 분할화 하여 SQL쿼리문은 XML을 이용하도록 구현되어있으며, 또한 AOP,자바의 객체지향 프로그램의 특성을 살려 해당 쿼리문들을 객체화하여 다시한번 묶어서 관리합니다.

이 방식의 최대 장점은 sql문을 완전히 분리해서 처리하기 때문에 향후에 sql문의 변경이 일어날 때, 대처가 수월하다는 장점이 있습니다.

 

앞서 https://u-it.tistory.com/26?category=908598 에서 정리한 코드를 가져왔습니다.

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="configLocation" value="classpath:/mybatis-config.xml"/>
        <property name="mapperLocations" value="classpath:/폴더경로/mappers/*/*.xml"/>
</bean>

코드에서 빈으로 등록된 SqlSessionFactoryBean는 SqlSessionTemplate에 의해서 수행한 쿼리문들을 빈들에 담아 쿼리문이 담긴 빈들을 관리해줍니다.

 

<property name="configLocation" value="classpath:/mybatis-config.xml"/>
<property name="mapperLocations" value="classpath:/폴더경로/*/*.xml"/>

 setter()의존성 주입인 property태그에 선언된 요소들은 SqlSessionFactoryBean의 각 필드에 적용되게 되는데 SqlSessionFactoryBean 클래스의 필드이름은 각각 name속성명과 일치하는 configLocation , mapperLocations 입니다.

 

이 레퍼런스들은 기능을 가지고있습니다.

 

먼저 configLocation데이터 저장빈 클래스 VO클래스의 객체 별칭을 지정하고, 관리합니다.

mybatis-config.xml 이라는 파일에서 지정,관리 하도록 configLocation 필드에 관리하고자하는 파일명을 value속성값으로 주입시켜 줬습니다.

 

mapperLocations는 value속성에 /폴더경로/*/*.xml 라고 등록되어 있으며 폴더경로의 모든폴더 하위의 모든 xml파일을 mybatis 매퍼 xml태그로 쿼리문을 다루는 매퍼태그의 위치를 조정할수 있도록 해줍니다.

만약 수행할 쿼리문을 작성하는 매퍼xml파일이 여러개가 존재할때, mapper namespace에 등록된 이름을 기준으로 SqlsessionFactoryBean에서 위치를 조정해 줍니다.

위치를 조정한다고 말하면 설명이 두루뭉실해지니 그냥 namespace가 등록된 매퍼파일을 SqlsessionFactoryBean 팩토리에 등록한다고 이해하면 될것같습니다.

 

추가적으로 이후에 접하게 될 mapper namespace에 대해 짧게 설명하겠습니다.

namespace라는 속성은 클래스의 패키지와 유사한 용도로 Mybatis 내에서 원하는 SQL문을 찾아서 실행할 때 동작하게 됩니다. 

 

mybatis 에 대한  추가 개념정리 및 예시코드 는 추후에 다시 제대로 정리하여 게시글을 작성할 예정입니다.

수고하셨습니다.

728x90
반응형