SSM框架,MyBatis框架的学习(下)

MyBatis多表映射

多表结果实体类设计技巧:

对一,属性中包含对方对象

对多,属性中包含对方对象集合

对一查询

对一查询在设计接收多表查询的结果的实体类时,设计一个对方类型的属性即可

查询的结果映射时,如果查询的列名映射到对象的属性,此属性是另一个类的对象,使用resultType方式映射便不会成功映射到此属性中,便要使用resultMap的方式处理此属性的对象

在resultMap中给对象属性赋值时,使用association标签进行赋值

association标签的属性:

  • property:对象属性的属性名
  • javaType:对象属性的类型的全限定符或全限定符的别名

在association标签内继续使用id标签和result标签对该对象属性的属性赋值

例:

Order类:

@Data
public class Order {
private Integer orderId;
private String orderName;
private Integer customerId;
private Customer customer;
}

OrderMapper.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""<https://mybatis.org/dtd/mybatis-3-mapper.dtd>">
<mapper namespace="com.ergou.mapper.OrderMapper"><resultMap id="orderMap" type="com.ergou.pojo.Order">
<!--        order的主键 id标签--><id column="order_id" property="orderId"/><result column="order_name" property="orderName"/><result column="customer_id" property="customerId"/><association property="customerName" javaType="com.ergou.pojo.Customer"><id column="customer_id" property="customerId"/><result column="customer_name" property="customerName"/></association></resultMap><select id="queryOrderById" resultMap="">SELECT * FROM t_order torJOIN t_customer turON tor.customer_id = tur.customer_idWHERE tor.order_id = #{id}</select>
</mapper>

select标签中的sql语句如下

SELECT * FROM t_order tor
JOIN t_customer tur
ON tor.customer_id = tur.customer_id
WHERE tor.order_id = 1

查询结果如下:

order_idorder_namecustomer_idcustomer_id(1)customer_name
1o111c01

测试:

@org.junit.jupiter.api.Test
public void test1() throws IOException {InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);SqlSession sqlSession = sessionFactory.openSession();OrderMapper mapper = sqlSession.getMapper(OrderMapper.class);Order order = mapper.queryOrderById(1);System.out.println(order);
}

对多查询

对多查询在设计接收多表查询的结果的实体类时,设计一个包含对方类型的集合属性即可

为了给集合属性赋值,也是要使用resultMap方式来映射

在resultMap标签中给集合属性赋值时,使用collection标签给集合属性赋值

collection标签的属性:

  • property:集合的属性名
  • ofType:集合的泛型类型

在collection标签中继续使用id标签和result标签完成集合内元素的映射即可

result标签自动映射

可以将autoMappingBehavior设置为full,进行多表resultMap映射的时候,可以省略符合列和属性命名映射规则(列名=属性名,或者开启驼峰映射也可以自定映射)的result标签

在mybatis-config.xml文件中的settings标签中设置:

将autoMappingBehavior设置的value值为FULL

<!--开启resultMap自动映射 -->
<setting name="autoMappingBehavior" value="FULL"/>

默认情况下,resultMap会自动映射一层result标签,想要多层自动映射(association标签和collection标签中),就要使用autoMappingBehavior的设置

MyBatis动态语句

if标签和where标签

判断test属性中的表达式,表达式结果为true就是sql语句中添加if标签中的sql语句,结果为false就是sql语句中不添加if标签中的sql语句

if标签的test属性的语法:(test中只能访问实体类的属性,不能访问数据库中的字段)

变量名 比较符号 数据值/变量名

如果要连接多个表达式,and表示且or表示或

 	  <select id="queryByNameAndSalary" resultType="com.ergou.pojo.Employee">SELECT * FROM t_empWHERE <if test="name != null">emp_name = #{name}</if><if test="name != null and salary != null">AND</if><if test="salary != null and">emp_salary = #{salary}</if></select>

以上例子一旦出现emp_name和emp_salary都是空的时候,WHERE关键字就失去作用,导致报错

WHERE语句的控制要让mybatis操作的话,可以使用where标签

将sql语句中的WHERE关键字替换成where标签,可以让mybatis自动控制WHERE和AND或OR的有无

where标签的作用:

  • 自动添加WHERE关键字,WHERE内任何一个if满足,都会自动添加where关键字,不满足就不会有WHERE关键字
  • 若if中的sql语句中因为动态变化出现有多余的AND或OR,就会自动去除其多余的AND或OR

以上代码用where标签改进后:

    <select id="queryByNameAndSalary" resultType="com.ergou.pojo.Employee">SELECT * FROM t_emp<where><if test="name != null">emp_name = #{name}</if><if test="salary != null and salary > 100">AND emp_salary = #{salary}</if></where></select>

