目录

一、参数的取值方式

二、select的参数传递

三、处理集合返回结果

3.1 resultType:自动映射结果集

3.2 resultMap:自定义映射结果集

3.2.1 resultMap标签的属性

3.2.2 resultMap的子标签的属性


一、参数的取值方式

在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博客

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