Здравствуйте, Sinclair, Вы писали:
S>Нам надо построить отчёт "студент — средняя оценка по всем курсам". Какого класса будет элемент этого списка?
Ну, какого надо, такого и будет. Предлагаю StudentAverage{Student student, Integer avg}
T>>lazy load вроде просто не лезет в базу за зависимыми сущностями, пока они не понадобятся. Это не кеш.
S>И где же лежат зависимые сущности, которые "понадобились"?
В памяти приложения. Если ты сделаешь не lazy load, они тоже будут лежать в памяти приложения. lazy load тут ничего не меняет.
S>Вкратце, там мы бежим по строчкам ордера, и для каждой из них уменьшаем остаток товара на складе на соответствуюшее количество. Если натыкаемся на недостаток — то откатываем всю транзакцию. Если всё нашлось — то помечаем ордер как "ожидает отгрузки".
S>В SQL это всё делается одним стейтментом. В ORM — это 2*N запросов на чтение и N на модификацию.
Это ты о том, что можно сделать один sql запрос, который все операции проведёт не выходя за пределы СУБД, а можно слать несколько отдельных запросов из приложения? И, так как ORM не поддерживает ничего, кроме базового sql — с помощью ORM такого сделать нельзя? Согласен — нельзя, согласен — недостаток, это тот случай, когда надо использовать хранимки.
S>Получается, что мы не можем пользоваться "прямым SQL" минуя кэш лейзи-лоада внутри транзакции, что как раз заставляет нас писать вот этот вот ужасный код с foreach(orderline in order.lines)
Мне кажется мы как-то по разному используем термин lazy load. Вот смотри, допустим, мы вытащили запросом студентов из первого пункта. Плюс мы знаем, что CourseMark загружаются лениво. Мы у половины студентов посмотрели оценки за курсы, а у половины — нет. Теперь у нас у половины студентов CourseMark есть в памяти приложения, а у половины — нет. А дальше мы отсылаем запрос с каунтом по всем студентам. Запрос пойдёт мимо приложения, сразу в БД. Подсчитает результат и вернёт его нам. То, что по факту у половины студентов CourseMark не загружен ни на что не повлияет.
А вот, если ты напишешь код типа
foreach(student in students) {
foreach (course in student.courseMarks){
sum += course.mark;
}
}
то нарвёшься на проблему N + 1. Из-за lazy load.