不是原创,整理尚硅谷的内容得到的

六、自定义映射ResultMap

①处理字段和属性名不一致的情况

处理字段名和属性名不一致的方式一:为表中字段增加别名:

select emp_id empId,emp_name empName,age,gender  from t_emp where emp_id=#{empId}

注意,表中没有empId和empName两个字段,MyBatis是根据查询结果的字段名为属性名赋值,这边字段名和属性名不一致,肯定是对应不上的。

方式二:设置一个全局配置

在全局配置中设置标签:

<setting name="mapUnderscoreToCamelCase" value="true"/>

这个标签必须要求符合MySQL和java命名规范才可以继续,Mybatis中的核心配置文件中设置一个全局配置,自动将下划线转化为驼峰

方式三:使用resultMap进行操作

<resultMap id="EmpAndDept" type="Emp">   <id column="emp_id" property="empId"></id><result column="emp_name" property="empName"></result><result column="age" property="age"></result><result column="gender" property="gender"></result>
</resultMap>

最上面id表示这个标签的唯一标识(这个id要和sql语句进行关联),type表示要处理的实体类

result处理普通字段和实体类对应关系

id用于处理主键

②处理多对一的映射关系(主要有三种方式):

方式一:多表联查,也就是用级联的方式,这时也是设置一个ResultMap就可以了,具体看下面这段代码:

<resultMap id="EmpAndDept" type="Emp"><id column="emp_id" property="empId"></id><result column="emp_name" property="empName"></result><result column="age" property="age"></result><result column="gender" property="gender"></result><result column="dept_id" property="dept.deptId"></result><result column="dept_name" property="dept.deptName"></result>
</resultMap>
<select id="getEmpAndDeptByEmpIdOne" resultMap="EmpAndDept">select t_emp.*,t_dept.*from t_empleft join t_depton t_emp.dept_id = t_dept.dept_idwhere t_emp.emp_id=#{empId}
</select>

现在要通过员工id获取员工部门id和员工的全部信息,这时典型的多对一(多个员工对应一个部门),那么要在员工信息里面多一个属性(这个属性就是部门),这个时候MyBatis进行查询的时候,对于查询的结果dept_id和dept_name,由于我们在员工类中没有这两个属性,因此没有办法进行赋值,于是要用resultMap进行对应。

方式二:使用association处理映射关系

<resultMap id="empAndDeptResultMap" type="Emp"><id column="emp_id" property="empId"></id><result column="emp_name" property="empName"></result><result column="age" property="age"></result><result column="gender" property="gender"></result><association property="dept" javaType="Dept"><id column="dept_id" property="deptId"></id><id column="dept_name" property="deptName"></id></association>
</resultMap>

标签property是用来表示要处理的属性,而javaType是设置要处理的属性的类型,这里本该写全类名,但是由于我在核心配置文件中为类型起了别名,所以可以这样写。

方式三:分布查询,写成两个sql语句

查询一:

 <resultMap id="empAndDeptByStepResultResultMap" type="Emp"><id column="emp_id" property="empId"></id><result column="emp_name" property="empName"></result><result column="age" property="age"></result><result column="gender" property="gender"></result><association property="dept" fetchType="lazy"                     select="com.atguigu.mybatis.mapper.DeptMapper.getEmpAndDeptByStepTwo"column="dept_id"></association></resultMap><select id="getEmpAndDeptByStepOne" resultMap="empAndDeptByStepResultResultMap">select *from t_emp where emp_id=#{empId}</select>

查询二:

<select id="getEmpAndDeptByStepTwo" resultType="Dept">select *from t_dept where dept_id=#{deptId}
</select>

说白了就是查两次,第一次查询部门id,第二次用查到的部门id去查询部门的信息;

这时association标签中字段有下面的含义:

Properties表示设置需要处理映射关系的属性的属性名

select表示我要跳转到哪个sql语句,注意这边(namespace+sql的id构成sql的唯一标识,也就是Mapper接口的抽象方法的全类名)

column表示将sql查询结果的某个字段作为分步查询的条件

这种方法单独有优势:

可以实现懒加载,也就是如果我单独只要获取员工姓名,那么也就不需要进行加载dept的信息了,此时只需要(核心)配置下面两个标签就可以了,也可以通过上面所描述的fetchType="lazy"标签来进行处理。

