Первый этап. Модуль 1 Примечания к пользовательскому фреймворку Mybatis

Каталог статей


Предисловие

Выходной источник содержания статьи: Lagou Education Java High Salary Training Camp. Курс P7
Эта статья является частью внеклассных заметок в учебном курсе.


адрес проекта

Код проекта:
Ссылка: https://pan.baidu.com/s/1pdtE7NkQb1SHQo9RnfSOTw
Код извлечения: sc4m

Адрес облачного кода: https://gitee.com/nie_jian_ming/njm_all_homework/tree/master/%E7%AC%AC%E4%B8%80%E9%98%B6%E6%AE%B5.%E6%A8% A1% E5% 9D% 97% E4% B8% 80.mybatis% E4% BD% 9C% E4% B8% 9A

1. Традиционные проблемы JDBC и индивидуальные решения для фреймворков

Вопросы:
1. Частое создание и освобождение соединений с базой данных приводит к неэффективной трате ресурсов системы и, таким образом, влияет на производительность системы.
2. Оператор sql, передача параметров и набор результатов анализа жестко запрограммированы.Изменения SQL требуют изменения кода Java, что затрудняет сопровождение кода.
Решение:
1. Используйте пул соединений с базой данных для инициализации ресурсов соединений, чтобы решить проблему частого создания и освобождения соединений с базой данных.
2. Извлеките операторы sql в файлы конфигурации xml, используйте отражение, самоанализ и другие базовые технологии для автоматического сопоставления сущностей и таблиц с атрибутами и полями, отражение для установки параметров и самоанализ для возврата пакета набора результатов.
Используемые шаблоны проектирования:
шаблон проектирования Builder, ручной шаблон (фабрика сеансов), режим прокси (динамический прокси JDK для создания объектов прокси для интерфейса Dao)

2. Индивидуальные идеи дизайна фреймворка уровня сохраняемости.

2.1. Пользовательская сторона (проект): представьте пакет jar пользовательской структуры уровня сохраняемости.

  • Предоставьте две части информации о конфигурации: информацию о конфигурации базы данных, информацию о конфигурации sql (инструкцию sql, тип параметра, тип возвращаемого значения)
  • Используйте файл конфигурации, чтобы предоставить эти две части информации о конфигурации:
    1. sqlMapConfig.xml: сохранить информацию о конфигурации базы данных, импортировать mapper.xml.
    2.mapper.xml: хранить информацию о конфигурации sql.

2.2. Сама структура настраиваемого уровня сохраняемости (инженерия): суть заключается в инкапсуляции JDBC.

2.2.1. Прочтите файл конфигурации:

  • Создайте класс для загрузки файла конфигурации во входной поток байтов в соответствии с путем к файлу конфигурации и сохранения его в памяти. Этапы
    реализации : Создание класса Resources, метод загрузки: InputSteam getResourceAsSteam (String path)
    Считываемая информация о конфигурации сохраняется в памяти в виде потока, с которым нелегко работать. Здесь создаются два javaBean-компонента (контейнерных объекта). для объектно-ориентированного мышления.: Сохраните проанализированное содержимое файла конфигурации, что также удобно для последующего доступа. Этапы
    реализации : Создайте два класса
    конфигурации. Конфигурация : Базовый класс конфигурации: сохраните содержимое, проанализированное sqlMapConfig.xml, сохраните основную информацию о базе данных, Map <only ID, Mapper> Unique ID: namespace + "." + Id
    MappedStatement : mapping Configuration класс: сохранить содержимое, проанализированное mapper.xml, сохранить оператор sql, тип оператора, тип java входного параметра, тип java выходного параметра

2.2.2. Анализ файла конфигурации: здесь я использую dom4j, но вы также можете использовать другие


Этапы реализации: Создайте класс SqlSessionFactoryBuilder, а затем создайте метод: build (InputSteam in) для создания фабрики сеансов.
В методе сборки реализованы две вещи:
1. Использование dom4j для анализа файла конфигурации и инкапсуляции проанализированного содержимого в объект-контейнер.
2. Создайте объект SqlSessionFactory (заводской режим); создайте объект сеанса sqlSession

