Java выбранное значение select

java8. Пишем SQL запросы к java коллекциям. (часть I).

Рассматривается возможность реализации в java8 синтаксиса SQL запросов (Select) для работы с java коллекциями записей, имитирующими таблицы БД.

Позиционирование задачи

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

Основной вопрос статьи

Часто для проведения конкретных расчетов в java приложении, требуется только малая часть данных, загруженных из БД в мастер-детальные коллекции. Чтобы получить эти данные, необходимо организовывать многочисленные вложенные циклы на этих коллекциях, отсеивать ненужные записи и т. д. В результате код получается громоздким. Альтернативой этому могли бы стать SQL запросы к коллекциям. Они имеют компактную и прозрачную форму записи.

Основной вопрос статьи – можно ли, на java8 обеспечить SQL-образный синтаксис для работы с коллекциями?

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

Многое зависит от знания программистом SQL. Язык SQL требует преодоления некоторого барьера для своего освоения, после чего работа с SQL становится ясной, простой и предпочтительной. И программист, владеющий SQL, вероятно предпочтет использовать SQL запросы к java-коллекциям, а не вложенные циклы, а не владеющий SQL выберет циклы.

Лирическое отступление. Сон первый. Богатые женятся на бедных, а бедные на богатых.

В стране к власти пришли демократы(большевики). Они сказали – разброс зарплат слишком большой – надо уровнять.

Читайте также:  What are collection objects in java

Имеется БД, в которой есть таблицы:

  • factories – фабрики и заводы страны
  • workers – рабочие и проч. и их зарплаты
  • family – семейный состав рабочих

Зарплаты должны быть скорректированы следующим образом:

  • максимальная зарплата не может быть больше Pmax.
  • минимальная зарплата не может быть меньше Pmin.
  • отношение Pmax/Pmin на предприятии не может быть больше Kmax.
  • сумма зарплат до корректировки должна быть равна сумме после корректировки для каждого предприятия. Если не получается, то излишки забираются в спецфонд или недостатки возмещаются из спецфонда.

Написать ПО корректировки поручено программисту Шарикову.

Да… подумал Шариков, проще всего было бы все реализовать на ORACLE – данные в таблицах, а алгоритм для пересчета на PLSQL. Под каждый алгоритм – один SQL запрос и делать больше нечего. Но демократы(большевики) объявили ORACLE буржуазной лжепрограммой. Алгоритм должен быть написан на HIBERNATE, а данные должны быть легко переносимы в любую БД, которую поддерживает HIBERNATE. И все должно работать быстро!

Алгоритм на java я напишу легко и он будет быстро работать, и данные в HIBERNATE в java коллекции загрузить легко, но загружаться данные будут долго! Логично и проще было бы загружать данные по каждому предприятию и делать по нему корректировку, но чтобы ускорить загрузку придется загружать сразу все данные (всю БД), а не по частям (загрузить из БД в приложение данные одним запросом быстрее, чем многими запросами по частям). Памяти хватит (память сейчас дешевая). Вот только после загрузки, чтобы найти нужные данные придется писать многочсленные вложенные циклы со сложными фильтрами. Работать это будет достаточно быстро, но код получится очень громоздкий и ошибки

Вот, если бы можно было писать к java коллекциям SQL запросы, как в БД к таблицам.

Если бы можно было писать к java коллекциям SQL запросы …

Если бы можно было писать к java коллекциям SQL запросы …

Если бы можно было писать к java коллекциям SQL запросы …

Если бы можно было писать к java коллекциям SQL запросы …

Для кого эта статья.

Эта статья может быть интересна для программистов, использующих java8 и SQL.

Желательно, чтобы читатель был знаком:

  • с SQL запросами select
  • функциональным программированием java8, например, в объеме статьи “Лямбда-выражения в Java 8” (https://habrahabr.ru/post/224593/)
  • java8 Stream, например, в объеме статьи “Шпаргалка Java программиста 4. Java Stream API” (https://habrahabr.ru/company/luxoft/blog/270383/)

Давайте теперь рассмотрим, что мы будем делать и что не будем.

Что будем делать

  1. Будем формировать класс, поддерживающий синтаксис SQL запроса Select, последовательно добавляя в него такие опции как:
  • простые поля, поле *, калькулируемые поля, агрегируемые поля
  • distinct
  • where
  • order by
  • многоэтажные select
  • group by + having
  • union, minus, intersection
  1. Нас будет интересовать только синтаксис. Скорость работы и объем необходимой памяти не будут исследоваться в данной статье.
  2. Классы значений полей элементов коллекций могут быть только String, Integer, Long. Другие классы не включены, чтобы не перегружать статью подробностями.

Что не будем делать

  • Не будем загружать данные из БД в коллекции и вообще не будем как-либо использовать jdbc. Будем считать, что данные уже загружены.
  • Не будем создавать программный интерфейс для реализации SQL запросов типа insert, update, delete и для DDL.
  • Не будем исследовать работу в параллельном режиме.
  • В данной, первой части статьи мы ограничимся только запросами к одной коллекции (то есть во from будет только одна коллекция). Создание синтаксиса для многих коллекций предполагается осуществить во второй части статьи.

Два основных нововведения java8

java версии 1.8 ввела два основных нововведения — Функциональное программирование (ФП) и Stream. Далее, чтобы проложить канву к основной теме статьи краткий обзор этих нововведений.

Функциональное программирование

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

Во многих языках такая возможность присутствует. Допустим в PLSQL (языке БД ORACLE) есть возможность записать код в виде строки и потом выполнить (execute immediate) в нужном месте программы и … получить ошибку, что-то вроде ”колонки не существует”.

В java такой номер не пройдет, так как это противоречит одному из краеугольных камней java – все (что только можно) должно быть проверено на этапе компиляции. Нельзя подсовывать java на выполнение какой-то “серый“ (не проверенный на этапе компиляции) код.

В java нет таких программных единиц – функция, в java есть только объекты (еще есть примитивы, массивы, классы и интерфейсы).

Между тем, необходимость ФП, в java всегда присутствовала (и была реализована). Представим себе, что надо написать на java визуальный интерфейс, с использованием объектов класса Button. При нажатии мышкой на кнопке – объекте класса Button, должен быть выполнен некий код. Но где задать этот код? В java нет самостоятельной программной единицы – блок кода или функция. Единственным носителем функции (метода) является класс. Объекты только пользуются методами класса. Получается, чтобы написать новый метод надо создать новый класс, у него переопределить метод и в нем написать необходимый блок кода. Кроме того, попутно придется создать объект нового класса. Если надо, чтобы при нажатии на другую кнопку выполнился другой код, мы опять должны создать новый класс и новый объект класса, если нам надо, чтобы код выполнился при двойном клике, то опять надо создавать новый класс и новый объект.

Аналогичными задачами являются выполнение по таймеру и запуск задачи в новом потоке.

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

Что же дает java8 для ФП. По сути ничего нового. По-прежнему, надо создавать новый класс и новый объект. Но разработчики java, как бы говорят – Вам нужна возможность задавать блок кода. Хорошо, мы дадим такой синтаксис, что Вы будете писать только блок кода и список параметров, а все остальное (создание нового класса и объекта) будет автоматически выполнено за сценой.

Такой синтаксис назван лямбда выражением (далее просто лямбда).

Лямбда состоит из трех частей:

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

Источник

Оцените статью