공식 성명에 따르면 Spring3의 개발 작업은 ibatis3, 즉 Mybatis3가 등장하기 전에 완료되었으므로 Spring3에서는 아직 Mybatis3에 대한 지원이 없습니다. 따라서 Mybatis 커뮤니티는 Spring을 통합하려는 Mybatis 사용자의 요구를 충족하기 위해 Mybatis-Spring 자체를 개발했습니다. 다음은 Mybatis-Spring을 통해 Mybatis와 Spring을 통합하는 사용법을 간략하게 소개한다.
매퍼팩토리빈
먼저 Mybatis 공식 웹사이트에서 Mybatis-Spring jar 패키지를 다운로드하여 프로젝트의 클래스 경로에 추가해야 합니다. 물론 Mybatis의 관련 jar 패키지와 Spring의 관련 jar 패키지도 추가해야 합니다. 우리는 Mybatis의 모든 작업이 SqlSession을 기반으로 하며 SqlSession은 SqlSessionFactory에 의해 생성되고 SqlSessionFactory는 SqlSessionFactoryBuilder에 의해 생성된다는 것을 알고 있습니다. 그러나 Mybatis-Spring은 SqlSessionFactoryBean을 기반으로 합니다. Mybatis-Spring을 사용할 때 SqlSession도 필요하며, 이 SqlSession은 프로그램에 내장되어 있으며 일반적으로 직접 액세스할 필요가 없습니다. SqlSession도 SqlSessionFactory에 의해 생성되지만 Mybatis-Spring은 SqlSessionFactoryBean을 캡슐화합니다. 이 빈에서는 SqlSessionFactoryBuilder를 사용하여 해당 SqlSessionFactory를 설정한 다음 해당 SqlSession을 얻습니다. SqlSessionFactoryBean을 통해 우리는 Mybatis에 대한 일부 속성을 지정함으로써 Mybatis의 일부 구성 정보를 제공할 수 있습니다. 그래서 다음에는 Spring의 applicationContext 구성 파일에 SqlSessionFactoryBean을 정의해야 합니다.
XML 코드
<bean id="sqlSessionFactory"> <property name="dataSource" ref="dataSource" /> <property name="mapperLocations" value="classpath:com/tiantian/ckeditor/mybatis/mappers/*Mapper.xml" / > <property name="typeAliasesPackage" value="com.tiantian.ckeditor.model" /> </bean>
SqlSessionFactoryBean을 정의할 때 데이터베이스에 연결하는 데 사용되는 데이터 소스를 나타내는 dataSource 속성을 지정해야 합니다. 물론, 다음과 같은 몇 가지 다른 속성을 지정할 수도 있습니다.
mapperLocations: Mapper 파일이 저장되는 위치를 나타냅니다. Mapper 파일이 해당 Mapper 인터페이스와 동일한 위치에 있는 경우 이 속성의 값을 지정할 필요가 없습니다.
configLocation: Mybatis의 구성 파일 위치를 지정하는 데 사용됩니다. 이 속성이 지정되면 해당 SqlSessionFactoryBuilder는 구성 파일의 내용을 구성 정보로 사용하여 구성되지만 후속 속성에 지정된 콘텐츠는 구성 파일에 지정된 해당 콘텐츠를 덮어씁니다.
typeAliasesPackage: 일반적으로 우리 엔터티 클래스가 위치한 패키지에 해당합니다. 이때 해당 패키지에서 패키지 이름을 포함하지 않는 단순 클래스 이름은 자동으로 패키지 이름을 포함하는 별칭으로 사용됩니다. 여러 패키지는 쉼표나 세미콜론으로 구분할 수 있습니다.
typeAliases: 배열 유형, 별칭을 지정하는 데 사용됩니다. 이 속성을 지정한 후 Mybatis는 @Alias 주석이 클래스에 표시되지 않은 경우 이 유형의 별칭으로 이 유형의 짧은 이름을 사용합니다. 그렇지 않으면 주석에 해당하는 값이 별칭으로 사용됩니다. 이 유형.
XML 코드
<property name="typeAliases"> <array> <value>com.tiantian.mybatis.model.Blog</value> <value>com.tiantian.mybatis.model.Comment</value> </array> </property >
플러그인: Mybatis의 인터셉터를 지정하는 데 사용되는 배열 유형입니다.
typeHandlersPackage: TypeHandler가 위치한 패키지를 지정하는 데 사용됩니다. 이 속성이 지정되면 SqlSessionFactoryBean은 해당 TypeHandler로 패키지 아래의 클래스를 자동으로 등록합니다. 여러 패키지는 쉼표나 세미콜론으로 구분할 수 있습니다.
typeHandlers: TypeHandler를 나타내는 배열 유형입니다.
다음 단계는 Spring의 applicationContext 파일에서 원하는 Mapper 객체에 해당하는 MapperFactoryBean을 정의하는 것입니다. 우리가 원하는 Mapper 객체는 MapperFactoryBean을 통해 얻을 수 있습니다. MapperFactoryBean은 Spring의 FactoryBean 인터페이스를 구현하므로 MapperFactoryBean은 FactoryBean 인터페이스에 정의된 getObject 메소드를 통해 해당 Mapper 객체를 얻습니다. MapperFactoryBean을 정의할 때 주입해야 하는 두 가지 속성이 있습니다. 하나는 SqlSession 인터페이스를 구현하는 SqlSessionTemplate 개체를 생성하기 위해 Mybatis-Spring에서 사용하는 sqlSessionFactory이고, 다른 하나는 반환하려는 해당 Mapper 인터페이스입니다.
해당 Mapper 인터페이스에 해당하는 MapperFactoryBean을 정의한 후 해당 Mapper 인터페이스를 Service 빈 객체와 같이 Spring이 관리하는 빈 객체에 삽입할 수 있습니다. 이러한 방식으로 해당 Mapper 인터페이스를 사용해야 할 때 MapperFactoryBean은 getObject 메서드에서 해당 Mapper 인터페이스를 얻고 내부적으로 getObject는 반환하기 위해 주입한 속성을 통해 SqlSession 인터페이스의 getMapper(Mapper 인터페이스) 메서드를 계속 호출합니다. 해당 매퍼 인터페이스. 이러한 방식으로 Mybatis와 Spring의 통합은 SqlSessionFactory와 해당 Mapper 인터페이스를 Spring 관리에 넘겨줌으로써 달성됩니다.
Spring의 applicationContext.xml 구성 파일:
XML 코드
<?xml version="1.0" 인코딩="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:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans /spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring- mvc-3.0.xsd"> <context:comComponent-scan base-package="com.tiantian.mybatis"/> <context:property-placeholder location="classpath:config/jdbc.properties"/> <bean id="dataSource" destroy-method="close"> <property name="driverClassName" value="${jdbc.driver}" /> <속성 이름 ="url" value="${jdbc.url}" /> <속성 이름="사용자 이름" value="${jdbc.username}" /> <속성 이름="비밀번호" value="${jdbc.password}" /> </bean> <bean id="sqlSessionFactory"> <property name="dataSource" ref="dataSource" /> <property name="mapperLocations" value="classpath: com/tiantian/mybatis/mapper/*.xml"/> <속성 이름="typeAliasesPackage" value="com.tiantian.mybatis.model" /> </bean> <bean id="blogMapper"> <property name="mapperInterface" value="com.tiantian.mybatis.mapper.BlogMapper" /> <property name="sqlSessionFactory" ref="sqlSessionFactory" /> </bean> 콩> 콩> </beans>
BlogMapper.xml 파일:
XML 코드
<?xml version="1.0" 인코딩="UTF-8" ?> <!DOCTYPE 매퍼 PUBLIC "-//mybatis.org//DTD 매퍼 3.0//EN" "http://mybatis.org/dtd/mybatis -3-mapper.dtd"> <mapper 네임스페이스="com.tiantian.mybatis.mapper.BlogMapper"> <!-- 새 레코드 추가--> <insert id="insertBlog" parameterType="Blog" useGeneratedKeys="true" keyProperty="id"> t_blog(title,content,owner) 값(#{title},#{content},#{owner})에 삽입 </ insert> <!-- 단일 레코드 쿼리--> <select id="selectBlog" parameterType="int" resultMap="BlogResult"> select * from t_blog where id = #{id} </select> <!-- 레코드 수정--> <update id="updateBlog" parameterType="Blog"> 업데이트 t_blog set title = #{title},content = #{content},owner = #{owner} 여기서 id = #{id} </update> <!-- 모든 기록 쿼리--> <select id="selectAll" resultType="Blog"> select * from t_blog </select> <!-- 레코드 삭제--> <delete id="deleteBlog" parameterType="int"> id = #{id}인 t_blog에서 삭제 </delete> </mapper>
BlogMapper.java:
자바 코드
package com.tiantian.mybatis.mapper; import java.util.List; publicinterface BlogMapper { publicvoid insertBlog(블로그 블로그); ); publicvoid deleteBlog(int id); 공개 목록<Blog> selectAll() }
BlogServiceImpl.java:
자바 코드
패키지 com.tiantian.mybatis.service.impl; import javax.annotation.Resource; import org.springframework.stereotype.Service; import com.tiantian. mybatis.model.Blog; import com.tiantian.mybatis.service.BlogService; @Service publicclass BlogServiceImpl은 BlogService를 구현합니다. BlogMapper blogMapper; publicvoid deleteBlog(int id) { blogMapper.deleteBlog(id) } 공개 블로그 find(int id) { returnblogMapper.selectBlog(id) } public List<Blog> find() { returnblogMapper.selectAll(); publicvoid insertBlog(블로그 블로그) { blogMapper.insertBlog(블로그) } publicvoid updateBlog(블로그 블로그); blogMapper.updateBlog(블로그); } 공개 BlogMapper getBlogMapper() { returnblogMapper; } @Resource publicvoid setBlogMapper(BlogMapper blogMapper) { this.blogMapper = blogMapper } }
MapperScannerConfigurer
위 방법을 사용하여 통합할 때 Mapper가 있으면 해당 MapperFactoryBean을 정의해야 하는데, Mapper가 상대적으로 적을 때는 괜찮지만, Mapper가 많을 때는 이렇게 각 Mapper를 정의합니다. 해당 MapperFactoryBean이 느린 것 같습니다. 이를 위해 Mybatis-Spring은 MapperScannerConfigurer라는 클래스를 제공합니다. 이 클래스를 통해 Mybatis-Spring은 Mapper에 해당하는 MapperFactoryBean 개체를 자동으로 등록합니다.
Mapper 인터페이스를 자동으로 스캔하고 등록하기 위해 MapperScannerConfigurer를 사용해야 하는 경우 Spring의 applicationContext 구성 파일에서 MapperScannerConfigurer에 해당하는 Bean을 정의해야 합니다. MapperScannerConfigurer의 경우 지정해야 하는 속성이 하나 있는데, 바로 basePackage입니다. basePackage는 Mapper 인터페이스 파일이 있는 기본 패키지를 지정하는 데 사용됩니다. 이 기본 패키지 또는 모든 하위 패키지 아래의 Mapper 인터페이스가 검색됩니다. 여러 기본 패키지는 쉼표나 세미콜론으로 구분할 수 있습니다. 가장 간단한 MapperScannerConfigurer 정의는 다음과 같이 하나의 basePackage 속성만 지정하는 것입니다.
XML 코드
<bean> <property name="basePackage" value="com.tiantian.mybatis.mapper" /> </bean>
이러한 방식으로 MapperScannerConfigurer는 지정된 기본 패키지 아래의 모든 인터페이스를 검색하고 이를 MapperFactoryBean 개체로 등록합니다. MapperScannerConfigurer를 사용하고 basePackage 속성을 추가하면 위 예제의 applicationContext 구성 파일은 다음과 같습니다.
XML 코드
<?xml version="1.0" 인코딩="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:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans /spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring- mvc-3.0.xsd"> <context:comComponent-scan base-package="com.tiantian.mybatis" /> <context:property-placeholder location="classpath:config/jdbc.properties" /> <bean id="dataSource" destroy-method="close"> <property name="driverClassName" value="${jdbc.driver}" /> <속성 이름 ="url" value="${jdbc.url}" /> <속성 이름="사용자 이름" value="${jdbc.username}" /> <속성 이름="비밀번호" value="${jdbc.password}" /> </bean> <bean id="sqlSessionFactory"> <property name="dataSource" ref="dataSource" /> <property name="mapperLocations" value="classpath: com/tiantian/mybatis/mapper/*.xml" /> <속성 이름="typeAliasesPackage" value="com.tiantian.mybatis.model" /> </bean> <bean> <property name="basePackage" value="com.tiantian.mybatis.mapper" /> </bean> </beans>
때때로 우리가 지정하는 기본 패키지가 우리가 정의한 Mapper 인터페이스의 전부가 아닌 경우가 있습니다. 이러한 이유로 MapperScannerConfigurer는 검색 및 등록 범위를 좁힐 수 있는 두 가지 다른 속성도 제공합니다. 하나는 AnnotationClass이고 다른 하나는 markerInterface입니다.
AnnotationClass: AnnotationClass가 지정되면 MapperScannerConfigurer는 AnnotationClass 주석으로 표시된 인터페이스만 등록합니다.
markerInterface: markerInterface는 인터페이스를 지정하는 데 사용됩니다. markerInterface가 지정되면 MapperScannerConfigurer는 markerInterface에서 상속된 인터페이스만 등록합니다.
위 속성이 모두 지정되면 MapperScannerConfigurer는 교차점 대신 결합을 사용합니다. AnnotationClass를 마킹에 사용하거나 markerInterface에서 상속된 인터페이스가 MapperFactoryBean으로 등록되는 경우에도 마찬가지입니다.
이제 Mapper 인터페이스가 SuperMapper 인터페이스를 상속한다고 가정하면 MapperScannerConfigurer를 다음과 같이 정의할 수 있습니다.
XML 코드
<bean> <property name="basePackage" value="com.tiantian.mybatis.mapper" /> <property name="markerInterface" value="com.tiantian.mybatis.mapper.SuperMapper"/> </bean>
MybatisMapper 주석이 사용되면 MapperScannerConfigurer를 다음과 같이 정의할 수 있습니다.
XML 코드
<bean> <property name="basePackage" value="com.tiantian.mybatis.mapper" /> <property name="annotationClass" value="com.tiantian.mybatis.annotation.MybatisMapper"/> </bean>
등록된 Mapper 인터페이스의 범위를 좁히는 데 사용되는 속성 외에도 다음과 같은 다른 속성을 지정할 수도 있습니다.
sqlSessionFactory: 이 속성은 더 이상 사용되지 않습니다. 여러 데이터 소스를 사용하는 경우 MapperFactoryBean 등록 시 사용해야 하는 SqlSessionFactory를 지정하기 위해 sqlSessionFactory를 사용해야 합니다. sqlSessionFactory를 지정하지 않으면 자동으로 Autowired 방식으로 주입되기 때문입니다. 즉, 하나의 데이터 소스만 사용하는 경우, 즉 하나의 SqlSessionFactory만 정의하는 경우 MapperScannerConfigurer에 SqlSessionFactory를 지정할 필요가 없습니다.
sqlSessionFactoryBeanName: 해당 기능은 정의된 SqlSessionFactory에 해당하는 Bean 이름을 지정한다는 점을 제외하면 sqlSessionFactory와 동일합니다.
sqlSessionTemplate: 이 속성은 더 이상 사용되지 않습니다. 그 기능은 sqlSessionFactory와 동일합니다. 앞서 언급했듯이 MapperFactoryBean은 궁극적으로 SqlSession의 getMapper 메소드를 사용하여 해당 Mapper 객체를 얻기 때문입니다. 여러 SqlSessionTemplate이 정의된 경우에만 지정하면 됩니다. MapperFactoryBean의 경우 SqlSessionFactory와 SqlSessionTemplate 중 하나만 필요합니다. 둘 다 지정하면 SqlSessionFactory가 무시됩니다.
sqlSessionTemplateBeanName: 사용할 sqlSessionTemplate에 해당하는 Bean 이름을 지정한다.
참고: sqlSessionFactory 및 sqlSessionTemplate 속성을 사용하면 PropertyPlaceholderConfigurer보다 먼저 일부 콘텐츠가 로드되므로 구성 파일에 사용된 외부 속성 정보를 제때 교체할 수 없으며 따라서 공식적으로 새로운 오류가 발생합니다. sqlSessionFactory 및 sqlSessionTemplate 속성은 Mybatis-Spring에서 폐기되었습니다. sqlSessionFactoryBeanName 속성과 sqlSessionTemplateBeanName 속성을 사용하는 것이 좋습니다.
XML 코드
<?xml version="1.0" 인코딩="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:mvc="http://www.springframework.org/schema/mvc" xmlns:mybatis="http://www.mybatis.org/schema/mybatis" xsi:schemaLocation="http://www.springframework .org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.mybatis.org/schema/mybatis http:/ /www.mybatis.org/schema/mybatis/mybatis-spring.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"> <context:comComponent-scan base-package="com.tiantian.mybatis" /> <context:property-placeholder location= "classpath:config/jdbc.properties" /> <bean id="dataSource" destroy-method="close"> <property name="driverClassName" value="${jdbc.driver}" /> <속성 이름="url" value="${jdbc.url}" /> <속성 이름="사용자 이름" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </bean> <bean id="sqlSessionFactory"> <property name="dataSource" ref="dataSource" /> <property name="mapperLocations" value="classpath:com/tiantian/mybatis/mapper/*.xml" /> <property name="typeAliasesPackage" value="com.tiantian.mybatis.model" /> </bean> <bean> <속성 이름="basePackage" value="com.tiantian.mybatis.mapper" /> <속성 이름="markerInterface" value="com.tiantian.mybatis.mapper.SuperMapper"/> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> </bean> </beans>
SqlSessionTemplate
위 통합 후 Mapper 인터페이스를 직접 사용하는 것 외에도 Mybatis-Spring은 SqlSession을 직접 사용할 수 있는 방법도 제공합니다. Mybatis-Spring은 SqlSession 인터페이스를 구현하는 SqlSessionTemplate 클래스를 제공합니다. 이는 스레드로부터 안전하며 동시에 여러 Dao에서 사용할 수 있습니다. 동시에 이는 현재 사용되는 SqlSession이 Spring 트랜잭션에 바인딩된 것인지 확인하기 위해 Spring 트랜잭션과도 연결됩니다. 또한 세션 제출 및 종료를 자체적으로 관리할 수도 있습니다. Spring의 트랜잭션 관리 메커니즘이 사용되면 SqlSession도 Spring의 트랜잭션과 함께 제출되고 롤백될 수 있습니다.
SqlSessionTemplate을 사용할 때 다음과 같이 Spring의 applicationContext 구성 파일에서 정의할 수 있습니다.
<bean id="sqlSession"> <constructor-arg index="0" ref="sqlSessionFactory" /> </bean>
이런 식으로 우리는 SqlSessionTemplate을 사용하여 Spring의 의존성 주입을 통해 Dao에서 프로그래밍할 수 있습니다. 이때 Dao는 다음과 같습니다.
자바 코드
패키지 com.tiantian.mybatis.dao; import javax.annotation.Resource; import org.mybatis.spring.SqlSessionTemplate; import com.tiantian.mybatis.model 블로그; @Repository publicclass BlogDaoImpl은 BlogDao { private SqlSessionTemplate을 구현합니다. sqlSessionTemplate; publicvoid deleteBlog(int id) { sqlSessionTemplate.delete("com.tiantian.mybatis.mapper.BlogMapper.deleteBlog", id) } 공개 블로그 find(int id) { returnsqlSessionTemplate.selectOne("com.tiantian.mybatis. mapper.BlogMapper.selectBlog", id); } public List<Blog> find() { returnthis.sqlSessionTemplate.selectList("com.tiantian.mybatis.mapper.BlogMapper.selectAll") } publicvoid insertBlog(블로그 블로그) { this.sqlSessionTemplate.insert("com.tiantian. mybatis.mapper.BlogMapper.insertBlog", 블로그); } publicvoid updateBlog(블로그 블로그) { this.sqlSessionTemplate.update("com.tiantian.mybatis.mapper.BlogMapper.updateBlog", 블로그) } public SqlSessionTemplate getSqlSessionTemplate() { returnsqlSessionTemplate } @Resource publicvoid setSqlSessionTemplate(SqlSessionTemplate; sqlSessionTemplate) { this.sqlSessionTemplate = sqlSessionTemplate } }
메모:
이 글은 Mybatis3.2.1, Mybatis-Spring1.1.0, Spring3.1을 기반으로 작성되었습니다.
이상은 이번 글에서 소개한 mybatis와 spring 통합의 구현 과정에 대한 간략한 분석입니다. 다음 글에서는 spring과 mybatis의 통합 방법을 소개하겠습니다.