前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【MyBatis】day02参数传递和映射

【MyBatis】day02参数传递和映射

作者头像
陶然同学
发布2023-04-30 15:55:57
9010
发布2023-04-30 15:55:57
举报
文章被收录于专栏:陶然同学博客

第四章 Mybatis映射文件详解

4.1 映射文件概述

  • MyBatis 的真正强大在于它的语句映射,这是它的魔力所在。
  • 如果拿它跟具有相同功能的 JDBC 代码进行对比,你会立即发现省掉了将近 95% 的代码。

4.2 映射文件根标签

  • mapper标签
  • mapper中的namespace要求与接口的全类名一致

4.3 映射文件子标签

子标签共有9个,注意学习其中8大子标签

  • insert标签:定义添加SQL
  • delete标签:定义删除SQL
  • update标签:定义修改SQL
  • select标签:定义查询SQL
  • sql标签:定义可重用的SQL语句块
  • cache标签:设置当前命名空间的缓存配置
  • cache-ref标签:设置其他命名空间的缓存配置
  • resultMap标签:描述如何从数据库结果集中加载对象
    • resultType解决不了的问题,交个resultMap。

4.4 映射文件中常用属性

  • resultType:设置期望结果集返回类型【全类名或别名】
    • 注意:如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身的类型。
    • resultType 和 resultMap 之间只能同时使用一个。

day03

4.5 获取主键自增数据

  • useGeneratedKeys:启用主键生成策略
  • keyProperty:设置存储属性值

4.6 获取数据库受影响行数

  • 直接将接口中方法的返回值设置为int或boolean即可
    • int:代表受影响行数
    • boolean
      • true:表示对数据库有影响
      • false:表示对数据库无影响

第五章 Mybatis中参数传递问题

5.1 单个普通参数

  • 可以任意使用:参数数据类型、参数名称不用考虑

5.2 多个普通参数

  • Mybatis底层封装Map结构,封装key为param1、param2....【支持:arg0、arg1、...】

5.3 命名参数

语法:

  • @Param(value="参数名")
  • @Param("参数名")

位置:参数前面

注意:

  • 底层封装Map结构
  • 命名参数,依然支持参数【param1,param2,...】

示例代码

代码语言:javascript
复制
/**
 * 通过员工姓名及薪资查询员工信息【命名参数】
 * @return
 */
public List<Employee> selectEmpByNamed(@Param("lName")String lastName,
                                       @Param("salary") double salary);
代码语言:javascript
复制
<select id="selectEmpByNamed" resultType="employee">
    SELECT
        id,
        last_name,
        email,
        salary
    FROM
        tbl_employee
    WHERE
        last_name=#{param1}
    AND
        salary=#{param2}
</select>

源码分析

MapperMethod对象:142行代码【命名参数底层代码入口】

命名参数底层封装map为ParamMap,ParamMap继承HashMap

ParamNameResolver对象:130行代码,命名参数底层实现逻辑

代码语言:javascript
复制
//130行
final Map<String, Object> param = new ParamMap<>();
int i = 0;
for (Map.Entry<Integer, String> entry : names.entrySet()) {
  param.put(entry.getValue(), args[entry.getKey()]);
  // add generic param names (param1, param2, ...)
  final String genericParamName = GENERIC_NAME_PREFIX + (i + 1);
  // ensure not to overwrite parameter named with @Param
  if (!names.containsValue(genericParamName)) {
    param.put(genericParamName, args[entry.getKey()]);
  }
  i++;
}
return param;

5.4 POJO参数

  • Mybatis支持POJO【JavaBean】入参,参数key是POJO中属性

5.5 Map参数

  • Mybatis支持直接Map入参,map的key=参数key

5.6 Collection|List|Array等参数

  • 参数名:collection、list、array

第六章 Mybatis参数传递【#与$区别】

6.1 回顾JDBC

  • DriverManager
  • Connection
  • Statement:执行SQL语句,入参使用SQL【String】拼接方式
  • PreparedStatement执行SQL语句【预编译SQL】,入参使用占位符方式
  • ResultSet

6.2 #与$区别

  • 【#】底层执行SQL语句的对象,使用PreparedStatementd,预编译SQL,防止SQL注入安全隐患,相对比较安全。
  • 【$】底层执行SQL语句的对象使用Statement对象,未解决SQL注入安全隐患,相对不安全。

6.3 #与$使用场景

查询SQL:select col,col2 from table1 where col=? and col2=? group by ?, order by ? limit ?,?

#使用场景,sql占位符位置均可以使用#

使用场景,#解决不了的参数传递问题,均可以交给处理【如:form 动态化表名】

代码语言:javascript
复制
/**
 * 测试$使用场景
 */
public List<Employee> selectEmpByDynamitTable(@Param("tblName") String tblName);
代码语言:javascript
复制
<select id="selectEmpByDynamitTable" resultType="employee">
    SELECT
        id,
        last_name,
        email,
        salary
    FROM
        ${tblName}
