(Это относится к Project Student, и я вернусь к этой теме позже.)
Spring Data попал в прошлое в нескольких недавних интервью. Что такое Spring Data ?
Чтобы ответить на это, давайте рассмотрим стандартный подход к постоянству — весь доступ осуществляется через объекты доступа к данным (DAO). Это полностью изолирует остальную часть системы от конкретных деталей механизмов персистентности. Это звучит легко, но любой, кто когда-либо делал нетривиальный проект, знает, что есть большая головная боль.
Код DAO скучен.
Он монотонный, в нем много очень похожего кода, и небольшая ошибка может привести к значительному ущербу. Хуже того, он нарушает принцип « Не повторяйся» (СУХОЙ), так как большая часть информации уже зафиксирована в аннотациях JPA.
Это такая большая проблема, что в течение многих лет были инструменты генерации кода. Теоретически они решают проблемы, но на практике они представляют свои. Например, необходимость пользовательских файлов конфигурации или аннотаций.
Использование интерфейса в качестве сухого контракта
Каков окончательный СУХОЙ контракт в мире Java? Это просто — это интерфейс. Учитывая интерфейс и шаблон, мы можем использовать CGLib для генерации необходимых классов на лету во время запуска приложения. Есть небольшой удар по производительности, но он скромный по сравнению с преимуществами.
Student.java
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
@Entity public class Student { private Integer id; private String uuid; private String name; private String emailAddress; private Integer creditHours; @Id public Integer getId() { return id; } public void setId(Integer id) { this .id = id; } @Column (unique= true ) public String getUuid() { return uuid; } public void setUuid(String uuid) { this .uuid = uuid; } @Column public String getName() { return name; } public void setName(String name) { this .name = name; } @Column (unique= true ) public String getEmailAddress() { return emailAddress; } public void setEmailAddress(String emailAddress) { this .emailAddress; } @Column public Integer getCreditHours() { return creditHours; } public void setCreditHours(Integer creditHours) { this .creditHours = creditHours; } } |
Как может выглядеть наш интерфейс?
хранилище / StudentRepository.java
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository public interface StudentRepository extends CrudRepository<Student, Integer> { // this could also be getByUuid() or fetchByUuid() - all are recognized Student findStudentByUuid(String uuid); Student findStudentByEmailAddress(String emailAddress); List<Student> findStudentsByNameLike(String pattern); // we can use a custom query @Query ( "select s from Student s where s.creditHours < 15" ) List<Student> findFreshmen(); } |
и так далее. Всего существует 15 предикатов, которые можно использовать отдельно или в комбинации.
- И
- Или же
- Между
- Меньше, чем
- Лучше чем
- Нулевой
- IsNotNull
- Ненулевой
- подобно
- Не как
- Сортировать по
- Не
- В
- Не в
- IgnoreCase
NB, нет необходимости реализовывать этот интерфейс! CGLib позаботится об этом за нас.
Пользовательские Методы
Иногда нам нужно написать наши собственные методы DAO. Их легко интегрировать в сгенерированный код.
01
02
03
04
05
06
07
08
09
10
11
|
public interface StudentExtras { Student flogStudent(Student student); } @Repository public interface StudentRepository extends CrudRepository<Student, Integer>, <em>StudentExtras</em> { } // this class does NOT implement StudentRepository! public class StudentRepositoryImpl implements StudentExtras { public Student flogStudent(Student student) { ... } } |
Пользовательские методы должны быть определенным классом (из-за конфигурации по соглашению), но в остальном не ограничены.
NoSQL
Spring Data также прозрачно поддерживает базы данных NoSQL: Mondo (документы), Neo4j (график), Redis (ключ-значение), Hadoop (отображение-уменьшение) и GemFire.
пагинация
Наконец, у нас есть вопрос о нумерации страниц. Пользовательские интерфейсы обычно рассматривают только подмножество доступной информации, например, страницу из 25 элементов. Разбивка на страницы не сложна, просто скучна и подвержена ошибкам.
Spring Data поддерживает разбиение на страницы, расширяя интерфейс PagingAndSortingRepository вместо интерфейса CrudRepository.