笔记簿
ᴄᴏᴅɪɴɢ ɪs ᴀʀᴛ
首页
关于
搜索
登录
注册
Mybatis中的参数传递 - 各种类型的传参如何在mybatis的sql映射文件中正确获取
**MyBatis不要定义接口的方法重载,因为通过id无法区分** ##### 1、单个参数: ```text 非自定义对象 传参:getStuById(Integer id); 取值:#{id} 单个基本类型参数,随便取值都行;#{ok} 对象: 传参:saveStudent(Student student) 取值:#{属性名} 这个不能随便写 ``` ##### 2、多个参数: ```text 传参:getStudentByLastNameAndAge(String lastName,Integer age) 取值:#{参数名}不好使;报错提示可用的参数是[0,1,param1,param2] 可用的取值方式: 1)#{参数索引} #{0} #{1} 2)#{param参数第几个} #{param1} #{param2} 原因:一但方法传入了多个参数以后,mybatis会进行一个处理;把这些参数全部放在一个map中;map中的key就是参数的索引,或者是param1…N ``` ##### 3、命名参数: ```text 我们可以使用@Param注解来指定mybatis在给多个参数封装map的时候,这个参数使用的key;默认参数索引或者paramx 传参:public Student getStudentByLastNameAndAge(@Param(“lastName”)String lastName,@Param(“age”)Integer age); 取值:#{命名的参数名}或者#{paramx} 什么时候用基本类型传参:不将参数封装成pojo直接传给mybatis;很少用到;有些方法的参数是业务无关的; ``` ##### 4、POJO: ```text 建议: 如果传递的参数正好是业务逻辑定义的pojo,就用pojo; 传参:saveStudent(Student student); 取值:#{属性名} ``` ##### 5、Map(集合); ```text 传参:public Student getStuByLastNameAndAge(Map
map); 取值:#{key} 不管传什么?如果单个参数,mybatis直接就拿来用,如果多个参数,mybatis会将多个参数封装进一个map中,封装参数用的key默认是0,1,paramx。。。,我们可以使用@Param(“key”)为这个参数指定一个新的key 传参: getStudent(@Param(“stu”)Student stu,@Param(“map”)Map
hahamap,@Param(“lastName”)String lastName); 取值: 取值student对象中的age值:#{param1.age}===#{stu.age} 取值hahamap中的email:#{param2.email}===#{map.email} 取值lastName:#{param3}===#{lastName} ``` ##### 7:POJO,Map怎么选择? ```text 业务逻辑中定义的POJO我们就使用它,有比较多临时的参数,并不是某个javaBean的,可以为了方便将其封装一个map传递。 TO:(Transfer Object)(专门用它来传递数据的) POJO:(普通的java类) DO:(Domain Object)对象模型 DTO:Data Transfer Object:数据传输对象 DAO:Data Access Object:数据访问对象 VO:Value Object:值对象; ``` ##### 8:注意点一 ```text #{}取值的时候还可以为当前值设置一些特别的属性 #{lastName,javaType=String,jdbcType=JdbcType.VARCHAR} jdbcType:如果我们数据库是oracle数据库,插入null值的时候如果oracle数据库不知道这个null值原来的类型就会报错; jdbcType=JdbcType.VARCHAR; 报错的原因: 默认的不知道值的情况下;JdbcType=JdbcType.OTHER;oracle不认识 解决办法:随便指定一个类型;JdbcType=JdbcType.NULL;oracle认识; 也可以在参数位置不指定;全局的setting可以设置; 这个设置希望是mybatis的标配;
``` ##### 9:注意点二 ```text 取值有两种取值方式:${},#{} 1)、select * from tbl_student where last_name=#{lastName} and age=#{age} 日志打印: 编译sql:select * from tbl_student where last_name=? and age=? (BaseJdbcLogger.java:145) 设置参数:Parameters: adminaaa(String), 11(Integer) (BaseJdbcLogger.java:145) 运行结果:Total: 0 (BaseJdbcLogger.java:145) 2)、select * from tbl_student where last_name=${lastName} and age=#{age} 日志打印: 编译sql:select * from tbl_student where last_name=’adminaaa’ and age=? 设置参数:11(Integer) 区别: ${}直接取值进行和原生sql拼串;不安全 select * from tbl_student where last_name=’adminaaa’ and age=? ${}取值不安全,会有sql注入; select * from tbl_student where username=’1′ or 1=1 and password=? 我们希望真正查询的是一个名字叫 ‘1’ or 1=1 的人; #{}有预编译设置参数过程;安全,经常使用 ${}每个月都建立了一个日志表(分表) tbl_log_2017_11 tbl_log_2017_12 查询的时候表名需要动态传入; 原生JDBC,参数位置才支持占位符和预编译的。其他位置都不支持 select * from ${tblName} where last_name=#{lastName} and age=#{age} order by ${fieldName} ```