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 {
    @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 的基础上只做增强不做改变,为简化开发、提高效率而生。

相关推荐

  1. <span style='color:red;'>MyBatis</span>

    MyBatis

    2024-05-09 17:18:04      58 阅读
  2. <span style='color:red;'>Mybatis</span>

    Mybatis

    2024-05-09 17:18:04      67 阅读
  3. Mybatis

    2024-05-09 17:18:04       59 阅读
  4. <span style='color:red;'>MyBatis</span>

    MyBatis

    2024-05-09 17:18:04      43 阅读
  5. <span style='color:red;'>Mybatis</span>

    Mybatis

    2024-05-09 17:18:04      53 阅读
  6. Mybatis

    2024-05-09 17:18:04       54 阅读
  7. <span style='color:red;'>Mybatis</span>

    Mybatis

    2024-05-09 17:18:04      47 阅读
  8. <span style='color:red;'>Mybatis</span>

    Mybatis

    2024-05-09 17:18:04      30 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-05-09 17:18:04       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-05-09 17:18:04       100 阅读
  3. 在Django里面运行非项目文件

    2024-05-09 17:18:04       82 阅读
  4. Python语言-面向对象

    2024-05-09 17:18:04       91 阅读

热门阅读

  1. impdp和expdp注意事项

    2024-05-09 17:18:04       36 阅读
  2. 11 防火墙配置信息的认识

    2024-05-09 17:18:04       27 阅读
  3. Centos Yum

    2024-05-09 17:18:04       39 阅读
  4. 获取污染修复设计乙级资质的重要因素

    2024-05-09 17:18:04       38 阅读
  5. 面试:CopyOnWriteArrayList

    2024-05-09 17:18:04       37 阅读
  6. 限流算法学习

    2024-05-09 17:18:04       38 阅读
  7. 如何设置并行度 ——《OceanBase 并行执行》系列 2

    2024-05-09 17:18:04       28 阅读
  8. Leetcode 102:二叉树的层次遍历

    2024-05-09 17:18:04       31 阅读
  9. 大势智慧有可以制作白模的软件吗?

    2024-05-09 17:18:04       29 阅读
  10. 自然语言处理(NLP)技术及举例说明

    2024-05-09 17:18:04       37 阅读
  11. 游戏中常用的设计模式及场景

    2024-05-09 17:18:04       35 阅读
  12. Unity 状态机

    2024-05-09 17:18:04       37 阅读