若映射器中的方法只有一个参数,则在对应的SQL语句中,可以采用#{参数名}的方式来引用此参数,以前的例子多属于此类。但这种方法却不适用于需要传递多个参数的情况,今天就来介绍如何使用注解传递多个参数(示例×××地址:http://down.51cto.com/data/537051)。
一、使用注解实现多参数传递
首先应引入“org.apache.ibatis.annotations.Param”,我们在接口TeacherMapper中引入,并增加一个教师分页查询的方法findTeacherByPage的声明。如下所示:
package com.abc.mapper; import com.abc.domain.Teacher; import org.springframework.stereotype.Component; import java.util.List; //使用@Param注解需要先引入Param import org.apache.ibatis.annotations.Param; //@Component指定映射器名称为myTeacherMapper //相关内容,可参考笔者博客: //http://legend2011.blog.51cto.com/3018495/980150 @Component("myTeacherMapper") public interface TeacherMapper { public Teacher getById(int id); //分页查询教师信息 public List<Teacher> findTeacherByPage( //使用@Param("sort")注解,即可在SQL语句中 //以“#{sort}”的方式引用此方法的sort参数值。 //当然也可以在@Param中使用其他名称, //如@Param("mysort") @Param("sort") String sort,//排序字段 //以下三个注解同理 @Param("dir") String dir, //排序方向 @Param("start") int start, //起始记录 @Param("limit") int limit //记录条数 ); }
对应的映射文件TeacherMapper.xml的内容如下:
<?xmlversion="1.0"encoding="utf8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!--与以前一样,namespace的值是对应的映射器接口的完整名称--> <mapper namespace="com.abc.mapper.TeacherMapper"> <!--教师实体映射--> <resultMap id="supervisorResultMap"type="Teacher"> <id property="id"/> <result property="name"/> <result property="gender"/> <result property="researchArea"column="research_area"/> <result property="title"/> <!--collection元素映射教师的指导学生集合的属性。这里采用了 “命名空间名.select语句id”的形式来引用StudentMapper.xml中的 select语句getStudents。关于这种collection元素使用嵌套的 select语句的详情,请参考笔者博客: http://legend2011.blog.51cto.com/3018495/985907 --> <collection property="supStudents" column="id" ofType="Student" select="com.abc.mapper.StudentMapper.getStudents"/> </resultMap> <select id="findTeacherByPage" resultMap="supervisorResultMap"> select * from teacher order by ${sort} ${dir} limit #{start},#{limit} </select> </mapper>
运行主程序如下:
package com.demo; import org.springframework.context.ApplicationContext; import com.abc.mapper.StudentMapper; import com.abc.mapper.TeacherMapper; import com.abc.domain.Teacher; import com.abc.domain.Student; import org.springframework.context.support.ClassPathXmlApplicationContext; import java.util.List; public class CollectionDemo { private static ApplicationContext ctx; static { //在类路径下寻找resources/beans.xml文件 ctx = new ClassPathXmlApplicationContext("resources/beans.xml"); } public static void main(String[] args) { //从Spring容器中请求映射器 TeacherMapper mapper = (TeacherMapper)ctx.getBean("myTeacherMapper"); Teacher teacher = null; //查询教师分页信息 List<Teacher> teachers = //以name字段升序排序,从第0条记录开始查询。 //查询2条记录 mapper.findTeacherByPage("name","asc",0, 2); if(teachers == null) { System.out.println("未找到相关教师信息。"); } else { Object[] t = teachers.toArray(); System.out.println("**********************************************"); for(int i = 0; i < t.length; i++) { teacher = (Teacher)t[i]; System.out.println("教师姓名:" + " " + teacher.getName()); System.out.println("教师职称:" + " " + teacher.getTitle()); System.out.println("指导学生信息:"); //遍历指导的学生 for(Student s : teacher.getSupStudents()) { System.out.println( s.getName() + " " + s.getGender() + " " + s.getGrade() + " " + s.getMajor()); } System.out.println("**********************************************"); } } } }
运行结果如下:
二、可能会遇到的错误
1、关于order by
一般而言,我们会使用#{参数名}的形式来引用方法中的参数,但这种方式对于order by子句无效或报错。例如,当TeacherMapper.xml的select语句findTeacherByPage中的order by子句以#{sort}的形式引用方法中的sort参数的值时,是无效的(读者可自行验证);以#{dir}的形式引用方法中的dir参数的值时,会报MySQLSyntaxErrorException,如下图所示:
因此,在这里使用了${参数名}的形式引用了相应的参数值。
2、invalid XML character错误
这是一个诡异的错误。当在映射文件内的注释中,汉字“错”后紧跟中文的句号时即报此错误,如下图所示:
在Spring的配置文件beans.xml中,也是一样。类似地,汉字“错”后紧跟中文的逗号时也会报此错误。此时若在“错”字后面加一汉字,即不再报错;然而加“啊”字却仍然报错。读者可自行尝试,说不定还能找出其他错误的情形。
报出的异常都是org.xml.sax.SAXParseException(如上面错误图片中红框左边所示),这也许意味着它们都是使用同样的xml解析组件。而这种错误,会不会是此组件的bug?
MyBatis技术交流群:188972810,或扫描二维码:
【MyBatis学习笔记】系列之预备篇一:ant的下载与安装
【MyBatis学习笔记】系列之二:MyBatis增删改示例
【MyBatis学习笔记】系列之三:MyBatis的association示例
【MyBatis学习笔记】系列之四:MyBatis association的两种形式
【MyBatis学习笔记】系列之五:MyBatis与Spring集成示例
【MyBatis学习笔记】系列之六:MyBatis与Spring集成示例续
【MyBatis学习笔记】系列之七:MyBatis一对多双向关联
【MyBatis学习笔记】系列之八:MyBatis MapperScannerConfigurer配置
【MyBatis学习笔记】系列之九:MyBatis collection的两种形式
【MyBatis学习笔记】系列之十:MyBatis日志之Log4j示例
【MyBatis学习笔记】系列之十一:MyBatis多参数传递之注解方式示例
【MyBatis学习笔记】系列之十二:MyBatis多参数传递之默认命名方式示例
【MyBatis学习笔记】系列之十三:MyBatis多参数传递之Map方式示例
【MyBatis学习笔记】系列之十四:MyBatis中的N+1问题
【MyBatis学习笔记】系列之十五:MyBatis多参数传递之混合方式
【MyBatis学习笔记】系列之十六:Spring声明式事务管理示例
【MyBatis学习笔记】系列之十七:MyBatis多对多保存示例
【MyBatis学习笔记】系列之十八:MyBatis多对多关联查询示例
【MyBatis学习笔记】系列之十九:如何在MyBatis-3.2.7中使用Log4j2 rc2