MyBatis认识
一、定义
MyBatis是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
官网:https://mybatis.org/mybatis-3/zh_CN/index.html
二、核心概念
1、SqlSessionFactoryBuilder
2、SqlSessionFactory
3、SqlSession
4、插件
(1)定义
MyBatis允许通过使用插件在映射语句执行过程中的某一点进行拦截。
默认情况下,MyBatis允许使用插件来拦截的方法调用有:
A、Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)(执行器拦截器)
允许拦截和自定义MyBatis执行器的行为。例如,可以添加缓存、日志记录或审计功能到执行器中。这些拦截器可以在MyBatis执行的不同阶段扩展或修改其行为。您可以通过实现MyBatis提供的相应接口并在MyBatis配置文件中进行配置来实现这些拦截器
B、ParameterHandler (getParameterObject, setParameters)(参数拦截器)
允许在将参数设置到SQL语句之前修改或验证它们。例如,可以对作为参数传递的敏感信息进行加密或解密。
C、ResultSetHandler (handleResultSets, handleOutputParameters)(结果集拦截器)
可以在将结果集返回给应用程序之前修改或分析它们。例如,可以对结果集数据进行转换或执行额外的计算。
D、StatementHandler (prepare, parameterize, batch, update, query)(语句拦截器)
可以在SQL语句执行之前修改或增强它们。例如,可以向WHERE子句添加额外的条件或记录执行的语句。分页等
(2)自定义插件
在MyBatis中,只需实现 Interceptor 接口,并指定想要拦截的方法签名即可对某个方法进行拦截。
A、Executor方法的拦截
示例代码:对query执行过程的拦截
@Intercepts({@Signature(type= Executor.class,method="query",args={MappedStatement.class, Object.class,RowBounds.class, ResultHandler.class })})
public class QueryExecutorPlugin implements Interceptor {@Overridepublic Object intercept(Invocation invocation) throws Throwable {// 执行query方法Object obj=invocation.proceed();// 修改执行结果List<Object> list= JSONUtil.parseArray(obj);list.add(new Category().setName("测试插件1"));return list;}@Overridepublic Object plugin(Object target) {// 包装目标对象的:包装:为目标对象创建一个代理对象return Interceptor.super.plugin(target);}@Overridepublic void setProperties(Properties properties) {// 将插件注册时的property属性设置进来Interceptor.super.setProperties(properties);}
}
B、StatementHandler方法的拦截
示例代码:对sql语句的修改
@Intercepts({@Signature(type = StatementHandler.class,method ="prepare",args = {Connection.class,Integer.class})})
public class StatementPlugin implements Interceptor {@Overridepublic Object intercept(Invocation invocation) throws Throwable {StatementHandler statementHandler= PluginUtils.realTarget(invocation.getTarget());MetaObject metaObject= SystemMetaObject.forObject(statementHandler);BoundSql boundSql= (BoundSql) metaObject.getValue("delegate.boundSql");String originSql=boundSql.getSql();System.out.println("原始sql:"+originSql);// 对原始sql进行改写metaObject.setValue("delegate.boundSql.sql",originSql.replace("?","8888888"));return invocation.proceed();}
}
或者
@Intercepts({@Signature(type = StatementHandler.class,method ="prepare",args = {Connection.class,Integer.class})})
public class StatementPlugin implements Interceptor {@Overridepublic Object intercept(Invocation invocation) throws Throwable {StatementHandler statementHandler= (StatementHandler) invocation.getTarget();BoundSql boundSql= statementHandler.getBoundSql();String originSql=boundSql.getSql();System.out.println("原始sql:"+originSql);// 直接对原始sql进行改写ReflectUtil.setFieldValue(boundSql,"sql",originSql.replace("?","9878948"));return invocation.proceed();}
}
C、ParameterHandler方法的拦截
@Intercepts({@Signature(type = ParameterHandler.class, method = "setParameters", args = PreparedStatement.class)})
public class ParameterPlugin implements Interceptor {@Overridepublic Object intercept(Invocation invocation) throws Throwable {// 修改参数值return null;}
}
D、ResultSetHandler方法的拦截
@Intercepts({@Signature(type = ResultSetHandler.class, method = "handleResultSets", args = Statement.class)})
public class ResultSetPlugin implements Interceptor {@Overridepublic Object intercept(Invocation invocation) throws Throwable {// 修改结果集return null;}
}
E、测试
a、添加插件
public class MyBatisConfig {@Beanpublic SqlSessionFactory sqlSessionFactory(){DriverManagerDataSource dataSource=new DriverManagerDataSource();dataSource.setUrl("jdbc:mysql://xxx:xxx/xxx?characterEncoding=utf-8&useSSL=false");dataSource.setUsername("xxx");dataSource.setPassword("xxx");dataSource.setDriverClassName("com.mysql.jdbc.Driver");TransactionFactory transactionFactory = new JdbcTransactionFactory();Environment environment = new Environment("development", transactionFactory, dataSource);org.apache.ibatis.session.Configuration config=new org.apache.ibatis.session.Configuration(environment);config.addMapper(CategoryMapper.class);// 添加插件config.addInterceptor(new QueryExecutorPlugin());config.addInterceptor(new ParameterPlugin());config.addInterceptor(new StatementPlugin());return new SqlSessionFactoryBuilder().build(config);}
}
b、测试代码
public class TestMyBatis {public static void main(String[] args) {AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext(MyBatisConfig.class);SqlSessionFactory factory= (SqlSessionFactory) context.getBean("sqlSessionFactory");try(SqlSession sqlSession=factory.openSession()){CategoryMapper categoryMapper=sqlSession.getMapper(CategoryMapper.class);categoryMapper.insert(new Category().setName("222222"));List<Category> list=categoryMapper.selectList();System.out.println(JSONUtil.toJsonPrettyStr(list));sqlSession.commit();// 默认mybatis是不会自动提交的,需要手动自动提交修改才会生效}}
}
5、类型转换器TypeHandler
(1)常用的TypeHandler
(2)自定义TypeHandler
可以通过继承BaseTypeHandler来自定义TypeHandler
三、使用
1、Spring使用MyBatis
(0)数据库中已存在category表
(1)引入依赖
<!-- mybatis依赖 --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.16</version></dependency>
(2)编写配置类MyBatisConfig
@ComponentScan(basePackages = "org.example.mybatis")
@Configuration
public class MyBatisConfig {@Beanpublic SqlSessionFactory sqlSessionFactory(){DriverManagerDataSource dataSource=new DriverManagerDataSource();dataSource.setUrl("jdbc:mysql://xxx:xxx/xxx?characterEncoding=utf-8&useSSL=false");dataSource.setUsername("xxx");dataSource.setPassword("xxx");dataSource.setDriverClassName("com.mysql.jdbc.Driver");TransactionFactory transactionFactory = new JdbcTransactionFactory();Environment environment = new Environment("development", transactionFactory, dataSource);org.apache.ibatis.session.Configuration config=new org.apache.ibatis.session.Configuration(environment);config.addMapper(CategoryMapper.class);return new SqlSessionFactoryBuilder().build(config);}
}
(3)编写测试类
public class TestMyBatis {public static void main(String[] args) {AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext(MyBatisConfig.class);SqlSessionFactory factory= (SqlSessionFactory) context.getBean("sqlSessionFactory");try(SqlSession sqlSession=factory.openSession()){CategoryMapper categoryMapper=sqlSession.getMapper(CategoryMapper.class);categoryMapper.insert(new Category().setName("222222"));List<Category> list=categoryMapper.selectList();System.out.println(JSONUtil.toJsonPrettyStr(list));sqlSession.commit();// 默认mybatis是不会自动提交的,需要手动自动提交修改才会生效}}
}
四、原理
五、关于MyBatisPlus
1、定义
MyBatis-Plus (opens new window)(简称 MP)是一个 MyBatis (opens new window)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
2、特性
- 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
- 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
- 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
- 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
- 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
- 支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
- 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
- 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
- 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
- 分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
- 内置性能分析插件:可输出 SQL 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
- 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作
相关文章:

MyBatis认识
一、定义 MyBatis是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java O…...

【WEEK11】 【DAY6】Employee Management System Part 7【English Version】
2024.5.11 Saturday Continued from 【WEEK11】 【DAY5】Employee Management System Part 6【English Version】 Contents 10.8. Delete and 404 Handling10.8.1. Modify list.html10.8.2. Modify EmployeeController.java10.8.3. Restart10.8.4. 404 Page Handling10.8.4.1. …...

【52】Camunda8-Zeebe核心引擎-Clustering与流程生命周期
Clustering集群 Zeebe本质是作为一个brokers集群运行,形成一个点对点网络。在这个网络中,所有brokers的功能与服务都相同,没有单点故障。 Gossip协议 Zeebe实现了gossip协议,并借此知悉哪些broker当前是集群的一部分。 集群使用…...

从零开始的软件测试学习之旅(八)jmeter线程组参数化及函数学习
jmeter线程组参数化及函数学习 Jmeter基础基本使用流程组件与元件 线程组线程的执行方式Jmeter组件执行顺序 常见属性设置查看结果数的作用域举例 Jmeter参数化实现方式1.用户定义参数2.用户参数3.函数4.csv数据文件设置 每日复习 Jmeter基础 基本使用流程 启动项目案例 启动…...

图文并茂:解析Spring Boot Controller返回图片的三种方式
欢迎来到我的博客,代码的世界里,每一行都是一个故事 图文并茂:解析Spring Boot Controller返回图片的三种方式 前言使用Base64编码返回图片使用byte数组返回图片使用Resource对象返回图片图片格式转换与性能对比 前言 在互联网的世界里&…...
问题处理记录 | 表输出报错 Packet for query is too large (5,214,153 > 4,194,304).
这个错误是由于MySQL服务器接收到的查询数据包太大而引起的。具体来说,错误消息中提到的数据包大小为5,214,153字节,而MySQL服务器默认只接受最大为4,194,304字节的数据包。 要解决这个问题,你可以尝试通过修改MySQL服务器的配置来增大max_a…...

数据结构_栈和队列(Stack Queue)
✨✨所属专栏:数据结构✨✨ ✨✨作者主页:嶔某✨✨ 栈: 代码:function/数据结构_栈/stack.c 钦某/c-language-learning - 码云 - 开源中国 (gitee.com)https://gitee.com/wang-qin928/c-language-learning/blob/master/function/…...

基于docker 的elasticsearch冷热分离及生命周期管理
文章目录 冷热集群架构的应用场景冷热集群架构的优势冷热集群架构实战搭建集群 索引生命周期管理认识索引生命周期索引生命周期管理的历史演变索引生命周期管理的基础知识Rollover:滚动索引 冷热集群架构的应用场景 某客户的线上业务场景如下:系统每天增…...

pikachu靶场(xss通关教程)
(注:若复制注入代码攻击无效,请手动输入注入语句,在英文输入法下) 反射型xss(get型) 1.打开网站 发现有个框,然后我们在框中输入一个“1”进行测试, 可以看到提交的数据在url处有显示…...

实验0.0 Visual Studio 2022安装指南
Visual Studio 2022 是一个功能强大的开发工具,对于计算机专业的学生来说,它不仅可以帮助你完成学业项目,还能为你将来的职业生涯打下坚实的基础。通过学习和使用 Visual Studio,你将能够更高效地开发软件,并在编程领域…...
数据结构之----线性表
线性表分为 顺序存储结构 和 链式存储结构 线性表的顺序存储结构: 线性表的顺序存储结构,指的是用一段地址连续的存储单元依次存储线性表的数据元素。 1,顺序表的结构: #define MAXSIZE 20 typedef int El…...
thinkphp5.1 模型auto
在ThinkPHP5.1中,模型的自动完成功能可以通过在模型类中定义auto属性来实现。这个属性是一个数组,包含了需要自动填充的字段和对应的处理规则。 以下是一个简单的例子,展示了如何在ThinkPHP5.1的模型中使用自动完成功能: <?…...

企业微信创建应用(一)
登录到企业微信后台管理(https://work.weixin.qq.com/)进入自建应用(应用管理-应用-创建应用) 3.查看参数AgentId和 Secret 4.企业微信查看效果...

Cosmo Bunny Girl
可爱的宇宙兔女郎的3D模型。用额外的骨骼装配到Humanoid上,Apple混合了形状。完全模块化,包括不带衣服的身体。 技术细节 内置,包括URP和HDRP PDF。还包括关于如何启用URP和HDRP的说明。 LOD 0:面:40076,tris 76694,verts 44783 装配了Humanoid。添加到Humanoid中的其他…...

初始化linux数据盘(3TB)分区-格式化-挂载目录
场景说明:某云给我们服务器加载了一块3TB的硬盘扩容(没有直接扩,原因是原来的盘做的是mbr(什么年代了,谁干的)的分区,最大识别2TB) 确认磁盘 输入命令lsblk 查看数据盘信息 &#…...
NFS网络文件系统的应用
1.配置2台服务器要求如下: a)服务器1: 主机名:user-server.timinglee.org ip地址: 172.25.254.100 [rootserver100 桌面]# hostnamectl hostname user-server.timinglee.org [rootserver100 桌面]# ifconfig eth0: fl…...

AttributeError: module ‘PIL.Image‘ has no attribute ‘ANTIALIAS‘
问题描述 修改图片大小的时候,代码报错:AttributeError: module PIL.Image has no attribute ANTIALIAS 解决方案 在pillow的10.0.0版本中,ANTIALIAS方法被删除了。 方法1:修改版本(不推荐) pip instal…...

进程的共享主存通信实验
进程的共享主存通信 【预备知识】 共享存储区为进程提供了直接通过主存进行通信的有效手段,不像消息缓冲机制那样需要系统提供缓冲,也不像pipe机制那样需要事先建立一个特殊文件,而是由通信双方直接访问某些共享虚拟储存空间。在Linux中&…...

深度缓冲技术在AI去衣中的神奇作用
引言: 随着人工智能技术的飞速发展,其在图形处理和视觉领域的应用日益增多。AI去衣技术便是其中一个颇具争议但又技术上引人入胜的话题。今天,我们将深入探讨一项关键技术——深度缓冲(Depth Buffering),它…...

能效?性能?一个关于Windows下使用openssl speed进行速度测试的诡异问题
问题描述 最近的某个软件用到了openssl,所以就想着测试一下速度。我的电脑是惠普的,CPU是AMD Ryzen 7 PRO 6850HS,系统是Win11。我使用openssl自带的speed测试加密/解密的速度,命令大致如下: openssl speed -evp aes…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...
Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务
通过akshare库,获取股票数据,并生成TabPFN这个模型 可以识别、处理的格式,写一个完整的预处理示例,并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务,进行预测并输…...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...
基于数字孪生的水厂可视化平台建设:架构与实践
分享大纲: 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年,数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段,基于数字孪生的水厂可视化平台的…...

Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...

听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...

短视频矩阵系统文案创作功能开发实践,定制化开发
在短视频行业迅猛发展的当下,企业和个人创作者为了扩大影响力、提升传播效果,纷纷采用短视频矩阵运营策略,同时管理多个平台、多个账号的内容发布。然而,频繁的文案创作需求让运营者疲于应对,如何高效产出高质量文案成…...

浪潮交换机配置track检测实现高速公路收费网络主备切换NQA
浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求,本次涉及的主要是收费汇聚交换机的配置,浪潮网络设备在高速项目很少,通…...
CSS | transition 和 transform的用处和区别
省流总结: transform用于变换/变形,transition是动画控制器 transform 用来对元素进行变形,常见的操作如下,它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...
MinIO Docker 部署:仅开放一个端口
MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...