Подробное объяснение исходного кода MybatisPlus

MyBatis

Начинать

Время ограничено и возможности ограничены, если что-то не так, поправьте меня.

Говоря оMybatis-Plus, если вы хотите понять его исходный код, вам нужно знатьMybatis-Plusчто сделано в проекте. Эта структура по-прежнему очень полезна. Это очень просто и относительно популярно, так что вотО MyBatis-PlusСкопируйте его характеристики.

  • Неинвазивность: делайте только улучшения без изменений, их внедрение не повлияет на существующие проекты, гладко как шелк.
  • Низкие потери: базовый CURD автоматически вводится при запуске, производительность практически без потерь и прямая объектно-ориентированная операция.
  • Мощные операции CRUD: встроенный общий преобразователь и общая служба, большинство операций CRUD для одной таблицы можно реализовать с небольшой настройкой и более мощными условными конструкторами для удовлетворения различных потребностей использования.
  • Поддержка вызова лямбда-форм: с помощью лямбда-выражений вы можете легко написать различные условия запроса, и вам не нужно беспокоиться о написании неправильных полей.
  • Поддерживает автоматическую генерацию первичного ключа: поддерживает до 4 стратегий первичного ключа (включая распределенный генератор уникальных идентификаторов — Sequence), которые можно свободно настроить для идеального решения проблемы первичного ключа.
  • Поддержка режима ActiveRecord: поддержка вызова формы ActiveRecord, классы сущностей могут выполнять мощные операции CRUD только путем наследования класса Model.
  • Поддержка настраиваемых глобальных общих операций: поддержка внедрения глобального общего метода (запись один раз, использование в любом месте)
  • Встроенный генератор кода: используйте код или подключаемый модуль Maven для быстрого создания кода уровня Mapper, Model, Service, Controller, механизма поддержки шаблонов и других настраиваемых конфигураций, ожидающих вашего использования.
  • Встроенный плагин пейджинга: на основе физического пейджинга MyBatis разработчикам не нужно заботиться о конкретных операциях.После настройки плагина запись пейджинга эквивалентна обычному запросу списка.
  • Плагин подкачки поддерживает несколько баз данных: MySQL, MariaDB, Oracle, DB2, H2, HSQL, SQLite, Postgre, SQLServer и т. д.
  • Встроенный плагин анализа производительности: может выводить Sql-операторы и время их выполнения.Рекомендуется включать эту функцию во время разработки и тестирования, что позволяет быстро выявлять медленные запросы
  • Встроенный подключаемый модуль глобального перехвата: обеспечивает интеллектуальный анализ и блокировку операций удаления и обновления для всей таблицы, а также может настраивать правила перехвата для предотвращения ошибочных операций.

в заключении,Mybatis-PlusВ проекте было сделано три вещи.

  1. Генератор кода.
  2. Действия при запуске (настройка базы данных, сканирование Mapper и т. д.).
  3. CRUD-операции в проекте.

Здесь в основном разбираем стартап, а CRUD в проекте,Mybatis-Plusкак это работает.

при запуске

Если вы хотите, чтобы конфигурация вступала в силу автоматически при запуске проекта, вам нужно знать, как написатьSpringBoot Starter, Я только что сам написал Starter раньше. существуетmybatis-plus-boot-starterизresourcesЕсть папкаMETA-INFпапка

  • additional-spring-configuration-metadata.jsonОн используется для подсказки, когда мы пишем конфигурацию, связанную с Mybatis-plus, в свойствах или файле yml.
  • spring.factoriesАвтоматическая настройка происходит при запуске проекта. Класс автозапуска, настроенный внутри# Auto Configure org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration

MybatisPlusAutoConfiguration

@Configuration
@ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})//系统中有指定的类
@ConditionalOnSingleCandidate(DataSource.class)//容器中只有一个指定的Bean,或者这个Bean是首选Bean
@EnableConfigurationProperties(MybatisPlusProperties.class)//为带有@ConfigurationProperties注解的Bean提供有效的支持
@AutoConfigureAfter(DataSourceAutoConfiguration.class)//将一个配置类在另一个配置类之后加载
public class MybatisPlusAutoConfiguration implements InitializingBean {

Этот класс реализуетInitializingBeanинтерфейс, получилafterPropertiesSetметод, который автоматически вызывается после инициализации компонента. отмечены еще три@ConditionalOnMissingBeanМетод аннотации.

Этот метод не настроенSqlSessionFactoryКомпоненты будут созданы SpringBoot и сохранены в контейнере.


Этот метод не настроенSqlSessionTemplateКомпоненты будут созданы SpringBoot и сохранены в контейнере.

Этот метод не настроенMapperFactoryBeanКомпоненты будут созданы SpringBoot и сохранены в контейнере.

один способ входаcom.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration#sqlSessionFactoryесть предложениеMybatisSqlSessionFactoryBean factory = new MybatisSqlSessionFactoryBean();

MybatisSqlSessionFactoryBean

Этот класс реализует три интерфейсаFactoryBean<SqlSessionFactory>, InitializingBean, ApplicationListener<ApplicationEvent>

