Использование Spring Data JPA

Spring

В предыдущей статье JPA использовался для настройки источника данных в Spring JavaConfig, здесь мы представим общие методы Spring data jpa.

Введение в весенние данные jpa

Что такое JPA

JPA (Java Persistence API) — это спецификация сохраняемости Java, официально предложенная Sun. Он предоставляет разработчикам Java инструмент сопоставления объектов и ассоциаций для управления реляционными данными в приложениях Java.

Spring Data JPA — это набор фреймворков приложений JPA, инкапсулированных Spring на основе фреймворка ORM и спецификации JPA, что позволяет разработчикам получать доступ к данным и работать с ними с минимальным кодом. Он предоставляет общие функции, включая CRUD и т. д., и его легко расширять! Изучение и использование Spring Data JPA может значительно повысить эффективность разработки!

spring data jpa освобождает нас от работы слоя DAO, в основном все CRUD могут полагаться на него для достижения

Простой запрос

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

Spring data jpa по умолчанию предварительно сгенерировал некоторые основные методы CURD, такие как: добавить, удалить, изменить и т. д.

public interface ItemRepository extends JpaRepository<Item, Integer>, JpaSpecificationExecutor<Item> {
//空的,可以什么都不用写
}
@Test
public void test1() throws Exception {
    Item item = new Item();
    itemRepository.save(item);
    List<Item> itemList = itemRepository.findAll();
    Item one = itemRepository.findOne(1);
    itemRepository.delete(item);
    long count = itemRepository.count();
}

Пользовательский простой запрос

Item findByItemName(String itemName);

List<Item> findByItemNameLike(String itemName);

Long deleteByItemId(Integer id);

List<Item> findByItemNameLikeOrderByItemNameDesc(String itemName);

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

Keyword Sample JPQL snippet
And findByLastnameAndFirstname … где x.lastname = ?1 и x.firstname = ?2
Or findByLastnameOrFirstname … где x.lastname = ?1 или x.firstname = ?2
Is,Equals findByFirstnameIs,findByFirstnameEquals … где x.имя = ?1
Between findByStartDateBetween … где x.startDate между ?1 и ?2
LessThan findByAgeLessThan … где x.age
LessThanEqual findByAgeLessThanEqual … где x.age ⇐ ?1
GreaterThan findByAgeGreaterThan … где x.age > ?1
GreaterThanEqual findByAgeGreaterThanEqual … где x.age >= ?1
After findByStartDateAfter … где x.startDate > ?1
Before findByStartDateBefore … где x.startDate
IsNull findByAgeIsNull … где x.age равно нулю
IsNotNull,NotNull findByAge(Is)NotNull … где x.age не нуль
Like findByFirstnameLike … где x.firstname как ?1
NotLike findByFirstnameNotLike … где x.firstname не похоже на ?1
StartingWith findByFirstnameStartingWith … где x.firstname как ?1 (параметр связан с добавленным %)
EndingWith findByFirstnameEndingWith … где x.firstname как ?1 (параметр связан с предваряемым %)
Containing findByFirstnameContaining … где x.firstname как ?1 (параметр привязан к %)
OrderBy findByAgeOrderByLastnameDesc …где x.age = ?1 порядок по x.lastname desc
Not findByLastnameNot … где x.lastname ?1
In findByAgeIn(Collection ages) … где x.age в ?1
NotIn findByAgeNotIn(Collection age) … где x.age не в ?1
TRUE findByActiveTrue() … где х.актив = истина
FALSE findByActiveFalse() … где х.актив = ложь
IgnoreCase findByFirstnameIgnoreCase … где ПРОПИСНЫЕ(x.firstname) = ПРОПИСНЫЕ(?1)

Пейджинговый запрос

Page<Item> findALL(Pageable pageable);
@Test
public void test1() throws Exception {
    int page=1,size=10;
    Sort sort = new Sort(Sort.Direction.DESC, "id");//根据id降序排序
    Pageable pageable = new PageRequest(page, size, sort);
    Page<Item> pageResult = itemRepository.findALL(pageable);
    List<Item> itemList = pageResult.getContent();
}

