My retrived data from SQL looks like this
ID Name
1 abc
2 xyz
3 def
Which Java collection variable shall I use to store and retrieve them based on postion alter.
I tried with list...But is was only including ID values,not the Name column.
Any help would be highly Appriciated
You might want to use Map collection which is useful to store key value pairs where Id is your key and value is your name.
Map<Long,String> map = new HashMap<Long,String>();
Like Suresh ATTA said Map is the best solution for this scenario. But in case you are going to get more columns from the DB, then it is better if you write a class around it.
An object of that class will represent a row, and the list of object will represent the result set you queried for.
For your current scenario it looks like:
class Name {
String ID;
String Name;
}
List<Name> allNames = // query from DB and resultset mapped to classes properly.
allNames.get(0) will give you the first row, and allNames.get(allNames.size()-1) will give you the last row.
Related
I want to extract data by joining tables from two different postgres hosted on different servers using java.
ResultSet resA = statement_A.executeQuery("select issue_id from Server_A.table_name");
ResultSet resB = statement_B.executeQuery("select issue_id from Server_B.table_name");
How can I get join query executed to get result set in this case ? Any pointers would be highly appreciated..
You can't do it in any automatic/magical way. What you can do is define a class that will have the union of properties of the two tables like:
public class JoinedResult{
private int id;
private int name;
// all other common properties to both
...
// properties exclusive to first table
...
// properteis exclusive to second table
...
}
and construct a list of these object that will contain the joined result of both tables.
To make the actual construction you have a few options:
The first one and the easiest one (but not efficient) is to iterate both results with nested loops, and once the ids (or whatever key is used) match you should construct a JoinedResult.
The second one is a bit more complex but also more efficient:
Iterate first result set and construct a map that will map the id to the object.
Iterate second result set and construct a map that will map the id to the object.
Run a loop over the keys of one of the maps you constructed and use that key to access the matching values in both maps, finally construct the joined object.
I am currently writing code which contains an arraylist. This arraylist includes data which is name, lastname, job and id. I need to seperate the data into different arraylists. Currently i am using the method which is shown below.
for (int i = 0; i < details.size(); i = i + 4) {
names.add(details.get(i));
lastname.add(details.get(i + 1));
job.add(details.get(i + 2));
id.add(details.get(i+3));
}
I want to know if there is a better way of doing this. The initial arraylist can be very long, and i dont know if there are any issues with this method.
You asked: "I want to know if there is a better way of doing this". There is a better way.
You should consider creating a class called Record that contains the data (name, last name, job, and ID), and create an ArrayList. Then, instead of using index locations (and potentially grab the wrong data item), you could use the Record getter methods to get the data item you need (and perhaps store it in a different list).
Step 1: Create a Record class:
public class Record
{
private String firstName;
private String lastName;
private String job;
private String id;
// TODO add constructor(s), getters and setters
}
Step 2: Create a list of Records (this is an better alternative that create a list having the information in different index locations. That way, each set of name, last name, job, and ID will be self-contained which is way better than disjointed in different index locations in a list.
ArrayList<Record> records = new ArrayList<Record>();
Step 3: Instead of using index locations (and potentially grab the wrong data item), you could use the Record getter methods to get the data item you need (and perhaps store it in a different list).
ArrayList<String> names = new ArrayList<String>();
ArrayList<String> jobs = new ArrayList<String>();
...
names.add(records.getLastName() + ", " + records.getFirstName());
jobs.add(records.getJob());
Alternatively, and maybe a better solution, you could use a Map to store this information. For example, a job ID could be the key in a Map that returns a job description and who has been assigned to perform it. Job IDs have to be unique. Adding IDs to a list can be duplicated, because the List interface doesn't restrict entering duplicate data. If you use a Map, they keys are guaranteed to be unique. The value being returned from the Map could be a Record object (or some other kind) that contains the name of the person and the job the person is responsible for. Since values can be duplicates, you can have a person performing multiple jobs, which is probably what you want to do. To use a Map:
Map<String, Record> jobs = new HashMap<String, Record>(); //This record class doesn't have ID in it.
jobs.put("ABC123", new Record("John", "Doe", "Fix Drywall");
jobs.put("321CBA", new Record("Bill", "Smith", "Install Light Fixtures");
A few things to consider if using a Map. If you try to make a new entry with an existing key, the old one will be overwritten.
jobs.put("ABC123", new Record("John", "Doe", "Fix Drywall");
jobs.put("ABC123", new Record("Bill", "Smith", "Install Light Fixtures"); //Overwrote the previous entry because key is the same
If you want to change the key for an existing value, you must obtain the value, store temporarily, remove the old record, and make a new entry with the old temp value:
jobs.put("ABC123", new Record("John", "Doe", "Fix Drywall");
Record rec = jobs.remove("ABC123"); // gets the record and removes old entry
jobs.put("321CBA", rec); // new job ID for old record
The main issue is that your details can have missing data. For example it has the size=5. Then your method will crush with IndexOutOfBounds. Your details list should contain a Person object which has all the details you want and then just use them to fill other lists.
The main performance kill will be the add operation since it will have to grow the data structure over time. Since you know details.size() you should initialize the other arraylists with details.size()/4.
You should also check that details.size() % 4 == 0 before the for loop. If not it means your data is somehow wrong and you will run for sure into an IndexOutOfBounds.
Just for correctness you should write i < details.size()+3 as your condition, since you will access element i+3 in the for body. You should always check for i < details.size()+x do it like this if you ever access i+x in the body. (for the largest x there will be in the body)
Using an object that extends HibernateDaoSupport, I ran a query using this right here:
List<Object> trialList2 = getSession().createSQLQuery(trialQuery2).list();
Where trialQuery2 is just some query that returned a single row. I got back a list with one Object on it, which when inspected in Eclipse looks like this:
[some, random, data]
I'd like to create an Object that can accommodate what I got back from the query, but a simple Javabean object that can has those fields doesn't seem to work. Does anyone know what kind of object I would have to make to be able to access those values?
It would be actually Object[] not Object
List<Object[]> trialList2
Based on columns in your select query, you get values from index
Let us say, if your query is select firstname, lastname from employee;
Object[0] would be firstname
Object[1] would be lastname.
As per documentation :
These will return a List of Object arrays (Object[]) with scalar values for each column in the table
U can replace any class name for BEANCLASSNAME
List<BEANCLASSNAME> trialList2 = getSession().createSQLQuery(trialQuery2).setResultTransformer(new AliasToBeanResultTransformer(BEANCLASSNAME.class)).list();
Since the play documentation on models is terrible I'll ask here. I have the basic code;
public static void Controller() {
List<Item> item = Item.find("SELECT itemname,id FROM Item WHERE itembool = true ORDER BY itemcreated ASC LIMIT 0,1").fetch();
if ( item == null ) {
notFound();
}
}
What I'm trying to do is get the value for 'itemname' returned for the first value returned from an SQL query (The real query is much more complicated and other things so it can't be replaced with methods). I can get the entire first object with item.get(0) but I can't figure out how to get the value of 'itemname' as a string and it doesn't seem to be documented anywhere.
Edit
Probably should have mentioned in the original question, I need to retrieve by field name, not index. I.E. I can't do items.get(0)[0]; I need to do items.get(0)['itemname'];
The documentation explains this if you read it, in here. Hibernate doesn't use SQL, but JPQL, which has a different syntax as it works with objects, not individual fields.
What you want to do can be achieved in two ways (both in the documentation):
List<Item> item = Item.find("SELECT i FROM Item i WHERE i.itembool = true ORDER BY i.itemcreated ASC").fetch(1);
List<Item> item = Item.find("itembool = true ORDER BY itemcreated ASC").fetch(1);
EDIT:
On the retrieval part, you will get a list of Item, so you can just access the field directly on the object:
item.get(0).getItemName();
Since Play uses Hibernate under the hood, you need to take a look at Hibernate's documentation.
In particular, SELECT itemname,id ... yields Object[] rather than Item, so that you can get itemname as follows:
List<Object[]> items = ...;
String itemname = items.get(0)[0];
well if you have to do a select itemname,id ..., you would not be able to do a items.get(0)["itemname"] because as axtavt and Pere have mentioned, you would get a Object[] back. You can instead create another (perhaps immutable) entity class that can be used in this query. Please refer to hibernate documentation for details. You can then model the entity based on your query requirements and use it to fetch information, thus letting hibernate handle all the magic number game for you. That ways, you would have a bean with filled up values that you can use to map back to your model class if you like.
HTH!
I have a query in Data Access Object DAOComments that joins users table and comments table and then store the result into Data Transfer Object DTOComments:
private static final String SQL_FIND_WITH_USERNAME =
"SELECT u.username, comments.* FROM users u JOIN comments
ON u.id = comments.id ORDER BY created_date DESC LIMIT 10;";
However, DTOComments does not have property "username" since it is the property of DTOUsers.
Option 1
So I decided to use Map<String, DTOComments>
In this case the map has username as KEY, DTOComments as VALUE.
But this approach will fails, because I care about the ORDER of result and that's why my query returns result in descending order. If I iterate the map on JSP page, the order is not consistent, so my JSP page would output the comment in random order.
(Even if order doesn't matter, I don't know if JSTL can display map's KEY. I know displaying the VALUE though)
Option 2
I could put the query result into ArrayList<DTOComments>
But I don't see any room to store the "username" now. Maybe I can add new property to DTOComments like private String username;
hmm... this would violate the concept of having DTO since it SHOULD reflect the database table schema.
Option 3
Create new class that hold all the information I need (ie. username + properties of DTOComments).
But just because I need one more property "username" in addition to the properties of DTOComments, creating new class seems not right way.
Could anyone give me advice how can I store all info returned by the query above in more organized way?
If I iterate the map on JSP page, the order is not consistent, so my JSP page would output the comment in random order.
That's the nature of HashMap. If you want to maintain insertion order in a Map, then you should be using LinkedHashMap instead. But the Map<User, Comment> approach has another disadvantage, if an user has posted more than one comment, you would be overwriting the previously inserted comment this way. You would like to use a Map<Comment, User> instead.
But IMHO it's better to make the User a property in Comment class, indicating a many-to-one relationship:
public class Comment {
private User user; // +getter +setter
}
This way you can end up with a List<Comment>.
That said, I wanted to comment on another statement of you:
I don't know if JSTL can display map's KEY. I know displaying the VALUE though)
You can iterate over a map using <c:forEach>. It goes over Map#entrySet(). Each iteration gives a Map.Entry object back which in turn has getKey() and getValue() methods.
Here's a kickoff example:
<c:forEach items="${map}" var="entry">
Key: ${entry.key}, value: ${entry.value}<br>
</c:forEach>