on
Italy
- Get link
- X
- Other Apps
@Query
annotation and how to create custom query using the @Query
annotation.@Query
annotation. This annotation supports both, JPA Query Language (JPQL) and SQL. I am going to explain how to write query using query annotation in Spring Data JPA.@Query
could be used to write the more flexible query to fetch data.@Query
annotation supports both JPQL and native SQL queries.@Query
annotation will be using JPQL to execute the queries. If you try to use
the normal SQL queries, you would get the query syntax error
exceptions.nativeQuery
flag to true
. Also pagination and dynamic sorting for native queries are not supported in spring data jpa.@Query
annotation, this will take the precedence over @NamedQuery
, named queries in orm.xml and method names.@Query
annotation, Spring Data JPA will not find the entity with name property
is equal then the given method parameter. It would invoke the query
that is configured by using the @Query
annotation.@Query(value = "select name,author,price from Book b where b.price>?1 and b.price findByPriceRange(long price1, long price2);It is a simple example for query annotation. In the above snippet, we are having to parameters to compare the prices and filter the results. The parameter in the query is preceded by ? character to indicate that this is the parameter to be bind with method arguments.
@Query
definition. The example for using the like expressions inside query as below:@Query(value = "select name,author,price from Book b where b.name like %:name%") ListfindByNameMatch(@Param("name") String name);
nativeQuery
flag in the query annotation. This feature is very handy when you want
to try just the normal database query syntax instead of JPQL syntax.@Query
annotation:@Query(value = "select * from #{#entityName} b where b.name=?1", nativeQuery = true) ListIn the above example code snippet, we are using thefindByName(String name);
nativeQuery=true
for telling spring data jpa to use the native query execution. By default the value for this flag is false
.@Param
annotation can be used in the method parameter to bind the query parameter names.:paramName
to indicate that the same paramName has to be bind with the method parameter.@Query(value = "select name,author,price from Book b where b.name = :name AND b.author=:author AND b.price=:price") ListfindByNamedParam(@Param("name") String name, @Param("author") String author, @Param("price") long price);
@Query(value = "select * from #{#entityName} b where b.name=?1", nativeQuery = true) List#{#entityName} is the SpEL expression used to get the entity name. At this time SpEL expressions are used only for the entity name, in the future version there could be more expressions.findByName(String name);
@Query
annotation.@Query
annotation.public interface BookQueryRepositoryExample extends RepositoryApart from the above class, I have modified the controller class, service implementation access this repository from the REST API.{ @Query(value = "select * from Book b where b.name=?1", nativeQuery = true) List findByName(String name); @Query(value = "select name,author,price from Book b where b.price>?1 and b.price findByPriceRange(long price1, long price2); @Query(value = "select name,author,price from Book b where b.name like %:name%") List findByNameMatch(@Param("name") String name); @Query(value = "select name,author,price from Book b where b.name = :name AND b.author=:author AND b.price=:price") List findByNamedParam(@Param("name") String name, @Param("author") String author, @Param("price") long price); }
data.sql
and schema.sql
to initialize the data at the time of spring boot application startup.INSERT INTO book(id,name,author,price) VALUES (1,'Spring In Action:Covers Spring 3.0','Craig Walls', 400); INSERT INTO book(id,name,author,price) VALUES (2,'Spring Batch In Action','Arnaud Cogoluegnes', 500); INSERT INTO book(id,name,author,price) VALUES (3,'Spring Book','Rod', 300); INSERT INTO book(id,name,author,price) VALUES (4,'Java Book','test', 100); INSERT INTO book(id,name,author,price) VALUES (5,'Spring Boot Application','test', 200); INSERT INTO book(id,name,author,price) VALUES (6,'Learn Spring Data JPA','test', 300); INSERT INTO book(id,name,author,price) VALUES (7,'Hibernat in Action','Gavin King', 300); INSERT INTO book(id,name,author,price) VALUES (8,'JSF in Action','Kit', 400); INSERT INTO book(id,name,author,price) VALUES (9,'Java Interview Questions','Subramanian', 450); INSERT INTO book(id,name,author,price) VALUES (10,'Java Complete Reference','Herbert', 450);schema.sql
create table book( id int not null primary key, name varchar_ignorecase(50) not null, author varchar_ignorecase(50) not null, price int);
@Query
annotation in the query methods, using like expressions, using named
parameters for the binding and SpEL expression inside query. If you are
interested in reading the basics of Spring Data JPA, please read our
more detailed tutorial about Spring Data JPA.nativeQuery=true
. If you are using the SQL query without the attribute nativeQuery=true
, Spring Data JPA will try to validate the query against the JPQL format. You will get the below exception.Caused by: java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.util.List net.javabeat.spring.data.service.BookQueryRepositoryExample.findByName(java.lang.String)! at org.springframework.data.jpa.repository.query.SimpleJpaQuery.validateQuery(SimpleJpaQuery.java:92) at org.springframework.data.jpa.repository.query.SimpleJpaQuery.(SimpleJpaQuery.java:62) Caused by: java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: * near line 1, column 8 [select * from net.javabeat.spring.data.domain.Book b where b.name=?1] at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1750) at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1677)
@Query(value = "select * from #{#entityName} b where b.name=?1", nativeQuery = true) ListIf this tutorial is useful, we are happy. If you could find the information what you are looking for, please request us to update the tutorial in the comments section.findByName(String name);
Comments
Post a Comment