</select>

第七章 Mybatis查询中返回值四种情况

7.1 查询单行数据返回单个对象

代码语言:javascript
复制
/**
 * 通过id获取员工信息
 */
public Employee selectEmpById(int empId);
代码语言:javascript
复制
<select id="selectEmpById" resultType="employee">
    SELECT
        id,
        last_name,
        email,
        salary
    FROM
        tbl_employee
    WHERE
        id=#{empId}
</select>

7.2 查询多行数据返回对象的集合

代码语言:javascript
复制
/**
 * 查询所有员工信息
 */
public List<Employee> selectAllEmps();
代码语言:javascript
复制
<select id="selectAllEmps" resultType="employee">
    SELECT
        id,
        last_name,
        email,
        salary
    FROM
        tbl_employee
</select>
  • 注意:如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身的类型。

7.3 查询单行数据返回Map集合

Map<String key,Object value>

  • 字段作为Map的key,查询结果作为Map的Value

示例代码

代码语言:javascript
复制
/**
 * 查询单行数据返回Map集合
 * @return
 */
public Map<String,Object> selectEmpReturnMap(int empId);
代码语言:javascript
复制
<!--    查询单行数据返回Map集合-->
<select id="selectEmpReturnMap" resultType="map">
    SELECT
        id,
        last_name,
        email,
        salary
    FROM
    	tbl_employee
    WHERE
    	id=#{empId}
</select>

7.4 查询多行数据返回Map集合

Map<Integer key,Employee value>

  • 对象的id作为key
  • 对象作为value

示例代码

代码语言:javascript
复制
/**
 * 查询多行数据返回Map
 * Map<Integer,Object>
 * Map<Integer,Employee>
 *      对象Id作为:key
 *      对象作为:value
 * @return
 */
@MapKey("id")
public Map<Integer,Employee> selectEmpsReturnMap();
代码语言:javascript
复制
<select id="selectEmpsReturnMap" resultType="map">
    SELECT
        id,
        last_name,
        email,
        salary
    FROM
        tbl_employee
</select>

第八章 Mybatis中自动映射与自定义映射

自动映射【resultType】 自定义映射【resultMap】

8.1 自动映射与自定义映射

  • 自动映射【resultType】:指的是自动将表中的字段与类中的属性进行关联映射
    • 自动映射解决不了两类问题
      • 多表连接查询时,需要返回多张表的结果集
      • 单表查询时,不支持驼峰式自动映射【不想为字段定义别名】
  • 自定义映射【resultMap】:自动映射解决不了问题,交给自定义映射
  • 注意:resultType与resultMap只能同时使用一个

8.2 自定义映射-级联映射

代码语言:javascript
复制
<!--    自定义映射 【员工与部门关系】-->
<resultMap id="empAndDeptResultMap" type="employee">
    <!--  定义主键字段与属性关联关系 -->
    <id column="id" property="id"></id>
    <!--  定义非主键字段与属性关联关系-->
    <result column="last_name" property="lastName"></result>
    <result column="email" property="email"></result>
    <result column="salary" property="salary"></result>
    <!--        为员工中所属部门,自定义关联关系-->
    <result column="dept_id" property="dept.deptId"></result>
    <result column="dept_name" property="dept.deptName"></result>
</resultMap>
<select id="selectEmpAndDeptByEmpId" resultMap="empAndDeptResultMap">
   SELECT
        e.`id`,
        e.`email`,
        e.`last_name`,
        e.`salary`,
        d.`dept_id`,
        d.`dept_name`
    FROM
        tbl_employee e,
        tbl_dept d
    WHERE
        e.`dept_id` = d.`dept_id`
    AND
        e.`id` = #{empId}
</select>

8.3 自定义映射-association映射

特点:解决一对一映射关系【多对一】

示例代码

代码语言:javascript
复制
<!--    自定义映射 【员工与部门关系】-->
<resultMap id="empAndDeptResultMapAssociation" type="employee">
    <!--  定义主键字段与属性关联关系 -->
    <id column="id" property="id"></id>
    <!--  定义非主键字段与属性关联关系-->
    <result column="last_name" property="lastName"></result>
    <result column="email" property="email"></result>
    <result column="salary" property="salary"></result>
    <!--        为员工中所属部门,自定义关联关系-->
    <association property="dept"
                javaType="com.atguigu.mybatis.pojo.Dept">
        <id column="dept_id" property="deptId"></id>
        <result column="dept_name" property="deptName"></result>
    </association>
</resultMap>

8.4 自定义映射-collection映射

示例代码

代码语言:javascript
复制
/**
 * 通过部门id获取部门信息,及部门所属员工信息
 */
public Dept selectDeptAndEmpByDeptId(int deptId);
代码语言:javascript
复制
<resultMap id="deptAndempResultMap" type="dept">
    <id property="deptId" column="dept_id"></id>
    <result property="deptName" column="dept_name"></result>
    <collection property="empList"
                ofType="com.atguigu.mybatis.pojo.Employee">
        <id column="id" property="id"></id>
        <result column="last_name" property="lastName"></result>
        <result column="email" property="email"></result>
        <result column="salary" property="salary"></result>
    </collection>
