深入淺出mybatis之映射器


目錄

概述

映射器是MyBatis中最核心的組件之一,在MyBatis 3之前,只支持xml映射器,即:所有的SQL語句都必須在xml文件中配置。而從MyBatis 3開始,還支持接口映射器,這種映射器方式允許以Java代碼的方式注解定義SQL語句,非常簡潔。

XML映射器

xml映射器是MyBatis原生支持的方式,功能非常強大。

定義xml映射器

xml映射器支持將SQL語句編寫在xml格式的文件中。

<?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="org.chench.test.mybatis.mapper">
	<select id="selectOneTest" resultType="org.chench.test.mybatis.model.Test">
		select * from test where id = #{id}
	</select>
</mapper>

配置xml映射器

對於MyBatis是獨立使用還是與Spring框架集成這2種不同的場景,可以使用2種可選的方式注冊xml映射器。

  • 獨立使用MyBatis

獨立使用時注冊xml映射器只能在MyBatis配置文件中(如:mybatis-config.xml)通過mapper節點實現。

<configuration>
    <mappers>
        <!-- 注冊xml映射器: 2種方式 -->
        <!-- 方式一: 使用相對於類路徑的資源引用 -->
        <mapper resource="org/chench/test/mybatis/mapper/xml/TestMapper.xml"/>

        <!-- 方式二: 使用完全限定資源定位符(URL) -->
        <!--<mapper url="file:///var/config/TestMapper.xml" />-->
    </mappers>
</configuration>
  • 在Spring框架中集成MyBatis

在Spring框架中集成MyBatis時,注冊xml映射器有2種可選的方式:既可以在MyBatis配置文件中(如:mybatis-config.xml)配置,也可以直接在SqlSessionFactoryBean中通過屬性mapperLocations進行注冊。
(1)將xml映射器注冊放在MyBatis配置文件中(如:mybatis-config.xml),但是此時必須在SqlSessionFactoryBean中通過屬性configLocation指定MyBatis配置文件的位置。

<!-- 配置sqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
	<property name="dataSource" ref="dataSource"/>
	<!-- 指定MyBatis配置文件(只支持類路徑,典型的值為"WEB-INF/mybatis-configuration.xml") -->
	<property name="configLocation" value="mybatis-config.xml"/>
</bean>

(2)在SqlSessionFactoryBean中通過屬性mapperLocations進行注冊xml映射器。

<!-- 配置sqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
	<property name="dataSource" ref="dataSource"/>
	<!-- 注冊xml映射器 -->
	<property name="mapperLocations" value="classpath*:org/chench/test/mybatis/mapper/xml/**/*.xml"/>
</bean>

使用xml映射器

對於xml映射器的使用方式,如果使用SqlSession進行調用,獨立使用或者在Spring框架中集成基本上是一致的。需要注意的是:當MyBatis在Spring框架中集成使用時,不需要直接從sqlSessionFactory中獲取sqlSession對象,而是可以使用spring管理的sqlSession對象。另外當在Spring框架中集成MyBatis時,還可以直接通過接口使用xml映射器。

  • 獨立使用MyBatis

獨立使用MyBatis時,對於xml映射器只能使用SqlSession進行調用。

// 從類路徑下的xml配置中構建SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream is = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
// 從sqlSessionFactory中獲取sqlSession
// SqlSession的作用域最好是請求或方法域,且在使用完畢之后及時釋放資源,而且一定要確保資源得到釋放
SqlSession sqlSession =	sqlSessionFactory.openSession();
// 從xml映射配置中查詢
Test test =	sqlSession.selectOne("org.chench.test.mybatis.mapper.selectOneTest", 1);
sqlSession.close();
  • 在Spring框架中集成MyBatis

(1)使用SqlSession調用xml映射器,方式與獨立使用MyBatis時基本一致,只是獲取SqlSession實例的方式不同。