<!--延迟加载全局开关--><setting name="lazyLoadingEnabled" value="true"/>
<!--   aggressiveLazyLoading 当开启时,任何sql查询的加载会导致所有属性的加载     --><setting name="aggressiveLazyLoading" value="false"/>

③处理一对多的映射关系

下面要查询一个部门里面的所有员工信息,那么要为部门类添加一个list这个属性,为这个属性加上泛型:员工。这时候只有两种处理方式:多步查询和collection。

方式一:使用Collection进行处理

<resultMap id="DeptAndEmpResultMap" type="Dept"><id column="dept_id" property="deptId"></id><result column="dept_name" property="deptName"></result><collection property="emps" ofType="Emp"><id column="emp_id" property="empId"></id><result column="emp_name" property="empName"></result><result column="age" property="age"></result><result column="gender" property="gender"></result></collection></resultMap>

<!-- 要处理的是Dept,因为Dept中有一个属性找不到映射关系,这边是处理映射关系的,所以Type是dept-->

ofType用于处理表与集合的映射关系,下面就和Collection是一样的了。

方式二:使用多步查询

先查询部门id,再根据部门id查询员工信息

两个接口分别如下:

Dept getDeptAndEmpByStepOne(@Param("deptId") Integer deptId);
List<Emp> getDeptAndEmpByStepTwo(@Param("deptId") Integer deptId);

对应的映射文件如下

resultMap id="DeptAndEmpByStepOne" type="Dept"><id column="dept_id" property="deptId"></id><result column="dept_name" property="deptName"></result><collection property="emps"select="com.atguigu.mybatis.mapper.EmpMapper.getDeptAndEmpByStepTwo"column="dept_id">
<!--以dept_id为条件,我们是先查询部门的dept_id再根据部门的dept_id查询我要的emp的信息--></collection></resultMap><select id="getDeptAndEmpByStepOne" resultMap="DeptAndEmpByStepOne">select*from t_dept where dept_id=#{deptId}</select>
<!--    List<Emp> getDeptAndEmpByStepTwo(@Param("deptId") Integer deptId);--><select id="getDeptAndEmpByStepTwo" resultType="Emp">select *from t_emp where dept_id=#{deptId}</select>

这个没有什么创新,和前面也大同小异

七、动态sql

动态sql就是几个标签

标签一:if标签

if标签:通过if判断标签中的内容是否有效,即标签中的内容是否会拼接到SQL中

比方说,服务器获取到信息后,如果得到的是空表示初始状态,如果获取的是空字符串表示客户没有填写信息,那么通过if标签可以判断是不是要将获取的信息拼接到sql语句当中,比如说:

<!--    List<Emp> getEmpByCondition(Emp emp);根据条件查询员工信息--><select id="getEmpByConditionOne" resultType="Emp">select * from t_emp where <if test="empName!=null and empName != ''">语句emp_name = #{empName}</if><if test="age!=null and age !=''">
<!-- 目标是为了拼接到我的Emp对象当中-->and age=#{age}</if><if test="gender!=null and gender !=''"><!-- 目标是为了拼接到我的Emp对象当中-->and gender=#{gender}</if></select>

表示如果字符串不是空对象或者不为空,那么才进行对sql的拼接,值得注意的是这边要手动添加and这一信息。

问题一:如果第一个emp_name是空,那么sql语句就变为

select * from t_emp where and 。。。。这显然有问题;

问题二:如果全是空那么,sql语句select * from t_emp where也有问题

这时可以添加1=1,然后if第一个标签中添加and即可,即:

<!--    List<Emp> getEmpByCondition(Emp emp);根据条件查询员工信息--><select id="getEmpByConditionOne" resultType="Emp">select * from t_emp where 1=1<if test="empName!=null and empName != ''">and emp_name = #{empName}</if><if test="age!=null and age !=''">
<!-- 目标是为了拼接到我的Emp对象当中-->and age=#{age}</if><if test="gender!=null and gender !=''"><!-- 目标是为了拼接到我的Emp对象当中-->and gender=#{gender}</if></select>

标签二:where标签,where标签有三个功能

作用一:自动生成where关键字

作用二:自动将多余的前面的and去掉,内容后多余的and没有办法去掉

