【SSM】SSM之MyBatis框架:mappers 映射器的兩種映射方案

mappers 映射器的兩種映射方案:

要定義 SQL 映射語句先要告訴 MyBatis 到哪裏去找到這些語句。 Java 在這方面沒有提供一個很好的方法, 所以最佳的方式是用mappers 映射器告訴 MyBatis 到哪裏去找映射文件。mappers 映射器提供了兩種映射方案,一是直接指定相應的mapper .xml文件,二是指定與mapper .xml相關聯的接口。例如:

<mappers>
  <!--指定mapper.xml的相對路徑-->
  <mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
  <!--指定mapper.xml的絕對路徑-->
  <mapper url="file:///var/mappers/AuthorMapper.xml"/>
</mappers>
<mappers>
  <!--指定相關聯的接口的全限定路徑-->
  <mapper class="org.mybatis.builder.AuthorMapper"/>
  <!--指定包下所有相關聯的接口-->
  <package name="org.mybatis.builder"/>
</mappers>

前面所述俱是用的第一種方案,第一種方案適用於傳統的DAO封裝。下面介紹一下第二種方案,第二種方案纔是Mybatis推薦的方案,因爲它具有很多優點,其中最顯著的優點在於:

  • 調用sql命令時,直接調用接口中的方法,由程序內部自動關聯mapper.xml文件中對應的sql命令,因此不用再寫冗長的namespace;
  • 在第一種方案中,調用sql命令時只能傳入一個參數,如果要傳入多個參數還得用對象或集合將其封裝,而第二種方案中由於調用的是接口中聲明的方法,既然是方法那麼就可以傳入多個參數。

但是第二種方案有以下兩個要求:

  • 接口和映射文件必須在同一個包中;
  • 接口和映射文件除去文件後綴其文件名必須相同。

第二種方案適用於動態代理DAO開發,是Mybatis推薦的方案,動態代理對接口和映射文件也有幾個要求:

  • 接口中聲明的方法名必須和映射文件中對應的sql的id一致;
  • 接口中聲明的方法參數必須和映射文件中對應的sql的parameterType一致;
  • 接口中聲明的方法返回值必須和映射文件中對應的sql的resultType一致。

例:

1、在MySQl中建表,在相應的web項目的src目錄下,新建包與實體類:
此處用上一篇博客的flower表,包名“cn.jingpengchong.pojo”及包下的Flower.java
2、在src目錄下,新建包與mapper.xml文件:
包名“cn.jingpengchong.mapper”,文件“FlowerMapper.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="cn.jingpengchong.mapper.FlowerMapper">
	<!-- 根據價格和產地查找花 -->
	<select id="selByPriPro" resultType="flower">
		<!-- 用#{0}/#{param1}接收第一個參數,用#{1}/#{param2}接收第一個參數 -->
		select * from flower where price = #{0} and production = #{1}
	</select>
</mapper>

3、在src目錄下,新建XML映射配置文件:
文件“mybatis.xml”文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	<!--給Flower類設置別名,這樣在聲明該類類型時直接寫“Flower”或“flower”即可-->
	<typeAliases>
		<package name="cn.jingpengchong.pojo"/>
	</typeAliases>
	<environments default="default">
		<environment id="default">
			<transactionManager type="JDBC"></transactionManager>
			<dataSource type="POOLED">
				<property name="driver" value="com.mysql.jdbc.Driver"/>
				<property name="url" value="jdbc:mysql://127.0.0.1:3306/ssm"/>
				<property name="username" value="root"/>
				<property name="password" value="1234"/>
			</dataSource>
		</environment>
	</environments>
	<mappers>
		<!--將該包下文件名相同的接口的方法和xml文件的sql命令一一關聯起來-->
		<package name="cn.jingpengchong.mapper"/>
	</mappers>
</configuration>

4、在mapper.xml文件所在包下新建接口,接口名要與對應的mapper.xml文件名相同:
在包“cn.jingpengchong.mapper”下新建接口“FlowerMapper.java”:

package cn.jingpengchong.mapper;

import java.util.List;

import cn.jingpengchong.pojo.Flower;

public interface FlowerMapper {
	/**
	 * 根據價格和產地查詢花
	 * selByPriPro:方法名要與對應xml文件中對應方法的id相同
	 * pri:價格price
	 * pro:產地production
	 */
	List<Flower> selByPriPro(double pri, String pro);

}

5、新建測試類:
這裏在“cn.jingpengchong.test”包下新建了一個“Test.java”文件:

package cn.jingpengchong.test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import cn.jingpengchong.mapper.FlowerMapper;
import cn.jingpengchong.pojo.Flower;

public class Test {

	public static void main(String[] args) throws IOException {

		InputStream is = Resources.getResourceAsStream("mybatis.xml");
		SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
		SqlSession session = factory.openSession();
		FlowerMapper mapper = session.getMapper(FlowerMapper.class);
		List<Flower> list = mapper.selByPriPro(4, "南美阿根廷");
		for (Flower flower : list) {
			System.out.println(flower);
		}
	}
}

運行結果如下:
在這裏插入圖片描述

附:mapper.xml文件中SQL命令的參數接收

1、#{0}、#{1}、#{2}…:用於獲取第1、2、3…個參數;
2、#{param1}、#{param2}、#{param3}…:用於獲取第1、2、3…個參數;
3、上面的#{}不能換成${},因爲除了獲取Map集合中的元素或對象中的屬性值,${}中的內容都會被sql簡單的作爲字符串拼接;
4、可以用“@Param()”註解將參數封裝成Map集合,如果想要用下面的方法獲取參數:

<select id="selByPriPro" resultType="flower">
	select * from flower where price = #{price} and production = #{production}
</select>

那麼接口中聲明的方法應該加上對應的註解:

List<Flower> selByPriPro(@Param("price") double pri, @Param("production") String pro);

修改完畢運行測試類仍然正確,結果如下:
在這裏插入圖片描述
這種方式是將註解中傳入的參數作爲key,將後面的參數作爲value封裝成了一個Map集合傳給了mapper.xml文件,但即便如此,把#{}換成${}仍然會出錯:
在這裏插入圖片描述
可以在日誌中看到接收字符串參數時單/雙引號丟失了,這也是在開發中用#{},而不用${}的原因!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章