【MyBatis】MyBatis如何传入参数以及处理返回结果(XML配置)
MyBatis如何传入参数以及处理返回结果,通过XML进行配置。
目录
一、参数的取值方式
在xml文件中编写sql语句的时候有两种获取传入的参数值的方式,分别是#{}和${},下面来看一下他们之间的区别:
<!--获取参数的方式:
1.#{} ==> jdbc String sql=" SELECT id,user_name FROM EMP WHERE id=?"
1.会经过JDBC当中PreparedStatement的预编译,会根据不同的数据类型来编译成对应数据库所对应的数据。
2.拼接进去的内容是带着单引号的,能够有效的防止SQL注入。 推荐使用!!
特殊用法:
自带很多内置参数的属性:通常不会使用。了解
javaType、jdbcType、mode、numericScale、resultMap、typeHandler.
比如 需要改变默认的NULL===>OTHER:#{id,javaType=NULL}
想保留小数点后两位:#{id,numericScale=2}
2.${} ==> jdbc String sql=" SELECT id,user_name FROM EMP WHERE id="+id
1.不会进行预编译,会直接将输入进来的数据拼接在SQL中,不会带单引号。
2.存在SQL注入的风险。不推荐使用。
特殊用法:
1.调试情况下可以临时使用。
2.实现一些特殊功能:前提一定要保证数据的安全性。
比如:动态表、动态列. 动态SQL.
-->
<select id="SelectEmp" resultType="Emp" resultMap="emp_map" >
SELECT id,user_name,create_date FROM EMP where id=#{id}
</select>
参数:向sql语句中传递的可变参数
- 预编译 #{}:将传入的数据都当成一个字符串,会对自动传入的数据加一个单引号,能够很大程度防止sql注入;
- 传值 ${}:传入的数据直接显示生成在sql中,无法防止sql注入;
- 表名、选取的列是动态的,order by和in操作, 可以考虑使用$
二、select的参数传递
传递多个查询入参
- 使用map传递参数;可读性差,导致可维护性和可扩展性差,杜绝使用;
- 使用注解传递参数;直观明了,当参数较少一般小于5个的时候,建议使用;
- 使用Java Bean的方式传递参数;当参数大于5个的时候,建议使用;
将参数传递给sql语句的方法,用得比较多的就是使用@Param注解。
<!--
参数传递的处理:
1.单个参数:SelectEmp(Integer id);
mybatis 不会做任何特殊要求
获取方式:
#:{输入任何字符获取参数}
2.多个参数:Emp SelectEmp(Integer id,String username);
mybatis 会进行封装
会将传进来的参数封装成map:
1个值就会对应2个map项 : id===> {key:arg0 ,value:id的值},{key:param1 ,value:id的值}
username===> {key:arg1 ,value:id的值},{key:param2 ,value:id的值}
获取方式:
没使用了@Param:
id=====> #{arg0} 或者 #{param1}
username=====> #{arg1} 或者 #{param2}
除了使用这种方式还有别的方式,因为这种方式参数名没有意义:
设置参数的别名:@Param(""):SelectEmp(@Param("id") Integer id,@Param("username") String username);
当使用了@Param:
id=====> #{id} 或者 #{param1}
username=====> #{username} 或者 #{param2}
3. javaBean的参数:
单个参数:Emp SelectEmp(Emp emp);
获取方式:可以直接使用属性名
emp.id=====>#{id}
emp.username=====>#{username}
多个参数:Emp SelectEmp(Integer num,Emp emp);
num===> #{param1} 或者 @Param
emp===> 必须加上对象别名: emp.id===> #{param2.id} 或者 @Param("emp")Emp emp ====>#{emp.id}
emp.username===> #{param2.username} 或者 @Param("emp")Emp emp ====>#{emp.username}
4.集合或者数组参数:
Emp SelectEmp(List<String> usernames);
如果是list,MyBatis会自动封装为map:
{key:"list":value:usernames}
没用@Param("")要获得:usernames.get(0) =====> #{list[0]}
:usernames.get(0) =====> #{agr0[0]}
有@Param("usernames")要获得:usernames.get(0) =====> #{usernames[0]}
:usernames.get(0) =====> #{param1[0]}
如果是数组,MyBatis会自动封装为map:
{key:"array":value:usernames}
没用@Param("")要获得:usernames.get(0) =====> #{array[0]}
:usernames.get(0) =====> #{agr0[0]}
有@Param("usernames")要获得:usernames.get(0) =====> #{usernames[0]}
:usernames.get(0) =====> #{param1[0]}
5.map参数
和javaBean的参数传递是一样。
一般情况下:
请求进来的参数 和pojo对应,就用pojo
请求进来的参数 没有和pojo对应,就用map
请求进来的参数 没有和pojo对应上,但是使用频率很高,就用TO、DTO(就是单独为这些参数创建一个对应的javaBean出来,使参数传递更规范、更重用)
-->
<!--
接口:SelectEmp(String username,@Param("id") Integer id);
username====> #{arg0} #{param1}
id====> #{id} #{param2}
接口:SelectEmp(@Param("beginDate") String beginDate,
String endDate,
Emp emp);
beginDate====> #{beginDate} #{param1}
endDate====> #{arg1} #{param2}
emp.id====>#{arg2.id} #{param2.id}
接口:SelectEmp(List<Integer> ids,
String[] usernames,
@Param("beginDate") String beginDate,
String endDate,);
ids.get(0)=====> #{list[0]} #{param1[0]}
usernames[0]=====> #{array[0]} #{param2[0]}
beginDate====> #{beginDate} #{param3}
end====> #{arg3} #{param4}
-->
三、处理集合返回结果
3.1 resultType:自动映射结果集
resultType:当使用resultType做SQL语句返回结果类型处理时,对于SQL语句查询出的字段在相应的pojo中必须有和它相同的字段对应,而resultType中的内容就是pojo在本项目中的位置(pojo类的全限定名)。
自动映射注意事项:
- 前提:SQL列名和JavaBean的属性是一致的;
- 使用resultType,如用简写需要配置typeAliases (别名);
- 如果列名和JavaBean不一致,但列名符合单词下划线分割,Java是驼峰命名法,则标签属性mapUnderscoreToCamelCase可设置为true;
EmpDao.xml
<!--当返回值的结果是List集合的时候,返回值的类型依然要写集合中具体的类型,不要去写List-->
<select id="selectAllEmp" resultType="cn.tulingxueyuan.bean.Emp">
select * from emp
</select>
<!--
在查询的时候可以设置返回值的类型为map,当mybatis查询完成之后会把列的名称作为key
列的值作为value,转换到map中
-->
<select id="selectEmpByEmpReturnMap" resultType="map">
select * from emp where empno = #{empno}
</select>
<!--
注意,当返回的结果是一个Map集合对象时,返回值的类型一定要写集合具体value的类型
同时在dao的方法上要添加@MapKey的注解,来设置key是什么结果
@MapKey("empno")
Map<Integer,Emp> getAllEmpReturnMap();
-->
<select id="getAllEmpReturnMap" resultType="cn.tulingxueyuan.bean.Emp">
select * from emp
</select>
UserDao.java
public interface EmpDao {
public Emp findEmpByEmpno(Integer empno);
public int updateEmp(Emp emp);
public int deleteEmp(Integer empno);
public int insertEmp(Emp emp);
Emp selectEmpByNoAndName(@Param("empno") Integer empno, @Param("ename") String ename,@Param("t") String tablename);
Emp selectEmpByNoAndName2(Map<String,Object> map);
List<Emp> selectAllEmp();
Map<String,Object> selectEmpByEmpReturnMap(Integer empno);
@MapKey("empno")
Map<Integer,Emp> getAllEmpReturnMap();
}
3.2 resultMap:自定义映射结果集
- resultMap 元素是 MyBatis 中最重要最强大的元素。它可以让你从 90% 的 JDBC ResultSets 数据提取代码中解放出来,在对复杂语句进行联合映射的时候,它很可能可以代替数千行的同等功能的代码。
- resultMap 的设计思想是,简单的语句不需要明确的结果映射,而复杂一点的语句只需要描述它们的关系就行了。
3.2.1 resultMap标签的属性
属性 | 描述 |
id | 当前命名空间中的一个唯一标识,用于标识一个result map. |
type | 类的完全限定名, 或者一个类型别名. |
autoMapping | 如果设置这个属性,MyBatis将会为这个ResultMap开启或者关闭自动映射。这个属性会覆盖全局的属性 autoMappingBehavior。默认值为:unset。 |
3.2.2 resultMap的子标签的属性
- id – 一个 ID 结果;标记出作为 ID 的结果可以帮助提高整体性能,一对多的查询中用于结果集合并;
- result – 注入到字段或 JavaBean 属性的普通结果
- association – 一个复杂类型的关联;许多结果将包装成这种类型
- 嵌套结果映射 – 关联可以指定为一个 resultMap 元素,或者引用另一个
- collection – 一个复杂类型的集合
- 嵌套结果映射 – 集合可以指定为一个 resultMap 元素,或者引用另一个
在日常使用的时候,强烈建议全部使用resultMap,不要用resultType。因为映射关系一旦改变,使用resultMap的话,就只需要修改一个位置就行了,降低工作量。
这个映射配置,也是要写在对应的mapper.xml文件中的。和那些查询的sql标签写在同一个地方。
EmpMapper.xml
<!--1.声明resultMap自定义结果集 resultType 和 resultMap 只能使用一个。
id:唯一标识, 需要和<select> 上的resultMap 进行对应
type:需要映射的pojo对象, 可以设置别名
autoMapping“自动映射,(默认=true) 只要字段名和属性名遵循映射规则就可以自动映射,但是不建议,哪怕属性名和字段名一一对应上了也要显式的配置映射,因为后期数据库字段结构发生改变的话,就需要改很多地方,如果使用resultMap显式映射的话,就只需要改这一个映射关系就可以了
extends:如果多个resultMap有重复映射,可以声明父resultMap,将公共的映射提取出来, 可以减少子resultMap的映射冗余
-->
<resultMap id="emp_map" type="emp" autoMapping="false" extends="common_map">
<result column="create_date" property="cjsj"></result>
</resultMap>
<resultMap id="common_map" type="emp" autoMapping="false" >
<!--
<id> 主键必须使用 对底层存储有性能作用
<result>
column 需要映射的数据库字段名
property 需要映射的pojo属性名
-->
<id column="id" property="id"></id>
<result column="user_name" property="username"></result>
</resultMap>
<!--2.使用resultMap关联 自定义结果集的id-->
<select id="SelectEmp" resultType="Emp" resultMap="emp_map" >
SELECT id,user_name,create_date FROM EMP where id=#{id}
</select>
建立映射关系的时候,强制用XML里用resultMap标签去定义映射关系,而不是靠它自动根据相同的字段名去自动映射关联,因为后面数据表字段一旦修改,这个项目中可能有很多地方用到了这一块,我们就将只需要改一个resultMap就行了。不用所有的mapper查询都去做修改。
相关文章:
【MyBatis】MyBatis缓存原理详解-CSDN博客
【MyBatis】MyBatis的一级缓存和二级缓存简介_mybatis 的一级缓存和二级缓存-CSDN博客
【MyBatis】史上最全的MyBatis执行SQL原理分析_mybatis sql-CSDN博客
【MyBatis】MyBatis解析动态SQL原理分析-CSDN博客
【MyBatis】一篇文章带你彻底搞懂MyBatis解析SQL映射文件底层原理_mybatis 注解映射sql 原理-CSDN博客
【MyBatis】MyBatis内置数据源_pooleddatasource-CSDN博客
【MyBatis】MyBatis解析全局配置文件源码详解_mybatis解析配置文件源码-CSDN博客
【MyBatis】MyBatis的日志实现_mybatis 日志-CSDN博客
【MyBatis】MyBatis的介绍和基本使用_mybatis db-CSDN博客
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)