2.2.3 Создайте интерфейс SqlSessionFactory и класс реализации DefaultSqlSessionFactory.

Затем создайте интерфейс SqlSessionFactory и класс реализации DefaultSqlSessionFactory на основе принципа открытия и закрытия. Напишите метод создания sqlSession.
Метод: openSession () // Получить объект экземпляра класса реализации
интерфейса sqlSession Не забудьте создать интерфейс sqlSession и класс реализации DefaultSqlSession для инкапсуляции метода CRUD JDBC.

2.2.4 Создайте интерфейс Executor и класс реализации SimpleExecutor, создайте метод запроса для выполнения кода JDBC.

Метод: query (Configuration, MappedStatement, Object ... params);
Конфигурация : при использовании dom4j для синтаксического анализа sqlMapConfig.xml проанализированный контент будет инкапсулирован в объект Configuration в различных формах, а информация в конфигурации базы данных сохраняется внутри .
MappedStatement : при использовании dom4j для синтаксического анализа mapper.xml содержимое каждого тега соответствует объекту mappedStatement, в котором хранится информация SQL.
Object ... params : это параметр, переданный пользователем, потому что он не уверен, сколько будут носить. Итак, Объект ... Переменные параметры

3. класс парсера тегов genericTokenParserzheg

  1. Этот класс может быть создан только с помощью параметризованной конструкции
  2. genericTokenParser - это общий класс парсера токенов
  3. Когда genericTokenParser анализирует заполнители # {}, он должен взаимодействовать с tokenHandler
  4. Три параметра конструкции genericTokenParser - это начальный тег, конечный тег и процессор тегов.

4. О sqlessionFactoyBuilder, sqlessionFactoy, sqlession.

  1. Лучшая область видимости sqlessionFactoyBuilder - это область действия метода, которую можно определить как локальную переменную метода.
  2. Лучший диапазон sqlessionFactoy - это диапазон применения
  3. Лучшая область действия sqlession - это область действия метода или область запроса.

5. О возвращаемом значении resultType и входном параметре paramterType

  1. Тип возвращаемого значения resultType: полное имя или псевдоним класса, разрешены базовые типы данных, String, int и т. Д.
  2. Структура данных resultType и resultMap одинакова, оба являются структурами карты.
  3. В mybatis, помимо использования аннотации @param для реализации ввода нескольких параметров, вы также можете использовать объект Map для реализации передачи нескольких параметров.

6. Спецификация разработки интерфейса в mybatis

  1. Пространство имен в mapper.xml такое же, как путь к классам интерфейса mapper.
  2. Имя метода интерфейса сопоставителя совпадает с идентификатором каждого оператора, определенного в mapper.xml.
  3. Тип входного параметра метода интерфейса mapper совпадает с типом parameterType каждого SQL, определенного в mapper.xml.
  4. Тип выходного параметра метода интерфейса mapper такой же, как тип resultType каждого sql, определенного в mapper.xml.

7. О содержании исходного кода mybatis

  1. Используемые шаблоны проектирования: модель агента, модель строителя (построителя / конструктора), модель фабрики, модель итератора.
  2. Функциональную архитектуру можно разделить на три уровня: уровень интерфейса, уровень обработки данных, уровень поддержки инфраструктуры.
  3. Поддержка подключаемых модулей для перехвата основных объектов, таких как statementHandler, paramterHandle и resultsHandler.
  4. Executor - исполнитель, отвечающий за создание sql и обслуживание кеша запросов.
  5. statementtHandler инкапсулирует оператор jdbc (интерфейс для выполнения sql базы данных) и отвечает за работу оператора jdbc
  6. typeHandler отвечает за отображение и преобразование между типами данных java и типами данных jdbc
  7. sqlSource отвечает за динамическое создание операторов SQL в соответствии с параметром Object, переданным пользователем, и за инкапсуляцию информации в объект boundsql ()

8. Mybatis lazy loading, каков принцип его реализации

