当前位置: 首页 > news >正文

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 操作智能分析阻断,也可自定义拦截规则,预防误操作
http://www.lryc.cn/news/347592.html

相关文章:

  • 【WEEK11】 【DAY6】Employee Management System Part 7【English Version】
  • 【52】Camunda8-Zeebe核心引擎-Clustering与流程生命周期
  • 从零开始的软件测试学习之旅(八)jmeter线程组参数化及函数学习
  • 图文并茂:解析Spring Boot Controller返回图片的三种方式
  • 问题处理记录 | 表输出报错 Packet for query is too large (5,214,153 > 4,194,304).
  • 数据结构_栈和队列(Stack Queue)
  • 基于docker 的elasticsearch冷热分离及生命周期管理
  • pikachu靶场(xss通关教程)
  • 实验0.0 Visual Studio 2022安装指南
  • 数据结构之----线性表
  • thinkphp5.1 模型auto
  • 企业微信创建应用(一)
  • Cosmo Bunny Girl
  • 初始化linux数据盘(3TB)分区-格式化-挂载目录
  • NFS网络文件系统的应用
  • AttributeError: module ‘PIL.Image‘ has no attribute ‘ANTIALIAS‘
  • 进程的共享主存通信实验
  • 深度缓冲技术在AI去衣中的神奇作用
  • 能效?性能?一个关于Windows下使用openssl speed进行速度测试的诡异问题
  • block性能考虑和线程安全
  • 没有公网ip,如何实现外网访问内网?
  • Python中如何将小数转化为百分数进行输出
  • 加入全球少儿编程运动:Scratch让每个孩子都能成为创造者(Scratch最新版客户端和初/中/高级学习资料整理分享)
  • 引擎:主程渲染
  • Java 高级面试问题及答案
  • 邮件的安全认证(dkim/spf/dmarc)
  • 单调栈问题
  • Hexo博客重新部署与Git配置
  • KUKA机器人专业名词解释
  • 阿里云 物联网平台 MQTT连接、数据传输