Для тех, кто ранее использовал функции 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
|
@Service public 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 .