作用三:where标签中没有任何一个标签成立,where中没有任何功能

可以发现,运用where标签也可以解决上面的问题。

<select id="getEmpByConditionTwo" resultType="Emp">select *from t_emp<where><if test="empName!=null and empName != ''">emp_name = #{empName}</if><if test="age!=null and age !=''"><!-- 目标是为了拼接到我的Emp对象当中-->and age=#{age}</if><if test="gender!=null and gender !=''"><!-- 目标是为了拼接到我的Emp对象当中-->and gender=#{gender}</if></where>
</select>

标签三:trim标签

     prefix与suffix:在标签前面后者后面添加指定内容prefixOverWrides和suffixOverrides:在标签中内容前面或者后面去掉指定内容

比方说(这个代码表示前面接上where后面去掉and然后进行操作):

<select id="getEmpByCondition" resultType="Emp">select* from t_emp<trim prefix="where" suffixOverrides="and"><if test="empName!=null and empName != ''">emp_name = #{empName} and</if><if test="age!=null and age !=''"><!-- 目标是为了拼接到我的Emp对象当中-->age=#{age} and</if><if test="gender!=null and gender !=''"><!-- 目标是为了拼接到我的Emp对象当中-->gender=#{gender}</if></trim>
</select>

标签四:choose...when...otherwise(if...else if...else)进行处理操作,

其实也就是switch。。。case结构

<!--    List<Emp>getEmpByChoose(Emp emp);--><select id="getEmpByChoose" resultType="Emp">select *from t_emp<where><choose><when test="empName!=null and empName != ''">emp_name = #{empName}</when><when test="age!=null and age !=''">age=#{age}</when><when test="gender!=null and gender !=''">gender=#{gender}</when></choose></where></select>

标签四:forEach标签

Collection:设置要循环的数组或者集合
item:用一个数组表示数组或集合中的每一个数据
separator:用于设置每一次循环数据的分隔符
open:循环的所有内容,以什么开始
close:循环的所有内容,以什么结束

如下面所示:

