JDBI: How to map query as list of objects - java

I am using JDBI to iterate through a resultset via streams. Currently mapToMap is causing problems when there is a column with the same name in the result. What I need is just the values without the column names.
Is there a way to map the results to an Object list/array? The docs does not have an example for this. I would like to have something like
query.mapTo(List<Object>.class).useStream(s -> { . . .})

First of all - what kind of use case would allow you not care at all about the column name but only the values? I am genuinely curious
If it does make sense, it is trivial to implement a RowMapper<List<Object>> in your case, which runs through all the columns by index and puts the results of rs.getObject(i) into a list.

Related

How to get result set by checking a specific element in an aggregated array using JOOQ?

I want to filter results by a specific value in the aggregated array in the query.
Here is a little description of the problem.
Section belongs to the garden. Garden belongs to District and District belongs to the province.
Users have multiple sections. Those sections belong to their gardens and they are to their Districts and them to Province.
I want to get user ids that have value 2 in district array.
I tried to use any operator but it doesn't work properly. (syntax error)
Any help would be appreciated.
ps: This is possible writing using plain SQL
rs = dslContext.select(
field("user_id"),
field("gardens_array"),
field("province_array"),
field("district_array"))
.from(table(select(
arrayAggDistinct(field("garden")).as("gardens_array"),
arrayAggDistinct(field("province")).as("province_array"),
arrayAggDistinct(field("distict")).as("district_array"))
.from(table("lst.user"))
.leftJoin(table(select(
field("section.user_id").as("user_id"),
field("garden.garden").as("garden"),
field("garden.province").as("province"),
field("garden.distict").as("distict"))
.from(table("lst.section"))
.leftJoin("lst.garden")
.on(field("section.garden").eq(field("garden.garden")))
.leftJoin("lst.district")
.on(field("district.district").eq(field("garden.district")))).as("lo"))
.on(field("user.user_id").eq(field("lo.user_id")))
.groupBy(field("user.user_id"))).as("joined_table"))
.where(val(2).equal(DSL.any("district_array"))
.fetch()
.intoResultSet();
Your code is calling DSL.any(T...), which corresponds to the expression any(?) in PostgreSQL, where the bind value is a String[] in your case. But you don't want "district_array" to be a bind value, you want it to be a column reference. So, either, you assign your arrayAggDistinct() expression to a local variable and reuse that, or you re-use your field("district_array") expression or replicate it:
val(2).equal(DSL.any(field("district_array", Integer[].class)))
Notice that it's usually a good idea to be explicit about data types (e.g. Integer[].class) when working with the plain SQL templating API, or even better, use the code generator.

Accessing Neo4j List in Java After Query

I don't have much code to post, and I'm quite confused on where to start. There's a lot of documentation online and I can't seem to find what I'm looking for.
Suppose I have this query result saved into a StatementResult variable:
result = session.run("MATCH (n:person {tag1: 'Person1'})"
+ "RETURN [(n)-->(b) WHERE b:type1 | m.tag2]")
In the Neo4j browser, this returns a list of exactly what I'm looking for. My question is how we can access this in Java. I know how to access single values, but not a list of this type.
Any help would be appreciated.
Thanks.
Usually you just iterate over the statement results, to access each record and then with each record you can access each named column. You didn't use any names.
The column will return Value objects which you then can turn into the types you expect, so in your case into a list with asList().
See the API docs for StatementResult and Value.asList()
also your statement is not correct you probably meant b where you wrote m and you need to name your column to access it

How to rearrange rows of resultset data in java?

List userProcessedCountCol = new ArrayList();
while (iResultSet1.next()) {
afRealTimeIssuance afRealTimeIssuance = new afRealTimeIssuance();
Integer i = 0;
afRealTimeIssuance.setSub_channel(iResultSet1.getString(++i));
afRealTimeIssuance.setAgent_names(iResultSet1.getString(++i));
afRealTimeIssuance.setFtd(iResultSet1.getDouble(++i));
afRealTimeIssuance.setMtd(iResultSet1.getDouble(++i));
afRealTimeIssuance.setQtd(iResultSet1.getDouble(++i));
userProcessedCountCol.add(afRealTimeIssuance);
}
where afRealTimeIssuance is ActionForm
Using the above snippet I get something like below output
1 A 100
2 B 200
3 C 300
4 D 400
But I want to rearrange the output as
2 B 200
4 D 400
3 C 300
1 A 100
In short I want to rearrange the rows as I want.How to arrange the resultset data based on one particular value.Please guide
you can act as at two levels here:
Database level
Java level
At the database level the only way to manipulate the order of results to be returned is using ''ORDER BY ASC/DESC'' in your sql query. Note, that you can't rely on any other way to get the ordered results from the database.
At the java level you can store your objects like this:
- use a sortable collection. Make your action form comparable or implement a comparator that
allows to sort elements as you wish.
Then your can use This method to get the ordered collection by your own criteria.
You can consider also using TreeSet instead of ArrayList
This data structure will allow you to just add the data and given the comparator that you've defined in advance it will be always sorted. The addition has a logarithmic complexity though, so its up to you to decide.
Hope this helps
The ResultSet cannot be rearranged manually (only with sql) . What you can rearrange is your data structure that you hold your Objects
You can use an ArrayList of your row Objects and insert each row in the position you would like.
Lets say in your example, in the while loop:
userProcessedCountCol.add(index, element);
There are two ways of doing this. One you can modify the query to use ORDER BY clause to arrange the results. Second you can implement the Comparator interface and define your comparator classes and use Collection.sort(List list,Comparator c) to order the data.
Either use an ORDER BY clause in your SQL query, or Collections.sort() the List using a Comparator<afRealTimeInssuance>. The former is easier and places the load on the database, the latter more versatile as you can sort based on external information.
On a side note, you should name your classes using the Java conventions: AFRealTimeInssuance instead of afRealTimeInssuance.

how to initialize java array size to store database ResultSet data?

I'm new to java but my experience with Matlab and C trained me to ALWAYS pre-allocate memory for an array variable before filling that variable inside a loop (e.g. For loop, While loop, etc).
I find myself retrieving data from a database in Java using ResultSet. A quick search shows there's no way to obtain the number of rows in the ResultSet without stepping through it. Thus the basic question: how to pre-allocate array length of a Java variable intended to store the results of the ResultSet query, without knowing the number of rows in that ResultSet?
What's the conventional wisdom? For example, if the ResultSet contains two columns of data, how to place each column into an separate Java array variable?
UPDATE 1: Some background -- I need to place everything returned by the ResultSet into an object so that I may pass that object to a non-Java (e.g. ActionScript) program that communicates with the Java program via this object's contents.
UPDATE 2: Here's the documentation on the conversion rules from Java to non-Java (e.g. ActionScript). Perhaps
http://help.adobe.com/en_US/LiveCycleDataServicesES/3.1/Developing/WSc3ff6d0ea77859461172e0811f00f6eab8-7ffdUpdate.html
Why are you adding it to arrays? You can easily iterate through the ResultSet, transform the results to the appropriate Objects, and add them to an ArrayList... gives you much more flexibility than adding to an array.
But if you really need the number of rows, I think you'll need to run a count query before running your original one.
EDIT: From the documentation you linked, it would seem that if you use a Java ArrayList you'd end up with an ActionScript mx.collections.ArrayCollection object instead of the ActionScript Array object you'd get if you used a Java array. Your choice which one to use, just convert List -> array if you can't change your ActionScript code...:
List<MyObject> myList = new ArrayList<MyObject>();
... populate myList from ResultSet ...
MyObject[] array = myList.toArray(new MyObject[myList.size()]);
as what Marcelo said, ArrayList is a better option for this problem, but instead of executing a COUNT query to know how many rows is returned, you can trick it by using:
rs.last();
rs.getRow();
then gat back to the first row after,.

insert data into a lot of columns in java JDBC

I have a table with 50 columns and I want to insert all items in a HashMap variable into it (HashMap keys and table column names are the same).
How can I do that without writing 50 lines of code?
Get the key set for the HashMap. Iterate that key set to build a String containing your insert statement. Use the resulting String to create a PreparedStatement. Then iterate that key set again to set parameters by name using the Objects you retrieve from the HashMap.
You might have to write a few extra lines of special-case code if any of your values are of a Class that the JDBC driver isn't sure how to map.
I'd suggest you bite the dust and simply write a method that will do the dirty work for you containing 50 lines of parameter setting code. This isn't so bad, and you only have to write it once. I hope you aren't that lazy ;-)
And by the way, isn't 50 columns in a table a bit much? Perhaps a normalization process could help and lower complexity of your database and the code that will manipulate it.
Another way to go is to use an ORM like Hibernate, or a more lightweight approach like Spring JDBC template.
Call map.keySet() to get the name of all columns.
Create an INSERT statement by iterating the key set.
The column is from an item (a key) in the key set.
The data is from map.get(key).

Categories