In java, how to add result sets under one big parent resultset - java

In my java code, I have multiple select statements running against a database. Each select returns a different resultset. Now I want to have all the result sets under one resultset & pass as the return object.
I want the result sets to be children of the final result being passed. How can I achieve this. I am new to Java. Please help.
In addition to the result sets from select, there are also some values in local variable that need to be passed back.

This sounds like joining for me. If you do not modify data then you can use a join in your query and process each row after the values are returned.
If for some reason a join is not an option, then you can create a tree and add nodes at their appropriate position to achieve the hierarchy you want.
I cannot give you more information, as the only specified technology was Java and I do not know what database server are you using.

Related

SQL query speed: multiple queries vs sorting within Java

Lets say I have a table with 2 columns:
city
name (of a person).
I also have a Java "city" object which contains:
city name
a list of all the people in that city
So now I have two options to get the data:
First use DISTINCT to get a list of all the cities. Then, for each city, query the database again, using WHERE to get only records where the person lives in that city. Then I can store this in a City object.
Get a list of all the data, using ORDER BY to order by the city name. Then loop through all the records and start storing them in City objects. When I detect that the city name changes then I can create a new City object and store the records in that.
Which of these methods is faster / better practice? Or is there some better way of getting this information than these two methods? I am using Oracle database.
A database query is a relatively expensive operation - you need to communicate with another server over the network, it then may need to access its disk, compute a result, return it to you, etc. You'd want to minimize these as much as possible. Having a single query and going over its results is by far a better idea than having multiple queries, unless you have some killer reason not to do so - which doesn't seem to be the case here, at least not from the information you shared.
Sort answer is #2. You wish to make as less queries to the database as possible. #2 if i got it correct you will make a join of city/people and then create the object.
Better way: Use JPA/Hibernate. i.e check http://www.baeldung.com/hibernate-one-to-many
Answer number #2 is optimal, in all cases.
You'll need to code the logic in Java to differentiate when you change from one city to the next one.
Alternatively, if you were using MyBatis the solution becomes very simple by using "collections". These perform a single database call and retrieve the whole Java tree you specify, including all sublists in multiple levels. Very performant and also easy to code.

Is it possible to refer/use to ANOTHER mapper/datasource from a myBatis mapper?

I am trying to figure out (and so far it seems I am out of luck), if it possible to refer (for association, for example) to a nested select from a different mapper/datasource ? Or may be some HashMap, which I could prepare manually beforehand..
What am I trying to achieve is basically the following:
say we have a database ONE, which has a table with a list of items. Every item has a field like "external_id"
we have also a database TWO, which is on different host and/or of a different driver type, which has a table with id; name pairs
And I would like to return a Mapped type which would contain fields from BOTH databases ONE and TWO.
Any ideas? So far I can only suggest constructing 2 POJOs independently, one with a returned ResultSet from db ONE and another with a list of id/name-pairs from db TWO and building the resulting object "by hands". But this is so boring...

Joint data set limited to two tables in BIRT

I have a request that should extract data from three tables A, B, C based on two conditions, these tables A,B and C are located in the same data source.
does BIRT 3.1 supports joint data sets with more than two tables?
Otherwise, is there a way to overcome this limitation?
You don't say what your data source is, but assuming that it is a SQL data base. You can do something like this in the SQl. You only need to do BIRT joins if the data is in different data sources.
select TableA.Field
, TableB.OtherField
, TableC.SomeOtherField
from dbo.TableA
left join dbo.TableB
on TableA.Same = TableB.Same
left join dbo.TableC
on TableA.Same = TableC.Same
where TableA.Important = 'Something'
In addition to James' answer:
In many cases just joining the tables using SQL is the best solution (you should know SQL if you are developing with BIRT, unless someone else prepared the Data Sets and corresponding report items for you).
As an alternative, keep in mind that BIRT does not have a "data model" like other report designers (e.g. Oracle Reports) and that you link data from different data sets by creating a corresponding layout structure, with data set parameter bindings.
You didn't mention the logical structure of your data.
If it's master-detail-detail (for example, artist-album-title), then you would use for example a list item bound to DS "artist", containing a list or table item bound to DS "album" which in turn contains a table bound to DS "title".
The DS "album" would need a DS parameter like "artist_id" or whatever (which you use in the WHERE clause of the SELECT statement), and in the list/table item bound to DS "album", you would use row["artist_id"] as the value for the DS parameter "artist_id".
This is similar for the table item bound to DS "title". However, if the primary key consists of (artist_id, album_id, title_no), you probably need access to the current artist from the outer-most list item. To access this, you use row._outer["artist_id"].
The solution for this problem is using the stored procedure query, you set your proceure with whatever sql request you want, compile it with your DBMS, and you call it from BIRT with the syntax
call nameOfYourProceure{(?,?,?...)}
Question marks refer to the parameters that you will pass to your stored procedure.

