Having a simple SQL Table like:
NOTIFICATION (ID, NAME, NOTIF_DATE, ...)
I am excecuting a SQL query from my back-end app using code like:
this.findBySQL(MY_SQL_QUERY, params...);
The SQL SELECT QUERY is excecuted correctly and returns the rows expected. The problem i am facing is that the returned rows are wrapped to Object[], but after this query, i want to filter the results using Java 8 stream and filter functionality.
I want the results to be mapped to my custom Object Notification, which look like:
Notification { long id, String name, Date notif_date, ... }
I could create my own mapper, getting the result values from the Object i get from the query, example:
Notification not = new Notification();
not.setName(obj[1]);
...
But i think that this approach is not a good implementation beacause it depends on the order of the columns returned, and i have to code for every attribute to be setted.
Is there any way of mapping from this Object[] to my Notification?
Thanks in advance and sorry for the poor code but I have no better approach for this issue.
It’s easiest if your Notification class has a constructor that accepts the fields from the database (or you can add such a constructor):
List<Object[]> rows = this.findBySQL(MY_SQL_QUERY, params);
List<Notification> notifs = rows.stream()
.map(r -> new Notification((Long) r[0], (String) r[1], (Date) r[2]))
.filter(n -> n.getName().startsWith("m"))
.collect(Collectors.toList());
You haven’t told us the exact return type of findBySQL(), so I am guessing a bit. I hope you will be able to tailor the code to your exact situation.
I put in a fairly meaningless filter() in the stream just for the sake of the example. I would find it more convenient to filter after you have created the Notification objects. You can also filter before if you prefer. I didn’t really understand why you didn’t do your filtering in SQL.
If you cannot add a good constructor for the purpose, it’s a bit longer, but really not very much more complicated:
List<Notification> notifs = rows.stream()
.map(r -> {
Notification notif = new Notification();
notif.setId((Long) r[0]);
notif.setName((String) r[1]);
notif.setNotif_date((Date) r[2]);
return notif;
})
.filter(n -> n.getName().startsWith("m"))
.collect(Collectors.toList());
Related
I need to copy the records of one table to another table based on some condition.
String query = "insert into public.ticket_booking_archive select * from public.ticket_booking where ticketId in (:ticketIds)";
So here the :ticketIds are dynamic, where i need to pass ticketIds to make sure whether it satisfies the condition. So it may be the matching and non matching ticket id's here at runtime.
The values of ticketIds are something like this
('f1fa3a42-5837-11ec-bf63-0242ac130002','516fd14d-3c9d-4b4b-91a0-b684d8592dfe','c9652f86-734c-4df5-8ef9-d407cb3eaf7a','df7f2812-b445-45b4-b731-da23c36d7738','f1fa3a42-5837-11ec-bf63-0242ac130002'). And this is just an example. And the list might goes on.
Since it is of type UUID, I'm storing it into a Set<UUID>
Set<UUID> tktIds = new HashSet<UUID>();
for(int i=0 ; i<ticketIds.size(); i++) {
String ticketId = ticketIds[i];
tktIds.add(UUID.fromString(ticketId));
}
Map<String, Object> params = new HashMap<>();
params.put("ticketIds", tktIds);
SqlParameterSource namedParameters =
new MapSqlParameterSource().addValue("ticketIds",params.get("ticketIds"));
Since I'm using NamedParameterJdbcTemplate, so I'm using like below
int res = writeNamedJdbcTemplate.update(query, namedParameters);
res = 3 when executed programmatically.
Here the problem is, as soon as it finds the first matching value in the IN clause it executes. And it is not considering the other matching values (ticketIds here)
But if I execute the same query in pgadmin it works fine
insert into public.ticket_booking_archive select * from public.ticket_booking where ticketId in ('f1fa3a42-5837-11ec-bf63-0242ac130002','516fd14d-3c9d-4b4b-91a0-b684d8592dfe','c9652f86-734c-4df5-8ef9-d407cb3eaf7a','df7f2812-b445-45b4-b731-da23c36d7738','f1fa3a42-5837-11ec-bf63-0242ac130002');
result is 6. Working as expected.
writeNamedJdbcTemplate.queryForObject(query, namedParameters, Integer.class); //. throws an error
Can anyone please assist? I'm really not sure where I'm making a mistake
I am not quite sure whether you are using the appropriate JDBC template for the named parameters, but you can do the following:
you can consult this article to use the right template and employ proper SQL query composition,
for string passing you can wrap the parameter mapping as shown here
after all your named parameter should work
On a database level I have a table product that has two columns: gtin and market along with other columns.
I want to write a java code that would be transformed to the following query:
select * from product where (gtin, market) IN (('USA', 1), ('CA',2), ('PL', 3), ('CZ, 4))
On a java code level I have special entity GtinMarket that is dedicated to store these two gtin and market values:
GtinMarket {
String gtin;
String market;
}
On a code level I would expect something like:
using(configuration)
.select()
.from(table(PRODUCT_TABLE))
.where((field(GTIN, Long.class),field(MARKET, Long.class)).in(gtinMarketList))
.fetch()
After some investigation I was unable to find a way to write such a code,
I would really really appreciate any help,
Thanks,
Use DSL.row(Field, Field) for type safe row value expression construction:
using(configuration)
.select()
.from(table(PRODUCT_TABLE))
.where(row(field(GTIN, Long.class), field(MARKET, Long.class)).in(gtinMarketList))
.fetch()
This is assuming that your gtinMarketList is a Collection<? extends Row2<Long, Long>> as expected by the relevant Row2.in() method. The in() method has several overloads, so you can pick whatever suits you.
More information here:
https://www.jooq.org/doc/latest/manual/sql-building/conditional-expressions/in-predicate-degree-n
Disclaimer: I am new to MongoDB. I just started to use it few days back. Sorry if my question doesn't make much sense.
Hello,
I am trying to make a Query to MongoDB from Java method, I want to create and make a query only if that parameter is not null. So let us say that my method is
public List<Object> getSomethingFromMongoDB(String searchParameter){
Query query = new Query().addCriteria(Criteria.where("something").is((searchParameter)));
}
Now I only want to search when SearchParameter only when it is notNull. Can I do this in a better way? I tried to check $ne but cannot understand how to apply it in my Java method.
Thanks in advance
I would advise the following:
public List<Document> getSomethingFromMongoDB(List<String> searchParameters){
List<Document> results = new ArrayList<>();
if (searchParameters == null) return results;
Document criteria = new Document();
searchParameters.forEach(parameter -> criteria.append("yourField",parameter));
collection.find(criteria).iterator().forEachRemaining(results::add);
return results;
}
If the parameters list is empty, you will just get all the documents.
If not, the corresponding criteria will be applied.
You could even get rid of the null-checking line, by making sure you pass a new ArrayList() for example, instead of null.
I am using rally lookback api with java. I am trying to fetch historical data features, sample code that i am using is as shown below.
LookbackApi lookbackApi = new LookbackApi();
lookbackApi.setCredentials("username", "password");
lookbackApi.setWorkspace(47903209423);
lookbackApi.setServer("https://rally1.rallydev.com");
//lookbackApi.setWorkspace("90432948");
LookbackQuery query = lookbackApi.newSnapshotQuery();
query.addFindClause("_TypeHierarchy", "PortfolioItem/Feature");
query.setPagesize(200) // set pagesize to 200 instead of the default 20k
.setStart(200) // ask for the second page of data
.requireFields("ScheduleState", // A useful set of fields for defects, add any others you may want
"ObjectID",
"State",
"Project",
"PlanEstimate",
"_ValidFrom",
"_ValidTo")
.sortBy("_UnformattedID")
.hydrateFields("ScheduleState","State", "PlanEstimate","Project"); // ScheduleState will come back as an OID if it doesn't get hydrated
LookbackResult resultSet = query.execute();
int resultCount = resultSet.Results.size();
Map<String,Object> firstSnapshot = resultSet.Results.get(0);
Iterator<Map<String,Object>> iterator = resultSet.getResultsIterator();
while (iterator.hasNext()) {
Map<String, Object> snapshot = iterator.next();
}
I need a way to put a condition so that it will fetch all the records from history which will have plan estimate changed,but will ignore other history for any feature and underlying user story. I need it this way so that we can track plan estimate change but, will be able to avoid fetching un-necessary data and reduce the time to do this.
I'm not familiar with the java toolkit, but using the raw Lookback API, you would accomplish this with a filter clause like {"_PreviousValues.PlanEstimate": {"$exists": true}}.
Map ifExist = new HashMap();
ifExist.put("$exists", true);
// Note:- true is java boolean, be careful with this as string "true" will not work.
query.addFindClause("_PreviousValues.PlanEstimate",ifExist);
Additinally one need to consider adding "_PreviousValues.PlanEstimate" into
.requireFields() in case only "PlanEstimate" is required to hydrated
I'm working with Java Apache Cayenne, under a MySQL DB.
I have quite a large table with a single bigint PK and some fields.
I'd like to retrieve just only the PK values and not all the object that maps this entity, as it would be too resource-consuming.
Is there a snippet that I can use, instead of this one that retrieves all the objects?
ObjectContext context = ...
SelectQuery select = new SelectQuery(MyClass.class);
List<MyClass> result = context.performQuery(select);
You should try using SQLTemplate instead of SelectQuery.
Here's a quick example:
ObjectContext context = ...
SQLTemplate select = new SQLTemplate(MyClass.class, "SELECT #result('PK_COLUMN' 'long') FROM MY_TABLE");
List result = context.performQuery(select);
You can find more information here
+1 for Josemando's answer. And here is another way that may work in case you are planning to only work with a subset of fetched objects:
ObjectContext context = ...
SelectQuery select = new SelectQuery(MyClass.class);
select.setPageSize(100);
List<MyClass> result = context.performQuery(select);
'setPageSize' ensures that 'result' only contains ids, until you attempt to read an object from the list. And when you do, it will resolve it page-by-page (100 objects at a time in the example above). This may fit a number of scenarios. Of course if you iterate through the entire list, eventually all objects will be fully resolved, and there will be no memory benefit.