<!--    void insertMoreEmp(@params(list)List<Emp> emps);--><insert id="insertMoreEmp">insert into t_emp values
<!-- item 表示数组或者集合中的元素数据--><foreach collection="list" item="emp" separator=",">(null,#{emp.empName},#{emp.age},#{emp.gender},null)</foreach></insert><!--    void deleteMoreEmp(@Param("empIds") Integer[] empIds);--><delete id="deleteMoreEmp">delete from t_emp where emp_id in
<!-- open和close用来设置左括号和右括号以什么开始--><foreach collection="empIds" item="empId" separator="," open="(" close=")">#{empId}</foreach></delete>

标签五:sql标签

所谓sql标签就是可以记录一段公共sql片段,在使用的地方通过include标签进行引入

比如说,如下所示:

<sql id="empColumns">emp_id,emp_name,age,gender,dept_id
</sql>

<include></include>标签,在需要引用的地方,进行引用

<select id="getEmpByCondition" resultType="Emp">select <include refid="empColumns"></include> from t_emp<trim prefix="where" suffixOverrides="and"><if test="empName!=null and empName != ''">emp_name = #{empName} and</if><if test="age!=null and age !=''"><!-- 目标是为了拼接到我的Emp对象当中-->age=#{age} and</if><if test="gender!=null and gender !=''"><!-- 目标是为了拼接到我的Emp对象当中-->gender=#{gender}</if></trim>
</select>

明哥复习Mybatis(2)相关推荐

  1. 明哥复习MyBatis(1)

    这不是原创,借鉴尚硅谷的,不是原创 一.核心配置文件详解 ① <properties resource="jdbc.properties"/> 这个标签用于引入prop ...

  2. 【明哥报错簿】之 mybatis异常invalid comparison: java.util.Date and java.lang.String

    [明哥报错簿]之 mybatis异常invalid comparison: java.util.Date and java.lang.String 参考文章: (1)[明哥报错簿]之 mybatis异 ...

  3. 继明哥的否定之后,java泰又出新作!明哥接码!

    上次做那个系统是swing+jdbc实现的,无奈被明哥一句否定,数据库连接完全体现不了数据结构的作用,哎,这就是向小弟施加压力呀.人无压力不出油,经过10天的努力,终于李刚的通讯录更新为1.1版本! ...

  4. 华为云官网负责人明哥:我们是如何做到门面不倒,8个月挑战业界翘楚?

    本文分享自华为云社区<华为云官网负责人明哥:我们是如何做到门面不倒,8个月挑战业界翘楚?>,原文作者:华为云社区精选 . 4月的一个周五傍晚,刚刚结束一场语音会议的明哥,拿起桌上的咖啡,一 ...

  5. 【学习笔记】明哥聊求职第二季

    个人认为笔记记录的建议并不一定是对的.但针对这些问题,需要有自己的准备和思考,当然要诚实,坦然面对自己优劣 000:面试过程中,一定要明白所有问题都不是闲聊.要缜密思考,谨慎回答 001:你为什么离开 ...

  6. python 复制dict_Python高级数据类型之字典、集合【明哥陪你学Python-六】

    上一篇我们简单对Python的基础数据类型做了说明和讲[Python高级数据类型之列表.元组],本篇我们继续针对Python的数据类型进行高级数据类型的介绍. 我们来先看一张图表: 字典(dict) ...

  7. 三年时间做到年薪百万,推荐明哥的职场心得

    前段时间有朋友在圈子问怎么做职场,刚好认识的朋友中有人在做职场,因此推荐给大家. 明哥 在职场已经有十年有余,做过上百个项目,自己业余时间除了创作小说,写一些技术文章,同时也在分享自己的成长经历,职场 ...

  8. 明哥-带你三步开发JavaSE跨平台视频播放器

    前言 这两天有一个学生来问我,说明哥JavaSE能不能开发一个简单版的视频播放器,网上的代码都太多了,这不,我这就写了一个简易版本的,利用 VLC media player 配合GUI 写了一个简单的 ...

  9. 【明哥版】2020最新Android Studio Win10 安装教程

    前言 本篇文章主要明哥主要讲解Android开发环境的搭建,也就是Android Studio安装教程,为什么要写这篇文章呢?主要还是用于辅助明哥教学,方便学员查询资料,按照本片文章课下搭建开发环境. ...

最新文章

  1. php 的webservice类库NuSoap介绍
  2. java弱引用弱点_终于有人把Java强、软、弱、虚四种引用知识点整理出来了
  3. MyObjectUtil对象工具类
  4. 浙江省经信委与新华三签署战略合作协议
  5. js java post提交_如何从Express.js发送Post请求到另一个服务器(Java)?
  6. Anacoda 的 Python 包管理器 Conda 的常用使用命令
  7. BZOJ3591 最长上升子序列(状压dp)
  8. Android Gradle 完整指南(转)
  9. Java设计模式之工厂模式
  10. eoLinker-API_Shop_知识类API调用的代码示例合集:驾考题库、ISBN书号查询等
  11. windows11的ps界面字体显示过小
  12. linux下dbf是什么文件,DBF文件怎么打开?DBF文件的打开方法教程
  13. 计算机系统引导失败怎么办,win7系统引导选择失败怎么办|win7系统引导选择失败的解决方法...
  14. picker多选 vant_Vant picker 多级联动操作
  15. 微信小程序实现锚点效果 scroll-view的scroll-into-view属性
  16. 水星路由器wan口ip显示0_路由器WAN口获取不到IP地址怎么办?
  17. 【190319】VC++ C/S结构视频聊天软件源码源代码
  18. lqc_shell批量操作linux主机
  19. 微信公众号运营商,如何选择适合自己的微信第三方平台?
  20. 武汉理工大学计算机学院分流,2018考生来信——我在读的武汉理工大学

热门文章

  1. 面试题:说一说你对HashMap的理解
  2. 人脸识别SeetaFace2原理与代码详解
  3. 使用org.apache.pdfbox 2.x PDF 转Doc 转图片 转字符串
  4. 联想卡在logo界面_联想电脑卡在logo界面 联想电脑卡在载入界面怎么办
  5. python真的好难过张嘉洵_现在好难过怎么办?
  6. Teamviewer 15.0 中文版 — 远程控制软件
  7. 吃掉坤坤网页游戏源码
  8. mac远程链接windows桌面
  9. matplotlib 中深色颜色选取
  10. 未完成版本链表通讯录脑壳疼只做了一个添加