MyBatis认识

news2025/1/11 12:41:09

一、定义

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 {
    @Override
    public 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;
    }

    @Override
    public Object plugin(Object target) {
        // 包装目标对象的:包装:为目标对象创建一个代理对象
        return Interceptor.super.plugin(target);
    }

    @Override
    public 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 {
    @Override
    public 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 {
    @Override
    public 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 {
    @Override
    public 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 {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        // 修改结果集
        return null;
    }
}
E、测试
a、添加插件
public class MyBatisConfig {
    @Bean
    public 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 {
    @Bean
    public 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 的基础上只做增强不做改变,为简化开发、提高效率而生。

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

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

相关文章

Ci24R1 (SOP8)2.4GHz无线收发一体、双向系统的智能家居芯片

Ci24R1 &#xff08;SOP8&#xff09;工作范围在2.4GHzISM频段&#xff0c;专为低系统应用成本的无线场合设计&#xff0c;集成嵌入式ARQ基带协议引擎的无线收发器芯片。它的工作频率范围为2400MHz-2525MHz&#xff0c;共有126个1MHz带宽的信道。 Ci24R1 &#xff08;SOP8&…

深度学习Day-16:实现天气预测

&#x1f368; 本文为&#xff1a;[&#x1f517;365天深度学习训练营] 中的学习记录博客 &#x1f356; 原作者&#xff1a;[K同学啊 | 接辅导、项目定制] 要求&#xff1a;根据提供的数据集对RainTomorrow进行预测 一、 基础配置 语言环境&#xff1a;Python3.7编译器选择…

微服务核心01-Maven【项目管理工具】基础

一、Maven 简介 1.1 传统项目管理&#xff1a; 1.2 Maven 的作用 项目构建&#xff1a;提供标准的、跨平台的自动化项目构建方式。依赖管理&#xff1a;管理项目依赖的资源&#xff08;jar 包&#xff09;&#xff0c;避免资源间的版本冲突问题统一开发结构&#xff1a;提供标…

RGB-D分割相关调研

一、常见的RGB-D分割网络结构 单分支 RGB和Depth信息进行前期融合&#xff08;a&#xff09;&#xff0c;常规的编码-解码结构&#xff0c;对卷积核进行改进以适应RGB和Depth信息&#xff0c;不需要改变网络结构 双分支 不同的分支对RGB和Depth信息进行&#xff08;中期b或者后…

如何在树莓派 Raspberry Pi中本地部署一个web站点并实现无公网IP远程访问

文章目录 前言1. 安装 Raspberry Pi OS2. 测试 web 站点3. 安装静态样例站点4. 将web站点发布到公网4.1 安装 Cpolar4.2 cpolar进行token认证4.3 生成cpolar随机域名网址4.4 生成cpolar二级子域名4.5 将参数保存到cpolar配置文件中4.6 测试修改后配置文件4.7 配置cpolar服务开机…

华为静态路由跨网段通信eNSP

拓扑图&#xff1a; 底层原理&#xff1a; 通信需要4个地址 源MAC 源IP 目标MAC 目标IP ARP地址解析协议 通过ip地址解析MAC 如果是相同的网段直接通过 arp直接发送广播 谁是192.168.1.2 我需要的MAC 1.2就会回应告诉 1.1他的MAC 1.1会封装4个地址 发送方的IP MAC 接受方IP和MA…

电脑文件加密软件有哪些?口碑、安全性最好的文件加密软件

某企业的一位员工因不慎将包含敏感客户数据的电脑丢失&#xff0c;导致企业面临巨大的法律风险和经济损失。 这一事件凸显了电脑文件加密的必要性。 如果该企业事先采用了文件加密软件对敏感数据进行保护&#xff0c;即使电脑丢失&#xff0c;攻击者也无法轻易获取到文件内容…

液压阀比例电磁铁控制放大器

液压阀比例电磁铁控制放大器是一种将电信号精确转换为液压动力的技术&#xff0c;用于实现对液压系统的精细控制。与传统的开关型电磁铁不同&#xff0c;比例电磁铁可以实现连续控制&#xff0c;允许进行微调以适应不同的控制需求。比例液压阀包括比例压力阀、比例流量阀等&…

SSE介绍(实现流式响应)

写在前面 本文一起来看下SSE相关内容。 1&#xff1a;SSE是什么 全称&#xff0c;server-send events&#xff0c;基于http协议&#xff0c;一次http请求&#xff0c;server端可以分批推送数据&#xff0c; 不同于websocket的全双工通信&#xff0c;SSM单向通信,一般应用于需…

代码生成工具1 ——项目简介和基础开发

1 项目简介 需要提前在数据库建好表&#xff0c;然后执行代码生成工具&#xff0c;会生成简单的Java文件&#xff0c;避免重复编写增删改查代码。类似的工具网上有很多&#xff0c;本人开发这个工具属于自娱自乐。这个专栏会记录开发的过程。 2 项目搭建 数据库使用MySQL &…

激光跟踪仪在石油化工领域高效应用

管板式换热器是一种实现物料之间热量传递的节能设备&#xff0c;在石油化工行业生产过程中扮演着重要的角色。无论是在提高生产效率&#xff0c;保证产品质量还是节约能源方面&#xff0c;都发挥着重要作用。 测量需求 管板式热交换器内部有多个管板和折流板&#xff0c;每一…

BigInteger和BigDecimal类

BigInteger 和 BigDecimal 介绍 应用场景 BigInteger适合保存比较大的整型BigDecimal适合保存精度更高的浮点型&#xff08;小数&#xff09; BigInteger 和 BigDecimal 常见方法 1&#xff0c;add 加2&#xff0c;subtract 减3&#xff0c;multiply 乘4&#xff0c;divide…

小程序开发之tdesignUI组件的简易使用教程

文章目录 TDesign简介小程序端使用TDesign一、安装二、使用可能的问题 附&#xff1a;如何使用weui开发参考链接 TDesign简介 TDesign 是腾讯各业务团队在服务业务过程中沉淀的一套企业级设计体系。 该UI框架支持桌面端、移动端、小程序端等全端。 小程序端使用TDesign 开发…

深沪300etf期权如果放弃行权了会怎么样?

今天期权懂带你了解深沪300etf期权如果放弃行权了会怎么样&#xff1f;期权行权是指期权持有人根据合约规定&#xff0c;在合约有效期内以约定的行权价格购买或卖出标的资产的权利&#xff0c;投资者可以选择行权&#xff0c;当然也有个别的选择放弃行权。 深沪300etf期权如果放…

不要被git的记录误导了,git也会犯错

Android studio中有个很方便的功能&#xff0c;可以查看单个文件的修改记录 显示这条记录把一行代码给删除了 我们找到这条完整的提交记录看看 在这次提交中我们确实没有删除那行代码。 那这行代码到底是怎么删除的&#xff1f;为什么又会被认为是我们删除的呢&#xff1f; …

OpenAI推出DALL·E 3识别器、媒体管理器

5月8日&#xff0c;OpenAI在官网宣布&#xff0c;将推出面向其文生图模型DALLE 3 的内容识别器&#xff0c;以及一个媒体管理器。 随着ChatGPT、DALLE 3等生成式AI产品被大量应用在实际业务中&#xff0c;人们越来越难分辨AI和人类创建内容的区别&#xff0c;这个识别器可以帮…

MongoDB Atlas Vector Search与Amazon Bedrock集成已全面可用

亮点前瞻 ●MongoDB Atlas Vector Search知识库与Amazon Bedrock的最新集成&#xff0c;将极大加速生成式AI应用的开发。 ●诺和诺德利用MongoDB Atlas Vector Search与Amazon Bedrock集成&#xff0c;加速构建AI应用程序。 MongoDB&#xff08;纳斯达克股票代码&#xff1a…

小白必看:数据防泄密软件介绍|安在云和Ping32对比?

在当今数字化时代&#xff0c;数据防泄密软件已经成为企业和组织不可或缺的重要工具。随着信息技术的发展&#xff0c;企业面临着越来越多的网络安全威胁&#xff0c;数据泄露事件也屡见不鲜。数据防泄密软件的出现&#xff0c;为企业提供了有效的解决方案。 一、数据防泄密软…

每日OJ题_记忆化搜索⑤_力扣329. 矩阵中的最长递增路径

目录 力扣329. 矩阵中的最长递增路径 解析代码1_爆搜递归&#xff08;超时&#xff09; 解析代码2_记忆化搜索 力扣329. 矩阵中的最长递增路径 329. 矩阵中的最长递增路径 难度 困难 给定一个 m x n 整数矩阵 matrix &#xff0c;找出其中 最长递增路径 的长度。 对于每…

vscode 使用正则搜索

ctrl c 复制&#xff0c;内容如下&#xff1a; Vue3简介创建Vue3工程Vue3核心语法路由pinia组件通信其它 APIVue3新组件