Для тех, кто ранее использовал функции Hibernate Native SQL, вы обнаружите, что его гораздо проще использовать, чем @NamedNativeQuery от JPA. В последних проектах я использую Spring Data JPA. Я добавил функции собственных запросов гибернации в свой репозиторий базы данных Spring. Теперь вы можете выполнить собственный запрос в JPA без SqlResultSetMapping.
1. Добавьте свои аннотации @NativeQueries и @NativeQuery.
|
1
2
3
4
5
|
@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)public @interface NativeQueries { NativeQuery[] queries() default {};} |
|
1
2
3
4
5
|
@Retention(RetentionPolicy.RUNTIME)public @interface NativeQuery { String name() default ""; String sql() default "";} |
2. Добавьте метод «queryNatively» в базовый репозиторий данных Spring.
Если вы не знаете, как добавить пользовательское поведение в базовый репозиторий JPA данных Spring, см. Мой предыдущий пост о том, как подробно настроить базовый репозиторий JPA данных Spring . В предыдущем посте вы можете видеть, что я намеренно предоставляю интерфейс репозитория (то есть свойство springDataRepositoryInterface) в GenericRepositoryImpl. Эти маленькие хитрости позволяют мне легко получить доступ к аннотации в интерфейсе репозитория.
|
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
public List queryNatively(String nativeQueryName, LinkedHashMap<String,Class<?>> inEntityClasses, Map inParams ){ SQLQuery query = this.createHibernateNativeQuery( nativeQueryName, inParams ); //add entities if (inEntityClasses!=null) { for (Object key: inEntityClasses.keySet()) { String entityClassAlias = key.toString(); Class<?> entityClass = (Class<?>)inEntityClasses.get(key); query.addEntity(entityClassAlias,entityClass); } } //add parameter if (inParams != null){ for (Object key: inParams.keySet()) { String queryParamName = key.toString(); Object queryParamValue = inParams.get(key); query.setParameter(queryParamName, queryParamValue); } } return (query!=null)? query.list() : null ; } private SQLQuery createHibernateNativeQuery (String nativeQueryName, Map inParams ){ if (GenericRepository.class.isAssignableFrom(getSpringDataRepositoryInterface())) { Annotation nativeQueryAnn = getSpringDataRepositoryInterface().getAnnotation(NativeQueries.class); if(nativeQueryAnn != null){ NativeQueries nativeQueries = (NativeQueries)nativeQueryAnn; NativeQuery[] queries = nativeQueries.queries(); for (NativeQuery sqlquery : queries) { if (StringUtils.equals(nativeQueryName, sqlquery.name())) { String sql = sqlquery.sql(); Session hiernateSess = em.unwrap(Session.class); SQLQuery query = hiernateSess.createSQLQuery(sql); //add parameter if (inParams != null){ for (Object key: inParams.keySet()) { String queryParamName = key.toString(); Object queryParamValue = inParams.get(key); query.setParameter(queryParamName, queryParamValue); } } return query; } } } } return null; } |
3. Пример использования
В своем интерфейсе репозитория определите, какие собственные запросы SQL вы хотите использовать, используя аннотации @NativeQueries и @NativeQuery. Использование аналогично вызову спящих функций собственных запросов. Вы можете просто увидеть псевдоним гибернации и ссылки на свойства .
|
01
02
03
04
05
06
07
08
09
10
|
@NativeQueries ( queries = { @NativeQuery(name="query1", sql="SELECT {cat.*}, {mother.*} FROM CATS c, CATS m WHERE c.MOTHER_ID = c.ID and c.name = :catName "), @NativeQuery(name="query2", sql="SELECT {cat.*} FROM CATS where c.ID = :catName") })public interface CatRepository extends GenericRepository<Cat, Long> {} |
В вашем сервисе или бизнес-классе, который внедряет ваш репозиторий, вы можете просто вызвать метод queryNatively () для выполнения собственного запроса SQL.
|
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
|
@Servicepublic class CatService { @Inject private CatRepository catRepository; public List<Cat> searchCat( String catName) { List<Cat> catList; // Add entity mapping for your query HashMap<String, Object> inParams = new HashMap<String, Object>(); inParams.put("catName", "Felix"); // Prepare parameters for your native sql LinkedHashMap<String, Object> entityMap = new LinkedHashMap<String, Object>(); entityMap.put("cat", Cat.class); entityMap.put("mother",Mother.class); catList = catRepository.queryNatively( "query1", "",entityParam); return catList; }} |
Ссылка: Добавление собственных функций Hibernate SQL в ваш репозиторий Spring от нашего партнера по JCG Бориса Лама в блоге Programming Peaceful .