select statement where condition returns multiple rows - java

I am trying to get all the results from multiple rows returned by the same where condition:
public static String getResult(String mycondition)
{
ResultSet rsData = sql.RunSelect("select col1 from my_table where con ='"+myCondition+"'");
if (rsData.next())
{
String result = rsData,getString("col1");
}
}
Note that there is an id column that makes these rows distinguishable.
The display in jsp page should make text fields for every row returned.
Any thoughts?

You can return a List<String> or use a char to separate the multiple strings in a single String. IMO it would be better returning a List<String>:
public static List<String> getResult(String mycondition) {
List<String> results = new ArrayList<String>();
ResultSet rsData = sql.RunSelect("select col1 from my_table where con='"
+myCondition+"'");
while (rsData.next()) {
results.add(rsData.getString("col1"));
}
return results;
}
Also, this method is prone to SQL Injection. Note that your parameters should be sent apart from the query. Probably you can improve your sql.RunSelect method to use PreparedStatement instead of Statement. This is a basic example of the code skeleton:
public ResultSet runSelect(String query, Object ... params) {
//assumes you already have your Connection
PreparedStatement pstmt = con.prepareStatement(query);
int i = 1;
for(Object param : params) {
pstmt.setObject(i++, param);
}
return pstmt.executeQuery();
}
So now you could modify your method to
public static List<String> getResult(String mycondition) {
List<String> results = new ArrayList<String>();
//using the new runSelect method
ResultSet rsData = sql.runSelect(
"select col1 from my_table where con=?", mycondition);
while (rsData.next()) {
results.add(rsData.getString("col1"));
}
return results;
}

you should use while loop instead of if loop
instead of - if (rsData.next())
use - while (rsData.next())
Although answer of #Luiggi Mendoza is best if you want security in your code

Related

How to return List<Long> value from method in java and put it in new list?

