【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文件,但即便如此,把#{}换成${}仍然会出错:
在这里插入图片描述
可以在日志中看到接收字符串参数时单/双引号丢失了,这也是在开发中用#{},而不用${}的原因!

发布了128 篇原创文章 · 获赞 17 · 访问量 2737

猜你喜欢

转载自blog.csdn.net/qq_43705275/article/details/104065578