Есть ли у Spring Data JPA способ подсчета энтузиастов с использованием разрешения имени метода?

127

Spring Data JPA поддерживает подсчет сущностей с использованием спецификаций. Но есть ли способ подсчитать сущности с помощью разрешения имен методов? Допустим, мне нужен метод countByNameдля подсчета сущностей с определенным именем, точно так же, как метод findByNameдля получения всех сущностей с определенным именем.

YaoFeng
источник
6
Пожалуйста, прими один из ответов, Яо Фэн. Я протестировал Spring Data JPA 1.5.2, и синтаксис countByName () работает, как отмечает Абель.
nullPainter

Ответы:

216

Начиная с Spring Data 1.7.1.RELEASE, вы можете сделать это двумя разными способами:

1) Новый способ , использующий вывод запросов как для подсчета, так и для запросов на удаление. Прочтите это (Пример 5). Пример,

public interface UserRepository extends CrudRepository<User, Integer> {
    Long countByName(String name);
}

2) Старый способ , используя аннотацию @Query.
Пример,

public interface UserRepository extends CrudRepository<User, Integer> {
    @Query("SELECT COUNT(u) FROM User u WHERE u.name=?1")
    Long aMethodNameOrSomething(String name);
}

или также используя аннотацию @Param,

public interface UserRepository extends CrudRepository<User, Integer> {
    @Query("SELECT COUNT(u) FROM User u WHERE u.name=:name")
    Long aMethodNameOrSomething(@Param("name") String name);
}

Проверьте также это, так что ответьте .

Джордж Сиггуроглу
источник
3
как насчет других агрегатных функций, таких как сумма, среднее?
lrkwz
Вопрос касался функции счета, а не суммы или среднего. Данные Spring пока не поддерживают что-то вроде «нового способа» для этих функций. Вы могли бы использовать что-то вроде этого
Джордж Сиггуроглу
1
Во втором и третьем примерах, я думаю, вам нужно будет использовать «SELECT COUNT (u) ...», поскольку это должен быть запрос на подсчет.
TheChrisPratt
Спасибо за ваш комментарий. Это была моя ошибка.
Джордж Сиггуроглу
Чтобы не волноваться, нашел - commons-lang
NickJ
19

Пока вы не используете версию 1.4, вы можете использовать явную аннотацию:

пример:

@Query("select count(e) from Product e where e.area.code = ?1")
long countByAreaCode(String code);
Римский
источник
3
обратите внимание, что метод должен возвращать longвместо int, иначе вы получите исключение ClassCastException без каких-либо подсказок
Ранги Лин
13

JpaRepository также расширяет QueryByExampleExecutor. Таким образом, вам даже не нужно определять собственные методы в вашем интерфейсе:

public interface UserRepository extends JpaRepository<User, Long> {
    // no need of custom method
}

А затем запросите:

User probe = new User();
u.setName = "John";
long count = repo.count(Example.of(probe));
Л. Холанда
источник
Эта версия мне нравится больше всего - тем более, что я не мог понять, как это должно работать в соответствии с документом :-) Вы спасли мне день :-) В качестве примечания: примитивы (например, int) включены в поиск по expamle, т.е. int ageбудет включен, хотя и не установлен, но Integer ageбудет исключен из выборки (по крайней мере, в Eclipselink)
LeO
Это именно то, что я искал. Спасибо!
emrekgn 07
11

Эта функция была добавлена ​​в версии 1.4 M1.

Абель Пастур
источник
8

Рабочий пример

@Repository
public interface TenantRepository extends JpaRepository< Tenant, Long > {
    List<Tenant>findByTenantName(String tenantName,Pageable pageRequest);
    long countByTenantName(String tenantName);
}

Вызов из уровня DAO

@Override
public long countByTenantName(String tenantName) {
    return repository.countByTenantName(tenantName);
}
Сагар Мисал
источник
5

По словам Абеля, после версии 1.4 (проверено в версии 1.4.3.RELEASE) можно сделать так:

public long countByName (имя строки);

Маркос Нуньес
источник
2

Спасибо вам всем! Теперь работа. DATAJPA-231

Было бы неплохо, если бы можно было создать счетчик…… методами, как и find…. Пример:

public interface UserRepository extends JpaRepository<User, Long> {

   public Long /*or BigInteger */ countByActiveTrue();
}
Танонгсак Чамунг
источник
1

По выпуску DATAJPA-231 функция еще не реализована.

Александр Бондаренко
источник
Теперь это реализовано
Сергей Пономарев
1

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

Изменить: теперь это возможно в соответствии с DATAJPA-231

Марк Шолунд
источник
0
@Autowired
private UserRepository userRepository;

@RequestMapping("/user/count")
private Long getNumberOfUsers(){
    return userRepository.count();
}
Богдан Ляховецкий
источник
1
Этот пример не по теме. Пользователь спросил, как считать по имени поля, а не как вызвать базовый счет из службы REST.
Джад Б.
0

Если кто-то хочет получить счет на основе нескольких условий, то вот образец настраиваемого запроса

@Query("select count(sl) from SlUrl sl where sl.user =?1 And sl.creationDate between ?2 And ?3")
    long countUrlsBetweenDates(User user, Date date1, Date date2);
Инзимам Тарик IT
источник