// 啟動spring容器
ApplicationContext context = new ClassPathXmlApplicationContext("mybatis-spring.xml");
// 使用xml映射器
// 不需要直接從sqlSessionFactory中獲取sqlSession對象,而是可以使用spring管理的sqlSession對象
//	SqlSessionFactory sqlSessionFactory = (SqlSessionFactory) context.getBean("sqlSessionFactory");
//	SqlSession sqlSession =	sqlSessionFactory.openSession();
//	Test test =	sqlSession.selectOne("org.chench.test.mybatis.mapper.selectOneTest", 1);

// 直接使用spring提供的sqlSession
SqlSession sqlSession = (SqlSession) context.getBean("sqlSession");
Test test =	sqlSession.selectOne("org.chench.test.mybatis.mapper.selectOneTest", 1);

此時,需要在Spring框架中注入SqlSession實例。

<!-- 在Spring框架中注入SqlSession實例-->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
	<constructor-arg index="0" ref="sqlSessionFactory"/>
</bean>

(2)使用接口調用xml映射器
當在Spring框架中集成MyBatis時,對於xml映射器的使用除了可以通過SqlSession實例進行調用,還可以直接通過接口進行調用。注意:此時在定義Java接口和注冊xml映射器時需要遵循一定的約定。
首先,定義的Java接口必須在org.mybatis.spring.mapper.MapperScannerConfigurer的屬性basePackage指定的包或者子包下,如下所示:

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
	<property name="basePackage" value="org.chench.test.mybatis.mapper.impl"/>
</bean>

org.mybatis.spring.mapper.MapperScannerConfigurer由Spring框架注冊,並設置basePackage屬性值為org.chench.test.mybatis.mapper.impl,那么對應的Java接口就只能定義在Java包org.chench.test.mybatis.mapper.impl下,並通過Spring框架注冊Bean,如下所示:

// Jav接口所在包位置
package org.chench.test.mybatis.mapper.impl;
// 接口通過Spring框架注冊Bean
@Repository
public interface DemoMapper {
    public Demo selectOne(long id);
}

其次,注冊xml映射器時需要將namespace屬性設置為上述Java接口的完整類名稱,同時設置操作語句元素的id屬性為接口內的指定方法名稱。

<?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">
<!-- 將xml映射器的namespace屬性設置為完整的接口類名稱 -->
<mapper namespace="org.chench.test.mybatis.mapper.impl.DemoMapper">
	<!-- 將操作語句元素的id屬性設置為接口方法名稱 -->
	<select id="selectOne" resultType="org.chench.test.mybatis.model.Demo">
        SELECT * FROM demo WHERE id=#{id}
    </select>
</mapper>

在遵守上述約定注冊對應的xml映射器之后,就可以直接通過對應的Java接口調用xml映射器了。

// 啟動spring容器
ApplicationContext context = new ClassPathXmlApplicationContext("mybatis-spring.xml");
// 使用接口調用xml映射器
DemoMapper demoMapper = context.getBean(DemoMapper.class);
Demo demo = demoMapper.selectOne(1);
  • xml映射器使用方法的比較

xml映射器的使用方式根據MyBatis的使用場景而不同,總結如下:
(1)獨立使用MyBatis時,只能通過SqlSession使用xml映射器,調用時必須指定xml映射器中的操作語句id,比較繁瑣。

Test test =	sqlSession.selectOne("org.chench.test.mybatis.mapper.selectOneTest", 1);

(2)在Spring框架中集成MyBatis時,使用xml映射器比較靈活。除了可以通過SqlSession使用,還可以通過Java接口直接調用。對於開發者來說,直接調用接口方法會更加簡潔;同時還能使用xml映射器的靈活與強大功能,可謂一舉多得。

接口映射器

接口映射器是從MyBatis 3才開始支持的,其實就是支持在Java接口方法上通過注解方式編寫SQL語句,而不再需要xml文件格式的配置。但請注意:使用注解編寫SQL語句這種方式在某些場景下存在一定的限制,特別是處理復雜SQL的時候。雖然其有一定的簡潔性,但同時也帶來了局限性。通常都是將xml映射器和接口映射器聯合使用。