Пользовательский SQL-запрос

Используйте его в методе запроса SQL@QueryКомментарии, такие как удаление и изменение, должны быть добавлены@Modifying, также можно добавить по мере необходимости@Transactionalподдержка вещей

//自定分页查询 一条查询数据,一条查询数据量
@Query(value = "select i from Item i",
        countQuery = "select count(i.itemId) from Item i")
Page<Item> findall(Pageable pageable);

//nativeQuery = true 本地查询  就是使用原生SQL查询
@Query(value = "select * from item  where item_id = ?1", nativeQuery = true)
Item findAllItemById(int id);

@Transactional
@Modifying
@Query("delete from Item i where i.itemId = :itemId")
void deleteInBulkByItemId(@Param(value = "itemId") Integer itemId);

//#{#entityName}就是指定的@Entity,这里就是Item
 @Query("select i from #{#entityName} i where i.itemId = ?1")
 Item findById(Integer id);

именованный запрос

Аннотируйте классы сущностей с помощью @NameQueries

Определите одноименный метод в интерфейсе репозитория DAO, реализованный самостоятельно

Затем его можно использовать, Spring сначала узнает, есть ли NamedQuery с таким же именем, если есть, то он не будет парситься в соответствии с методом, определенным интерфейсом.

//命名查询
@NamedQueries({
        @NamedQuery(name = "Item.findItemByitemPrice",
                query = "select i from Item i where i.itemPrice between ?1 and ?2"),
        @NamedQuery(name = "Item.findItemByitemStock",
                query = "select i from Item i where i.itemStock between ?1 and ?2"),
})
@Entity
@Data
public class Item implements Serializable {
    @Id
    @GeneratedValue
    @Column(name = "item_id")
    private int itemId;
    private String itemName;
    private Integer itemPrice;
    private Integer itemStock;
 }
/**
 * 这里是在domain实体类里@NamedQuery写对应的HQL
 * @NamedQuery(name = "Item.findItemByitemPrice",
               baseQuery = "select i from Item i where i.itemPrice between ?1 and ?2"),
 * @param price1
 * @param price2
 * @return
 */
List<Item> findItemByitemPrice(Integer price1, Integer price2);
List<Item> findItemByitemStock(Integer stock1, Integer stock2);

Итак, как spring data jpa собирает операторы запросов с помощью этих спецификаций?

Когда среда Spring Data JPA анализирует имя метода, она сначала перехватывает избыточный префикс имени метода, такой как find, findBy, read, readBy, get, getBy, а затем анализирует остальные.

Если вы создаете следующий запрос:findByUserDepUuid(), когда фреймворк анализирует метод, он сначала удаляет findBy, а затем анализирует оставшиеся свойства
  1. Сначала оцените, является ли userDepUuid (по спецификации POJO первая буква становится строчной) атрибутом сущности запроса, если да, то значит запрашивать по этому атрибуту, если такого атрибута нет, переходим ко второму шагу;
  2. Перехватываем строку, начинающуюся с первой заглавной буквы справа налево, здесь Uuid), а затем проверяем, является ли оставшаяся строка атрибутом сущности запроса, если да, то значит запрос по этому атрибуту; если такого нет attribute , затем повторите второй шаг, продолжайте перехватывать справа налево, наконец, предположим, что user является атрибутом объекта запроса;
  3. Затем обработайте оставшуюся часть (DepUuid), сначала определите, есть ли у типа, соответствующего пользователю, атрибут depUuid, если да, то значит метод окончательно основан наDoc.user.depUuidзапрос; в противном случае продолжить перехват справа налево по правилам шага 2 и, наконец, выразитьDoc.user.dep.uuidзначение для запроса.
  4. Может быть особый случай, например, Doc содержит атрибут пользователя, также имеет атрибут userDep, будет путаница. Вы можете явно добавить «_» между атрибутами, чтобы явно выразить намерение, например.findByUser_DepUuid()илиfindByUserDep_uuid()

Оригинальная ссылка:Использование Spring Data JPA | Хуо Яо