Обновить
43
6.4

Пользователь

Отправить сообщение

Да ладно. А MyBatis какие данные маппит? Случайно не реляционные? Может оно XML парсит?

Я же загуглить успел. MyBatis вполне себе ORM, на хабре статьи про неё есть. Внезапно с тегом ORM. Я не разобрался, умеет ли оно в джоин. Скорее всего нет. Там концепция "сам напиши свои джойны, я только маплю".

Дружище, определись уже. Либо оно мапит данные на класс, то тогда оно ORM, либо не маппит, тогда оно не ORM.

В каком порядке будет выполняться запрос?

Язык SQL декларативный. В том порядке, в котором захочет СУБД. Проще её саму спросить. Индексы БД не обязана использовать, но обычно использует. Если данных много - крутите кэши под ваш сценарий. Может у вас хэви инсерт, а для селекта можно подождать - тогда кэши не спасут.

Сомневайтесь, это полезно. Проясню ремарку: сегодняшние orm, пока в них не внедрили нейросети, очень сильно ограничены по функционалу. В сгенерированных запросах нет ничего сложного. Нет латерал джойнов, в юнионы по-моему ни одна не умеет. Даже group by с having умеют единицы. Про CTE вообще молчу. Человек намного изощрённее любой ORM. Естественная нейросеть способна нагородить куда более ужасную и изощрённую конструкцию, чем самый продвинутый фреймворк

В теории всё так. But.

In theory, theory and practice are the same. In practice, they are not.

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

p.s. триггеры, юники, ключи и прочие констрейнты работают не только для встроенного языка

Если вам сложно не нагородить десятиэтажных конструкций, может вам не надо в айти? Айти всё-таки про огромное количество вариантов, как сделать одно и то же. Здесь нет точного рецепта, как правильнее. Тут самому приходится выбирать пути, ошибаться и пробовать снова. И ещё нести ответственность за выбранные решения.

И кто вам запретит писать сложные тяжёлые запросы? У вас кто-то насильно отбирает SQL?

Специально сконструированный язык базы данных действительно быстрее за счёт быстрого доступа. В теории.

На практике эта скорость никому не нужна, пока приложение не умеет делать то, что оно должно делать. Быстро, но фигню - это не надо.

На практике получается парадоксальная ситуация: переписанная логика pl/sql в сишарп начинает работать быстрее в разы. Как такое возможно? Теоретически никак. Доступ к данным у шарпа по определению медленнее.

маппить результаты запросов на сущности

Это ORM. По определению.

без недостатков ORM

Заманчиво. Орм без недостатков орм. Как это?

Собственно, меня огорчает, что люди противопоставляют ORM чистому SQL. Одно другому не мешает. ОРМ - маппинг. SQL - язык запросов.

когда вы поняли, что будете работать с базой данных

Простите, а зачем вам база данных в контроллере с 16кб памяти?

Это одно из самых распространённых заблуждений об ORM, которые я встречал. Делать сложные запросы - это не задача ORM. ORM в первую очередь - маппер. ORM и SQL вообще ортогональны в этом вопросе.

Тут так: если хотите читаемый и поддерживаемый код: пишете на орм. Хотите любить гусей - пишете на чистом sql. Как-то одно другому мешает? На практике оказывается, что сложные запросы нужны, мягко скажем, не в критичном количестве. А ежедневная рутина делается проще на орм.

Некоторые ORM вообще могут работать с raw sql. Просто позволяют писать запросы, и после делают маппинг на объекты.

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

Я уже однажды приводил пример:

Orders.Where(o => o.IsCompleted && o.CreatedDate.Year > 2020).OrderBy(o.ID)

Трансформируется в:

SELECT * FROM db.Orders a WHERE a.IsCompleted = 1 AND YEAR(a.CreatedDate) > 2020 ORDER BY a.ID

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

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

Мы просто не знаем, зачем добавили прямоугольник в приложение. Это область детектирования номерных знаков автомобиля? Это баундбокс текстовой строки? Это примитив рисования?

Наследование квадрата от прямоугольника может быть правильным. Как и наследования прямоугольника от квадрата. Смотря чего хотите.

С одной стороны соглашусь. Команда должна быть сильная, чтобы понимать, что она делает и зачем. Конечно, без базовых знаний SQL заниматься разработкой приложения с ORM прямо противопоказано. Архитектурой тем более должен заниматься сильный программист, а внедрение ORM - это архитектура приложения.

С другой стороны, ORM умеет генерить селекты c where и некоторые умеют в left join. У EF правда есть linq to entities, где можно совращать гусей, но тут синтаксис максимально близок к sql. Если честно, совсем не понимаю, что в этих запросах может быть сложного.

Простите, а когда это "потом" начнётся? Один проект у меня уже 13 лет на ORM, пока всё хорошо. Или имеется в виду, что падает скорость разработки? Тогда тем более непонятно. ORM как раз нужен, чтобы снизив сложность, её повысить. И это работает.

Потому, что интерфейсом пользуются. Если им не пользуются, то "you ain't gonna need it". Тебе не нужен интерфейс без реализации, потому что им пользоваться не будут.

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

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

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

В случае с тестами оказывается, что мок класс - тоже класс. Внезапное такое откровение. И он станет второй реализацией.

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

  1. Single responsibility. В вашем примере нарушается инкапсуляция класса непонятно за какими целями. Вообще вполне нормально может быть, что робот может и move и speak. Вполне возможно, что у него эти методы завязаны на одних и тех же данных внутри класса. Если слепо следовать S, то у класса вылезают кишки наружу, логика переносится в другие классы, плодятся контроллеры, сервисы и прочие странные мутанты. Я уж не говорю про DDD, где класс соответствует термину предметной области - тут прямой конфликт с принципом единственной ответственности.

  2. Вы приводите в качестве примера простое использование наследования. Никакого отношения к OCP это не имеет. OCP - это когда часть класс спроектирован так, что можно без труда поменять логику в унаследованном классе, не трогая базовый класс.

  3. LSP. А что, если подставить экземпляр студента вместо персоны, он не будет работать? Пример нарушения - это как раз когда наследуют прямоугольник от квадрата и удивляются, почему при задании одного размера его не видно. Конечно, квадрат - это частный случай прямоугольника.

  4. ISP. Интерфейс вообще-то строится для клиентского кода. Соответственно, интерфейс может дробиться только до уровня требований этого кода. Если он требует объект, который должен и говорить и двигаться, то разделять эти интерфейсы не нужно. В вашем примере вы рассматриваете неправильную проектировку самого класса, а не интерфейсов. Ну на этапе создания Robot уже должно дойти, что он не умеет летать, верно?

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

Велосипед можно бросить в одно мгновение, чтобы отпрыгнуть в нужную сторону. Если, конечно, на нём не едешь.

У меня эта статья вызвала флешбеки )

Если мы получаем от словаря ссылку на структуру и потом работаем по ссылке, то чем, собственно говоря, это отличается от класса?

Да, есть небольшой выигрыш за счёт того, что ссылки не считаются и ансейф во все поля. Но этот выигрыш чувствителен только для сценария с большим количеством поисков и не пополняющимся словарём. Для такого сценария существуют контейнеры получше, вроде FrozenDictionary. А то и бинарное дерево.

И сравнение считаю некорректным. Структуры у вас с ружьём, направленным в ногу, а классы используют стандартный сейф механизм.

И ещё. Не нашёл в коде объявления GetHash и Equals. Может у вас хэш коллизит и поиск деградировал до линейного.

Какое кошмарное выравнивание на КДПВ...

Информация

В рейтинге
917-й
Зарегистрирован
Активность