Прорыв через CRUD | Рождение простого и элегантного инструмента для генерации кода

задняя часть

gencode.gif

0. Вы можете что-то почерпнуть из этой статьи

1. Думая обо всем процессе требования от генерации, анализа до решения
2. Простая практика объектно-ориентированного анализа
3. Практика диаграммы классов UML
4. Практическое применение шаблонов проектирования
5. Наконец-то я получил довольно хороший инструмент кодогенерации для реализации идей и исходников

Эта статья начнется со всего процесса, упомянутого в первом пункте выше.Требования -> Цели -> Идеи -> Дизайн -> Реализация -> РезюмеРасширяйте по одному.

Чтобы максимально восстановить, как реализовать требование с нуля в реальной сцене, в этой статье будет предполагаться, что никто не перемещает код для генерации этой вещи. Его нужно изучать с нуля.

Начните текст ниже.

1. Сначала посмотрите на потребности

Однажды Фэн Сяонань (молодой я) писал код, когда внезапно подошел технический менеджер и похлопал Фэн Сяонаня по плечу.

«Сяо Нань, посмотри на функции добавления, удаления, изменения и проверки в нашей системе. Хотя копирование можно сделать, эффективность все еще недостаточно высока».

Фэн Сяонань подумал

«Эффективность всех режимов CV невысока, почему бы вам не отправиться в рай?».

Затем технический менеджер сказал

Видите ли, теперь, когда модуль управления пользователями завершен, когда я управляю другими ролями и организациями, спецификация кода и базовая структура добавления, удаления, модификации и запроса остаются такими же, верно? Это правда, что две другие функции можно быстро скопировано и реализовано, но есть несколько проблем, все еще влияющих на эффективность

Во-первых: проблема переименования файлов.В базовом модуле около 7-10 файлов кода с переднего плана на задний, которые нужно переименовывать при копировании.Количество файлов зависит от системы разработки и стандартов каждой компании. Количество файлов также может быть меньше или больше

Во-вторых: должны быть некоторые различия в атрибутах объекта, и его необходимо изменить или добавить, что является частью рабочей нагрузки.

В-третьих: класс, методы, примечания к полям необходимо настроить его, например, примечания класса управления пользователями управления пользователями, вы должны скопировать в роли управления в роли управления. Метод был тот же, поля подстраиваются под панель

Четвертое: в классе также необходимо будет изменить свойства, имена методов, локальные переменные и т. д. Например, UserService, внедренный UserController, переменная userList, объявленная внутри метода, и имя, соответствующее копии управления ролью. быть приспособленным к ролиXXX

Пятое: лишние методы нужно удалять по одному

Шестое: Есть еще серьезная проблема, то есть после копирования люди часто забывают изменить упомянутые выше пункты, что снижает читабельность кода.

У Фэн Сяонаня действительно есть такая проблема в сочетании с его реальной ситуацией с написанием кода.Он не может не чувствовать, что CV Dafa действительно неудобно и быстро копировать весь модуль, так как же это решить? Фэн Сяонань был озадачен.

«Вы можете изучить его для нас за последние два дня, чтобы увидеть, есть ли в отрасли более эффективные решения.Если есть какие-либо проблемы, мы свяжемся с вами в любое время (закадровый голос, если есть какие-либо проблемы с прогрессом, пожалуйста, сообщите об этом вовремя)"

Поговорив, технический менеджер развернулся и ушел.

Эй, история не очень хорошо написана, давайте просто посмотрим на нее, и это нормально, чтобы выразить основные потребности.

2. Предварительная разведка

Исследование новых технологий - любимое дело Фэн Сяонаня, но пока нет четкого направления, и у него нет опыта в этой области раньше. В настоящее время старшие или поисковые системы могут указать ему путь. сначала должен быть поиск и исследование, если в краткосрочной перспективе нет результата, спросите у старшего.Короче говоря, принцип таков: все в порядке, если задачи выполняются вовремя, не задерживая дела компании.

Открой поисковик, что ищешь? Фэн Сяонань обнаружил, что не знает, какие ключевые слова вводить, чтобы найти то, что ему нужно, поэтому сначала ему пришлось определить ключевые слова. Поскольку это проблема, связанная с копированием кода, при условии, что существуют соответствующие инструменты или решения, ее также следует называть «Код XX».

Поскольку это связано с эффективностью, давайте сначала выполним поиск по «эффективности кода». Скриншот части картинки, результаты следующие

image.png

Я примерно прочитал содержание и обнаружил, что это связано с настройкой кода для ускорения эффективности выполнения, а не для повышения эффективности разработки кода, тогда ключевое слово неверно, и его нужно скорректировать.

Фэн Сяонань снова подумал об этом, инструмент для копирования кода? Инструмент для дублирования кода? Поразмыслив, должно быть неправильно, но я все же попробовал волну и не нашел желаемого результата.

Разве эффективность не связана только с быстротой? Как насчет «быстрой разработки кода»? Давайте попробуем еще раз. Результаты поиска следующие

image.png

В списке появился ряд платформ быстрой разработки, и слово «генерация кода» часто появлялось.Интуитивно Фэн Сяонань сказал Фэн Сяонаню, что это ключевое слово, которое он хотел, но не знал, как его выразить. Фэн Сяонань добавил, что, поскольку компания использует Java, поиск по фразе «генерация кода Java» должен быть более точным. Пока что ключевым словом является «генерация кода Java».

Дрожащими руками он набрал в поисковике «генерация кода Java» и нажал поиск.

image.png

Фэн Сяонань не мог дождаться, чтобы открыть несколько статей, чтобы просмотреть содержимое, а затем несколько раз корректировал ключевые слова После поиска «инструмент генерации кода Java» и «генератор кода Java» он проверил волну информации и прочитал соответствующие идеи реализации. Не могу не радоваться: «Разве это не именно то, что нам нужно, самогенерация, настройка шаблона, одноэтапная реализация». Нет такой вещи, как изменение имени переменной, переименование и примечания, Фэн Сяонань имеет в голове общую идею.

Существует примерно два пути реализации: один — использовать готовую платформу генерации кода, второй — реализовать самостоятельно, что требует помощи технологии шаблонизатора, здесь определяется техническое направление. , о чем нужно сообщить руководителю.

Фэн Сяонань организует информацию и собственное понимание в документы и отправляет их техническому менеджеру (активное и своевременное общение и отчетность очень важны), и пошел на станцию ​​технического менеджера, чтобы дать краткий отчет. После прослушивания технический менеджер просмотрел информацию, собранную Фэн Сяонанем, и сказал:

Молодцы, у нашей компании есть собственная платформа для исследований и разработок, и инструмент генерации кода лучше всего напрямую интегрировать с нашей текущей платформой.Я видел, что существующий инструмент генерации кода плохо интегрируется с нашей текущей платформой, и их слишком много функции. , используемые технические стандарты не совпадают, давайте реализуем простой набор самостоятельно, просто решим текущие основные проблемы, это не должно быть слишком сложным. Я оставлю это вам сделать это.

Фэн Сяонань был очень счастлив, когда услышал это. Есть ли в мире что-то более счастливое, чем программирование? Да, это код, который вы не знаете. Ха-ха.

На данный момент предварительная разведка предварительного плана завершена.

Работу на этапе геологоразведки часто трудно контролировать, потому что разведка должна быть неизвестной областью и неизвестной проблемой, сама задача неконкретна, и вы не знаете, что будет сделано в конце. Период времени может быть долгим, и вам нужно обратить внимание на это время.Это то, как вы работаете. Суть в том, чтобы своевременно сообщать и сообщать о прогрессе.

3. Трудовая книжка

У меня есть задача и общая цель, но она недостаточно конкретна.Чтобы конечный продукт не отличался от того, что хотел технический менеджер, я все же разбираюсь с содержанием разговора только сейчас, чтобы сформировать четкую цель работы , а затем найдите менеджера. Подтвердите наличие соглашения и начните заново.

Цель в принципе ясна, какую технологию использовать, руководитель сказал, что она должна легко интегрироваться в платформу разработки компании, то есть она должна соответствовать существующей технической базе и спецификациям компании, ах да, это тоже упомянул, что он должен быть прост в использовании. Отсюда следующее.

Книга задач инструмента генерации кода

рабочие цели
(1) Ядро решает проблему низкой эффективности копирования кода и репликации
(2) Внедрить набор инструментов для генерации кода и интегрировать их с платформой компании посредством независимых исследований и разработок.

Технический отбор
(1) springboot
(2) thymeleaf

Как пользоваться
(1) Его можно использовать в режиме командной строки и без использования веб-сервисов.

Фэн Сяонань отправил составленный краткий рабочий документ техническому менеджеру, через некоторое время технический менеджер ответил и добавил несколько рабочих задач.

рабочие цели
(1) Ядро решает проблему низкой эффективности копирования и репликации кода
(2) Внедрить набор инструментов для генерации кода посредством независимых исследований и разработок, которые можно интегрировать с платформой компании.
(3) Легко расширяется при добавлении новых шаблонов кода.
(4) Он может быть сгенерирован по запросу, например, могут быть сгенерированы только файлы контроллера вместо полной генерации кода модуля.

На этом этапе задачи работы определены, и следующим шагом является работа над конкретными задачами.

Когда руководитель очень занят, если конкретные пункты задачи не разбираются для вас, нам нужно научиться разбирать это самостоятельно и просить руководителя подтвердить. Это также процесс постепенного накопления себя. В будущем эти процедуры самостоятельного руководства командой могут быть повторно использованы и расширены, и они объектно-ориентированы. С другой стороны, они также могут помочь лидерам снизить стресс. Руководители не ненавидят таких сотрудников.

5. Технический проект

Первоначально Фэн Сяонань думал о том, как реализовать это, и это могло быть сделано в ближайшее время.К сожалению, технический менеджер добавил два требования, которые снова сделали этот вопрос не таким простым.Это все еще нужно проанализировать и хорошо спроектировать.

Основная схема

В таком случае, давайте сначала нарисуем общий принцип.Это основная идея реализации.Фэн Сяонань примерно нарисовал такую ​​картину.

原理图.png

Основная схематическая диаграмма примерно соответствует структуре выше. Чтобы кратко объяснить, это чтение метаданных таблицы базы данных и шаблона кода, а также объединение шаблона кода и метаданных базы данных через движок тимелеафа, то есть замена выражения шаблона конкретными данными и, наконец, вывод файла.

С этим основным принципом необходимо выполнить проектирование на основе этой структуры, чтобы удовлетворить следующие два требования.

(3) Легко расширяется при добавлении новых шаблонов кода. (4) Он может быть сгенерирован по запросу, например, могут быть сгенерированы только файлы контроллера вместо полной генерации кода модуля.

После интерпретации этих двух требований Фэн Сяонань пришел к выводу: на самом деле (3) должно удовлетворять принципу открытия-закрытия и (4) программа должна иметь возможность свободно комбинировать методы генерации и поддерживать индивидуальную настройку.

дизайн диаграммы классов

Во-первых, необходимо просто спроектировать базовую диаграмму классов и отношения, как это сделать? Без предыдущего опыта в этой области сделать это за один шаг заведомо невозможно.Тогда нам предстоит разобрать шаги шаг за шагом и проанализировать приведенную выше принципиальную схему.Не рассматривая взаимосвязь между классами, перечислить все классы,которые можно придумать Во-первых, это исчерпывающий метод, а затем постепенно оптимизируйте настройку, это первый шаг.

Если вы сделали слишком много, вы можете не использовать исчерпывающее исчерпание, если у вас есть определенный опыт.Исчерпывающий метод подходит для ситуаций, когда у вас нет хорошей идеи или вы не знаете, с чего начать.Это эквивалентно поиску для вдохновения и методов в процессе ведения дел и постепенного применения Привлекайте на сцену собственные мысли.

Взяв в качестве примера процесс чтения метаданных таблицы, чтобы иметь возможность читать метаданные таблицы, требуется ли класс подключения к базе данных, требуется ли для ссылки файл конфигурации, требуется ли класс для чтения конфигурации и возвращаемый элемент таблицы Куда поместить данные, нужен ли им также класс информации таблицы и информации поля, независимо от того, разумно это или нет, перечислите это первым. И так далее, таким же образом анализируются и другие шаги.

Простая популяризация метаданных Что такое метаданные? То есть данные, описывающие данные, называются метаданными, как вы это понимаете? Или возьмем простой пример Например, есть пользовательская таблица User с двумя полями id(int) name(String) Затем данные, описывающие информацию о таблице пользователей и информацию о полях, называются метаданными, см. рисунок ниже.

元数据.png
Данные слева выражают соответствующую информацию пользовательской таблицы справа, например, как называется эта таблица, какой тип, какой механизм хранения используется, версия и т. д. Эти данные, представляющие информацию пользовательской таблицы, называются метаданные таблицы User. Точно так же это верно и для полей.Данные, описывающие имя поля, тип поля, длину поля и т. д., являются метаданными поля.

Возьмите Mysql в качестве примера. После создания Mysql существует схема, называемая "information_schema". Эта библиотека представляет собой базу данных метаданных MySQL, в которой хранится некоторая метаданная информация об экземплярах базы данных MySQL, таблицах, полях, индексах и т. д. В таблицах Columns хранятся метаданные для таблиц и полей.

Наконец, основываясь на основном принципе процесса генерации кода, Фэн Сяонань перечислил следующий список классов, которые он может придумать.

имя класса использовать пошаговый процесс
Table Сведения о метаданных таблицы читать метаданные
Column Информация о метаданных поля читать метаданные
DbConnection получить ссылку на базу данных читать метаданные
YamlRead Читайте конфигурацию YAML читать метаданные
CodeTemplate файл шаблона Чтение информации о шаблоне
Command сгенерировать команду сгенерировать код
TypeMapping База данных и классы сопоставления типов Java сгенерировать код
GenCode генерация кода сгенерировать код
CodeOutput вывод кода вывод
GenCodeRunner Начальный класс, используемый разработчиками начать бежать

С базовым списком мы будем использовать инструменты UML для конкретного дизайна.Все проекты в компании Фэн Сяонана используют PowerDesign.

Первое издание диаграммы классов

Фэн Сяонань считает, что, поскольку это первое издание, оно должно сначала наметить большие границы и основные отношения, чтобы зафиксировать границы и определить ключевые элементы.По сути, это состоит в том, чтобы нарисовать классы, перечисленные выше, и пометить их как простые. отношения, так что есть следующая картина

image.png

Диаграмма классов версии 0.1

Базовый прототип имеется.Далее постепенно продумывать каждый процесс для прототипа,заполнять атрибуты и методы класса,проверять есть ли упущения,и корректировать неразумный дизайн.Корректировка выглядит следующим образом

image.png

Несколько ключевых моментов:

1. Генкодераннер
Существует только один метод GenCodeRunner, который запускается. Объект GenCode вызывается внутренне методом запуска. Зачем вам нужен GenCodeRunner? Чтобы упростить использование цели задачи, средство генерации кода будет использовать метод командной строки, а логика управления командной строкой должна быть отделена от основного бизнеса, ведь возможно потом можно будет изменить другие методы использования, такие как http, gui и т.д. метод использования, затем необходимо предоставить независимый работающий класс для получения пользовательского ввода для взаимодействия с пользователями.

2. Метаданные
Этот класс не был включен в предыдущий анализ первого издания. Новый класс заключается в том, что GenCode не нужно знать соответствующие детали базы данных. Для GenCode все, что ему нужно, это метаданные, как связать базу данных и как читать конфигурация, это не должно заботиться Так что эти вещи оставлены для метаданных.

3. Таблица, столбец
Атрибут класса добавляется к двум классам, className добавляется к таблице, а attrName добавляется к столбцу.В большинстве случаев стандарт именования базы данных имеет форму разделения подчеркиванием, например user_id, а класс представляет собой имя случая верблюда, такое как userId , поэтому для создания выражения шаблона кода достаточно просто и не обрабатывает никакой логики, хотя выражение шаблона также может выполнить такое преобразование, шаблон должен делать то, что должен делать шаблон, то есть для отображения данных, поэтому процесс user_id -> userId this A исключается в метаданных, поэтому атрибуты, соответствующие соглашениям об именах классов и атрибутов, предоставляются соответственно.

Говорят, что информация о классах и атрибутах должна быть определена отдельно, но не считается, что здесь оставляют слишком много места для расширения.Чтобы избежать введения слишком большого количества классов и усложнения дизайна, они объединены в один класс.

Диаграмма классов версии 0.2

После разработки версии 0.1 Фэн Сяонань считает, что общая структура в целом ясна.Следующий шаг — найти точки изменения в середине и абстрагировать возможные изменения, чтобы избежать внутренней корректировки, вызванной модификацией или добавлением кода. . Близкий к модификации, открытый для нового добавления, открытый и закрытый принцип. То есть выполняется 3-е требование технического менеджера.

После анализа Фэн Сяонань обнаружил, что в соответствии с реальной ситуацией в компании основные места, которые могут измениться, заключаются в том, что шаблон может быть скорректирован и добавлен в любое время, после чего будет вызвано изменение вызывающего класса GenCodeRunner, что вызовет класс Command для настройки, и есть еще один Это метод вывода после того, как код сгенерирован.Он может быть выведен в файл сейчас, и не исключен вывод в базу данных или командную строку в будущем. После вышеизложенного Фэн Сяонань сделал абстрактные рисунки для вышеупомянутого содержания соответственно, сформировав следующую картину.

image.png

Несколько ключевых моментов дизайна:
1. Команда
Команда выполнена в виде интерфейса, для генерации разных шаблонов предусмотрены разные команды генерации, а также могут быть предусмотрены комбинированные команды генерации, то есть все коды модуля генерируются одновременно.

2. Вывод кода
Codeout адаптирован к интерфейсу, предоставляя разные классы реализации для разных форм вывода.

3. Шаблон кода
CodeTemplate спроектирован как базовый класс, предоставляющий различные подклассы расширения для разных файлов шаблонов.

Таким образом, для базового класса GenCode все связанные с ним классы, с которыми он работает, являются интерфейсами или базовыми классами, поэтому этот уровень может быть в основном стабильным, и независимо от того, как изменяется уровень реализации, этот уровень не будет затронут.

Диаграмма классов версии 0.3

Общая структура была сформирована, но Фэн Сяонань вдруг обнаружил, что расположение класса Command кажется неподходящим.Команда должна запускаться пользователем, а не GenCode, так как же пользователь запускает ее?Единственная запись находится в GenCodeRunner , тогда Command в GenCodeRunner более уместен. Таким образом, Фэн Сяонань снова скорректировал положение командного класса.

Команда может быть одной командой генерации, а несколько команд генерации могут быть объединены для формирования команды, которая отвечает четвертому требованию технического менеджера.Программа должна иметь возможность свободно комбинировать методы генерации и поддерживать индивидуальную настройку. Окончательный результат показан ниже.

image.png

Несколько ключевых моментов дизайна:

1. Генкодераннер
В соответствии с вводом пользователя GenCodeRunner создаст экземпляр соответствующего объекта Command и вызовет метод gen GenCode.

2. Генкод
Принципиальный метод gen в GenCode не имеет входных параметров, после настройки метод gen получает команду генерации и выполняет генерацию определенного кода.

Диаграмма классов версии 0.4

Все отношения классов обрабатываются правильно, но есть один недостающий момент.Фэн Сяонань внезапно подумал, что если начальное значение по умолчанию для класса, такого как TypeMapping, не соответствует требованиям, то пользователь должен иметь возможность определить его самостоятельно.Ну, вот по-прежнему отсутствует конфигурация глобального уровня.

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

Назовем его GenCodeConfiguration, новые члены диаграммы классов, и окончательный полный дизайн выглядит следующим образом.

image.png

Дизайн закончен

На этом работа над дизайном закончена, и можно проектировать и реализовывать по диаграмме классов.Может быть, вы чувствуете, что такая простая вещь, накидать столько классов, не надоедает, я могу сделать это с двумя-тремя классами , да, это можно сделать. Но как можно заменить каждый процесс, чтобы он был несвязанным, расширяемым и простым в обслуживании? Это требует реализации большего количества интерфейсов, абстрактных классов, объектно-ориентированных проектных идей и применения шаблонов проектирования. На самом деле дизайн выше класса может быть и посложнее, но потребностей на данный момент очень много, и текущего дизайна достаточно.

Итак, вы немного чувствуете, почему Spring такой сложный?Функции, реализованные некоторыми фреймворками с открытым исходным кодом, могут быть очень простыми.Почему так много интерфейсов и абстрактных классов предназначены для разделения, расширяемости и простоты обслуживания, а внутренняя реализация можно настроить заменить.

Может быть, вы все еще чувствуете, что не нужно, тогда вы должны так подумать, не оттачивайте свое программирование немного подумывать от этих небольших инструментов и кодов и углубить ваше понимание объектно-ориентированного дизайна. Накопление, вы можете реализовать MyBatis за один шаг? Нет никакого способа пойти на тысячу миль без накапливания шагов. Следовательно, можно разработать более полные и лучшие инструменты или рамки после тренировки в небольших сценах, непрерывных накоплении и непрерывных попытках прорыва.

6. Процесс реализации

Основной принцип ясен, и дизайн на месте.Для Фэн Сяонаня остальная часть кодирования — самое простое. Конечно, для молодых людей, которые только вошли в индустрию, могут быть определенные препятствия для внедрения, в основном это связано с отсутствием видения и письма, недостаточно умения писать чистый код и отсутствием опыта кодирования. . Решение состоит в том, чтобы практиковать свой мозг.

Следует отметить, что приведенный выше дизайн не является окончательным вариантом, так как некоторый контент, не учтенный в дизайне, может быть обнаружен в процессе конкретной реализации, поэтому дизайн и реализация – это процесс взаимного продвижения и улучшения. есть некоторые детали без рук. Ситуацию нельзя принимать во внимание, не говоря уже о том, что данная статья не была написана автором заранее, а максимально восстановить реальный процесс, при реализации и выводе статьи.

Первое, что делает реализация кода, — определяет структуру пакета проекта. По сути, это классификация классов при проектировании и построение пакета кода. После анализа базовая структура пакета формируется следующим образом

包结构.png

Осталось реализовать каждый класс отдельно. С чего начать, вы можете шаг за шагом следить за фактическим процессом выполнения кода. Какие классы должны взаимодействовать на каком этапе, а затем реализовать требуемые классы. Фэн Сяонань нарисовал общий процесс выполнения кода, как показано ниже.

执行流程.png

В части реализации общие идеи реализации описаны в единицах пакетов, код в ключевых позициях кратко вставлен с некоторыми инструкциями, а остальное содержимое не вставлено построчно, полный код будет выложен на Github позже.

GenCodeRunner

Класс взаимодействия с командной строкой, основной функцией которого является инициализация глобальной конфигурации и GenCode, а другой функцией является получение пользовательского ввода и определение команды и метода вывода, которые необходимы пользователю для создания кода посредством взаимодействия. Код ключа выглядит следующим образом.

Scanner scanner = new Scanner(System.in);
scanner.useDelimiter("\n");

// 初始化代码生成配置
GenCodeConfiguration genCodeConfiguration = new GenCodeConfiguration();
GenCode genCode = new GenCode(genCodeConfiguration);

// 控制用户交互过程
Command command = this.selectCommand(genCodeConfiguration,scanner);
CodeOutput output = this.selectOutput(genCodeConfiguration,scanner);
String tableName = this.selectTableName(scanner);

// 生成
Console.log("\n");
Console.log("开始生成....");
genCode.process(tableName,command,output);
Console.log("生成完成....");

GenCode

Основной класс, который координирует соответствующие параметры, требуемые различными ресурсами для получения команды, и вызывает команду для выполнения генерации кода. Основной код выглядит следующим образом.

public void process(String tableName,Command command,CodeOutput codeOutput){
		Table tableInfo = MetaData.getTableInfo(tableName,configuration.getTypeMapping());
		command.execute(tableInfo,springTemplateEngine,codeOutput);
}

Есть небольшая разница между реализацией и дизайном.В дизайне шаблон получен в GenCode, но оказалось, что в реальной реализации его удобнее выложить в Command.Здесь он корректируется, и мы увидим его, когда мы обратимся к пакету Command.

command

Пакет команд используется для реализации генерации и реализации различных кодов.Посмотрите на структуру диаграммы классов всего пакета.

Command.png

Целое разделено на два типа: одиночная команда и комбинированная команда.В настоящее время одна команда реализует три типа контроллера, сущности и Vo.Другие могут быть расширены и реализованы.

Посмотрите на основной код одной команды

public class GenControllerCommand extends SingleCommand {

    public GenControllerCommand() {
        this.commandName = "Controller生成命令";
        this.commandCode = "01";
        this.template = new ControllerCodeTemplate();
    }

    @Override
    public void process(Table table, Map map) {
       // 留给用户自定义处理过程,比如一些自定义参数的处理加一些控制等等,此处暂不需要
    }
}

Определите имя команды, назовите код (используется для соответствия коду команды, введенному пользователем в интерактивном режиме) и привяжите соответствующий шаблон генерации кода. Роль зарезервированной функции процесса заключается в предоставлении пользователям вторичной обработки данных или другой необходимой логики перед созданием конкретных кодов. Пакет команд использует комбинацию шаблона команды и метода шаблона.

В основном коде комбинированной команды

// 摘自GenControllerAndEntityCommand
public GenControllerAndEntityCommand() {
    this.commandName = "Controller & Entity 生成命令";
    this.commandCode = "03";
    singleCommands.add(new GenControllerCommand());
    singleCommands.add(new GenEntityCommand());
}

// 摘自 ComposeCommand
// 执行命令
@Override
public void execute(Table table, SpringTemplateEngine springTemplateEngine, CodeOutput codeOutput){
    for(SingleCommand singleCommand : singleCommands){
        singleCommand.execute(table,springTemplateEngine,codeOutput);
    }
}

Команда представляет собой комбинацию множества отдельных агрегированных команд, т. е. выполнение каждого хода по одному методу вызова одной команды выполнения, команда завершается одиночным мультиплексированием.

configuration

Класс глобальной конфигурации предоставляет конфигурацию параметров по умолчанию и пользовательскую конфигурацию расширений. В основном завершена конфигурация регистрации команд, конфигурация регистрации типа вывода, конфигурация базы данных и сопоставления типов Java.

微信截图_20200105225630.png

Все записи конфигурации находятся в GenCodeConfiguration, и можно легко вызвать унифицированную запись, что снижает нагрузку на память пользователя. Цель централизованного управления также может быть достигнута в рамках.

db

Этот пакет относительно прост и инкапсулирует процесс получения соединения с базой данных.Он в основном включает в себя класс конфигурации и класс получения соединения.Он относительно прост и не будет здесь объясняться.

微信截图_20200105230047.png

exception

Унифицированный класс исключений GenCodeException определен для модуля генерации кода, и исключения модуля генерации кода будут упакованы и выброшены как это исключение.

meta

Пакет сбора метаданных таблиц и полей, основная логика обработки заключается в чтении метаданных базы данных и их упаковке в соответствующие Java-объекты Table и TableColumn.

// 表元数据
Statement stmt = conn.createStatement();
String sql = "select table_comment from information_schema.tables where table_name = '"+ tableName + "'";
ResultSet tableResultSet = stmt.executeQuery(sql);
while (tableResultSet.next()) {
		table.setComment(tableResultSet.getString("table_comment"));
		break;
}

// 字段元数据
DatabaseMetaData metaData = conn.getMetaData();
ResultSet resultSet = metaData.getColumns(null, null, table.getCode(), "%");
List<TableColumn> tableColumnList = CollectionUtil.newArrayList();
while (resultSet.next()) {
    TableColumn tableColumn = new TableColumn();
    tableColumn.setCode(resultSet.getString("column_name").toLowerCase());
    tableColumn.setType(typeMapping.getJavaType(resultSet.getString("type_name")));
    tableColumn.setComment(resultSet.getString("remarks"));
    tableColumnList.add(tableColumn);
}
table.setColumnList(tableColumnList);

output

Пакет вывода в основном реализует форму вывода окончательного сгенерированного кода. В настоящее время реализован вывод в консоль и вывод в файл. См. структуру класса ниже.

CodeOutput.png

Относительно простая, простая структура наследования, примерно посмотрите на код реализации

// 摘自 ConsoleOutput
@Override
public void out(Table table, String content, CodeTemplate template) {
    Console.log("\n");
    Console.log("-----------------------------");
    Console.log(content);
    Console.log("-----------------------------");
}

// 摘自 FileOutput
@Override
public void out(Table table, String content, CodeTemplate template) {
    String fileName = "dist/" + table.getClassName() + template.getFileTag() + template.getFileSuffix();
    File file = new File(fileName);
    FileUtil.writeBytes(content.getBytes(),file);
    Console.log("文件位置:" + file.getAbsolutePath());
}

template

Класс определения шаблона сгенерированного кода без избыточного логического управления представляет собой определение атрибутов шаблона и соответствующих атрибутов окончательно сгенерированного файла.

CodeTemplate.png

Посмотрите на определение шаблона кода контроллера

public ControllerCodeTemplate() {
		this.tplName = "控制器模板";
		this.tplPath = "templates/Controller.tpl";
		this.fileTag = "Controller";
		this.fileSuffix = ".java";
}

tpl

Конкретный файл шаблона использует текстовый режим тимелеафа, чтобы увидеть простое содержимое шаблона.

/**
* [(${comment})]-实体
*
* @author yuboon
* @version v1.0
* @date [(${createDate})]
*/
@Data
public class [(${className})] implements Serializable {
    [# th:each="column : ${columnList}"]
    /** [(${column.comment})]  */
    @Column("[(${column.code})]")
    private [(${column.type})] [(${column.attrName})];
    [/]
}

7. Пользовательский опыт

взаимодействие с командной строкой

gencode.gif

пользовательский вызов

public class GenCodeTest {
    public static void main(String[] args) {
        GenCodeConfiguration genCodeConfiguration = new GenCodeConfiguration();
        GenCode genCode = new GenCode(genCodeConfiguration);
        genCode.process("sys_user",new GenVoCommand(),new ConsoleOutput());
    }
}

На основе этой структуры легко перейти в режим графического интерфейса для получения веб-страниц.

Расширить новый шаблон

Это очень просто, определите новую команду, новый файл шаблона Tpl, файл определения шаблона CodeTemplate и зарегистрируйте новую команду через глобальную конфигурацию Весь процесс не вносит никаких изменений в существующий код.

8. Резюме

До сих пор простым инструментом генерации кода был реализован в руках Feng Xiaonan.

Есть ли еще возможности для оптимизации? Конечно есть, например, движок шаблонов можно заменить по желанию? Что делать, если существует несколько версий файлов шаблонов кода? Реализация на стороне веб-сайта, одновременная генерация нескольких модулей и т. д.

В этой статье в качестве примера рассматриваются только основные функции инструмента генерации кода, от требований до окончательной реализации, в ней подробно описывается рабочий процесс и некоторые методы работы, включая некоторые идеи и концепции проектирования программ.

После этого вам нужно выполнить шаги выше, чтобы создать гаджет самостоятельно?Это не так, чем больше вы сделали, тем больше опыта вы видели, тем больше вы видели, процесс может быть упрощен, и вы Вы можете просто продумать несколько шагов в своем уме. Вы даже можете написать код напрямую. Это не должно быть так сложно, как в этой статье, шаг за шагом. Статья предназначена для описания всего процесса, так что это написано более подробно, но на первый взгляд это выглядит сложно.

Наконец, давайте уточним некоторые ключевые моменты в полном тексте:
(1) Очень важно сообщать и отчитываться своевременно и активно.
(2) Очистить целы работы и избежать бесполезных работ
(3) ключевые слова поиска важны
(3) Сначала разработайте, идеи важнее реализации
(4) Если вы не знаете, что делать, попробуйте исчерпывающий метод в конкретном случае.
(5) Не делайте слишком много шагов, итеративно реализуйте шаг за шагом
(6) Подводя итог, узнайте, почему? делать что? Как это сделать? Пространство последующей эволюции?

9. Полный кодовый адрес

GitHub.com/Ю Бохью/Java…

10. Пасхальные яйца

Я считаю, что многие студенты не могут настаивать на чтении содержания статьи, а содержание статьи не может полностью отражать общую идею дизайна и процесс реализации, поэтому я записал видео для части реализации, обратите внимание на официальный аккаунт. в конце статьи и ответьте на [gencode], чтобы получить поясняющее видео.

11. Более увлекательно

Если вы считаете, что это нормально, пошевелите пальцами, чтобы поставить лайк.
На сегодня все, увидимся в следующий раз.
Более качественный контент, первый публичный аккаунт [Фэн Xiangnan], добро пожаловать на внимание.