set标签

set标签的作用类似于where标签,控制动态的update标签的sql语句

set标签的作用:

  • 自动去掉多余的逗号
  • 自动添加SET关键字,当set标签中的if标签都是false的结果时,就不会添加SET关键字
  	<update id="update">UPDATE t_emp <set><if test="empName != null">emp_name = #{empName},</if><if test="empSalary != null">emp_salary = #{empSalary}</if></set>WHERE emp_id = #{empId}</update>

trim标签

使用trim标签控制条件部分两端是否包含某些字符

  • prefix属性:指定要动态添加的前缀
  • suffix属性:指定要动态添加的后缀
  • prefixOverrides属性:指定要动态去掉的前缀,使用“|”分隔有可能的多个值
  • suffixOverrides属性:指定要动态去掉的后缀,使用“|”分隔有可能的多个值

例:

        <where><if test="name != null">emp_name = #{name}</if><if test="salary != null and salary > 100">AND emp_salary = #{salary}</if></where>

等同于:

<trim prefix="WHERE" prefixOverrides="AND|OR"><if test="name != null">emp_name = #{name}</if><if test="salary != null and salary > 100">AND emp_salary = #{salary}</if>
</trim>

也等同于:

<trim prefix="WHERE" suffixOverrides="AND|OR"><if test="name != null">emp_name = #{name} AND</if><if test="salary != null and salary > 100">emp_salary = #{salary}</if>
</trim>

prefix=”WHERE” 意思是当WHERE关键字缺少的时候自动加上WHERE关键字(在if中的开头处加上WHERE关键字)

prefixOverrides="AND|OR" 意思是AND关键字或OR关键字多余的时候自动去掉多余的AND和OR关键字(去掉if中的开头的AND或OR)

suffix属性和suffixOverrides属性同理,只不过操作的是结尾后缀

同理也可以替代set标签

choose/when/otherwise标签

在多个分支条件中,仅执行一个。有点类似于Java中的switch语句

  • 从上到下依次执行条件判断
  • 遇到的第一个满足条件的分支会被采纳
  • 被采纳分支后面的分支都将不被考虑
  • 如果所有的when分支都不满足,那么就执行otherwise分支
<!-- List<Employee> selectEmployeeByConditionByChoose(Employee employee) -->
<select id="selectEmployeeByConditionByChoose" resultType="com.atguigu.mybatis.entity.Employee">select emp_id,emp_name,emp_salary from t_empwhere<choose><when test="empName != null">emp_name=#{empName}</when><when test="empSalary &lt; 3000">emp_salary &lt; 3000</when><otherwise>1=1</otherwise></choose><!--第一种情况:第一个when满足条件 where emp_name=?第二种情况:第二个when满足条件 where emp_salary < 3000第三种情况:两个when都不满足 where 1=1 执行了otherwise-->
</select>

foreach标签

foreach标签的属性值

  • collection属性:指定要遍历的数据
  • item属性:遍历集合的过程中能得到每一个具体对象,在item属性中设置一个名字,将来通过这个名字引用遍历出来的对象
  • separator属性:指定当foreach标签的标签体重复拼接字符串时,各个标签体字符串之间的分隔符
  • open属性:指定整个循环把字符串拼好后,字符串整体的前面要添加的字符串
  • close属性:指定整个循环把字符串拼好后,字符串整体的后面要添加的字符串
  • index属性:这里起一个名字,便于后面引用
    • 遍历List集合,这里能够得到List集合的索引值
    • 遍历Map集合,这里能够得到Map集合的key

例:以id批量查询员工

<select id="queryBatch" resultType="com.ergou.pojo.Employee">SELECT * FROM t_empWHERE emp_id IN<foreach collection="ids" open="(" separator="," close=")" item="id" index="index">#{id}</foreach>
</select>

若ids是一个里面的数据为1和2和3三个Integer类型的变量的List集合,此处的foreach标签的结果为:

(1,2,3)

例:批量插入员工

