MyBatis学习笔记:进阶知识2

MyBatis 作为一款优秀的持久层框架,在 Java 开发中占据着重要地位。它简化了数据库操作,提供了灵活且高效的数据访问方式。本文将深入探讨 MyBatis 的核心功能,包括分页查询、联表查询、动态 SQL 以及代码自动生成,并结合实际案例进行详细分析,帮助读者更好地理解和应用这些功能。

一、MyBatis 框架回顾

在深入学习 MyBatis 的高级特性之前,我们先来回顾一下 MyBatis 框架的基础知识。MyBatis 框架主要用于数据库访问,它通过将 SQL 语句与 Java 代码分离,实现了数据持久化层的解耦。以下是 MyBatis 框架的一些关键知识点:

(一)注解方式实现单表操作

MyBatis 提供了一系列注解,如@Select@Insert@Delete@Update,用于在接口方法上直接编写 SQL 语句,实现对单表的增删改查操作。这种方式简单直观,适用于简单的数据库操作场景。

(二)MyBatis 的优化策略

  1. 日志添加
    • 引入log4jjar包,并添加log4j.properties配置文件,以便在开发过程中更好地跟踪和调试 MyBatis 的执行过程,帮助开发者快速定位问题。
  2. 实体类别名设置
    • 为实体类起别名,在编写 SQL 语句时可以直接使用别名代替完整的类名,使 SQL 语句更加简洁易读,提高代码的可维护性。
  3. 数据源信息抽取
    • 将数据源的信息抽取到属性文件中,通过${key}的方式引用属性值。这样,在切换数据源或修改数据库连接信息时,无需修改代码,只需调整属性文件即可,增强了程序的灵活性和可配置性。

