28个案例问题分析---027---单表的11个Update接口--MyBatis
一:背景介绍
项目开发中。我们使用的是MyBatis,在MyBatis的xml文件里,两个表的更新功能,写了足足11个更新接口,毫无复用的思想

这种方式可以正常的实现功能,但是没有复用,无论是从时间上还是维护性上,都会增加额外的成本,那么我们该如何解决这个问题呢?如何写出可以复用的语句呢?在下面的例子里我会给大家进行展示
二:前期准备
我们需要准备一个使用MyBatis的maven项目。大家需要提前准备好Mysql数据库
引入pom依赖
<dependencies><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.47</version></dependency><!--mybatis--><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.2</version></dependency><!--junit--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency></dependencies>
这里我们只需要引入mysql,mybatis,junit测试三个依赖即可。
引入之后我们要配置一些数据库的连接问题
数据库连接文件

这里注意将自己数据库机器的ip地址和对应的库名写对,不然无法连接自己的数据库。
MyBatis配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""https://mybatis.org/dtd/mybatis-3-config.dtd">
<!--configuration mybatis的核心配置文件-->
<configuration>
<!--引入外部配置文件--><properties resource="db.properties"/><!--配置--><settings><!--标准日志工厂设置--><setting name="logImpl" value="STDOUT_LOGGING"/>
<!--显示的开启全局缓存--><setting name="cacheEnabled" value="true"/></settings><!--可以给实体类取别名--><typeAliases><!--可以指定一个包名,MyBatis会在包名下面搜索需要的Java Bean--><package name="org.example.pojo"/></typeAliases><!--environments 后面的s表示这是一个复数,可以编写多套环境 default表示默认的环境为development--><environments default="development"><!--编写一套环境 名称为configuration--><environment id="development"><!--jdbc的事务管理--><transactionManager type="JDBC"/><!--配置数据库相关数据--><dataSource type="POOLED"><property name="driver" value="${driver}"/><!--userSSL是一个按权连接 &是一个转移符 等同于and CharacterEncoding=utf-8可以保证输入数据库的数据不乱码--><property name="url" value="${url}"/><property name="username" value="${username}"/><property name="password" value="${password}"/></dataSource></environment></environments><!--绑定接口--><mappers><mapper class="org.example.dao.UserInfoMapper"/></mappers></configuration>
MyBatis配置类
public class MybatisUtils {private static SqlSessionFactory sqlSessionFactory;//静态代码块:一旦初始化就加载static{try {//使用Mybatis第一步:获取sqlSessionFactory对象//获取资源,直接读到mybatis-config.xmlString resource = "mybatis-config.xml";//需要用到输入流(InputStream) 把resource类加载进来InputStream inputStream = Resources.getResourceAsStream(resource);//通过build把输入流加载进来sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);} catch (IOException e) {e.printStackTrace();}}public static SqlSession getSqlSession() {//openSession中有自动commit(提交)事务的方法,加上true就能实现return sqlSessionFactory.openSession(true);}
}
到这里,我们的基本环境就准备好了,可以进行代码的编写
三:通用的更新语句
我写了一个通用的更新语句,将这个语句写好之后,我们可以去上文提到的,两张表 11个更新接口其中一个写了9个更新接口的mapper.xml文件,看一看这个通用的mapper能够覆盖到多少个。
通用update语句
<update id="updateCourseGroupConfiguration" parameterType="org.example.pojo.UserCourseGroupConfigurationPojo">update arpro_user_course_group_configuration<trim prefix="SET" suffixOverrides=",1"><if test="infoId != null">info_id = #{infoId}</if><if test="courseId != null">course_id = #{courseId}</if><if test="classId != null">class_id = #{classId}</if><if test="groupId != null">group_id = #{groupId}</if><if test="type != null">type = #{type}</if><if test="isDelete != null">is_delete = #{isDelete}</if><if test="remark != null">remark = #{remark}</if><if test="isLike != null">is_like = #{isLike}</if></trim>where is_delete = 0<if test="infoId != null"> and info_id = #{infoId}</if><if test="courseId != null">and course_id = #{courseId}</if><if test="classId != null">and class_id = #{classId}</if><if test="groupId != null">and group_id = #{groupId}</if><if test="isLike != null">and is_like = #{isLike}</if><if test="type != null">and type = #{type}</if></update>
可以覆盖的更新接口
<update id="updateGroupRelationship">UPDATE arpro_user_course_group_configurationset group_id = #{newGroupId}WHEREgroup_id = #{oldGroupId} andtype = #{type}</update><update id="updateGroupIsDelete">UPDATE arpro_user_course_group_configurationSET is_delete=1WHERE class_id = #{classId}AND course_id = #{courseId}</update><update id="updateGroupIsDeleteByCourseId">UPDATE arpro_user_course_group_configurationSET is_delete=1WHERE course_id = #{courseId}</update><update id="updateGroupRelationshipByClassIdAndCourseId">UPDATE arpro_user_course_group_configurationset group_id = #{groupCourseModel.newGroupId} ,is_like = #{isLike}WHEREtype = #{groupCourseModel.type} and class_id = #{groupCourseModel.classId} and course_id = #{groupCourseModel.courseId} and info_id =#{groupCourseModel.infoId}</update><update id="updateCourseIsLike" parameterType="com.tfjy.arprobackend.model.GroupCourseModel">UPDATE arpro_user_course_group_configurationset is_like = #{isLike}where group_id = #{groupId} and type = #{type}</update><update id="updateUserCourseIsLike">UPDATE arpro_user_course_group_configurationset is_like = 1where info_id = #{infoId} and type = #{type} and group_id != #{groupId} and is_delete = 0</update><update id="updateUserCourseNotLike">UPDATE arpro_user_course_group_configurationset is_like = 0where info_id = #{infoId} and type = #{type} and group_id = #{groupId} and is_delete = 0</update><update id="updateGroupRelation">UPDATE arpro_user_course_group_configurationset group_id = #{newGroupId} ,info_id = #{newInfoId}WHEREtype = 1 and class_id = #{classId} and course_id = #{courseId} and info_id = #{oldInfoId}</update>
暂时无法覆盖到的更新接口
<update id="updateGroupIsDeleteByUserId">update `arpro_user_course_group_configuration` set is_delete =1 WHERE course_id=#{courseAndStudentInfoModel.courseId} AND class_id=#{courseAndStudentInfoModel.classId} ANDinfo_id IN<foreach item="student" collection="studentList" open="(" separator="," close=")">#{student}</foreach></update>
从结果上来看,二者的对比是惊人的。一个通用的更新接口,竟然覆盖了我写的更新的9个接口中的8个,也就是说,在之前的开发中,造了7个重复的轮子。并且至少多了7处使用这些sql语句的地方,多了7个需要维护的代码。
复用思想多么的重要啊,没有这种思想,写一些重复的代码,不但效率低,时间长,还加大了出错的可能。
四:总结
写代码的时候,一定,一定,一定,要考虑维护的问题,考虑复用的问题。这样我们写出的代码才能不仅可以实现功能,而且还容易维护。
接下来还要总结MyBatis的动态sql的写法,写出复用性高的sql
相关文章:
28个案例问题分析---027---单表的11个Update接口--MyBatis
一:背景介绍 项目开发中。我们使用的是MyBatis,在MyBatis的xml文件里,两个表的更新功能,写了足足11个更新接口,毫无复用的思想 这种方式可以正常的实现功能,但是没有复用,无论是从时间上还是维…...
大数据开发治理平台 DataWorks
序言学习下阿里DataWorks的设计理念以及要做的事情cuiyaonan2000163.com参考文档:https://www.aliyun.com/product/bigdata/idehttps://help.aliyun.com/document_detail/73015.htmlhttps://help.aliyun.com/document_detail/324149.html ----数据治理LaunchDataWorks基于阿里云…...
Xshell的下载、使用、配置【ssh、telnet、串口】
目录 一、概述 二、Xshell的使用 2.1 Xshell使用ssh协议远程连接Linux主机或服务器 2.2 Xshell使用telnet协议远程连接Linux开发板 2.3 Xshell使用SERIAL协议远程连接Linux开发板 三、Xshell常用配置 3.1 配置默认会话属性 一、概述 Xshell是由NetSarang公司开发的强大…...
C++回顾(七)—— 面向对象模型
7.1 静态成员变量和静态成员函数 7.1.1 静态成员变量 关键字 static 可以用于说明一个类的成员;静态成员提供了一个同类对象的共享机制;把一个类的成员说明为 static 时,这个类无论有多少个对象被创建,这些对象共享这个 static …...
开源监控服务uptime-kuma
好久没写文章了,刚好最近用了一个开源的监控服务,感觉蛮有意思的,记录一下 (一)安装 uptime-kuma安装方式有几种,这里当然是选择大家都爱的docker,一条命令搞定 docker run -d --restartalways -p 3001:…...
JavaScript混淆技术:了解其核心原理和常用手段
当今互联网时代,JavaScript已经成为了web前端开发的重点技术之一。其中,JavaScript代码的安全性问题一直是关注的焦点。为了保护JavaScript代码的安全性,很多人对其进行加密处理,众所周知,对于单纯的加密算法ÿ…...
大型医院云HIS系统:采用前后端分离架构,前端由Angular语言、JavaScript开发;后端使用Java语言开发 融合B/S版电子病历系统
一套医院云his系统源码 采用前后端分离架构,前端由Angular语言、JavaScript开发;后端使用Java语言开发。融合B/S版电子病历系统,支持电子病历四级,HIS与电子病历系统均拥有自主知识产权。 文末卡片获取联系! 基于云计…...
SAP UI5 Upload/Download file through NetWeaver Gateway
1、创建 SEGW对象 2、创建Entity Type 要把Media 标识打上 3、 激活对象然后到DPC Class的扩展对象里面重定义 /IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_STREAM /IWBEP/IF_MGW_APPL_SRV_RUNTIME~CREATE_STREAM /IWBEP/IF_MGW_APPL_SRV_RUNTIME~UPDATE_STREAM METHOD /iwbep/if_m…...
opencv校正图像
目录1、前言2、例程2.1、代码2.2、效果口罩说明书网页3、按步骤分析转灰度图降噪 Canny边缘检测膨胀(可视具体情况省略)轮廓检索选取角度1、前言 我们用相机拍照时,会因为角度问题造成拍歪,会影响图像的识别,这时就需…...
JavaScript:函数与箭头函数的区别
ref 1. 定义 函数 function getName() {}箭头函数 const getName () > {}2. 命名 函数分为匿名、具名。 function getName() {} let getName function () {}箭头函数只有匿名。 const getName () > {}3. 构造函数 箭头函数都是匿名函数,所以不能作为构造…...
八股文(四)
目录 一、 Vue2的双向数据绑定原理 二、 vue2数据绑定缺点是什么?vue3是怎么解决的? (1)因为vue2.0 object.defineProperty只能劫持对象属性 (2)Proxy是直接代理对象 (3)proxy不…...
XSS挑战赛(xsslabs)1~10关通关解析
简介 XSS挑战赛,里面包含了各种XSS的防御方式和绕过方式,好好掌握里面的绕过细节,有助于我们更好的去发现XSS漏洞以及XSS的防御。本文更多的是分享解析的细节,不是一个标准的答案,希望大家在渗透的时候有更多的思维。…...
什么是以太网供电POE
POE指的是以太网供电,就是一根网线在传输网络的同时还传输设备所需的电源。我们最常见的就是通过POE交换机连接网络摄像头,网络摄像头无需的电源适配器,仅靠一根网线就能实现电源和网络的传输。POE供电一般可以到100米。POE包含两个部分&…...
【JUC2022】第七章 AQS、ReentrantReadWriteLock 和 StampedLock
【JUC2022】第七章 AQS 文章目录【JUC2022】第七章 AQS一、AQS1.概述2.同步器3.抽象的4.队列式二、ReentrantReadWriteLock1.概述2.案例3.存在的问题三、StampedLock1.概述2.案例3.存在的问题一、AQS 1.概述 AQS(AbstractQueueSynchronizer,抽象的队列式同步器)&am…...
Spark 磁盘作用
Spark 磁盘作用磁盘作用性能价值失败重试ReuseExchangeSpark 导航 磁盘作用 临时文件、中间文件、缓存数据,都会存储到 spark.local.dir 中 在 Shuffle Map 时, 当内存空间不足,就会溢出临时文件存储到磁盘上溢出的临时文件一起做归并计算…...
三、Spark 内存管理
文章目录Spark 内存管理堆内和堆外内存堆内内存堆外内存堆外与堆内的平衡内存空间分配静态内存管理(早期版本)统一内存管理Spark 内存管理 堆内和堆外内存 Spark 引入了堆外(Off-heap)内存,使之可以直接在工作节点的…...
Java 面试常见项目问题回答
之前整理了好几期,我面试时遇到的面试候选人,我是如何我去筛选的,这一期,我们来看下一些 面试常问的业务性的问题 你们公司权限认证是如何实现的? 这其实是个通用性的问题,大部分公司 小型公司,或者中型公…...
文件上传和下载(原生JS + SpringBoot实现)
目录 概述 前端编写-上传表单和图片回显 HTML表单代码 发送请求逻辑 CSS代码 后端编写-文件上传接口 后端编写-文件下载接口 概述 在现代Web应用程序中,文件上传和下载是常见的功能。本博客将介绍如何使用原生JS和Spring Boot实现文件上传和下载的功能。 在其…...
【C语言学习笔记】:安全性
用const修饰变量或方法,从而告诉编译器这些都是不可变的,有助于编译器优化代码,并帮助开发人员了解函数是否有副作用。此外,使用const &可以防止编译器复制不必要的数据。John Carmack对const的评论[2]值得一读。 // Bad Ide…...
Linux - 磁盘存储管理 磁盘引入
# 我们要介绍下 磁盘管理, 那不妨先来看一张图来简单 引入 :这张图呢,是我们 Windows 上的磁盘管理的显示 。根据这幅图呢,提出一个问题 :>>> 这幅图磁盘管理所显示的内容,你能判断出 该电脑 有几…...
西门子博图V16实战:5种工作模式机械手PLC程序全解析(附HMI组态文件)
西门子博图V16实战:5种工作模式机械手PLC程序全解析(附HMI组态文件) 在工业自动化领域,机械手控制系统一直是核心难点之一。如何实现多工作模式的灵活切换、确保信号互锁安全可靠,是每个PLC程序员必须掌握的技能。本文…...
误删Anaconda?4招紧急救援方案
问题背景与常见场景Anaconda被误删可能由误操作、系统崩溃、病毒攻击等原因导致,涉及环境、包、配置等关键数据丢失。抢救前的准备工作立即停止对Anaconda所在磁盘的写入操作,避免数据被覆盖。 确认删除方式(回收站、ShiftDelete、格式化等&a…...
基于偏振无关的传输相位调控技术,实现可见光超透镜的优化设计
基于传输相位的可见光超透镜 偏振无关搞过光学设计的工程师都知道,传统透镜那个笨重的曲面有多让人头疼。现在有了一种黑科技——可见光波段的超透镜,厚度只有几百纳米,却能实现传统透镜的光学效果。关键是这玩意儿还搞定了偏振相关性这个老大…...
图像处理算法资料(FPGA Verilog): RGB2GRAY、阈值分割、滤波、边缘检测等算...
图像处理算法资料( FPGA Verilog) 分别有RGB2GRAY、阈值分割(二值化)、均值滤波、中值滤波、sobel边缘检测、膨胀、腐蚀、开闭运算。 各个模块的结构与上图的顶层模块结构一致,通过模块之间的组合串联组成 ISP 顶层模块。 使用vivado软件&…...
【空气涡轮发动机Matlab_simulink动态仿真模型 ✔【空气涡轮发动机Matlab_simulink动态仿真模型】 1、部件级模型;进气道,涡轮,气室,压气机,尾喷管,转子模块,容积模块 2、
【空气涡轮发动机Matlab/simulink动态仿真模型 ✔【空气涡轮发动机Matlab/simulink动态仿真模型】 1、部件级模型;进气道,涡轮,气室,压气机,尾喷管,转子模块,容积模块 2、PID控制器: 输出扭矩阶跃扰动下&am…...
Kubernetes + LLM 实战:如何用 Gateway API Inference Extension 优化推理服务(附避坑指南)
Kubernetes LLM 实战:Gateway API Inference Extension 深度优化指南 在当今AI技术迅猛发展的背景下,大语言模型(LLM)已成为企业智能化转型的核心驱动力。然而,当这些复杂的模型需要部署到生产环境时,传统的Kubernetes路由方案往…...
超越简单拼接:如何用SuperFusion的语义约束,让你的图像融合结果直接服务于目标检测与分割?
超越简单拼接:语义约束如何重塑图像融合的下游任务价值 当红外与可见光图像在自动驾驶感知系统中相遇时,工程师们往往面临一个两难选择:追求视觉上自然的融合效果,还是确保关键目标特征能被检测算法准确识别?传统融合方…...
QT:Tab Widget的进阶应用与实战技巧
1. Tab Widget的动态管理技巧 第一次用QT做带标签页的界面时,我习惯在设计器里把Tab页都固定好。直到接手一个需要动态加载配置文件的仪表盘项目,才发现动态增删Tab才是真实开发中的常态。比如用户点击"新建图表"按钮时,我们需要实…...
RevokeMsgPatcher:微信QQ防撤回终极指南,轻松保留重要消息
RevokeMsgPatcher:微信QQ防撤回终极指南,轻松保留重要消息 【免费下载链接】RevokeMsgPatcher :trollface: A hex editor for WeChat/QQ/TIM - PC版微信/QQ/TIM防撤回补丁(我已经看到了,撤回也没用了) 项目地址: htt…...
Bypass Paywalls Clean 3大突破策略:2024浏览器扩展技术指南
Bypass Paywalls Clean 3大突破策略:2024浏览器扩展技术指南 【免费下载链接】bypass-paywalls-chrome-clean 项目地址: https://gitcode.com/GitHub_Trending/by/bypass-paywalls-chrome-clean 当你在撰写行业分析报告时,是否曾因关键数据被付费…...