I have in one java class a method which SELECT one coloumn from a table from my database, and that column is an INT type in the database, and then I select items from that coloumn, put it in a List and return this List. Here is the method:
public List<Long> vratiSveSifreRacuna() throws SQLException {
String sqlVratiSifruRacuna = "SELECT RacunID FROM racun";
Statement stat = konekcija.createStatement();
ResultSet rs = stat.executeQuery(sqlVratiSifruRacuna);
Long racunID = 0L;
List<Long> sifre = new ArrayList<Long>();
while (rs.next()){
racunID = rs.getLong("RacunID");
sifre.add(racunID);
}
return sifre;
}
Now, how can I return a list from this method and put in another list?
When I try to do it, it doesn`t work...like it sees the returned list empty or something...
Why is that happenning? Is this method ok?
I want to have a method which returns a whole coloumn from from a database table as List and then I want to use this List somehow...
As you said, you have an INT value in your database and you're using getLong() to try and get an INT value which is probably why it's not working.
Try to use this instead:
while (rs.next()){
racunID = (Long) rs.getInt("RacunID");
sifre.add(racunID);
}
return sifre;
EDIT 1 (Simplified) :
while (rs.next()){
sifre.add(new Long(rs.getInt("RacunID")));
}
return sifre;
You don't even need to add to a new List, just pass your original list along in parameters:
public void vratiSveSifreRacuna(List<Long> passedList) throws SQLException {
String sqlVratiSifruRacuna = "SELECT RacunID FROM racun";
Statement stat = konekcija.createStatement();
ResultSet rs = stat.executeQuery(sqlVratiSifruRacuna);
Long racunID = 0L;
List<Long> sifre = passedList;
while (rs.next()){
racunID = rs.getInt("RacunID"); //column is int, it will automatically upcast to long don't worry about that
sifre.add(racunID);
}
//set sifre to null now to let it get garbage collected :)
sifre=null
}
Call the method as follows now:
yourclassreference.vratiSveSifreRacuna(yourListLong);
Keep your method as it is (side-effects on parameters should be avoided).
Call the method, store the result, and add it to the other list you want to complete.
List<Long> foo = ...; // i don't know where it comes from
List<Long> bar = vratiSveSifreRacuna();
foo.addAll(bar);
See java.util.List#addAll API

How to write sql innerquery in hibernate?

presently my method uses basic jdbc concept like this,
public static ArrayList<VehicleDetailsBean>
getAllVehicleDetails(String groupId,String clientId)
throws ClassNotFoundException, SQLException {
ArrayList<VehicleDetailsBean> vehicleDetailsList =
new ArrayList<VehicleDetailsBean>();
try {
Statement statement = connection.createStatement();
String sql ="SELECT a.vehicleno,a.lat,a.lng,a.status, "+
"a.rdate,a.rtime from latlng a,vehicle_details b where"+
"a.vehicleno=b.vehicleno and b.clientid='"+
clientId+"' and b.groupid in(select groupid from group_details"+
" where groupname='"+groupId+"' and clientid='"+clientId+"')";
ResultSet rs = statement.executeQuery(sql);
while(rs.next()) {
VehicleDetailsBean vehicleDetailsBean=new VehicleDetailsBean();
vehicleDetailsBean.setVehicleno(rs.getString("vehicleno"));
vehicleDetailsBean.setLat(rs.getString("lat"));
vehicleDetailsBean.setLng(rs.getString("lng"));
vehicleDetailsBean.setStatus(rs.getString("status"));
vehicleDetailsBean.setRdate(rs.getInt("rdate"));
vehicleDetailsBean.setRtime(rs.getString("rtime"));
vehicleDetailsList.add(vehicleDetailsBean);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
it returns an ArrayList. Now I want to change it to hibernate SO I will change above code as,
query = session.createQuery(hqlquery);//I am not getting how to write hqlquery
List<Object[]> groupList = query.list();
for(Object[] arr : groupList){
System.out.println(Arrays.toString(arr));
}
by doing this it returns List object but my method has to return ArrayList. So can any one help me to write query and return the result as ArrayList.
You can do it the ugly way:
query = session.createQuery(hqlquery); // Take a walk in Hibernate Docs for HQL Queries
List<?> groupList = query.list();
ArrayList<VehicleDetailsBean> result = new ArrayList<VehicleDetailsBean>(groupList.size());
for (Object o : groupList) {
result.add((VehicleDetailsBean) o);
}
return result;
If you want to return it as ArrayList, you can just addAll it with your ArrayList.
List<VehicleDetailsBean> groupList = (List<VehicleDetailsBean>) query.list();
vehicleDetailsList.addAll(groupList);
return vehicleDetailsList;
You can see similar question here and a way to cast here
EDIT
Or try to add entity
List<LatitudeBean> bean = (List<LatitudeBean>) session.createSQLQuery(query)
.addEntity(LatitudeBean.class).list();
//add to ArrayList here

JDBC with MySQL - SELECT ... IN

Using PreparedStatement to build a query that looks like this...
SELECT * FROM table1 WHERE column1 IN ('foo', 'bar')
...without knowing the number of strings in the IN statement
Constructing a string like...
"'foo', 'bar'"
...and passing that in with ps.setString() results in:
"\'foo\', \'bar\'"
Which is probably a good thing, but it makes this approach to my problem useless.
Any ideas on how to pass in an unknown number of values into a JDBC PreparedStatement without dynamically creating the query string too (this query lives in a file for easy reuse and I'd like to keep it that way)?
I tend to use a method that will modify the query to modify the query accordingly. This is a basic example that omits error handling for simplicity:
public String addDynamicParameters(String query, List<Object> parameters) {
StringBuilder queryBuilder = new StringBuilder(query);
queryBuilder.append("?");
for (int i = 1; i < parameters.size(); i++) {
queryBuilder.append(", ?");
}
queryBuilder.append(") ");
return queryBuilder.toString();
}
public void addParameters(PreparedStatement pstmt, List<Object> parameters) {
int i = 1;
for(Object param : parameters) {
pstmt.setObject(i++, param);
}
}
public void testDynamicParameters() {
String query = "SELECT col3 FROM tableX WHERE col1 = ? AND col2 IN (";
List<Object> parametersForIn = ...;
query = addDynamicParameters(query, parametersForIn);
List<Object> parameters = ...;
PreparedStatement pstmt = ...; //using your Connection object...
parameters.addAll(parametersForIn);
addParameters(pstmt, parameters);
//execute prepared statement...
//clean resources...
}

Store rows of resultset in array of strings

I want to count the numbers of entries in resultset and then store these values in an array and pass this array to create a graph.
ResultSet rs = stmt.executeQuery( "SELECT distinct "+jTextField.getText()+" as
call from tablename"); // this statement will select the unique entries in a
particular column provided by jtextfield
int count=0;
while(rs.next())
{ ++count; } // This will count the number of entries in the result set.
Now I want to store the values of result set in an array of string. I used the following code
String[] row = new String[count];
while(rs.next())
{
for (int i=0; i <columnCount ; i++)
{
row[i] = rs.getString(i + 1);
}
}
Error : Invalid Descriptor Index.
Please suggest how to copy the result of resultset in array.
For example if I enter priority in jTextField , the result set will contain
priority1
priority2
priority3
In your first while loop you read all the entries in the ResultSet, so when executing the second while loop there's nothing else to read. Also, the index of ResultSet#getXxx starts at 1, not at 0. Also, since you don't know the amount of rows that you will read, it will be better using a List backed by ArrayList instead.
Considering these, your code should look like:
ResultSet rs = stmt.executeQuery( "SELECT distinct "+jTextField.getText()+
" as call from tablename");
List<String> results = new ArrayList<String>();
while(rs.next()) {
results.add(rs.getString(1));
}
Based in your comment, I extended the sample:
public List<String> yourRandomQuery(String columnName) {
Connection con = null;
ResultSet rs = null;
List<String> results = new ArrayList<String>();
try {
String baseQuery = "SELECT DISTINCT %s AS call FROM tablename";
con = ...; //retrieve your connection
ResultSet rs = stmt.executeQuery(String.format(baseQuery, columnName));
while(rs.next()) {
results.add(rs.getString(1));
}
} catch (SQLException e) {
//handle your exception
e.printStacktrace(System.out);
} finally {
closeResource(rs);
closeResource(con);
}
return results;
}
//both Connection and ResultSet interfaces extends from AutoCloseable interface
public void closeResource(AutoCloseable ac) {
try {
if (ac != null) {
ac.close();
}
} catch (Exception e) {
//handle this exception as well...
}
}
public void someMethod() {
//retrieve the results from database
List<String> results = yourRandomQuery(jTextField.getText());
//consume the results as you wish
//basic example: printing them in the console
for(String result : results) {
System.out.println(result);
}
}
Try this
ResultSet rs = stmt.executeQuery( "SELECT distinct "+jTextField.getText()+" as
call from tablename");
List<String> list=new ArrayList<>();
while(rs.next())
{
list.add(rs.getString(1));
}
Why not just create a HashSet<String> and write into that. Note that HashSet is unordered, just like your query. By using a collection that is of arbitrary size you don't need to determine the require dsize in advance.

Merging Multiple ResultSet into Single ResultSet in Java

Let say I have multiple ResultSet(each resultSet would refer to 1 row in database) (they are of same table.) . Now I want to create consolidated ResultSet which would intern have all other resultSet. So my primary goal is to create a combined ResultSet which would point to all rows which where previously pointed by individual resultSet.
I am using Java. Do any one know how pragmatically we can achieve this?
Edit : we are using java.sql.ResultSet.
Edit : To make it more clear :
Let say I have
List<ResultSet> someResults ; // each resultSet Would point to a single row in database.
I want to create a consolidated ResultSet finalResults;
psudo code :
List<ResultSet> resultSets = // poppulated from code
ResultSet rs = convert(resultSets) // psude conver method
If you are talking about a java.sql.ResultSet, it's not possible as far as I know. I suggest you change your query instead.
Or you can retrieve the results into an java object and then combine all the objects into a Collection.
I would do it this way
class GatheringResultSet implements ResultSet {
List<E> resultSets;
ResultSet current;
GatheringResultSet(List resultSets) {
this.resultSets = new ArrayList(resultSets);
current = resultSets.remove(0);
}
#Override
public boolean next() throws SQLException {
if (current.next()) {
return true;
}
if (resultSets.isEmpty()) {
return false;
}
current = resultSets.remove(0);
return true;
}
...
the rest of the methods just delegate call to current ResultSet
If the results are gonna be from the same table, why not use UNION/UNION ALL(depending on your needs) in your query itself.
Something like this:
select A, B
from C where Q = R
union
select A, B
from C where P = S
Or else, there is the hard way of iterating through each result set and populating POJOs and adding them to a List/Set(Based on your needs). This seems to be an overkill if there are a lot of result sets.
public class ResultSets {
private java.util.List<java.sql.ResultSet> resultSets;
private java.sql.ResultSet current;
#lombok.SneakyThrows
public ResultSets(java.util.List<java.sql.ResultSet> resultSets) {
this.resultSets = new java.util.ArrayList<>(resultSets);
current = resultSets.remove(0);
}
#lombok.SneakyThrows
public boolean next() {
if (current.next()) {
return true;
}else if (!resultSets.isEmpty()) {
current = resultSets.remove(0);
return next();
}
return false;
}
#lombok.SneakyThrows
public int getInt(int pos){
return current.getInt(pos);
}
#lombok.SneakyThrows
public String getString(String field){
return current.getString(field);
}
}
Usage :-
#lombok.SneakyThrows
public static void main(String ... args) {
Connection conn = pe.getConnection("backup");
String sql1 = "SELECT count(distinct(User_Key)) FROM user_table";
String sql2 = "SELECT count(distinct(Username)) FROM user_table";
Statement stmt1 = conn.createStatement();
Statement stmt2 = conn.createStatement();
List<ResultSet> resultSets = new ArrayList<>();
resultSets.add(stmt1.executeQuery(sql1));
resultSets.add(stmt2.executeQuery(sql2));
ResultSets rs = new ResultSets(resultSets);
while(rs.next()){
System.out.println(rs.getInt(1));
}
}

Categories