  1. FactoryBean: указывает, что используется заводской шаблон
  2. InitializingBean:afterPropertiesSetВызывается, когда установка свойства завершена (когда создание bean-компонента завершено)
  3. ApplicationListenerэто слушатель, который слушаетApplicationContextСобытие инициализации или обновления, вызываемое при инициализации или обновлении. Анализирует все необработанные операторные узлы в кеше. Рекомендуется чтобы вызвать этот метод после добавления всех картографов, поскольку он обеспечивает отказоустойчивую проверку операторов. обновитьMappedStatement

тогда смотриcom.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean#afterPropertiesSetСюда, В этом методе вызовитеcom.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean#buildSqlSessionFactory

buildSqlSessionFactory

Проще говоря, создайтеSqlSessionFactoryНапример, на самом деле в этом методе делается очень много всего.

  1. Сначала разберите конфигурацию Mybatis.
  2. Запуск без настройки Связанная конфигурация
  3. Инициализировать id-work и распечатать баннер
  4. Установите метаданные, связанные автоматически, если пользователь не настроил dbType
  5. Обработка сканирования пользовательского класса перечисления
  6. Сканировать пакеты псевдонимов
  7. Добавить плагин перехватчика
  8. Если это конфигурация xml, проанализируйте файл конфигурации xml.
  9. в соответствии сmapperLocationsРазобратьMapperдокумент
  10. Наконец, создайтеSqlSessionFactory, и вернуться.

Тут есть проблема.Это настраивается в конфигурационном классе.Тип базы данных Mysql,но все равно Other.

  @Bean
    public GlobalConfig globalConfig() {
        GlobalConfig conf = new GlobalConfig();
        DbConfig dbConfig = new DbConfig();
        dbConfig.setDbType(DbType.MYSQL);
        conf.setDbConfig(dbConfig);
        return conf;
    }

Поскольку этот объект новый, он не управляется Spring. Если вместо этогоResourceилиAutowiredЗалить, запустить ошибку.Но это не имеет значения, потому что он автоматически определит тип базы данных на основе метаданных соединения.

Далее посмотрите на этот метод здесь.Главное это фразаxmlMapperBuilder.parse();

этоparseМетод используется для анализа файла xml.Там, где указано, файл интерфейса анализируется.

org.apache.ibatis.builder.annotation.MapperAnnotationBuilder#parseStatementПоскольку он равен нулю, он не вводится.Этот метод в основном используется для разбора и использования.Insert,Select,Update,DeleteиSelectProvider,InsertProvider,UpdateProvider,DeleteProviderЭти восемь аннотированных методов являются нулевыми, поскольку их нет в проекте.Настоящая инъекция здесь
com.baomidou.mybatisplus.core.injector.AbstractSqlInjector#inspectInject this.getMethodList(mapperClass)Следующий инжектор называется
com.baomidou.mybatisplus.core.injector.DefaultSqlInjector#getMethodList

com.baomidou.mybatisplus.core.injector.AbstractMethod#inject
com.baomidou.mybatisplus.core.injector.AbstractMethod#injectMappedStatement Затем посмотрите на deleteById,Mybatis-PlusСекрет автоматического введения базового творога здесь.Конечно, есть одна последняя проверкаorg.springframework.dao.support.DaoSupport org.mybatis.spring.mapper.MapperFactoryBean#checkDaoConfig

CRUD операции в проекте

использовать в проектеMybatis-Plus, за исключением основных операций CRUD, в основном используют лямбда-выражения для сборки SQL.Mybatis-PlusРежим AR пока не обсуждается.
Давайте посмотрим на простой запрос SQL,Mybatis-PlusКак собрать SQL.этоMybatis-Plusмодульные тесты для проекта

  • com.baomidou.mybatisplus.test.MybatisTest#test

Этот метод называется

  • com.baomidou.mybatisplus.core.mapper.BaseMapper#selectCount

Когда дело доходит до операций CRUD Mybatis, мы должны сказать два класса.

