Passing dynamic queries in spring JPA - spring

I want to know how do we pass a query in spring JPA that has been prepared dynamically while program execution. The required query may vary according to the user input. So after framing the query manually using a for loop how do i execute this query ?
I have tried executing the query using the JDBC concept. but i want something more like :
#Query ( query_String)
public <return_type> filterNodes(String query_String);
Is this possible ?

The approach you sketched does not work.
Depending on how you create the query there are various options that might fit the bill:
Query by Example is quite limited but has it's uses
Specifications or their Querydsl equivalent are rather flexible and I'd expect them to work in your case but that is just guessing since you don't describe how you create your query.
If everything fails you can write a custom method implementation that takea s the query as parameter and uses an EntityManager to execute it.

Related

What is the purpose & advantage of spring specifications

I would like to know why we are using spring jpa specifications in spring boot application. I could see something like specifications (classname).and , .or these kind of operations what exactly it is?
Spring JPA specifications allow you to define a predicate (a part of WHERE clause of a query).
This helps you create complex queries in an object oriented style, allow you to create reusable predicates that you may use in different queries without repeating yourself, and it can help you create dynamic queries that can be constructed at runtime.
One example of a good use case for specifications is a search page with optional filtering criteria (think any eCommerce website). Using JPA specifications you can define a predicate for each filter and at runtime you can include in your query only the predicates that are related to the filters that the user has applied.

Is a Spring Data JPA #Query dynamic or named?

JPA #NamedQuery is translated to SQL only once when application is deployed and generated SQL is cached.
EntityManager.createQuery translates query every time our method is called.
What Spring-data-jpa is doing with query defined in #Query annotation? Is it translated to SQL once during deployment (like NamedQuery) or translated every time (like dynamic query) ?
Spring Data JPA calls EntityManager.createQuery(…) for every invocation of a query method annotated with #Query. The reason for that is quite simple: the Query instances returned by the EntityManager are not thread-safe and actually stateful as they contain bound parameter information.
That said, most of the JPA persistence provider perform some kind of text-based query caching anyway so that they basically build the actual SQL query once for a certain JPQL query and reuse the former on subsequent invocations.
As an interesting side note, when we started building the support for #Query in 2008 we looked into possibilities to rather register the manually declared queries as named queries with JPA. Unfortunately there wasn't - and up until today - there's no way to manually register a named query programmatically via the JPA.

ActiveRecord (CDbCriteria) vs QueryBuilder?

I have to make some filters, such as get persons who are in a given department, and I was wondering about the best way to do it.
Some of them are going to require the join of multiple tables.
Does anyone know about the main differences between CDbCriteria and Query Builder? I would particularly like to know about the compatibility with databases.
I found this in the Yii documentation about Query Builder:
It offers certain degree of DB abstraction, which simplifies migration to different DB platforms.
Is it the same for the CDbCriteria objects? Is it better?
The concept of CDbCriteria is used when working with Yii's active record (AR) abstraction (which is usually all of the time). AR requires that you have created models for the various tables in your database.
Query builder a very different way to access the database; in effect it is a structured wrapper that allows you to programmatically construct an SQL query instead of just writing it out as a string (as an added bonus it also offers a degree of database abstraction as you mention).
In a typical application there would be little to no need to use query builder because AR already provides a great deal of functionality and it also offers the same degree of database abstraction.
In some cases you might want to run a very specific type of query that is not convenient or performant to issue through AR. You then have two options:
If the query is fixed or almost fixed then you can simply issue it through DAO; in fact the query builder documentation mentions that "if your queries are simple, it is easier and faster to directly write SQL statements".
If the query needs to be dynamically constructed then query builder becomes a good fit for the job.
So as you can see, query builder is not all that useful most of the time. Only if you want to write very customized and at the same time dynamically constructed queries does it make sense to use it.
The example feature that you mention can and should be implemented using AR.

jpa specification query method

We are using the Spring Data JPA for database access. Our repositories contain basic query methods. What we want to do now is to use the Specification-Interface (criteria API) combined with complex query methods (like findByName(Specification spec)). The problem is that these two ways block each other out (since there are two where queries now). Is there any way to do this, like telling JPA to combine the two where parts with AND? The reason we want to do this is because some parts of the where query are essential for every query. They should be defined in the name of the query method. The Specification only should contain individual criterias for individual use-cases.
Or is there any other way to solve this?
Currently this is not supported. Please feel free to raise a JIRA issue if you think this would be a worthwhile enhancement.

addBatch support in Spring JDBCTemplate?

I want to execute multiple, separate SQL statements like in the JDBC cookbook:
Statement stmt = con.createStatement();
stmt.addBatch(
"update registration set balance=balance-5.00
where theuser="+theuser);
stmt.addBatch(
"insert into auctionitems(
description, startprice)
values("+description+","+startprice+")");
Must I use the Statement object directly? I'm looking for some spring JDBCTemplate service that provides the same functionality.
Extra points: Even better would be a service that takes a text with multiple SQL statements separated with ; and executes them all.
Thanks, Ido
JdbcTemplate has two batchUpdate methods that provide this functionality (javadoc). Which one you use depends on how much control you need. If you need full control, you can use the execute(StatementCallback) or even execute(ConnectionCallback) methods.

Resources