这是mybatis系列第5篇。 说到底Mybatis常见的传参形式无非是传递一个参数、Map、Java对象,亦或是多个参数。下面就分别对这些进行讲解和说明。 传递一个参数传递一个参数相对来说较为简单 用法Mapper接口方法中只有一个参数,如: UserModel getByName(String name); Mapper xml引用这个name参数: #{任意合法名称} 如:#{name}、#{val}、${x}等等写法都可以引用上面name参数的值。 传递一个Map参数用法如果我们需要传递的参数比较多,参数个数是动态的,那么我们可以将这些参数放在一个map中,key为参数名称,value为参数的值。在工作中,这种可以说是最常见的。大多数情况下都可以进行使用 Mapper接口中可以这么定义,如: List<UserModel> getByMap(Map<String,Object> map); 如我们传递: Map<String, Object> map = new HashMap<>(); map.put("id", 1L); map.put("name", "冢狐"); 对应的mapper xml中可以通过#{map中的key}可以获取key在map中对应的value的值作为参数,如: SELECT * FROM t_user WHERE id=#{id} OR name = #{name} 传递一个java对象参数当参数比较多,但是具体有多少个参数我们是确定的时候,我们可以将这些参数放在一个javabean对象中。这样也有利于理解,知道需要传递那些参数,不想map一样对于传递的参数不是很明确。 如我们想通过userId和userName查询,可以定义一个dto对象,属性添加对应的get、set方法,如: @Getter @Setter @ToString @Builder @NoArgsConstructor @AllArgsConstructor public class UserFindDto { private Long userId; private String userName; } 传递java对象的方式相对于map的方式更清晰一些,可以明确知道具体有哪些参数,而传递map,我们是不知道这个map中具体需要哪些参数的,map对参数也没有约束,参数可以随意传,建议多个参数的情况下选择通过java对象进行传参。 传递多个参数上面我们介绍的都是传递一个参数,那么是否可以传递多个参数呢?我们来试试吧。 多参数mybatis的处理mybatis处理多个参数的时候,会将多个参数封装到一个map中,map的key为参数的名称,java可以通过反射获取方法参数的名称,下面这个方法: UserModel getByIdOrName(Long id, String name); 编译之后,方法参数的名称通过反射获取的并不是id、name,而是arg0、arg1,也就是说编译之后,方法真实的参数名称会丢失,会变成arg+参数下标的格式。 所以上面传递的参数相当于传递了下面这样的一个map: Map<String,Object> map = new HashMap<>(); map.put("arg0",id); map.put("arg1",name); 所以说我们的方法真实的参数名称会丢失,如果要想使用真实的参数名称,就需要在编译java代码使用javac命令的时候带上-parameters参数,当编译代码的时候加上这个参数,方法的实际名称会被编译到class字节码文件中,当通过反射获取方法名称的时候就不是arg0、arg1这种格式了,而是真实的参数名称:id、name了。 我们来修改一下maven的配置让maven编译代码的时候加上这个参数,修改pom.xml中的build元素,这个元素中加入下面代码: <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.3</version> <configuration> <compilerArgs> <arg>-parameters</arg> </compilerArgs> </configuration> </plugin> </plugins> idea中编译代码也加一下这个参数,操作如下: 点击File->Settings->Build,Execution,Deployment->Java Compiler,如下图:
下面我们将xml中的getByIdOrName对应的sql修改成下面这样: SELECT * FROM t_user WHERE id=#{arg0} OR name = #{arg1} LIMIT 1 使用maven命令重新编译一下chat01的代码,cmd命令中mybatis-demo/pom.xml所在目录执行下面命令:
参数名称变成了真实的名称了,但是还是有param1、param2,方法参数名称不管怎么变,编译方式如何变化,param1, param2始终在这里,这个param1, param2就是为了应对不同的编译方式导致参数名称而发生变化的,mybatis内部除了将参数按照名称->值的方式放入map外,还会按照参数的顺序放入一些值,这些值的key就是param+参数位置,这个位置从1开始的,所以id是第一个参数,对应的key是param1,name对应的key是param2,value对应的还是参数的值,所以mybatis对于参数的处理相当于下面过程: Map<String,Object> map = new HashMap<>(); map.put("反射获取的参数id的名称",id); map.put("反射获取的参数name的名称",name); map.put("param1",id); map.put("param2",name); 使用注意
多参数中用@param指定参数名称刚才上面讲了多参数传递的使用上面,对参数名称和顺序有很强的依赖性,容易导致一些严重的错误。 mybatis也为我们考虑到了这种情况,可以让我们自己去指定参数的名称,通过@param(“参数名称”)来给参数指定名称。 /** * 通过id或者name查询 * * @param id * @param name * @return */ UserModel getByIdOrName(@Param("userId") Long id, @Param("userName") String name); 上面我们通过@Param注解给两个参数明确指定了名称,分别是userId、userName,对应的user.xml中也做一下调整,如下: <!-- 通过id或者name查询 --> <select id="getByIdOrName" resultType="zhonghu.mybatis.chat01.UserModel"> <![CDATA[ SELECT * FROM user WHERE id=#{userId} OR name = #{userName} LIMIT 1 ]]> </select> ResultHandler作为参数用法查询的数量比较大的时候,返回一个List集合占用的内存还是比较多的,比如我们想导出很多数据,实际上如果我们通过jdbc的方式,遍历ResultSet的next方法,一条条处理,而不用将其存到List集合中再取处理。 mybatis中也支持我们这么做,可以使用ResultHandler对象,犹如其名,这个接口是用来处理结果的,先看一下其定义: public interface ResultHandler<T> { void handleResult(ResultContext<? extends T> resultContext); } 里面有1个方法,方法的参数是ResultContext类型的,这个也是一个接口,看一下源码: public interface ResultContext<T> { T getResultObject(); int getResultCount(); boolean isStopped(); void stop(); } 4个方法:
ResultContext接口有一个实现类org.apache.ibatis.executor.result.DefaultResultContext,mybatis中默认会使用这个类。 最后
|
|
来自: python_lover > 《待分类》