Best way to indicate no change on row update with Java PreparedStatement

I am creating a method to update a row in a SQL Server 2008 database. The SQL String looks something like this:
private static final String UPDATE_ROW =
"UPDATE MyTable SET FieldOne = ?, FieldTwo = ? " +
"WHERE IDField = ?";
It's simplified, of course. But the rub is that not all of the fields will necessarily change. I know that with straight SQL you can just put the field name in for the value and nothing will change; however, I don't know how to do this with the Java PreparedStatement.
I could work around it by calling one update for each field to be changed (there are up to ten) for each row, but that is just fugly and I would really like to avoid it. Can anyone tell me how to put the field name in as a parameter value, or at least give me a clean solution?
I couldn't find a way to do what I described, so I ended up reading the values of the things I was updating and passing in those values.
It will be a lot more efficient if you do create specialized UPDATE statements that only state the columns that have changed.
If you always update all columns you'll generate a lot of overhead by e.g. updating indexed columns which will cause the corresponding index to be updated as well (and without the actual need for this).
This will happen even if you specify UPDATE foo SET bar = bar if I'm not mistaken. I don't think SQL Server optimizes such updates away.
Its good that you are trying to avoid generating a specialized statement for each update.
Are the fields not inter-related? Because if they are inter-related, the update had better maintain inter-field consistency. So you need to first read the values, and then write all of them back -- both the changed and unchanged ones.
If they really are completely unrelated to one another, have a series of updates all getting committed at the same time.
Usually, one ends up somewhere in-between -- there are clusters of fields that are inter-related. For example, a Person record that contains several fields related to BillingAddress. In such cases, have a prepared statement for each group of related fields.
If you are trying to avoid the cost of a read (to get the current values), then consider a stored procedure, where unchanged field values are encoded with NULLs.
If you are not using an ORM, you can also consider using a cursored ResultSet, and update the fields one by one, then commit the changes using updateRow(). See java.sql.ResultSet. To do the same thing as the Javadoc using a PreparedStatement, you will need to use a variant of Connection.prepareStatement(...).

ScrollMode.FORWARD_ONLY

Even I've searched on google I want to be very sure about a thing.
Does ScrollMode.FORWARD_ONLY means that I will receive the results in the order they are in DB?
I have something like:
Scroller<Integer> foundRecs = new Scroller<Integer>(query.scroll(ScrollMode.FORWARD_ONLY));
Maybe is a stupid question...
That specific API is Hibernate, which I don't know too much about, but I guess it maps down to TYPE_FORWARD_ONLY in the end (and its documentation agrees by mentioning that constant).
If that's the case, then no: this will not influence the order in which items are returned.
It only means that you can only traverse the result once and can only navigate forward (not backwards).
Databases don't really have an "order" in which they store data, because their tables are sets (not lists). If you need some order for your results, then you need to add an ORDER BY to your SQL (or the equivalent in whichever query system you use).
You cannot rely on the physical order of data in the database. This might work if you query only a single table, but will fail as soon as you are using joins.
If you want your data to appear in a specific order, you need an ORDER BY clause.

Categories

Resources