Mybatis поддерживает отложенную загрузку и поддерживает
только отложенную загрузку объектов ассоциации и объектов коллекции;
ассоциация относится к запросам «один к одному», а коллекция относится к запросу «один ко многим».
В файле конфигурации вы можете указать, следует ли включать отложенную загрузку lazyLoadingEnabled = true | false.

<settings>
    <!-- 打开延迟加载的开关 -->
    <setting name="lazyLoadingEnabled" value="true"/>
    <!-- 将积极加载改为消极加载,即延迟加载 -->
    <setting name="aggressiveLazyLoading" value="false"/>
</settings>

Принцип реализации
Используйте CGLIB для создания прокси-объекта целевого объекта.Когда целевой метод вызывается, он входит в
методперехватчика, а когда требуются данные, он вызывает SQL для запроса БД.
Например: когда вызывается a.getB (). GetName (), метод invoke () перехватчика обнаруживает, что a.getB () является
нулевым значением, затем он отдельно отправляет предварительно сохраненный sql для запроса связанного объекта B. , и запрос B. Затем вызовите a.setB (b), чтобы атрибут объекта b объекта a имел значение, а затем завершите вызов метода a.getB (). getName ().

9. Три типа Mybatis Executor, разница между ними.

По умолчанию используется SimplExcutor
SimpleExecutor: каждый раз, когда выполняется обновление или выбор, открывается объект Statement, а объект Statement закрывается сразу после использования.
ReuseExecutor: выполнить обновление или выбрать, использовать sql в качестве ключа для поиска объекта Statement, использовать его, если он существует, и создать его, если он не существует. После использования объект Statement не закрывается, а помещается на карту для следующее использование.
Короче говоря, это повторное использование объекта Statement.
BatchExecutor: выполнить обновление (без выбора, пакетная обработка JDBC не поддерживает выбор), добавить весь sql в пакет addBatch (), дождаться унифицированного выполнения executeBatch (), он кэширует несколько объектов Statement, каждый объект Statement - After addBatch ( ) завершится, дождитесь пакетной обработки executeBatch () один за другим.
То же, что и пакетная обработка JDBC.

Объем действия: эти характеристики Executor строго ограничены областью жизненного цикла SqlSession.

В файле конфигурации Mybatis можно указать тип исполнительного механизма ExecutorType по умолчанию или вручную передать параметр типа ExecutorType методу создания SqlSession из DefaultSqlSessionFactory.

10. Первичный и вторичный кеши Mybatis (распределенное кеширование невозможно реализовать, требуется сторонняя структура кэширования)

1. Структура хранилища: кэш первого уровня и кеш второго уровня кэшируются в структуре HashMap.
2. Область действия:
кэш первого уровня находится на уровне SqlSession, а область действия - SqlSession. Mybatis по умолчанию включает кеш первого уровня. В том же сеансе SqlSession при запросе того же Sql первый запрос будет взят из cache Если данных нет, то запросите их из БД и кешируйте в HashMap.Второй запрос извлекается напрямую из кеша, и, если есть данные, он возвращается напрямую без проверки БД.

Кэш второго уровня находится на уровне сопоставителя. Несколько сеансов SqlSessions работают с оператором SQL одного и того же сопоставителя. Несколько сеансов SqlSessions могут совместно использовать кеш второго уровня. Кэш второго уровня находится между сеансами SqlSessions.
Когда sql under mapper вызывается в первый раз, информация запрашивается. Запрошенная информация будет храниться во вторичной области кэша, соответствующей сопоставителю. При втором вызове файла сопоставления mapper в пространстве имен выполняется тот же SQL используется для прямого запроса. Получить результат во вторичный кеш.

3. Сценарий недействительности:
при добавлении, удалении или изменении кэша первого уровня кэш становится недействительным.
При управлении контейнерами Spring каждый запрос создает новый sqlSession, поэтому в распределенной среде не будет несогласованности данных.

При использовании кэша второго уровня вам необходимо открыть тег кеша, добавить для атрибута useCache значение true при выборе и вручную включить flushCache для обновления кеша при обновлении и удалении. Если установлено useCache = false, кэш второго уровня отключен.