</resultMap>
<select id="selectDeptAndEmpByDeptId" resultMap="deptAndempResultMap">
    SELECT
        e.`id`,
        e.`email`,
        e.`last_name`,
        e.`salary`,
        d.`dept_id`,
        d.`dept_name`
    FROM
        tbl_employee e,
        tbl_dept d
    WHERE
        e.`dept_id` = d.`dept_id`
    AND
        d.dept_id = #{deptId}
</select>

8.5 ResultMap相关标签及属性

  • resultMap标签:自定义映射标签
    • id属性:定义唯一标识
    • type属性:设置映射类型
  • resultMap子标签
    • id标签:定义主键字段与属性关联关系
    • result标签:定义非主键字段与属性关联关系
      • column属性:定义表中字段名称
      • property属性:定义类中属性名称
    • association标签:定义一对一的关联关系
      • property:定义关联关系属性
      • javaType:定义关联关系属性的类型
      • select:设置分步查询SQL全路径
      • colunm:设置分步查询SQL中需要参数
      • fetchType:设置局部延迟加载【懒加载】是否开启
    • collection标签:定义一对多的关联关系
      • property:定义一对一关联关系属性
      • ofType:定义一对一关联关系属性类型
      • fetchType:设置局部延迟加载【懒加载】是否开启

8.6 Mybatis中分步查询

为什么使用分步查询【分步查询优势】?

  • 将多表连接查询,改为【分步单表查询】,从而提高程序运行效率

示例代码

一对一

代码语言:javascript
复制
/**
 * 通过员工id获取员工信息及员工所属的部门信息【分步查询】
        1. 先通过员工id获取员工信息【id、last_name、email、salary、dept_id】
        2. 再通过部门id获取部门信息【dept_id、dept_name】
 */
public Employee selectEmpAndDeptByEmpIdAssociationStep(int empId);
代码语言:javascript
复制
<select id="selectEmpAndDeptByEmpIdAssociationStep" resultMap="empAndDeptResultMapAssocationStep">
    select
        id,
        last_name,
        email,
        salary,
        dept_id
    from
        tbl_employee
    where
        id=#{empId}
</select>
代码语言:javascript
复制
/**
 * 通过部门id获取部门信息
 */
public Dept selectDeptByDeptId(int deptId);
代码语言:javascript
复制
<select id="selectDeptByDeptId" resultType="dept">
    select
        dept_id,
        dept_name
    from
        tbl_dept
    where
        dept_id=#{deptId}
</select>

一对多

代码语言:javascript
复制
/**
 * 通过部门id获取部门信息,及部门所属员工信息【分步查询】
        1. 通过部门id获取部门信息
        2. 通过部门id获取员工信息
 */
public Dept selectDeptAndEmpByDeptIdStep(int deptId);
代码语言:javascript
复制
<!--    通过部门id获取部门信息,及部门所属员工信息【分步查询】-->
<!--    1. 通过部门id获取部门信息-->
<!--    2. 通过部门id获取员工信息-->
    <select id="selectDeptAndEmpByDeptIdStep" resultMap="deptAndEmpResultMapStep">
        select
            dept_id,
            dept_name
        from
            tbl_dept
        where
            dept_id=#{deptId}
    </select>
代码语言:javascript
复制
/**
 * 通过部门Id获取员工信息
 * @param deptId
 * @return
 */
public List<Employee> selectEmpByDeptId(int deptId);
代码语言:javascript
复制
<select id="selectEmpByDeptId" resultType="employee">
    select
        id,
        last_name,
        email,
        salary,
        dept_id
    from
        tbl_employee
    where
        dept_id=#{deptId}
</select>

8.7 Mybatis延迟加载【懒加载】

需要时加载,不需要暂时不加载

优势:提升程序运行效率

语法

全局设置

代码语言:javascript
复制
<!-- 开启延迟加载 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 设置加载的数据是按需加载3.4.2及以后的版本该步骤可省略-->
<setting name="aggressiveLazyLoading" value="false"/>

局部设置

fetchType

  • eager:关闭局部延迟加载
  • lazy:开启局部延迟加载

示例代码

代码语言:javascript
复制
<association property="dept"
            select="com.atguigu.mybatis.mapper.DeptMapper.selectDeptByDeptId"
            column="dept_id"
            fetchType="eager">
</association>

8.8 扩展

  • 如果分步查询时,需要传递给调用的查询中多个参数,则需要将多个参数封装成 Map来进行传递,语法如下: {k1=v1, k2=v2....}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-04-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • day03
  • 第五章 Mybatis中参数传递问题
  • 第六章 Mybatis参数传递【#与$区别】
  • 第七章 Mybatis查询中返回值四种情况
  • 第八章 Mybatis中自动映射与自定义映射
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档