Онлайн проект Topjava
добавил
setenv.shи@Override, пофиксил имяDATE_TIME_FORMATTER
- Apply 0-correction.patch
1. HW2
Изменения в проекте:
-
В репозиториях по другому инстанциировал компараторы
-
Пернес обработку пустых дат в
MealRestController.getBetween() -
Зарефакторил
<T extends Comparable<? super T>> TimeUtil.isBetween(T value, T start, T end). Дженерики означают, что мы принимаем экземпляры класса, который имплементит компаратор, который умеет сравнивать T или суперклассы от T -
Apply 1-HW2-repository.patch
Внимание: при удалении класса он остается скомпилированный у вас в target (и classpath). В этом случае (или вообще если непонятно почему проект глючит) сделайте в maven clean.
- Apply 2-HW2-meal-layers.patch
- Apply 3-HW2-optional-MealServlet.patch
- Apply 4-HW2-optional-filter.patch
- Apply 5-HW2-optional-select-user.patch
- Should services always return DTOs, or can they also return domain models?
- Mapping Entity->DTO goes in which application layer: Controller or Service?
Какой смысл в
Objects.requireNonNull()? Если у нас объект == null он бросает NPE (NullPointException), но оно вылетит и без этого метода. What is the purpose of Objects#requireNonNull
Предусловия будет на 4м уроке. Мы падаем сразу и понятно где по стактрайсу. А не может быть потом и разбирайся откудаю.
- Apply 6-bean-life-cycle.patch
- Spring изнутри. Этапы инициализации контекста.
- Ресурсы:
ВНИМАНИЕ: перед накаткой патча создайте каталог test (из корня проекта путь
\src\test), иначе часть файлов попадет вsrc\main.
- Apply 7-add-junit.patch
- Перенос mock реализации в test.
- JUnit 4
- Тестирование в Java. JUnit
5. Spring Test
- Apply 8-add-spring-test.patch
- Интеграция Spring и JUnit.
- Spring Testing
- PostgreSQL.
- Установка PostgreSQL.
- Решение проблемы устновки
Problem running post-install step. Installation may not complete correctly. The database cluster inicialisation failed.
Создать в pgAdmin новую базу
topjavaи новую рольuser, парольpassword
- NoSQL or RDBMS. Обзор NoSQL систем. CAP
- DB-Engines Ranking
- JDBC
- Обзор Java persistence solution без ORM: commons-dbutils, Spring JdbcTemplate, MyBatis, JDBI, jOOQ
- Основы:
- Apply 9-add-postgresql.patch
- Настройка Database в IDEA и запуск SQL.
- Apply 10-populate-and-init-db.patch
- Apply 11-impl-JdbcUserRepository.patch
- Подключение Spring Jdbc.
- Конфигурирование DataSource. Property Placeholder
Проверьте, что в контекст Spring проекта включены оба файла конфигурации.
- Имплементация UserRepository через Spring Jdbc Template.
Вопрос по реализации
JdbcUserRepositoryImpl: вgetиспользуетсяqueryа вgetByEmail-queryForObject. Где правильно и почему?
- Apply 12-test-UserService.patch
Изменение: обертку для сравнения инстансов при тестировании перенес в сам матчер (
ModelMatcher.Wrapper). Он сравнивает инстансы по переданному как параметр компаратору. Класс из видеоUserTestData.TestUserстал не нужен.
- Подготовка тестовых данных в UserServiceTest и ModelMatcher
- Тестирование UserService.
- Apply 13-test-logging.patch
- Apply 14-fix-servlet.patch
- Что такое REST? 10 Best Practices for Better RESTful API
- Зачем нужна сортировка еды?
- Можно ли обойтись без
MapSqlParameterSource? - Как происходит работа с DB в тестах?
- Как реализовывать RowMapper?
- Мои комментарии: решения проблем разработчиком.
- Нужен ли разработчику JavaScript?
Какая разница между @BeforeClass and @Before?
@BeforeClass выполняется один раз после загрузки класса (поэтому метод может быть только статический), @Before перед каждым тестом. Не ленитесь сходить в исходники по Ctrl+Enter и почитать javadoc.
Дополнение: для чистоты экземпляр тестового класса пересоздается перед каждым тестом: http://stackoverflow.com/questions/6094081/junit-using-constructor-instead-of-before
Тесты в классе в каком-то определенном порядке выполняются ("сверху вниз" например)?
Порядок по умолчанию неопределен, каждый тест должен быть автономен и не зависеть от других. См. также http://stackoverflow.com/questions/3693626/how-to-run-test-methods-in-specific-order-in-junit4
Обязательно ли разворачивать postgreSQL?
Желательно: хорошая и надежная DB:) Если совсем не хочется - можно работать со своей любимой RDBMS (поправить initDB.sql) или работать c heroku (креденшелы к нему есть в postgres.properties). На следующем уроке добавим HSQLDB, она не требует установки.
Зачем начали индексацию с 100000?
Тут уже нет "как принято". Так удобно вставлять в базу (если будет потребность) записи вручную , не мешая счетчику.
Разве не должно быть у каждой роли примари кей id и форин кей user_id ?
Отношение user <-> roles многие ко многим, делается это через таблицу-связку USER_ROLES. Но отдельной таблицы ROLES у нас нет, мы храним значение роли прямо в таблице-связке USER_ROLES. "Примари кей" тут не нужны. Есть еще варианты использовать тип enum у Postgres или хранить там INTEGER как Roles.ordinal(). При этом нельзя будет менять порядок в enum Role и добавлять новые роли можно будет только в конец: http://stackoverflow.com/questions/6789342/jpa-enum-ordinal-vs-string
Из 5-го видео - "Логика в базе - большое зло". Можно чуть поподробней об этом?
- Есть успешные проекты с логикой в базе. Те все относительно.
- Логика в базе - это процедуры и триггеры. Нет никакого ООП, переиспользовать код достаточно сложно, никагого рефакторинга, поиска по коду и других плюшек IDE. Нельзя делать всякие вещи типа кэширования, хранения в сесии - это все для логики на стороне java. Например json можно напрямую отдать в процедуру и там парсить и вставлять в таблицы или наоборот - собирать из таблиц и возвращать. А затем потребуется некоторая логика на стороне приложения и все равно придется этот json дополнительно разпарсивать в java. Я на таком проекте делал специальную миграцию, чтобы процедуры мигрировать не как sql скрипты, а каждую процедуру хранить как класс с историей изменений. Если логика: триггеры и простые процедуры записи-чтения, которые не требуют переиспользования кода или проект небольшой это допустимо, иначе проект становится очень трудно поддерживать.
У JUnit есть ассерты и у спринга тоже. Можно ли обойтись без JUnit?
Предусловия и JUnit-тесты совершенно разные вещи. Один другого не заменит, у нас будут предусловия в следующем уроке.
Я так понял VARCHAR быстрее, чем TEXT, когда мы работаем с небольшими записями. Наши записи будут небольшими (255). Почему вы приняли решение перейти на TEXT?
В отличие от MySql в Postgres VARCHAR и TEXT - тоже самое: http://stackoverflow.com/questions/4848964/postgresql-difference-between-text-and-varchar-character-varying
Зачем при создании таблицы мы создаем
CREATE UNIQUE INDEXиCREATE INDEX. При каких запросах он будет использоваться?
UNIQUE индекс нужен для обеcпечения уникальности, DB не даст сделать одинаковый индекс. Индексы используется для скорости выполнения запросов. Обычно они задействуются, когда в запросе есть условия, на которые сделан индекс. Узнать по конкретному запросу можно запросив план запроса: см. Оптимизация запросов. Основы EXPLAIN в PostgreSQL. На измерение производительности с индексами посмотрим в следующем уроке.
А это нормально, что у нас в базе у meals есть userId, а в классе - нет?
Что значит - "нормально"? Приложение работает. Ненормально, когда в приложении есть "лишний" код, который не используется. Для ORM он нам понадобится- мы ссылку на User добавим.
Почему мы использует 1 БД sequence на разные сущности?
Мы будем использовать Hibernate, по умолчанию он делает глобальный sequence на все таблицы. В этом подходе есть как плюсы, так и минусы, из плюсов - удобно делать ссылки в коде и в таблицах на при наследовании и мапы в коде. В дополнение: Configure Hibernate to create separate sequence for each table by default.
- Понять, почему перестали работать
SpringMain/InMemoryAdminRestControllerTest/ InMemoryAdminRestControllerSpringTest - Дополнить скрипты создания и инициализации базы таблицой MEALS. Запустить скрипты на вашу базу (через Run). Порядок таблиц при DROP и DELETE важен, если они связаны fk. Проверьте, что ваши скрипты работают
- Реализовать через Spring JDBC Template
JdbcMealRepositoryImpl3.1. сделать каждый метод за один SQL запрос 3.2.userIdв классMealвставлять НЕ надо (для UI и REST это лишние данные, userId это id залогиненного пользователя) 3.3.JbdcTemplateработает через сеттеры. Вместе с конструктором по умолчанию их нужно добавить вMeal3.4. Cписок еды должен быть отсортирован (тогда мы его сможем сравнивать с тестовыми данными). Кроме того это требуется для UI и API: последняя еда наверху. - Проверить работу MealServlet, запустив приложение
- Сделать тестовые данные
MealTestData, АНАЛОГИЧНЫЕ пропопулированным вpopulateDB.sql. Сравниваем данные через готовый MATCHER (по умолчанию) - Сделать
MealServiceTestизMealService(Ctrl+Shift+Tи выбрать JUnit4) и реализовать тесты. - Сделать тесты на чужих юзеров (delete, get, update) с тем чтобы получить
NotFoundExceptionи тесты наupdateчужой еды. - Предложить решение, как почнинить
SpringMain/ InMemory*Test.InMemory*Testпредполагает использовать нашу реализацию репозитория в памяти - Сделать индексы к таблице
Meals.
В JUnit тестах проблама с кодировкой
См. http://stackoverflow.com/a/17671104/548473, нужно в pom.xml в plugins добавить:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<argLine>-Dfile.encoding=UTF-8</argLine>
</configuration>
</plugin>
Из каталога
mainне видятся классы/ресурсы вtest
Все что находится в test используется только для тестов и недоступно в основном коде
Из
IDEAне видятся ресурсы в каталогеtest
- Сделайте Reimport All в Maven окне
- Поставьте чекбокс
Check test filesв Inspections. Spring test контекст не надо включать в Spring Facets проекта.
- В
MealTestDataеду делайте константами. Не надоMapконструкций! - SQL case-insensitive, не надо писать в стиле Camel. В POSTGRES возможно case-sensitive значения в кавычки заключать (но не нужно).
- ЕЩЕ РАЗ:
InMemoryтесты должны идти наInMemoryрепозитории - В
MealTestDataможно использовать дефолтный компаратор - Проверьте, что возвращает
JdbcMealRepositoryImplпри обновлении чужой еды