  • com.baomidou.mybatisplus.core.override.MybatisMapperProxy
  • com.baomidou.mybatisplus.core.override.MybatisMapperProxyFactory

MybatisMapperProxyДостигнутоInvocationHandlerИнтерфейс, использующий динамический прокси JDK. иMybatisMapperProxyFactoryЭтот класс привязывает все сгенерированные Mappers к прокси. существуетorg.mybatis.spring.SqlSessionTemplate#getMapperВсе методы, полученные при вызове метода, представляют собой классы, созданные динамическим прокси-сервером JDK.

отладка точки останова

Получите картограф первымполучить класс прокси

Получить SQL

  • com.baomidou.mybatisplus.core.conditions.AbstractWrapper#doIt
  • com.baomidou.mybatisplus.core.conditions.segments.MergeSegments#add
  • com.baomidou.mybatisplus.core.override.MybatisMapperMethod#MybatisMapperMethod
  • org.apache.ibatis.binding.MapperMethod.SqlCommand#SqlCommand
  • org.apache.ibatis.binding.MapperMethod.SqlCommand#resolveMappedStatement


Видно, что сначала склеивается оператор запроса, а затем динамически склеиваются условия запроса в соответствии с лямбда-выражением. такMybatis-PlusЕсли вы хотите реализовать запрос на объединение нескольких таблиц с использованием лямбда, это не сложно.

Поскольку этот метод является частью BaseMapper, он добавляется в Configuration при запуске, поэтому его можно найти напрямую.

в этом методеorg.apache.ibatis.binding.MapperMethod.MethodSignature#MethodSignatureУстановите сигнатуру метода.

выполнить SQLcom.baomidou.mybatisplus.core.override.MybatisMapperMethod#execute возможныйsqlSegmentза"",columnMapнулевой. Поскольку точка останова здесь позже, она пуста. (Конкретная причина пока не ясна.)

Поток выполнения SQL

Здесь вы можете увидеть, что происходит с кешем первого уровня Mybatis, каждый запрос будетcreateCacheKey, если второй запрос сработает, он попадет в кеш, а если не сработает, то перейдет к основному запросу. И каждый запрос сначала вызываетCachingExecutor, только после того, как кеш не попалBaseExecutor.

  • org.apache.ibatis.session.defaults.DefaultSqlSession#selectOne(java.lang.String, java.lang.Object)
  • org.apache.ibatis.session.defaults.DefaultSqlSession#selectList(java.lang.String, java.lang.Object)
  • org.apache.ibatis.session.defaults.DefaultSqlSession#selectList(java.lang.String, java.lang.Object, org.apache.ibatis.session.RowBounds)
  • org.apache.ibatis.executor.CachingExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler)
  • org.apache.ibatis.executor.CachingExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler, org.apache.ibatis.cache.CacheKey, org.apache.ibatis.mapping.BoundSql)
  • org.apache.ibatis.executor.BaseExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler, org.apache.ibatis.cache.CacheKey, org.apache.ibatis.mapping.BoundSql)
  • org.apache.ibatis.executor.BaseExecutor#queryFromDatabase


Суммировать

Почему вы хотите посмотреть на исходный код? На самом деле есть две причины: одна — удивляться, почему нет необходимости писать базовый CRUD, а BaseMapper вообще можно использовать. Во-вторых, очень здорово писать SQL с лямбда-выражениями, и я хочу посмотреть, смогу ли я преобразовать его для поддержки объединения нескольких таблиц. Хотя это являетсяMybatis-PlusЧтение исходного кода, на самом деле, большинство из нихMybatisИсходный код, чтение исходного кода имеет много преимуществ, по крайней мере, теперь я знаюSQLкак его вводят,MybatisЧто такое кеш первого уровня, динамический прокси JDK и так далее. правильноMybatis-PlusТакже имейте более глубокое понимание.

Идея: если вы хотите поддерживать запрос на объединение нескольких таблиц, вам нужно добавить новый базовый метод, есть только один оператор SQL.SELECT, а затем добавьте методы leftJoin, rightJoin, join, on, using, union и другие методы из таблицы к параметрам, все динамически генерируемые. Может быть.

Хотя анализа много, но это только основной процесс, многие детали не проанализированы, должны быть упущения. Напримерcom.baomidou.mybatisplus.core.enums.SqlMethod. Давайте открывать больше точек знаний вместе. Еще раз, время ограничено и возможности ограничены.Если есть какая-то ошибка, пожалуйста, поправьте меня.
Перепечатка укажите.

В этой статье используетсяmdniceнабор текста