定義接口映射器

定義接口映射器就是通過注解在Java接口方法上編寫SQL語句,如下所示:

// 定義接口映射器
public interface TestMapper {
	// 通過MyBatis的注解在Java接口方法上編寫SQL語句
	@Select("select * from test where id = #{id}")
	Test selectOneTest(long id);
}

配置接口映射器

對於MyBatis是獨立使用還是與Spring框架集成這2種不同的場景,注冊接口映射器的方式各不相同,必須注意這一點。

  • 獨立使用MyBatis

在獨立使用MyBatis時,接口映射器只能在MyBatis的配置文件中(如:mybatis-config.xml)通過mapper節點指定,如:

<mappers>
	<!-- 注冊接口映射器: 2種方式 -->
	<!-- 方式一: 明確注冊每一個接口 -->
	<!--
	<mapper class="org.chench.test.mybatis.mapper.impl.TestMapper" />
	<mapper class="org.chench.test.mybatis.mapper.impl.StudentMapper" />
	-->
	<!-- 方式二: 指定映射器接口所在Java包名稱,則該包下的所有映射器接口都會被注冊 -->
	<package name="org.chench.test.mybatis.mapper.impl"/>
</mappers>
  • 在Spring框架中集成MyBatis

在Spring框架中集成MyBatis時,接口映射器只能通過org.mybatis.spring.mapper.MapperScannerConfigurer注冊,指定其basePackage屬性值為需要注冊映射器接口所在的包,可以在該包及其子包下定義接口映射器。

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
	<!-- 定義接口映射器所在的Java包 -->
	<property name="basePackage" value="org.chench.test.mybatis.mapper.impl"/>
</bean>

使用接口映射器

根據MyBatis的使用場景不同,使用接口映射器的方式也不同。

  • 獨立使用MyBatis

獨立使用MyBatis時,只能通過SqlSession使用接口映射器,此時也需要開發者自己釋放SqlSession資源。

// 從類路徑下的xml配置中構建SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream is = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
// 從sqlSessionFactory中獲取sqlSession
// SqlSession的作用域最好是請求或方法域,且在使用完畢之后及時釋放資源,而且一定要確保資源得到釋放
SqlSession sqlSession =	sqlSessionFactory.openSession();
// 從映射器接口中查詢
Test test = sqlSession.getMapper(TestMapper.class).selectOneTest(1);
sqlSession.close();
  • 在Spring框架中集成MyBatis

在Spring框架中集成MyBatis時,接口映射器的Bean由Spring框架來管理,此時只需要直接獲取對應的接口映射器Bean並調用方法即可。

// 啟動spring容器
ApplicationContext context = new ClassPathXmlApplicationContext("mybatis-spring.xml");
// 從Spring容器中獲取接口映射器Bean
TestMapper testMapper =	context.getBean(TestMapper.class);
Test test =	testMapper.selectOneTest(1);

總結與對比

  1. 從MyBatis 3開始,同時支持2種類型的映射器:xml映射器和接口映射器。
  2. xml映射器是MyBatis原生支持的映射器方式,優點是功能強大,缺點是配置顯得臃腫和復雜;接口映射器支持通過注解的方式在Java接口方法上編寫SQL語句,優點是簡潔,不再依賴外部xml配置,缺點是功能沒有xml映射器強大。需要特別注意的是,在接口映射器中使用@SelectProvider注解動態拼裝SQL時存在SQL注入攻擊的風險。因此,通常都是將二者聯合使用,即可以使用接口映射器帶來的簡潔性,也能使用xml映射器的強大功能。
  3. 2種映射器都可以分為獨立使用和在Spring框架中集成使用2種不同的方式,獨立使用時需要開發者自己處理事務管理和資源釋放;在Spring框架中集成時事務管理和資源釋放交給Spring框架處理,對開發者是透明的,更加高效和友好。
  4. 對於批量添加記錄需要返回主鍵字段值的需求,只能在xml映射器中實現,接口映射器無能為力。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM