1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/lhg317-kduck-core

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
Внести вклад в разработку кода
Синхронизировать код
Отмена
Подсказка: Поскольку Git не поддерживает пустые директории, создание директории приведёт к созданию пустого файла .keep.
Loading...
README.md

K-Duck-Core

Структура фреймворка

K-Duck — это открытый и бесплатный фреймворк для разработки на основе Spring MVC, Spring и Spring JdbcTemplate. Он позволяет быстро создавать функциональные модули в соответствии с требованиями проекта. В отличие от других фреймворков, K-Duck инкапсулирует данные таблиц в виде объектов и полностью берёт на себя управление доступом к данным. Разработчикам не нужно писать код для DAO-слоя, а также создавать SQL-запросы в текстовом виде. Это снижает требования к навыкам написания SQL и уменьшает вероятность ошибок.

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

Технологии нижнего уровня

  1. JDK 8.
  2. Spring-Boot 2.4.0.

Архитектура фреймворка

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

Рисунок слева: Фреймворк инкапсулирует информацию о таблицах в объекты. Определяются конкретные классы объектов: определение сущности данных. В будущем планируется расширить функциональность, включая поддержку JSON-данных и отдельных функций обслуживания. Благодаря объектной модели для таблиц, обеспечивается поддержка на уровне полей и возможность создания унифицированных объектов доступа к данным.

Рисунок в центре: Изменения в структуре не влияют на разделение уровней. Однако параметры интерфейса и все бизнес-объекты были абстрагированы на более высокий уровень, чтобы обеспечить универсальность. Все переданные параметры и возвращённые объекты являются объектами ValueMap или ValueMapList (исключая объекты слоя данных, которые являются ValueBean). Это позволяет использовать их в качестве универсальных бизнес-объектов во всех сценариях. Однако это может усложнить контроль над разработкой. Поэтому фреймворк обеспечивает целостность данных и поддерживает проверку существования свойств. Также поддерживается форма Bean для объектов Map, которая сохраняет все характеристики Map и позволяет разработчикам работать с ними как с традиционными бизнес-Bean.

Рисунок справа: Доступ к данным управляется фреймворком (JdbcDao). Разработчики обычно не используют этот объект напрямую, а обращаются к реализации по умолчанию (DefaultService) для доступа к данным. Этот объект содержит общие операции доступа к данным, такие как добавление данных, пакетное добавление, удаление по первичному ключу, удаление по внешнему ключу, обновление по первичному ключу и обновление по внешнему ключу. Для запросов с условиями предоставляется специальный интерфейс QueryCreator. Если реализация по умолчанию не удовлетворяет требованиям бизнеса, необходимо наследовать этот интерфейс и расширять методы. Независимо от метода, разработчики должны вызывать только методы реализации по умолчанию.

Таким образом, при отсутствии сложных бизнес-сценариев разработчикам не требуется писать код для доступа к данным и бизнес-логике, что сокращает объём работы и позволяет сосредоточиться на логическом программировании.

Использование фреймворка

Настройка среды

Сначала создайте новый проект Maven с помощью IDE. Добавьте зависимость kduck-core в файл pom.xml:

<dependency>
    <groupId>cn.kduck</groupId>
    <artifactId>kduck-core</artifactId>
    <version>1.1.0</version>
</dependency>

Создание проекта может занять некоторое время из-за загрузки зависимостей.

Затем создайте пакет com.goldgov и внутри него файл Java для запуска основной программы. Например, создайте файл Application.java (если основной класс находится в другом пакете, Spring должен сканировать пакет cn.kduck):

package cn.kduck;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Этот код аналогичен стандартному классу запуска Spring Boot.

Создайте файл конфигурации application.yml для проекта. Обратите внимание, что это стандартное имя файла конфигурации, которое не следует изменять. Настройте информацию о источнике данных (поскольку фреймворк автоматически сканирует таблицы для получения информации об объектах):

spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/kduck_demo?useSSL=false&nullCatalogMeansCurrent=true&serverTimezone=Asia/Shanghai
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: liuhg
    password: liuhg317

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

Для MySQL рекомендуется добавить параметры соединения: nullCatalogMeansCurrent = true & useInformationSchema = true. Первый параметр гарантирует получение точных данных пользователя, а второй — получение комментариев определения таблицы. Если при запуске возникают проблемы, попробуйте удалить второй параметр.

Это стандартная конфигурация Spring Boot, и вы можете обратиться к официальной документации Spring для дополнительной настройки.

Запустите программу, запустив Application. Вы увидите следующий экран, указывающий на успешный запуск:

![Входная картинка](https://images.gitee.com/uploads/images/2021/0106/214758_3441f283_403814.png «Запуск успешно.png»)

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

Разработка модуля

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

![Входная картинка](https://images.gitee.com/uploads/images/2021/0106/214833_356c4698_403814.png «Демонстрация ER.png»)

Выполните следующие шаги для создания модуля:

  1. Создайте пакет для этого модуля, например, cn.kduck.example.
  2. Внутри пакета создайте пакет service и определите классы ClassInfo и StudentInfo, представляющие объекты класса и ученика соответственно.
  3. Создайте интерфейс DemoService и его реализацию DemoServiceImpl в пакете service.impl.
  4. Создайте класс DemoQuery в пакете query для построения объектов запроса.
  5. Создайте контроллер DemoController в пакете web. После выполнения этих шагов структура кода будет выглядеть следующим образом:

![Входная картинка](https://images.gitee.com/uploads/images/2021/0107/232910_44cc8449_403814.png «Структура демонстрации.png»)

Теперь мы можем заполнить каждый класс соответствующим кодом. Во фреймворке используются объекты ValueMap для инкапсуляции бизнес-данных. Однако для более сложных модулей использование ValueMap может привести к путанице. Чтобы решить эту проблему, фреймворк также поддерживает объекты Bean, сохраняя при этом характеристики ValueMap. Таким образом, наши классы ClassInfo и StudentInfo будут выглядеть следующим образом: createQuery: создать объект QuerySupport, который может получить используемый в реальности объект Query.

Обычно используется SelectBuilder для создания. В следующих разделах будет подробно описано использование SelectBuilder.

Пример кода означает, что нужно выполнить запрос к сущности CLASS_INFO и поддерживать возможность выполнения неточного запроса по className (название класса).

Необходимо объявить как Spring Bean.

В заголовке класса необходимо добавить аннотацию @Component.

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

Затем необходимо написать класс реализации интерфейса:

@Service
public class DemoServiceImpl extends DefaultService implements DemoService {

    @Override
    public void addClass(ClassInfo classInfo) {
        super.add(CODE_CLASS,classInfo);
    }

    @Override
    public void addStudent(Long classId, StudentInfo studentInfo) {
        Assert.notNull(classId,"班级ID不能为null");

        studentInfo.setClassId(classId);
        super.add(CODE_STUDENT,studentInfo);
    }

    @Override
    public void updateStudent(StudentInfo studentInfo) {
        super.update(CODE_STUDENT,studentInfo);
    }

    @Override
    public void deleteStudent(String[] studentId) {
        super.delete(CODE_STUDENT,studentId);
    }

    @Override
    public StudentInfo getStudent(String studentId) {
        return super.getForBean(CODE_STUDENT,studentId,StudentInfo::new);
    }

    @Override
    public List<StudentInfo> listStudent(String studentName, Page page) {
        Map<String, Object> paramMap = ParamMap.create("studentName", studentName).toMap();
        QuerySupport query = super.getQuery(DemoQuery.class, paramMap);
        return super.listForBean(query,page,StudentInfo::new);
    }
}

Здесь мы видим некоторые отличия от обычного написания классов реализации Service. Во-первых, класс наследуется от класса DefaultService, который предоставляет инкапсуляцию операций доступа к данным Dao и охватывает большинство общих операций доступа к данным. Поэтому мы можем видеть, что при выполнении операций добавления, удаления, изменения и запроса нам не нужно писать слишком много логики кода и внедрять конкретные Dao.

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

Для метода запроса, поскольку используется объект ValueMap в форме Bean, результаты могут быть преобразованы с помощью метода xxxForBean. Для получения дополнительной информации о других интерфейсах и методах использования вы можете обратиться к документации по другим методам в классе DefaultService.

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

@RestController
@RequestMapping("/example")
@Api(tags="示例模块")
public class DemoController {

    private DemoService demoService;

    @Autowired
    public DemoController(DemoService demoService){
        this.demoService = demoService;
    }

    @PostMapping("/class/add")
    @ApiOperation("添加班级")
    @ApiParamRequest({
            @ApiField(name="className",value="班级名称"),
            @ApiField(name="classNo",value="班号")
    })
    public JsonObject addClass(ClassInfo classInfo) {
        demoService.addClass(classInfo);
        return JsonObject.SUCCESS;
    }

    @PostMapping("/student/add")
    @ApiOperation("添加学生信息")
    @ApiParamRequest({
            @ApiField(name="classId",value="班级ID"),
            @ApiField(name="name",value="学生姓名"),
            @ApiField(name="gender",value="学生性别(1男,2女)",allowableValues = "1,2"),
            @ApiField(name="studentNo",value="学号")

    })
    public JsonObject addStudent(Long classId,StudentInfo studentInfo) {
        demoService.addStudent(classId,studentInfo);
        return JsonObject.SUCCESS;
    }

    @PutMapping("/student/update")
    @ApiOperation("更新学生信息")
    @ApiParamRequest({
            @ApiField(name="studentId",value="学生ID"),
            @ApiField(name="name",value="学生姓名"),
            @ApiField(name="gender",value="学生性别(1男,2女)",allowableValues = "1,2"),
            @ApiField(name="studentNo",value="学号")

    })
    public JsonObject updateStudent(StudentInfo studentInfo) {
        demoService.updateStudent(studentInfo);
        return JsonObject.SUCCESS;
    }

    @PutMapping("/student/delete")
    @ApiOperation("删除学生信息")
    @ApiParamRequest({
            @ApiField(name="ids",value="学生ID",allowMultiple = true)
    })
    public JsonObject deleteStudent(@RequestParam("ids") String[] ids) {
        demoService.deleteStudent(ids);
        return JsonObject.SUCCESS;
    }

    @PutMapping("/student/get")
    @ApiOperation("查看学生信息")
    @ApiParamRequest({
            @ApiField(name="studentId",value="学生ID")
    })
    @ApiJsonResponse({
            @ApiField(name="studentId",value="学生ID"),
            @ApiField(name="name",value="学生姓名"),
            @ApiField(name="gender",value="学生性别(1男,2女)",allowableValues = "1,2"),
            @ApiField(name="studentNo",value="学号")
    })
    public JsonObject

``` Вот перевод текста на русский язык:

Это стандартный способ написания контроллера с добавлением аннотаций Swagger. С точки зрения кода, в нём практически нет ничего особенного. Аннотации @ApiJsonResponse и @ApiField являются расширениями фреймворка. Поскольку объект JsonObject содержит только стандартные структуры свойств, он не может правильно и точно отражать структуру возвращаемых данных JSON. Эти две аннотации позволяют отобразить структуру JSON в интерфейсе Swagger.

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

>Поскольку здесь представлен только бэкэнд-интерфейсный сервис и отсутствует интегрированная страница, вы можете протестировать интерфейс через Swagger (http://localhost:8080/swagger-ui.html):

**О конструкторе запросов**

SelectBuilder  это конструктор для построения запросов. Он позволяет инкапсулировать часть SQL-запросов в конструктор, что способствует оптимизации логики SQL-инъекций. SelectBuilder часто используется в реализации интерфейса QueryCreator. Интерфейс предоставляет метод, который принимает объект репозитория сущностей для удобства получения объекта определения сущности. Это необходимо, поскольку конструктор требует предоставления объекта сущности при построении запроса. Затем вызывается метод where() для начала условий и, наконец, метод build() возвращает объект QuerySupport.

Ниже представлена диаграмма последовательности вызовов методов SelectBuilder, которая включает основные методы SQL-сборки:

Далее следует базовый пример использования SelectBuilder:

```java
// Подготавливаем карту значений параметров запроса
Map<String, Object> paramMap = ParamMap.create("userName", "刚").set("age","20").toMap();

// Создаём конструктор запросов
SelectBuilder sqlBuiler = new SelectBuilder(paramMap);

// Связываем два поля запроса, которые должны быть возвращены (все поля из a-псевдонима таблицы и все поля из b-псевдонима, кроме поля userId)
sqlBuiler.bindFields("a",userEntityDef.getFieldList())
           .bindFields("b", BeanDefUtils.excludeField(orgUserEntityDef.getFieldList(),"userId"));

// Сначала строим запрос к таблице и связываем их (первый параметр — псевдоним, второй — объект сущности, соответствующей таблице), затем строим условие запроса
sqlBuiler.from("a",userEntityDef).innerJoin("b",orgUserEntityDef)
   .where()
  .and("a.USER_NAME", ConditionType.BEGIN_WITH,"userName")
  .or("a.AGE", ConditionType.IS_NOT_EMPTY);

// Этот запрос требует подсчёта количества полей
sqlBuiler.bindAggregate("a.USER_NAME", AggregateType.COUNT);
QuerySupport querySupport = sqlBuiler.build();

Окончательный сформированный SQL-запрос выглядит следующим образом:

SELECT a.USER_ID,a.USER_NAME,a.GENDER,a.BIRTHDAY,COUNT(a.AGE) AS AGE,a.ENABLE,b.ORG_USER_ID,b.ORG_ID  FROM DEMO_USER a INNER JOIN DEMO_ORG_USER b ON a.USER_ID=b.USER_ID WHERE a.USER_NAME LIKE ? OR  (a.AGE IS NOT NULL AND a.AGE !='') 

Параметр: «刚%».

Мы будем постепенно улучшать этот проект. Если у вас есть какие-либо вопросы о K-Duck Framework, пожалуйста, напишите нам по адресу lhg_0317@163.com.

Комментарии ( 0 )

Вы можете оставить комментарий после Вход в систему

Введение

K-Duck-Core — это открытый и бесплатный фреймворк для разработки, основанный на Spring MVC, Spring и Spring JdbcTemplate. На его основе можно быстро создать нужные функциональные модули. В отличие от других фреймворков, в K-Duck-Core данные таблиц инкапсулированы в виде объектов. Фреймворк полностью берёт на себя логику доступа к данным, разраб... Развернуть Свернуть
Java
Apache-2.0
Отмена

Обновления

Пока нет обновлений

Участники

все

Недавние действия

Загрузить больше
Больше нет результатов для загрузки
1
https://api.gitlife.ru/oschina-mirror/lhg317-kduck-core.git
git@api.gitlife.ru:oschina-mirror/lhg317-kduck-core.git
oschina-mirror
lhg317-kduck-core
lhg317-kduck-core
PR-1