Using Spring Data nad Querydsl we can just declare repository interface and skip the implementation class. Some methods with a specific name or using @Query annotation and that's all.
But sometimes I'd like to use JPAQuery and define method's body by myself, let's say
@Repository
public class MyRepositoryImpl implements MyRepository {
@PersistenceContext
private EntityManager em;
@Override
public List<Tuple> someMethod(String arg) {
JPAQuery query = new JPAQuery(em);
...
}
but this way I would have to implement other MyRepository interface methods, which ruins all Spring Data's advantages!
I can see two options:
I like option #2 more, but as far I as know, in @Service class we should only call repository methods, so it's not a perfect solution as well.
So how does programmers deal with it?
Querydsl is a framework that enables the construction of statically typed SQL-like queries through its fluent API. Spring Data modules offer integration with Querydsl through QuerydslPredicateExecutor .
Querydsl is an extensive Java framework, which allows for the generation of type-safe queries in a syntax similar to SQL. It currently has a wide range of support for various backends through the use of separate modules including JPA, JDO, SQL, Java collections, RDF, Lucene, Hibernate Search, and MongoDB.
The querydsl-apt dependency is an annotation processing tool (APT) — implementation of corresponding Java API that allows processing of annotations in source files before they move on to the compilation stage.
Spring Data JPA is not an implementation or JPA provider, it's just an abstraction used to significantly reduce the amount of boilerplate code required to implement data access layers for various persistence stores.
Getting the Required Dependencies Before we can use Querydsl with Spring Data JPA, we have to add the Querydsl JPA module into our classpath. We can do this by adding the following dependency declaration into the dependenciessection of our pom.xmlfile:
To achieve dynamic SQL queries, there are several approaches within Spring Data as you can use JPA's Criteria API, use query by example, and the Querydsl integration support (for more information, have a look at the Spring Data documentation ).
In this example, we built a Spring boot project to demonstrate Spring Data JPA with Querydsl to allow developers to write type-safe queries in a RDBMS. We also compared it to Spring’s JdbcTemplate and concluded that Querydsl is easier to use. Both Spring Data and Querydsl support nosql database which is not covered in this example.
QuerydslPredicateExecutor Our Spring Data repository declaration needs to implement QuerydslPredicateExecutor which is Spring Data specific interface. This interface defines various query methods which allow execution of Querydsl for the provided com.querydsl.core.types.Predicate instances. Following is it's snippet:
You should not implement the actual Spring Data repository, instead you have to declare another custom interface where you can put your custom methods.
Let's say you have a MyRepository
, defined as
@Repository
public interface MyRepository extends JpaRepository<Tuple, Long> {}
Now you want to add your custom findTuplesByMyArg()
, for a sake of purpose you need to create custom repository interface
public interface MyRepositoryCustom {
List<Tuple> findTuplesByMyArg(String myArg);
}
Afterwards comes the implementation of custom interface
public class MyRepositoryImpl implements MyRepositoryCustom {
@PersistenceContext
private EntityManager em;
@Override
public List<Tuple> findTuplesByMyArg(String myArg) {
JPAQuery query = new JPAQuery(em);
...
}
}
And we need to change MyRepository
declaration, so it extends custom repository, so that
@Repository
public interface MyRepository extends JpaRepository<Tuple, Long>, MyRepositoryCustom {}
And you can easily access your findTuplesByMyArg()
by injecting MyRepository
, e.g.
@Service
public class MyService {
@Autowired
private MyRepository myRepository;
public List<Tuple> retrieveTuples(String myArg) {
return myRepository.findTuplesByMyArg(myArg);
}
}
Pay attention that names are important here (you need to have Impl
postfix by default configs in repo implementation).
You can find all needed information here
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With