<insert id="insertBatch">INSERT INTO t_emp(emp_name,emp_salary)VALUES <foreach collection="employees" separator="," item="employee" index="index">(#{employee.empName},#{employee.empSalary})</foreach>
</insert>

例:批量更新员工

<!-- int updateEmployeeBatch(@Param("empList") List<Employee> empList) -->
<update id="updateEmployeeBatch"><foreach collection="empList" item="emp" separator=";">update t_emp set emp_name=#{emp.empName} where emp_id=#{emp.empId}</foreach>
</update>

如果向批量更新员工这种在一个标签中出现有多个语句要运行,要设置允许运行多语句:

在数据库连接配置中找到url,在其后加上参数allowMultiQueries=true

jdbc:mysql:///mybatis-example?allowMultiQueries=true

sql片段

sql标签用于抽取重复出现的sql片段以方便重复调用

抽取重复的SQL片段

<!-- 使用sql标签抽取重复出现的SQL片段 -->
<sql id="mySelectSql">select emp_id,emp_name,emp_age,emp_salary,emp_gender from t_emp
</sql>

引用已抽取的SQL片段,使用include标签,refid属性指定sql片段的id值

<!-- 使用include标签引用声明的SQL片段 -->
<include refid="mySelectSql"/>

MyBatis拓展

Mapper按包批量扫描

在mybatis-config.xml文件中的mappers标签中,可以直接指定mapper包下的所有的接口都完成mapper文件的映射的配置:

<mappers>
<package name="com.ergou.mapper"/>
</mappers>

要求:

  1. Mapper.xml文件和mapper接口的命名必须相同
  2. 最终打包后的位置要一致,都是指定的包地址下

为了让打包后的位置一致,可以将resources下的存放mapper.xml文件的目录命名为和接口所在的包一样的文件夹结构命名(若mapper接口在java的com.ergou.mapper包下,mapper.xml应该在resource的com.ergou.mapper包下

注:在创建resources目录下的多层结构时,不是使用.分割,而是使用/分割

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/709661.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MYSQL05高级_查看修改存储引擎、InnoDB和MyISAM对比、其他存储引擎介绍

文章目录 ①. 查看、修改存储引擎②. InnoDB和MyISAM对比③. Archive引擎 - 归档④. Blackhole引擎丢数据⑤. CSV - 引擎⑥. Memory引擎 - 内存表⑦. Federated引擎 - 访问远程表⑧. Merge引擎 - 管理多个MyISAM⑨. NDB引擎 - 集群专用 ①. 查看、修改存储引擎 ①. 查看mysql提…

动态获取权限,文件管理器选择文件,I/O流

AndroidManifest.xml <?xml version"1.0" encoding"utf-8"?> <manifest xmlns:android"http://schemas.android.com/apk/res/android"xmlns:tools"http://schemas.android.com/tools"><!-- <uses-permission and…

链表的总结

题目&#xff1a;将26个英文字母储存在链表中 #include <stdlib.h> #include <stdio.h> struct list { char Ach; struct list* next; }; void create( struct list* head , char* ch ) 而这个head是定义在局部函数的变量&#xff0c;当出局部函数的时候&…

Kotlin的各种骚气语法

1.奇怪的中括号? 前几星期在群里见群友问这种是什么鬼,kt中有这种语法吗? 但其实这种是重写的操作符,分别是重写了setter和getter,类似于list[0]1这样 上面的两个方法声明如下: 不过这种语法很容易引起歧义,所以除非很适合的情况下不建议重写 ps:更多的操作符重载参考最下…

uniapp 部署h5,pdf预览

1.hubuilderx 打包h5。 2.上传部署包到服务器。 解压部署包&#xff1a;unzip h5.zip 。 3.nginx配置。 user root; worker_processes 1; #worker_cpu_affinity 0001 0010 0100 1000; #error_log logs/error.log; #error_log logs/error.log notice; error_log /var/l…

【工具类】repo是什么,repo常用命令,repo和git和git-repo的关系

1. repo 1. repo 1.1. repo是什么1.2. 安装1.3. repo 命令 1.3.1. repo help1.3.2. repo init1.3.3. repo sync1.3.4. repo upload1.3.5. repo start1.3.6. repo forall 1.4. mainfest 文件1.5. git-repo简介(非android repo)1.6. 参考资料 1.1. repo是什么 Repo 是一个 go…

【重温设计模式】桥接模式及其Java示例

【重温设计模式】桥接模式及其Java示例 桥接模式的介绍 今天我们要探讨的&#xff0c;正是一种名为“桥接模式”的设计模式。桥接模式&#xff0c;英文名Bridge Pattern&#xff0c;是一种结构型设计模式&#xff0c;它的主要目的是将抽象部分与实现部分分离&#xff0c;使得两…

Windows Docker 部署 Redis

部署 Redis 打开 Docker Desktop&#xff0c;切换到 Linux 内核。然后在 PowerShell 执行下面命令&#xff0c;即可启动一个 redis 服务 docker run -d --name redis -p 6379:6379 redis-如果需要自启动&#xff0c;加 --restart always 参数即可。 连接 Redis 使用客户端连…

python dictionary 字典

Python 字典 字典是另一种可变容器模型&#xff0c;且可存储任意类型对象。 字典的每个键值 key>value 对用冒号 : 分割&#xff0c;每个对之间用逗号(,)分割&#xff0c;整个字典包括在花括号 {} 中 ,格式如下 d {key1 : value1, key2 : value2, key3 : value3 }dict 作…

Vue依赖注入之Provide/Inject

1. 使用<script setup> 父组件 <template><div>这里是父组件的message值:{{ message }}</div><br /><div>这里是父组件的count值:{{ count }}</div><br /><classtest /> </template> <script setup> impor…

进程间的通信

进程间的通信方式&#xff1a; 1.管道 2.信号 3.消息队列 4.共享内存 5.信号灯 6.套接字 1.管道: 1.无名管道 无名管道只能用于具有亲缘关系的进程间通信 pipe int pipe(int pipefd[2]); 功能: 创建一个无名管道 …

上班族小王的考研与考证之路

上班族小王的考研与考证之路 小王是一名普通的上班族&#xff0c;他在一家互联网公司做产品经理。工作几年后&#xff0c;他感到自己的职业发展遇到了一些瓶颈&#xff0c;想要通过进一步的学习来提升自己。 小王首先想到的是考研。他认为&#xff0c;通过考研可以获得更高的…

SpringBoot项目中如何结合Mybatis进行数据库查询

在Spring Boot项目中使用Mybatis进行数据库操作是一种常见的实现方式。下面我将展示如何在Spring Boot项目中整合Mybatis。这个示例将包括几个主要部分&#xff1a;项目依赖配置、配置文件、实体类、Mapper接口及其XML配置文件、服务类、以及一个简单的控制器。 1. 项目依赖配…

Linux Centos7配置SSH免密登录

Linux Centos7配置SSH免密登录 配置SSH免密登录说明&#xff1a; 分两步 第一步、给Server A生成密钥对 第二步、给Server B授权 生成密钥对之后&#xff0c;我们可以看看它保存的目录下的文件。 接下来我们就要把Server A&#xff08;10.1.1.74&#xff09;的公钥拷贝到Se…

AI新秀Mistral:“Open AI“ 新时代

最近互联网出现不少类似“下一代openai”、“GPT-4最强竞品”、“法国AI独角兽”、“欧洲的OpenAI”、“微软新宠儿”.... 的文章&#xff0c;都会附带一张图片&#xff0c;就是下面这张&#xff1a; 那么到底发生了什么&#xff0c;出来个什么东西呢&#xff1f;就是本文的主…

跟着cherno手搓游戏引擎【28】第一个游戏!源码解读!逐行注释!

源码解读&#xff1a; GameLayer层级&#xff1a;在构造函数中&#xff1a;创建窗口和相机&#xff0c;对随机数种子初始化&#xff1b; 在OnAttach方法中&#xff1a;初始化关卡&#xff1a;加载资源初始化地图信息&#xff1b;设置字体&#xff1b; 在OnUpdate方法中&…

大白话解析LevelDB:LRUCache

文章目录 LRUCache 的实现思路lru_ 链表table_ 哈希表in_use_ 链表 LRUCache 的代码实现LRUCache 的定义LRUHandleLRUHandle::key, LRUHandle::hash, LRUHandle::valueLRUHandle::next_hashLRUHandle::next, LRUHandle::prevLRUHandle::chargeLRUHandle::in_cacheLRUHandle::re…

【Elasticsearch查询】查询环境

文章目录 Search查询环境routing&#xff08;路由&#xff09;自适应选择副本策略全局检索超时检索取消并发搜索terminate_aftersearch_typepreferencebatched_reduce_sizeSource禁止_source字段metrics用例数据从source中筛选字段查询 Storestored_fields映射查询 track_score…

从单体服务到微服务:多模式 Web 应用开发记录<三>预初始化属性

相关文章&#xff1a; 多模式 Web 应用开发记录<一>背景&全局变量优化多模式 Web 应用开发记录<二>自己动手写一个 Struts 开头先看一个简单的例子&#xff0c;这是 ftl 文件的一个表单&#xff1a; <form id"validateForm" action"#&quo…

【第十天】C++函数对象/仿函数、谓词、适配器及常见algorithm算法

一、函数对象 重载了函数调用运算符()的类 实例化的对象叫函数对象&#xff0c;也叫仿函数。 如果函数对象 有一个参数 叫&#xff1a;一元函数对象/仿函数如果函数对象 有二个参数 叫&#xff1a;二元函数对象/仿函数如果函数对象 有三个及以上参数 叫&#xff1a;多元函数对…