SSM之Mybatis(二)Mapper映射文件

2023-11-15

介绍

Mapper映射文件,作用是用来配置SQL映射语句,根据不同的SQL语句性质,使用不同的标签,mapper文件中常用的标签有<select>、<insert>、<update>、<delete>

增删改查的实现

一个简单的Mapper映射文件案例

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace:此处使用包名+文件名 的形式 -->
<mapper namespace="com.sl.mapper.ProductMapper">

    <!--select – 映射查询语句
       id:唯一标识 parameterType:参数类型,此处是根据id查询,类型为int resultType:返回值类型, 
        #{id}: 参数 -->
    <select id="selectProduct" parameterType="int" resultType="com.sl.po.Product">
        select * from products where id = #{id}
    </select>
    
    <!-- insert – 映射插入语句
      注: sql中参数最好和po中属性命名一致   
     -->
    <insert id="insertProduct" parameterType="com.sl.po.Product">
        insert into products(name,description,UnitPrice,IsNew)
        values(#{name},#{description},#{UnitPrice},#{IsNew})
    </insert>
    
    <!-- update – 映射更新语句 -->
    <update id="updateProduct" parameterType="com.sl.po.Product">
        update products set UnitPrice = #{UnitPrice},IsNew=#{IsNew} where id=#{id}
    </update>
    
    <!-- delete – 映射删除语句-->
    <delete id="deleteProduct" parameterType="int">
        delete from products where id=#{id}
    </delete>
</mapper>

Mapper 输入参数映射配置

Mybatis中parameterType为输入参数类型,可以配置为基本数据类型、基本数据包装类型、或自定义数据类型(JavaBean),Sql语句中使用#{}或${}传入参数。

#{}实现的是向prepareStatement中的预处理语句中设置参数值,sql语句中#{}表示一个占位符,使用占位符#{}可以防止sql注入,使用时不需要关心参数值的类型,mybatis将自动进行java类型和jdbc类型的转换。

可 以 将 参 数 拼 接 在 s q l 中 且 不 进 行 j d b c 类 型 转 换 , {}可以将参数拼接在sql中且不进行jdbc类型转换, sqljdbc{}可以接收简单类型值或pojo属性值,如果传入的是个简单类型,括号中只能是value,即:${value}:

注:parameterType为非必填属性,下面的情况中parameterType省略不写也不会报错。

使用示例:

<!-- ${} sql拼接 -->
<select id="selectProductByName" parameterType="string" resultType="com.sl.po.Product">
	select * from products where name like '%${value}%'
</select>
<!-- #{} 参数化 -->
<select id="selectProductByName2" parameterType="string" resultType="com.sl.po.Product">
	select * from products where name like #{value}
</select>
映射基本数据类型

映射基本数据类型时,参数名也可用value代替,#{value} 即: select * from products where id = #{value}

使用示例

<select id="selectProduct" parameterType="int" resultType="com.sl.po.Product">
        select * from products where id = #{id}
</select>
映射pojo对象

参数名必须与pojo对象属性一致,此处UnitPrice 与 IsNew为Product属性。

<!-- pojo -->
<select id="selectProductByPoJo" parameterType="com.sl.po.Product" resultType="com.sl.po.Product">
  select * from products where unitprice>#{UnitPrice} and isnew =#{IsNew} 
</select>
映射pojo封装对象

参数名必须与pojo对象属性一致,这种方法不经常使用,直接使用上面映射pojo对象的方法就可以了。

使用示例

 <!-- pojo包装对象 -->
<select id="selectProductByVo" parameterType="com.sl.po.ProductVo" resultType="com.sl.po.Product">
  select * from products where citycode=#{product.cityCode} and isnew =#{product.isNew} 
</select>
映射hashmap

参数名必须与map中的key一致
使用示例

<!-- hashmap -->
<select id="selectProductByHashMap" parameterType="hashmap" resultType="com.sl.po.Product">
	select * from products where citycode=#{cityCode} and isnew =#{isNew} 
</select>

Mapper 结果集映射配置

MyBatis的mapper映射文件中,resultType为输出结果集类型,同样支持基本数据类型及自定义数据类型。SQL语句查询后返回的结果集会映射到配置标签的输出映射属性对应的Java类型上。Mapper的输出映射有两种配置,分别是resultType和resultMap,注意两者不能同时使用

映射基本数据类型

返回结果只有一行一列时可以使用基本数据类型

使用示例

<select id="countProducts" resultType="int">
   select count(1) from products 
</select>
映射pojo对象或对象列表

返回自定义实体类类型 , 返回List<PoJo>的话,注意: resultType配置也是为PoJo类型,而不是List。查询的结果列名必须和实体类属性名一致。

使用示例

<select id="selectProductById" parameterType="int" resultType="com.sl.po.Product">
   select * from products where id = #{id}
</select>
映射hashmap或hashmap列表

返回自定义HashMap类型,与实体类的差别在于它不在乎查询的列名是什么。

使用示例

<!-- 返回hashmap -->
<select id="selectProductById2" parameterType="int" resultType="hashmap">
    select * from products where id = #{id}
</select>
<!-- 返回List<hashmap> -->
<select id="selectAllProduct2" resultType="hashmap">
    select * from products
</select>
使用resultMap映射结果集

使用resultType可以映射结果集时需要pojo的属性名和sql查询结果的列名一致才可以映射成功。如果sql查询结果集字段名和pojo的属性名不一致,则需要通过resultMap将字段名和属性名作一个对应关系(sql 查询取别名与pojo属性一致也可以) ,resultMap实质上还需要将查询结果映射到pojo对象中。resultMap可以实现将查询结果映射为复杂类型的pojo,比如在查询结果映射对象中包括pojo和list实现一对一查询和一对多查询。

使用示例

<!-- 使用resultMap映射结果集   -->
<select id="selectProductInfo" resultMap="productInfoResultMap">
    select p.`Name` pName,p.Description,c.citycode,c.`name` cName 
    from products  p
    join city c
    on p.citycode = c.citycode
</select>
<resultMap id="productInfoResultMap" type="com.sl.po.ProductInfo">
      <result property="ProductName" column="pName"/>
      <result property="CityName" column="cName"/>
</resultMap>

动态SQL

在mapper配置文件中,有时需要根据查询条件选择不同的SQL语句,或者将一些使用频率高的SQL语句单独配置,在需要使用的地方引用。Mybatis的一个特性:动态SQL,来解决这个问题。

mybatis动态sql语句是基于OGNL表达式的,主要有以下几类:

  1. if 语句 (简单的条件判断)
  2. choose (when,otherwize) ,相当于java 语言中的 switch ,与 jstl 中的choose 很类似
  3. trim (对包含的内容加上 prefix,或者 suffix 等,前缀,后缀)
  4. where (主要是用来简化sql语句中where条件判断的,能智能的处理 and or ,不必担心多余导致语法错误)、
  5. set (主要用于更新时)
  6. foreach (在实现 mybatis in 语句查询时特别有用)

if标签语句

if标签用来实现根据条件拼接sql语句,下面示例用来判断参数如果不为null,则拼接sql。

使用示例

<select id="ifTest" resultType="com.sl.po.Product">
	  select * from products where 
	  <if test="ProductName!=null">
	      name like #{ProductName}
	  </if>
	  <if test="description!=null">
	      and description like CONCAT(CONCAT('%', #{Description, jdbcType=VARCHAR}),'%')
	  </if>
</select>

当参数ProductName和Description不为null,则正常拼接处sql语句:select * from products where name like ? and description like CONCAT(CONCAT(’%’, ?),’%’)

where标签语句

当 where 中的条件使用的 if 标签较多时,这样的组合可能会导致错误, “where”标签会自动判断如果它包含的标签中有返回值的话,就在sql中插入一个‘where’,如果where标签最后返回的内容是以 and 或者or 开头的,也会被自动移除掉

使用示例

<select id="whereTest" resultType="com.sl.po.Product">
        select * from products
        <!-- where标签自动移除第一个and-->
        <where>
            <if test="Name!=null">
                and name like #{Name}
                <!--name like #{Name}-->
            </if>
            <if test="description!=null">
                and description like #{Description}
            </if>
        </where>
</select>

set标签语句

set 标签是用在更新操作的时候,功能和 where 标签元素差不多,主要是在包含的语句前输出一个 set,然后如果包含的语句是以逗号结束的话将会把该逗号忽略,如果 set 标签最终返回的内容为空的话则可能会出错(update table where id=1)

使用示例

<!-- if + set 实现按条件更新-->
 <update id="setTest">
      update products        <!-- set标签将移除最后一个“,” -->
      <set>
          <if test="cityCode!=null">
            citycode = #{cityCode} ,
          </if>
          <if test="Name!=null">
             name = #{Name} ,
          </if>
          <if test="description!=null">
              description = #{Description} ,
          </if>
      </set>
      where id =#{id}
</update>

trim标签语句

trim 元素的主要功能是可以在自己包含的内容前加上某些前缀,也可以在其后加上某些后缀,与之对应的属性是 prefix 和 suffix;可以把包含内容的首部某些内容覆盖,即忽略,也可以把尾部的某些内容覆盖,对应的属性是 prefixOverrides 和 suffixOverrides;正因为 trim 有这样的功能,它可以用来实现 where 和 set 的效果。

使用示例

<!-- if+trim 使用trim代理where-->
<select id="trimwhereTest" resultType="com.sl.po.Product">
    select * from products
<!-- 移除首部所有指定在 prefixOverrides 属性中的内容,并且插入 prefix 属性中指定的内容-->
    <trim prefix="WHERE" prefixOverrides="AND | OR">
        <if test="Name!=null">
            and name like #{Name}
        </if>
        <if test="description!=null">
            and description like #{Description}
        </if>
    </trim>

</select>

choose (when, otherwise)标签

choose标签是按顺序判断其内部when标签中的test条件出否成立,如果有一个成立,则 choose 结束。当 choose 中所有 when 的条件都不满则时,则执行 otherwise 中的sql,类似于sql server语句(case when then)

使用示例

<!-- choose + when + otherwise 只能选择一个作为查询条件 作用类似sql case when then -->
<select id="choosewhenotherwiseTest" resultType="com.sl.po.Product">
    select * from products
 <where>
    <choose>
        <when test="name!=null">
            and name like #{Name}
        </when>
        <when test="description!=null">
            and description like #{Description}
        </when>
        <otherwise>
            and unitprice > #{UnitPrice}
        </otherwise>
    </choose>
 </where>
</select>

如果name!=null,则解析出sql: select * from product where name like ?
Name==null&& description!=null,则解析出sql: select * from product where description like ?
否则:select * from product where unitprice >?

foreach标签语句

mybatis提供foreach标签,用来对一个集合进行遍历,通常是用来构建 IN 条件语句,也可用于其他情况下动态拼接sql语句。

foreach标签有以下几个属性collection, item,index,open,separator,close。

  1. collection表示需要遍历的集合
  2. item 表示每次遍历时生成的对象名
  3. index表示在迭代过程中,每次迭代到的位置)
  4. open表示开始遍历时要拼接的字符串
  5. separator表示在每次遍历时两个对象直接的连接字符串
  6. close表示结束遍历时要拼接的字符串

当使用 Map 对象(或者 Map.Entry 对象的集合)时,index 是键,item 是值。
在使用foreach的时候针对不同的参数类型, collection属性值要分为以下3种情况:
7. 如果传入的是单参数且参数类型是一个List的时候,collection属性值为list
8. 如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array
9. 如果传入的参数是多个的时候,我们就需要把它们封装成一个Map或者Object。

单个集合使用示例

<!-- 只有一个List参数时它的参数名为list,即collection="list" ;  如果参数类型时数组object[],则  collection="array" -->
<select id="foreachTest" resultType="com.sl.po.Product">
      select * from products 
      <where>
        <if test="list!=null">
          <foreach item="id" index="index"  collection="list" open="id in(" separator="," close=")">#{id}</foreach>
        </if>
      </where>
</select>

对象中含有集合属性使用示例:

<!-- 通过pojo传递list, collection值为pojo中对应的属性名-->
<select id="foreachVoTest" resultType="com.sl.po.Product">
      select * from products 
      <where>
         <if test="name!=null"> and name like #{name} </if>
         <if test="ids!=null">
            <foreach item="item" index="index"  collection="ids" open="and id in(" separator="," close=")">#{item}</foreach>
         </if>
      </where>
 </select>

Sql片段

Sql中可将重复的sql提取出来,使用时用include引用即可,最终达到sql重用的目的。

使用示例:

<select id="sqlTest" resultType="com.sl.po.Product">
        select * from products
        <where>        <!-- 引用sql片段 -->
        <include refid="sqltemp"/>
          <!-- 提取sql片段
            <if test="cityCode!=null">
               and citycode = #{cityCode}
            </if>
            <if test="Name!=null">
                and name like #{Name}
            </if>
            <if test="description!=null">
                and description like #{Description}
            </if>
             -->
        </where>
</select>
    <!-- 定义sql片段 :将where条件提取 -->
    <sql id="sqltemp">
    <if test="cityCode!=null">
               and citycode = #{cityCode}
            </if>
            <if test="Name!=null">
                and name like #{Name}
            </if>
            <if test="description!=null">
                and description like #{Description}
            </if>
    </sql>

Mapper接口动态代理

实现原理及规范

Mapper接口动态代理的方式需要手动编写Mapper接口,Mybatis框架将根据接口定义创建接口的动态代理对象,代理对象的方法体实现Mapper接口中定义的方法。

使用Mapper接口需要遵守以下规范:

  1. Mapper.xml文件中的namespace与mapper接口的类路径相同
  2. Mapper接口方法名和Mapper.xml中定义的每个statement的id相同
  3. Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同
  4. Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同

编写Mapper.xml映射文件

定义mapper映射文件ProductMapper.xml,需要修改namespace的值为 ProductMapper接口路径。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace:此处使用包名+文件名 的形式 -->
<mapper namespace="com.sl.mapper.ProductMapper">
    <!-- 返回自定义类型 注意 selectAllProduct返回的是集合,这种情况下resultType是集合包含的类型,而不能是集合本身 -->
    <select id="selectAllProduct" resultType="com.sl.po.Product">
        select * from products
    </select>
  <select id="selectProductsByVo" resultType="com.sl.po.Product">
        select * from products
        <where>
            <if test="product.cityCode!=null">
               and citycode = #{product.cityCode}
               <!-- citycode = #{cityCode} -->
            </if>
            <if test="product.Name!=null">
                and name like #{product.Name}
            </if>
            <if test="product.Description!=null">
                and description like #{product.Description}
            </if>
        </where>
  </select>  
</mapper>

编写Mapper.java接口

接口定义注意点:

  1. Mapper接口方法名和Mapper.xml中定义的statement的id相同
  2. Mapper接口方法的输入参数类型和mapper.xml中定义的statement的parameterType的类型相同
  3. Mapper接口方法的输出参数类型和mapper.xml中定义的statement的resultType的类型相同
package com.sl.mapper;
import java.util.List;
import com.sl.po.Product;
import com.sl.po.ProductVo;

public interface ProductMapper {
    
    List<Product> selectAllProduct();
    
    List<Product> selectProductsByVo(ProductVo vo);
    
}

注册Mapper.xml配置文件(或者Mapper.java接口)

修改SqlMapConfig.xml文件:

<mappers>
        <!-- 注册productMapper.xml文件 -->
        <mapper resource="mapper/productMapper.xml"></mapper> <!-- mapper.xml文件和mapper接口可以不在一个包下  -->
        
        <!-- 注册mapper接口 -->
        <!-- <mapper class="com.sl.mapper.ProductMapper"></mapper>  --> <!--通过注册mapper接口方式: Mapper接口和mapper.xml必须在同一个包下 -->
        
</mappers>

由于参数类型在mapper.xml配置文件中ParameterType配置,所以Mapper.java中接口方法只有一个参数,且类型与mapper.xml中配置的相同(mapper.xml可省略参数类型配置)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SSM之Mybatis(二)Mapper映射文件 的相关文章

随机推荐

  • openGauss学习笔记-56 openGauss 高级特性-DCF

    文章目录 openGauss学习笔记 56 openGauss 高级特性 DCF 56 1 架构介绍 56 2 功能介绍 56 3 使用示例 openGauss学习笔记 56 openGauss 高级特性 DCF DCF全称是Distrib
  • snipaste——一款强大的、免费的截图软件

    说到截图软件 大家首相想到的恐怕就是QQ 甚至有人戏称steam在中国是 吃鸡启动器 QQ在很多人眼中就是一款截图软件 诚然 日常使用QQ截个图没什么问题 但是和snipaste比起来确实小巫见大巫 加之很多朋友并不喜欢打开电脑就启动QQ
  • HashMap源码分析

    HashMap源码分析 HashMap是Java集合框架中常用的数据结构之一 它提供了一种用于存储键值对的哈希表实现 在本文中 我们将深入源码 详细分析HashMap的实现原理和关键方法 HashMap的基本结构是一个数组和一组链表 或红黑
  • Spring Boot参考指南——Starter POMs

    13 2 Gradle Gradle用户可以直接在它们的dependencies节点处导入 starter POMs 跟Maven不同的是 这里没有用于导入共享配置的 超父 super parent apply plugin java re
  • unity 毛笔字笔触(画图)

    毛笔字笔触 RawImage using System Collections Generic using UnityEngine using UnityEngine UI using Random UnityEngine Random p
  • redis相关

    如果redis没有设置expire 他是否默认永不过期 清理线上Redis没有设置过期时间的key 青苔小榭的博客 CSDN博客 如何给Redis中未设置过期时间key添加过期时间 知乎 Redis中的几种更新策略 如何实现redis数据的
  • git配置与常用命令

    git配置与常用命令 git是一个开源的分布式版本控制系统 可以有效 高速地处理从很小到非常大的项目版本管理 gitbash是一个适用于Windows环境的应用程序 它为Git命令行体验提供了一个仿真层 相当于在window上通过git b
  • Linux下tar简介

    最常见的压缩与解压命令是tar 1 命令格式 tar 参数选择 压缩后的文件名 需要压缩的文件 文件名 压缩命令 例如 tar cf all tar jpg tar 参数选择 需要解压的文件名 解压命令 例如 tar xf all tar
  • mysql 单表字段多少合适_公司DBA关于MySQL开发的一点经验

    尽量不要让数据库做过多运算 数据库主要是用来存储的 我们应避免让数据库做运算 比如写定时任务 存储过程等 复杂的计算应该在程序代码中实现 我们应该尽量简单的使用数据库 控制数据量 一年内单表数据量一般含char不超过500W条 我们需要合理
  • R语言特征提取与特征选择

    数据决定了机器学习的上限 而算法只是尽可能逼近这个上限 这里的数据指的就是经过特征工程得到的数据 特征工程指的是把原始数据转变为模型的训练数据的过程 它的目的就是获取更好的训练数据特征 使得机器学习模型逼近这个上限 特征工程能使得模型的性能
  • C++虚函数基础

    c 静态成员变量和静态成员函数 类的静态成员有两种 静态成员变量和静态成员函数 静态成员变量本质上是全局变量 静态成员函数本质也是全局函数 静态成员变量和静态成员函数都可以使用类名去调用 非静态成员的访问方式 对象名 成员名 需要指明被访问
  • 1.4 安装git

    官网下载 https git scm com download win 下载后双击安装即可 安装过程中需要把git base勾上 因为后面开发需要用到它 本文由小韦云原创 转载请注明出处 https www bctos cn doc 4 1
  • python 提取指定目录下的图片名称

    导入需要的包 import os 图片目录 dir path D happy丶 Pictures Camera Roll imageName list os listdir dir path imagePath list os path j
  • 真的!!!两行css代码实现瀑布流,html,css最简单的瀑布流实现方式且没有缺点!

    两行css如下 列间距 可有可无 默认30px column gap 0 效果图 说明 不存在一边列表过长问题 很均匀 没有缺点 抱歉 有坑 但可以一链代码解决 这个列表显示顺序是 左边 123右边456 不符合正常展示逻辑 然后可以使用j
  • Spring Cloud RestTemplate调用IP或域名

    在SpringCloud的项目中 我们使用了自动配置的OAuth2RestTemplate RestTemplate 但是在使用这些restTemplate的时候 url必须是服务的名称 如果要调用真实的域名或者ip的url 会有错误 如下
  • 数据库:drop、truncate、delete三者删除的区别

    一 用法和区别 drop drop table 表名 删除内容和定义 并释放空间 执行drop语句 将使此表的结构一起删除 truncate 清空表中的数据 truncate table 表名 删除内容 释放空间但不删除定义 也就是保留表的
  • React与响应式系统

    响应式系统与React 1 React的历史与应用 React的历史 2010年Facebook在其php生态中引入了xhp框架 首次引入了组合式组件的思想 启发了后来的React的设计 2011年Jordan Walke创造了FaxJs
  • 服务器可以放置多少个网站

    服务器可以放置多少个网站 一 网站大小 能影响一个网站大小的因素是比较多的 例如网站的设计 网站里的内容大小 通常网站尺寸比较大 动态页面比较多的 例如视频网站和小说网站 通常对储存的要求也会比较高 所以网站大小必然还是比较大的 一台主机上
  • linux查看ip地址命令ipconfig命令不存在解决方法

    linux查看ip地址命令ipconfig命令不存在 在新版的Linux发行版中 ipconfig已经不行了 不能使用了 那么 Linux查看ip地址应该使用什么命令呢 如何在Linux命令行中查找系统的IP地址 对于许多Linux用户来说
  • SSM之Mybatis(二)Mapper映射文件

    介绍 Mapper映射文件 作用是用来配置SQL映射语句 根据不同的SQL语句性质 使用不同的标签 mapper文件中常用的标签有