Data filtering in Dropwizard using DAOs based on optional parameters
I want to implement filtering of data in my Dropwizard server. Let us say we want to search for Monuments. The user could use filters like name, city, category for filtering from the list of monuments.
The uri will look something like /monuments?name="Eiffel"&city"Paris"&category="Engineering Marvel"
I am not clear on how to implement the API for this because some users may stop after just specifying the name filter, while others may use all 3.
In such a case how do I implement the Java code and Queries in my DAO to modify the query based on what filters were passed on?
What I thought of and tried :
1 (worst case) - Have a list of all possible combinations of queries for these filters and use one depending on which combination of arguments was passed on.
2 - I thought the JDBI would automatically eliminate the params that are null when calling the DAO method, but that isn't the case, at least with the ilike
clause (since all the above params are strings).
3 - Use Case in Postgres. But this is not scale-able since I might have other params to search with over time as the use cases increase.
4 - Use Java data structures along with DAOs to filter down the results internally like get all the monuments based on (let's say) name first, then pass the Ids to an SQL Query with city clause and then same with category clause. But this will take a long time to process as data increases.
This seems like a fairly common scenario but I can't find any good answers around this, Most talk about the URI and RESTful design instead of the implementation details.
Any guidance would be of help.
Thanks
java filtering dropwizard jdbi
add a comment |
I want to implement filtering of data in my Dropwizard server. Let us say we want to search for Monuments. The user could use filters like name, city, category for filtering from the list of monuments.
The uri will look something like /monuments?name="Eiffel"&city"Paris"&category="Engineering Marvel"
I am not clear on how to implement the API for this because some users may stop after just specifying the name filter, while others may use all 3.
In such a case how do I implement the Java code and Queries in my DAO to modify the query based on what filters were passed on?
What I thought of and tried :
1 (worst case) - Have a list of all possible combinations of queries for these filters and use one depending on which combination of arguments was passed on.
2 - I thought the JDBI would automatically eliminate the params that are null when calling the DAO method, but that isn't the case, at least with the ilike
clause (since all the above params are strings).
3 - Use Case in Postgres. But this is not scale-able since I might have other params to search with over time as the use cases increase.
4 - Use Java data structures along with DAOs to filter down the results internally like get all the monuments based on (let's say) name first, then pass the Ids to an SQL Query with city clause and then same with category clause. But this will take a long time to process as data increases.
This seems like a fairly common scenario but I can't find any good answers around this, Most talk about the URI and RESTful design instead of the implementation details.
Any guidance would be of help.
Thanks
java filtering dropwizard jdbi
Declare your method with all the parameters using the @QueryParam annotation. The ones the user does not provide will be null or empty-string. Write your SQL to ignore null values.
– Hitobat
Nov 25 '18 at 10:45
How do I write an SQL query to ignore null values?
– LeoNeo
Nov 27 '18 at 15:19
I looked around and I see cases where if the argument is null or empty pass in a default value or the same value that already exists in the table but none that says that if there is a query likeSelect * from users where name = :name
and if the passed in arg is null then just do `Select * from users.
– LeoNeo
Nov 27 '18 at 15:30
You can do something likeSELECT * FROM users WHERE (:name IS NULL OR name=:name)
.
– Hitobat
Nov 30 '18 at 13:19
add a comment |
I want to implement filtering of data in my Dropwizard server. Let us say we want to search for Monuments. The user could use filters like name, city, category for filtering from the list of monuments.
The uri will look something like /monuments?name="Eiffel"&city"Paris"&category="Engineering Marvel"
I am not clear on how to implement the API for this because some users may stop after just specifying the name filter, while others may use all 3.
In such a case how do I implement the Java code and Queries in my DAO to modify the query based on what filters were passed on?
What I thought of and tried :
1 (worst case) - Have a list of all possible combinations of queries for these filters and use one depending on which combination of arguments was passed on.
2 - I thought the JDBI would automatically eliminate the params that are null when calling the DAO method, but that isn't the case, at least with the ilike
clause (since all the above params are strings).
3 - Use Case in Postgres. But this is not scale-able since I might have other params to search with over time as the use cases increase.
4 - Use Java data structures along with DAOs to filter down the results internally like get all the monuments based on (let's say) name first, then pass the Ids to an SQL Query with city clause and then same with category clause. But this will take a long time to process as data increases.
This seems like a fairly common scenario but I can't find any good answers around this, Most talk about the URI and RESTful design instead of the implementation details.
Any guidance would be of help.
Thanks
java filtering dropwizard jdbi
I want to implement filtering of data in my Dropwizard server. Let us say we want to search for Monuments. The user could use filters like name, city, category for filtering from the list of monuments.
The uri will look something like /monuments?name="Eiffel"&city"Paris"&category="Engineering Marvel"
I am not clear on how to implement the API for this because some users may stop after just specifying the name filter, while others may use all 3.
In such a case how do I implement the Java code and Queries in my DAO to modify the query based on what filters were passed on?
What I thought of and tried :
1 (worst case) - Have a list of all possible combinations of queries for these filters and use one depending on which combination of arguments was passed on.
2 - I thought the JDBI would automatically eliminate the params that are null when calling the DAO method, but that isn't the case, at least with the ilike
clause (since all the above params are strings).
3 - Use Case in Postgres. But this is not scale-able since I might have other params to search with over time as the use cases increase.
4 - Use Java data structures along with DAOs to filter down the results internally like get all the monuments based on (let's say) name first, then pass the Ids to an SQL Query with city clause and then same with category clause. But this will take a long time to process as data increases.
This seems like a fairly common scenario but I can't find any good answers around this, Most talk about the URI and RESTful design instead of the implementation details.
Any guidance would be of help.
Thanks
java filtering dropwizard jdbi
java filtering dropwizard jdbi
edited yesterday
Rishab178
11517
11517
asked Nov 25 '18 at 7:11
LeoNeoLeoNeo
472518
472518
Declare your method with all the parameters using the @QueryParam annotation. The ones the user does not provide will be null or empty-string. Write your SQL to ignore null values.
– Hitobat
Nov 25 '18 at 10:45
How do I write an SQL query to ignore null values?
– LeoNeo
Nov 27 '18 at 15:19
I looked around and I see cases where if the argument is null or empty pass in a default value or the same value that already exists in the table but none that says that if there is a query likeSelect * from users where name = :name
and if the passed in arg is null then just do `Select * from users.
– LeoNeo
Nov 27 '18 at 15:30
You can do something likeSELECT * FROM users WHERE (:name IS NULL OR name=:name)
.
– Hitobat
Nov 30 '18 at 13:19
add a comment |
Declare your method with all the parameters using the @QueryParam annotation. The ones the user does not provide will be null or empty-string. Write your SQL to ignore null values.
– Hitobat
Nov 25 '18 at 10:45
How do I write an SQL query to ignore null values?
– LeoNeo
Nov 27 '18 at 15:19
I looked around and I see cases where if the argument is null or empty pass in a default value or the same value that already exists in the table but none that says that if there is a query likeSelect * from users where name = :name
and if the passed in arg is null then just do `Select * from users.
– LeoNeo
Nov 27 '18 at 15:30
You can do something likeSELECT * FROM users WHERE (:name IS NULL OR name=:name)
.
– Hitobat
Nov 30 '18 at 13:19
Declare your method with all the parameters using the @QueryParam annotation. The ones the user does not provide will be null or empty-string. Write your SQL to ignore null values.
– Hitobat
Nov 25 '18 at 10:45
Declare your method with all the parameters using the @QueryParam annotation. The ones the user does not provide will be null or empty-string. Write your SQL to ignore null values.
– Hitobat
Nov 25 '18 at 10:45
How do I write an SQL query to ignore null values?
– LeoNeo
Nov 27 '18 at 15:19
How do I write an SQL query to ignore null values?
– LeoNeo
Nov 27 '18 at 15:19
I looked around and I see cases where if the argument is null or empty pass in a default value or the same value that already exists in the table but none that says that if there is a query like
Select * from users where name = :name
and if the passed in arg is null then just do `Select * from users.– LeoNeo
Nov 27 '18 at 15:30
I looked around and I see cases where if the argument is null or empty pass in a default value or the same value that already exists in the table but none that says that if there is a query like
Select * from users where name = :name
and if the passed in arg is null then just do `Select * from users.– LeoNeo
Nov 27 '18 at 15:30
You can do something like
SELECT * FROM users WHERE (:name IS NULL OR name=:name)
.– Hitobat
Nov 30 '18 at 13:19
You can do something like
SELECT * FROM users WHERE (:name IS NULL OR name=:name)
.– Hitobat
Nov 30 '18 at 13:19
add a comment |
1 Answer
1
active
oldest
votes
While the answer suggested by @Hitobat would work fine when your optional arguments are few, but if you are dealing with a lot of optional arguments a more elegant solution would be to consider creating a request pojo and use Hibernate Criterias where you add a restriction only if the argument is not null.
Request class:
public class FilteredRequest{
String name;
String city;
String category;
}
Resource Class:
@GET
@Path("/monuments")
public Response searchMonuments(@ApiParam("filters") FilteredRequest filteredRequest){
return Response.ok().entity(monumentsDAO.findAll(filteredRequest)).build()
}
DAO:
public List<Monuments> class MonumentsDAO() {
public findAll(FilteredRequest filteredRequest){
Criteria criteria = getSearchCriteria(filteredRequest);
return list(criteria);
}
private Criteria getSearchCriteria(FilteredRequest filteredRequest){
Criteria criteria = criteria();
if (StringUtils.isNotEmpty(filteredRequest.getName())) {
criteria.add(Restrictions.eq("name", filteredRequest.getName()));
}
if (StringUtils.isNotEmpty(filteredRequest.getCity())) {
criteria.add(Restrictions.eq("city", filteredRequest.getCity()));
}
if (StringUtils.isNotEmpty(filteredRequest.getCategory())) {
criteria.add(Restrictions.eq("category", filteredRequest.getCategory()));
}
return criteria;
}
}
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53465419%2fdata-filtering-in-dropwizard-using-daos-based-on-optional-parameters%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
While the answer suggested by @Hitobat would work fine when your optional arguments are few, but if you are dealing with a lot of optional arguments a more elegant solution would be to consider creating a request pojo and use Hibernate Criterias where you add a restriction only if the argument is not null.
Request class:
public class FilteredRequest{
String name;
String city;
String category;
}
Resource Class:
@GET
@Path("/monuments")
public Response searchMonuments(@ApiParam("filters") FilteredRequest filteredRequest){
return Response.ok().entity(monumentsDAO.findAll(filteredRequest)).build()
}
DAO:
public List<Monuments> class MonumentsDAO() {
public findAll(FilteredRequest filteredRequest){
Criteria criteria = getSearchCriteria(filteredRequest);
return list(criteria);
}
private Criteria getSearchCriteria(FilteredRequest filteredRequest){
Criteria criteria = criteria();
if (StringUtils.isNotEmpty(filteredRequest.getName())) {
criteria.add(Restrictions.eq("name", filteredRequest.getName()));
}
if (StringUtils.isNotEmpty(filteredRequest.getCity())) {
criteria.add(Restrictions.eq("city", filteredRequest.getCity()));
}
if (StringUtils.isNotEmpty(filteredRequest.getCategory())) {
criteria.add(Restrictions.eq("category", filteredRequest.getCategory()));
}
return criteria;
}
}
add a comment |
While the answer suggested by @Hitobat would work fine when your optional arguments are few, but if you are dealing with a lot of optional arguments a more elegant solution would be to consider creating a request pojo and use Hibernate Criterias where you add a restriction only if the argument is not null.
Request class:
public class FilteredRequest{
String name;
String city;
String category;
}
Resource Class:
@GET
@Path("/monuments")
public Response searchMonuments(@ApiParam("filters") FilteredRequest filteredRequest){
return Response.ok().entity(monumentsDAO.findAll(filteredRequest)).build()
}
DAO:
public List<Monuments> class MonumentsDAO() {
public findAll(FilteredRequest filteredRequest){
Criteria criteria = getSearchCriteria(filteredRequest);
return list(criteria);
}
private Criteria getSearchCriteria(FilteredRequest filteredRequest){
Criteria criteria = criteria();
if (StringUtils.isNotEmpty(filteredRequest.getName())) {
criteria.add(Restrictions.eq("name", filteredRequest.getName()));
}
if (StringUtils.isNotEmpty(filteredRequest.getCity())) {
criteria.add(Restrictions.eq("city", filteredRequest.getCity()));
}
if (StringUtils.isNotEmpty(filteredRequest.getCategory())) {
criteria.add(Restrictions.eq("category", filteredRequest.getCategory()));
}
return criteria;
}
}
add a comment |
While the answer suggested by @Hitobat would work fine when your optional arguments are few, but if you are dealing with a lot of optional arguments a more elegant solution would be to consider creating a request pojo and use Hibernate Criterias where you add a restriction only if the argument is not null.
Request class:
public class FilteredRequest{
String name;
String city;
String category;
}
Resource Class:
@GET
@Path("/monuments")
public Response searchMonuments(@ApiParam("filters") FilteredRequest filteredRequest){
return Response.ok().entity(monumentsDAO.findAll(filteredRequest)).build()
}
DAO:
public List<Monuments> class MonumentsDAO() {
public findAll(FilteredRequest filteredRequest){
Criteria criteria = getSearchCriteria(filteredRequest);
return list(criteria);
}
private Criteria getSearchCriteria(FilteredRequest filteredRequest){
Criteria criteria = criteria();
if (StringUtils.isNotEmpty(filteredRequest.getName())) {
criteria.add(Restrictions.eq("name", filteredRequest.getName()));
}
if (StringUtils.isNotEmpty(filteredRequest.getCity())) {
criteria.add(Restrictions.eq("city", filteredRequest.getCity()));
}
if (StringUtils.isNotEmpty(filteredRequest.getCategory())) {
criteria.add(Restrictions.eq("category", filteredRequest.getCategory()));
}
return criteria;
}
}
While the answer suggested by @Hitobat would work fine when your optional arguments are few, but if you are dealing with a lot of optional arguments a more elegant solution would be to consider creating a request pojo and use Hibernate Criterias where you add a restriction only if the argument is not null.
Request class:
public class FilteredRequest{
String name;
String city;
String category;
}
Resource Class:
@GET
@Path("/monuments")
public Response searchMonuments(@ApiParam("filters") FilteredRequest filteredRequest){
return Response.ok().entity(monumentsDAO.findAll(filteredRequest)).build()
}
DAO:
public List<Monuments> class MonumentsDAO() {
public findAll(FilteredRequest filteredRequest){
Criteria criteria = getSearchCriteria(filteredRequest);
return list(criteria);
}
private Criteria getSearchCriteria(FilteredRequest filteredRequest){
Criteria criteria = criteria();
if (StringUtils.isNotEmpty(filteredRequest.getName())) {
criteria.add(Restrictions.eq("name", filteredRequest.getName()));
}
if (StringUtils.isNotEmpty(filteredRequest.getCity())) {
criteria.add(Restrictions.eq("city", filteredRequest.getCity()));
}
if (StringUtils.isNotEmpty(filteredRequest.getCategory())) {
criteria.add(Restrictions.eq("category", filteredRequest.getCategory()));
}
return criteria;
}
}
answered yesterday
Rishab178Rishab178
11517
11517
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53465419%2fdata-filtering-in-dropwizard-using-daos-based-on-optional-parameters%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Declare your method with all the parameters using the @QueryParam annotation. The ones the user does not provide will be null or empty-string. Write your SQL to ignore null values.
– Hitobat
Nov 25 '18 at 10:45
How do I write an SQL query to ignore null values?
– LeoNeo
Nov 27 '18 at 15:19
I looked around and I see cases where if the argument is null or empty pass in a default value or the same value that already exists in the table but none that says that if there is a query like
Select * from users where name = :name
and if the passed in arg is null then just do `Select * from users.– LeoNeo
Nov 27 '18 at 15:30
You can do something like
SELECT * FROM users WHERE (:name IS NULL OR name=:name)
.– Hitobat
Nov 30 '18 at 13:19