(三)其他常用功能

  1. 获取递增 ID 值
    • 在执行插入操作时,通过设置<insert useGeneratorKey="true" keyProperty="属性">,可以方便地获取数据库自动生成的递增 ID 值,并将其赋值给实体类的相应属性。
  2. 多参处理
    • 使用@Param("名称")注解为方法参数命名,然后在 SQL 语句中通过#{名称}引用参数,解决了多参数传递的问题,使 SQL 语句与方法参数的对应关系更加清晰。
  3. 特殊符号处理
    • 当 SQL 语句中包含特殊符号时,可以使用转义符或者<![CDATA[sql]]>的方式进行处理,避免因特殊符号导致的 SQL 语法错误。
  4. 模糊查询实现
    • 通过concat("%",#{},"%")函数,在查询条件中实现模糊查询,方便根据关键字搜索相关数据。
  5. 属性名与列名不一致处理
    • 提供了两种解决方案。一是为查询的列起别名,使其与属性名一致;二是通过ResultMap标签建立列名和属性名的映射关系,确保数据的正确封装。

二、分页查询

在实际应用中,分页查询是常见的需求。MyBatis 本身没有提供分页功能,但可以通过集成分页插件来实现。以 PageHelper 插件为例,详细介绍分页查询的实现步骤。

(一)引入 PageHelper 依赖

在项目的pom.xml文件中添加 PageHelper 的依赖:

<dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>6.0.0</version>
</dependency>

(二)配置 MyBatis

在 MyBatis 的配置文件中,添加如下插件配置:

<plugins><!-- com.github.pagehelper为PageHelper类所在包名 --><plugin interceptor="com.github.pagehelper.PageInterceptor"><property name="param1" value="value1"/></plugin>
</plugins>
<select id="selectAll" resultType="java.util.Map">select * from tbl_emp e join tbl_dept d on e.did = d.dept_id
</select>

  1. 使用 association 标签(第二种方案)
    • 优点:通过定义实体类之间的关联关系,使代码结构更加清晰,属性调用更加直观。
    • 缺点:需要创建额外的实体类和映射配置。
    • 示例代码:
public List<Emp> selectAll01();
<resultMap id="EmpMapper" type="org.example.entity.Emp"><id column="emp_id" property="id"/><result column="emp_name" property="name"/><result column="emp_job" property="job"/><result column="emp_salary" property="salary"/><result column="did" property="di"/><!-- association:表示多对一的标签 property: 该类中实体类的属性名 javaType:该属性所属于的类型 --><association property="dept" javaType="org.example.entity.Dept"><id column="dept_id" property="id"/><result column="dept_name" property="name"/><result column="dept_loc" property="loc"/></association>
</resultMap>
<select id="selectAll01" resultMap="EmpMapper">select * from tbl_emp e join tbl_dept d on e.did = d.dept_id
</select>

(二)一对多关系查询

  1. 使用 Map 类(第一种方案,省略)

    • 与多对一关系中使用 Map 集合类类似,但在一对多场景下,使用 Map 可能会导致数据结构不够清晰,维护困难。
  2. 使用 Collection 标签(第二种方案)

    • 优点:能够清晰地表达一对多的关系,通过配置Collection标签,可以方便地获取关联的多个对象集合。
    • 缺点:配置相对复杂,需要仔细定义映射关系。
    • 示例代码(查询部门信息并携带部门对应的员工信息):
public Dept selectById(int id);
public List<Dept> selectAll();
<resultMap id="DeptMapper" type="org.example.entity.Dept"><id column="dept_id" property="id" /><result column="dept_name" property="name"/><result column="dept_loc" property="loc"/><!-- collection:表示一对多的标签 property:集合对应的属性名 ofType:该属性集合的泛型类型 --><collection property="emp" ofType="org.example.entity.Emp"><id column="emp_id" property="id"/><result column="emp_name" property="name"/><result column="emp_job" property="job"/><result column="emp_salary" property="salary"/><result column="did" property="did"/></collection>
</resultMap>
<select id="selectById" resultMap="DeptMapper">select * from tbl_emp e join tbl_dept d on e.did = d.dept_id where dept_id = #{id}
</select>
<select id="selectAll" resultMap="DeptMapper">select * from tbl_emp e join tbl_dept d on e.did = d.dept_id
</select>

(三)联表查询的 SQL 优化

  1. 合理选择连接方式
    • 根据业务需求和数据特点,选择合适的连接方式(如INNER JOINLEFT JOINRIGHT JOIN),避免不必要的数据冗余和查询性能问题。
  2. 建立合适的索引
    • 对关联字段建立索引,可以提高联表查询的效率。例如,在员工表的did字段和部门表的dept_id字段上建立索引。

四、动态 SQL 标签

在实际应用中,查询条件往往是动态变化的。MyBatis 提供了动态 SQL 标签,用于根据不同的条件动态拼接 SQL 语句,提高代码的灵活性和可维护性。

(一)动态 SQL 标签介绍

  1. <trim>标签
    • 通过修剪 SQL 语句的开头和结尾来动态生成 SQL 片段。可以去除不必要的 SQL 关键字或条件语句,并根据属性定义修剪规则。
  2. <where>标签
    • 用于在生成的 SQL 语句中添加WHERE子句。它能自动处理条件语句的前缀,在有条件语句存在时添加WHERE关键字,并去除 SQL 中的第一个AND标签。
  3. <set>标签
    • 用于在生成的 SQL 语句中添加SET子句,主要用于更新操作,根据条件动态生成需要更新的列。
  4. <foreach>标签
    • 用于在 SQL 语句中进行循环操作,可遍历集合或数组,并根据指定模板将元素插入到 SQL 语句中,常用于批量删除和批量添加操作。
  5. <if>标签
    • 根据指定条件决定是否包含某个 SQL 语句片段,实现条件判断。
  6. <choose><when><otherwise>标签
    • 类似于 Java 中的switch语句,<choose>根据条件选择执行不同的 SQL 语句片段,<when>定义条件分支,<otherwise>在所有<when>条件不匹配时执行的 SQL 语句片段。

(二)示例代码

  1. 使用<if>标签实现多条件查询
public List<Emp> selectByCondition01(@Param("name") String name, @Param("job") String job, @Param("salary") Double salary);
<select id="selectByCondition01" resultMap="EmpMapper">select * from tbl_emp<where><if test="name!=null and name!=''">and emp_name like concat('%',#{name},'%')</if><if test="job!=null and job!=''">and emp_job=#{job}</if><if test="salary!=null">and emp_salary=#{salary}</if></where>
</select>
  1. 使用<choose><when><otherwise>标签实现条件分支查询
<select id="selectByCondition02" resultMap="EmpMapper">select * from tbl_emp<where><choose><when test="name!=null and name!=''">and emp_name like concat('%', #{name}, '%')</when><when test="job!=null and job!=''">and emp_job=#{job}</when><when test="salary!=null">and emp_salary=#{salary}</when></choose></where>
</select>
  1. 使用<foreach>标签实现批量删除和批量添加
    • 批量删除示例:
public int batchDelete(@Param("ids") Integer[] ids);
<delete id="batchDelete">delete from tbl_emp where id in<foreach collection="ids" item="i" open="(" close=")" separator=", ">#{id}</foreach>
</delete>
  • 批量添加示例:
public int batchInsert(@Param("emps") List<Emp> emps);
<insert id="batchInsert">insert into tbl_emp(emp_name,emp_job,emp_salary,did) values<foreach collection="emps" item="e" separator=",">(#{e.name},#{e.job},#{e.salary},#{e.did})</foreach>
</insert>

(三)动态 SQL 的应用场景

  1. 多条件组合查询
    • 根据用户输入的不同查询条件,动态生成包含相应条件的 SQL 语句,如电商平台中的商品搜索功能,根据品牌、价格范围、规格等多个条件进行筛选查询。
  2. 动态更新操作
    • 根据业务规则,只更新部分字段。例如,用户信息修改功能,仅更新用户修改的字段,而不是全部字段。
  3. 批量操作
    • 如批量删除选中的记录或批量插入多条数据,提高操作效率,减少数据库交互次数。

五、MyBatis 代码自动生成

随着项目的不断发展,编写大量的 MyBatis 映射文件和实体类会变得繁琐且容易出错。MyBatis 提供了代码自动生成工具,可以根据数据库表结构快速生成实体类、映射文件和 DAO 接口等代码,提高开发效率。

(一)使用 MyBatis Generator 工具

  1. 配置文件编写
    • 创建一个generatorConfig.xml配置文件,指定数据库连接信息、生成代码的目标路径、实体类包名、映射文件包名等参数。例如:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfigurationPUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN""http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration><context id="DB2Tables" targetRuntime="MyBatis3"><jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"connectionURL="jdbc:mysql://localhost:3306/mydb?serverTimezone=UTC"userId="root"password="123456"></jdbcConnection><javaModelGenerator targetPackage="com.example.entity" targetProject="src/main/java"><property name="enableSubPackages" value="true"/><property name="trimStrings" value="true"/></javaModelGenerator><sqlMapGenerator targetPackage="com.example.mapper" targetProject="src/main/resources"><property name="enableSubPackages" value="true"/></sqlMapGenerator><javaClientGenerator type="XMLMAPPER" targetPackage="com.example.dao" targetProject="src/main/java"><property name="enableSubPackages" value="true"/></javaClientGenerator><table tableName="tbl_emp" domainObjectName="Emp"/><table tableName="tbl_dept" domainObjectName="Dept"/></context>
</generatorConfiguration>
  1. 执行生成命令
    • 在命令行中执行 MyBatis Generator 的命令,或者在项目中通过 Maven 插件执行。执行后,将根据配置生成相应的实体类、映射文件和 DAO 接口。

(二)代码生成器的优势与注意事项

  1. 优势
    • 大大提高开发效率,减少手动编写代码的工作量,降低出错率。
    • 保证代码结构的一致性,便于团队协作和项目维护。
  2. 注意事项
    • 生成的代码可能需要根据实际需求进行适当调整,如添加自定义的方法、修改注释等。
    • 当数据库表结构发生变化时,需要及时重新生成代码,以确保代码与数据库的一致性。

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

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

相关文章

2020-12-07 光棍数

由光棍数的特征可推导其商的个位数不存在偶数且只有1、3、7、9这4个数。一个数可匹配多个光棍数且必定是中间隔着0的循环数。 void 光棍数(int n) {//缘由http://ask.csdn.net/questions/3444069 做乘法运行时间超长int w 0; long long x 111111111111111, j 0;//j x*n;/…

【Linux系统】—— 初识 shell 与 Linux 中的用户

【Linux系统】—— 初识shell 与 Linux 中的用户 1 Xshell 运行原理1.1 命令行的组成1.2 外壳程序 2 Linux中的用户2.1 两种用户2.2 创建普通用户2.3 用户切换2.3.1 普通->超级2.3.2 超级->普通 3 指令的短暂提权3.1 为什么要提权3.2 sudo 指令3.3 人人都能提权吗 1 Xshe…

.NET平台使用C#设置Excel单元格数值格式

设置Excel单元格的数字格式是创建、修改和格式化Excel文档的关键步骤之一&#xff0c;它不仅确保了数据的正确表示&#xff0c;还能够增强数据的可读性和专业性。正确的数字格式可以帮助用户更直观地理解数值的意义&#xff0c;减少误解&#xff0c;并且对于自动化报告生成、财…

Android显示系统(10)- SurfaceFlinger内部结构

一、前言: 之前讲述了native层如何使用SurfaceFlinger,我们只是看到了简单的API调用,从本文开始,我们逐步进行SurfaceFlinger内部结构的分析。话不多说,莱茨狗~ 二、类图: 2.1、总体架构: 先看下SurfaceFlinger的关键成员和我们BootAnimation侧关键成员如何对应起来…

深度学习中的多通道卷积与偏置过程详解

目录 ​编辑 多通道卷积的深入理解 &#x1f50d; 卷积核的多维特性 &#x1f30c; 卷积操作的细节 &#x1f527; 多通道卷积的优势 &#x1f31f; 偏置过程的深入理解 &#x1f3af; 偏置的两种实现方式 &#x1f6e0;️ 偏置的作用与重要性 &#x1f308; 多通道卷…

易语言鼠标轨迹算法(游戏防检测算法)

一.简介 鼠标轨迹算法是一种模拟人类鼠标操作的程序&#xff0c;它能够模拟出自然而真实的鼠标移动路径。 鼠标轨迹算法的底层实现采用C/C语言&#xff0c;原因在于C/C提供了高性能的执行能力和直接访问操作系统底层资源的能力。 鼠标轨迹算法具有以下优势&#xff1a; 模拟…

LeetCode 718. 最长重复子数组 java题解

https://leetcode.cn/problems/maximum-length-of-repeated-subarray/description/ 动态规划 class Solution {public int findLength(int[] nums1, int[] nums2) {int len1nums1.length,len2nums2.length;int[][] dpnew int[len11][len21];dp[0][0]0;//没有意义&#xff0c;…

【蓝桥杯选拔赛真题93】Scratch青蛙过河 第十五届蓝桥杯scratch图形化编程 少儿编程创意编程选拔赛真题解析

目录 Scratch青蛙过河 一、题目要求 编程实现 二、案例分析 1、角色分析 2、背景分析 3、前期准备 三、解题思路 1、思路分析 2、详细过程 四、程序编写 五、考点分析 六、推荐资料 1、入门基础 2、蓝桥杯比赛 3、考级资料 4、视频课程 5、python资料 Scratc…

5.3 C++ 容器的嵌套

一&#xff09;容器嵌套的概念 在 C 中&#xff0c;容器嵌套是指将一种容器类型作为另一种容器的元素。这允许创建更复杂的数据结构&#xff0c;以满足各种编程需求。例如&#xff0c;可以将一个vector容器放入另一个vector容器中&#xff0c;或者将一个map容器的元素设置为lis…

spark读取普通文件

spark读取普通文件 txt文件 """ 将一行数据当做一个字段&#xff0c;需要自己切割 字段名称为value 表结构 可以从sql中搞 """ df spark.read.text("../../data/wordcount/input/data.txt") df spark.read.format("text"…

手机实时提取SIM卡打电话的信令声音--社会价值(一、方案解决了什么问题)

手机实时提取SIM卡打电话的信令声音 --社会价值(一、方案解决了什么问题) 一、前言 这段时间&#xff0c;我们在技术范围之外陷入了一个自证或者说下定义的怪圈&#xff0c;即要怎么样去介绍或者描述&#xff1a;我们是一个什么样的产品。它在当前这个世界上&#xff0c;处于…

【LeetCode】每日一题 2024_12_13 K 次乘运算后的最终数组 I(暴力)

前言 每天和你一起刷 LeetCode 每日一题~ 小聊两句 1、今天是 12.13 南京大屠杀国家公祭日。铭记历史&#xff0c;勿忘国耻。 2、今天早上去看了 TGA 年度游戏颁奖&#xff0c;小机器人拿下了年度最佳游戏&#xff0c;所有人都震惊了&#xff0c;大伙纷纷问到&#xff0c;谁…

算法刷题Day16: BM41 输出二叉树的右视图

题目链接 描述 思路&#xff1a; 递归构造二叉树在Day15有讲到。复习一下&#xff0c;就是使用递归构建左右子树。将中序和前序一分为二。 接下来是找出每一层的最右边的节点&#xff0c;可以利用队列层次遍历。 利用队列长度记录当前层有多少个节点&#xff0c;每次从队列里…

【修改源码】解决el-select值不匹配导致回显id、只能搜索label无法搜索value的问题

问题一&#xff1a;el-select值不匹配导致回显id&#xff08;此时只针对单选进行处理&#xff09; el-select数据的回显是根据id去匹配值的&#xff0c;最近项目出现了回显id的情况&#xff0c;原因是没有匹配的option 问题场景图如下&#xff1a; 解决方案 1、方法一&#xf…

Docker的初识

目录 1. 容器技术发展史1.1 Jail 时代1.2 云时代1.3 云原生时代1.3.1 Google & Docker 竞争1.3.2 k8s 成为云原生事实标准 2. 虚拟化和容器化的概念2.1 什么是虚拟化、容器化2.2 为什么要虚拟化、容器化&#xff1f;2.3 虚拟化实现方式2.3.1 应用程序执行环境分层2.3.2 虚拟…

【开源大屏】玩转开源积木BI,从0到1设计一个大屏

积木 BI 重磅推出免费大屏设计器&#xff01;功能超强大&#xff0c;操作超流畅&#xff0c;体验超酷炫。快来体验一下吧。 让我们一起来看一下如何从0到1设计一个大屏。 一、积木BI大屏介绍 积木BI可视化数据大屏 是一站式数据可视化展示平台&#xff0c;旨在帮助用户快速通…

挑食的机器

描述 未来世界有群机器人&#xff0c;他们以阿拉伯数字为食。但其中有个机器人Tom从小到大都不吃质数&#xff0c;为了Tom的健康着想&#xff0c;医生建议Tom有计划的只吃质数&#xff0c;以保证营养均衡。但超市的货架上只有从1到105并且按顺序排列好的实物售卖&#xff0c;所…

HarmonyOS 线性容器ArrayList 常用的几个方法

ArrayList是一种线性数据结构&#xff0c;底层基于数组实现。ArrayList会根据实际需要动态调整容量&#xff0c;每次扩容增加50%。 ArrayList和Vector相似&#xff0c;都是基于数组实现。它们都可以动态调整容量&#xff0c;但Vector每次扩容增加1倍。 ArrayList和LinkedList相…

leetcode230.二叉搜索树中第k小的元素

标签&#xff1a;二叉搜索树&#xff1b;中序遍历 给定一个二叉搜索树的根节点 root &#xff0c;和一个整数 k &#xff0c;请你设计一个算法查找其中第 k 小的元素&#xff08;从 1 开始计数&#xff09;。 示例 1&#xff1a; 输入&#xff1a;root [3,1,4,null,2], k 1…

如何在两台 PostgreSQL 服务器之间使用逻辑复制槽进行数据复制

如何在两台 PostgreSQL 服务器之间使用逻辑复制槽进行数据复制 如何在两台 PostgreSQL 服务器之间使用逻辑复制槽进行数据复制环境准备1. 配置主服务器&#xff08;Publisher&#xff09;1.1 修改 postgresql.conf1.2 修改 pg_hba.conf1.3 重启 PostgreSQL 服务1.4 创建逻辑复制…