11. Принцип работы плагина Mybatis и как написать плагин

MyBatis поддерживает следующие методы перехвата:
Executor: (методы обновления, запроса, фиксации, отката и т. Д.);
Построитель синтаксиса SQL StatementHandler: ( методы подготовки, параметризации, пакетной обработки, обновления запроса и т. Д.);
Обработчик параметров ParameterHandler : (getParameterObject, метод setParameters);
ResultSetHandler: (методы handleResultSets, handleOutputParameters и т. д.);

1. Принцип работы:
Mybatis может писать плагины для четырех интерфейсов Executor, StatementHandler, ParameterHandler и ResultSetHandler. Mybatis использует динамический прокси-сервер JDK для генерации прокси-объектов для интерфейсов, которые необходимо перехватить, а затем реализует перехват метод интерфейса, поэтому, когда выполнение должно быть перехвачено Когда метод интерфейса, он войдет в метод перехвата (мысль АОП).
2. Как писать:
1. Напишите класс реализации интерфейса Intercepror
2. Установите подпись плагина, сообщите mybatis, какой метод какого объекта перехватить
3. Наконец, зарегистрируйте плагин в глобальном файле конфигурации

Пример:

package com.njm.plugin;

import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.plugin.*;

import java.sql.Connection;
import java.util.Properties;


//插件签名,告诉mybatis当前插件拦截哪个对象的哪个方法
@Intercepts({  //这是个⼤花括号,也就这说这⾥可以定义多个@Signature,对多个地⽅拦截,都⽤这个拦截器
         /*
        type:表示要拦截的核心(目标)对象,拦截哪个接⼝,StatementHandler是一个sql语句构建器,用来完成sql语句预处理
        method:表示要要拦截的方法,prepare是StatementHandler里的sql预编译方法
        args:表示要拦截方法的参数,按方法里的参数顺序写,可能方法有重载,所以要通过⽅法名和⼊参来确定唯⼀。
         */
        @Signature(type = StatementHandler.class,
        method = "prepare",
        args = {Connection.class,Integer.class})
})
public class MyPlugin implements Interceptor {

    //截方法:只要被拦截的目标对象的目标方法被执行时,每次都会执行intercept方法
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        /*
         * 插件的主要功能:在执行目标方法之前,可以对sql进行修改已完成特定的功能
         * 例如增加分页功能,实际就是给sql语句添加limit;还有其他等等操作都可以
         * */
        System.out.println("对方法进行了增强。。。。。。。");
        return invocation.proceed(); //invocation.proceed():原方法执行并返回值
    }

    //主要为了把当前的拦截器生成代理存到拦截器链中,包装目标对象,为目标对象创建代理对象
    @Override
    public Object plugin(Object target) {
        //target:被拦截的目标对象,this:表示当前自定义的插件实现类,当前拦截器,也就是现在这个类,
        //wrap方法利用mybatis封装的方法为目标对象创建代理对象(没有拦截的对象会直接返回,不会创建代理对象)
        Object wrap = Plugin.wrap(target, this);
        return wrap;
    }

    //获取配置文件的参数,就是获取插件在配置文件中配置的参数值
    //插件初始化的时候调⽤,也只调⽤⼀次,插件配置的属性从这⾥设置进来
    @Override
    public void setProperties(Properties properties) {
        System.out.println("获取到的配置文件的参数是:"+properties);
    }
}

Плагин зарегистрирован в глобальном конфигурационном файле.

 <!--配置自定义插件类
        interceptor:配置类的路径
        property:配置的参数-->
    <plugins>
      <!--这个是我自定义的插件-->
		 <plugin interceptor="com.njm.plugin.MyPlugin">
		 	<property name="name" value="tom"/>
		 </plugin>
		 
        <!--这是分页插件,上面的是我自定义的插件-->
<!--        <plugin interceptor="com.github.pagehelper.PageHelper">-->
            <!--指定方言-->
<!--            <property name="dialect" value="mysql"/>-->
<!--        </plugin>-->

    </plugins>

рекомендация

отblog.csdn.net/weixin_39417423/article/details/108332236