i am getting some records from database and adding in HashMap<Integer, Object> .Then i am adding this HashMap to a Vector<HashMap<Integer, Object>>. Now problem is when. I am printing the Vector, I am not getting the records in the same insertion order ... Please help.
public Vector<HashMap<Integer, Object>> executeQueryAsIntegerColumnNames(String aQuery, HashMap<String,String> conditions, String likeQuery){
LOGGER.info("Query in Execute:"+aQuery);
LOGGER.info("Query in Execute:"+conditions);
LOGGER.info("Query in Execute:"+likeQuery);
Vector <HashMap<Integer,Object>> result = null;
Connection conn = connection.getMySQLConnection();
String concond = this.getConditions(conditions);
try {
Statement stmt = conn.createStatement();
stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(aQuery + concond);
ResultSetMetaData metaInfo = null;
if(rs != null){
metaInfo =rs.getMetaData();
}
while(rs != null && rs.next()){
if(result == null){
result = new Vector<HashMap<Integer, Object>>();
}
HashMap<Integer, Object> row = new HashMap<Integer, Object>();
for(int i = 1 ; i <= metaInfo.getColumnCount(); i++){
row.put(i, rs.getObject(i));
}
result.add(row);
}
}catch(Exception ex){
LOGGER.error("executeQueryAsIntegerColumnNames : "+ex);
}finally{
try {
conn.close();
} catch (SQLException e) {
LOGGER.error("Exception :",e);
}
}
LOGGER.info("Befor Returning to Caller : "+result.toString());
return result;
}
Does Vector support insertion Order??? IF YES then This is my OutPut Please have a look
Befor Returning to Caller : [{1=mah0300537, 2=nabi hussain, 3=Mah03, 4=05:50:00 PM, 5=233346, 6=0}, {1=cha0700003, 2=sita sharan ray, 3=cha07, 4=05:50:00 PM, 5=233347, 6=2}]
Befor Returning to Caller : [{1=cha0700003, 2=sita sharan ray, 3=cha07, 4=05:50:00 PM, 5=233347, 6=2}, {1=mah0300537, 2=nabi hussain, 3=Mah03, 4=05:50:00 PM, 5=233346, 6=0}]
HashMap doesn't maintain insertion order. Use LinkedHashMap instead.
From HashMap javadoc:
This class makes no guarantees as to the order of the map; in particular, it does not guarantee that the order will remain constant over time.
Use LinkedHashMap if you want to keep the order of inserted elements in a map.
If you have to maintain order use LinkedHashMap .
http://docs.oracle.com/javase/6/docs/api/java/util/LinkedHashMap.html
Related
So essentially, I am using java to obtain information, and then I am using Kotlin to manage the information. So what I have done so far is, I have stored my information into a ArrayList called tableData in java, I store all my elements into this list (I should have used a better name here) and then returned the list. My java code:
public static ArrayList<String> readAllData () {
//Connecting to database
Connection con = DbConnection.connect();
//Preparing statement
PreparedStatement ps = null;
//result set declaration
ResultSet rs = null;
//tableData String array
ArrayList<String> tableData = new ArrayList<String>();
try {
//Database initialization
String sql = "SELECT * FROM ProjectInfo";
ps = con.prepareStatement(sql);
rs = ps.executeQuery();
while (rs.next()) {
//for each iteration store the data into variable a from column projectName
String a = rs.getString("projectName");
//print out each element
//System.out.println("a = " + a);
tableData.add(a);
}
//other catch exceptions
} catch (SQLException e) {
System.out.println(e.toString());
} finally {
try {
rs.close();
ps.close();
con.close();
} catch (SQLException e){
System.out.println(e.toString());
}
}
//System.out.println(tableData);
//return all the data that has been stored into this array
return tableData;
}
In Kotlin, I created a property class called GettingData and passed one parameter projectName: ArrayList<String>. Then i moved onto actually printing out the data
class GettingData(var projectName: ArrayList<String>) {
}
fun ManageData() {
var arrayData = listOf<GettingData>(GettingData(DbConnection.readAllData()))
var projectNameData = arrayData.map {it.projectName}
for (projectName in projectNameData) {
println(projectName)
}
}
All my elements are printed out, however I cannot use the filter functions to call specific elements from the arrayList? I want to be able to call every element and print them out in a alphabetical order? I tried filter, sortedWith and find functions but I cannot seem to get it working. How can I achieve this?
I think your question boils down to wanting to print a list of strings in alphabetical order.
You can use the sorted() function:
for (projectName in projectNameData.sorted()) {
println(projectName)
}
I have a sql query to run in my java class (Servlet) what i am trying to do if there is no data in database for that query then want to do something else.
In simple terms i am checking if there is no data in resultset than want to do something else,but that's not working
What i have tried
String str = null;
Gson gson = new Gson();
LinkedHashMap<Object, Object> lhm = null;
LinkedList<LinkedHashMap<Object, Object>> mainList = new LinkedList<LinkedHashMap<Object, Object>>();
String sql;
try {
Connection con = DBConnection.createConnection();
Statement statement = con.createStatement();
sql = "select distinct a.DISPLAYCOUNTERNAME from DISPLAYCOUNTERNAMES a,DISPLAYCOUNTER b where a.DISPLAYCOUNTERCODE=b.DISPLAYCOUNTERCODE and USERNAME='"
+ userName + "'";
System.out.println(sql);
ResultSet resultSet = statement.executeQuery(sql);
if (!resultSet.isBeforeFirst()) { // if there is no data
lhm = new LinkedHashMap<Object, Object>();
lhm.put("outlet", "NoData");
mainList.add(lhm);
str = gson.toJson(mainList);
}
while (resultSet.next()) { // if there is data
lhm = new LinkedHashMap<Object, Object>();
counterName = resultSet.getString("DISPLAYCOUNTERNAME");
System.out.println("counternam"+counterName);
lhm.put("Counter name", counterName);
mainList.add(lhm);
str = gson.toJson(mainList);
}
System.out.println(str);
response.setContentType("application/json");
response.getWriter().write(str);
} catch (SQLException e) {
System.out.println("SQL Issues 2...");
e.printStackTrace();
}
The above code is throwing error as SQL Issues 2...
java.sql.SQLException: This method should only be called on ResultSet objects that are scrollable (type TYPE_SCROLL_INSENSITIVE).
I don't know what i am doing wrong here,any-kind of help will be appreciated
You can try modifying the line:
Statement statement = con.createStatement();
to
Statement statement = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
You could use next but switch to use a do/while loop, if the first call to next returns true then the row pointer points to the first row in the result set so you must read it before calling next again
if (!resultSet.next()) {
// do no data stuff
} else {
do {
//handle result set data
} while (rs.next());
}
I am trying to pass the output of a ResultSet to Java HashMap.
Map<Integer, String> sIDpNumberHashMap = new HashMap<Integer, String>();
while (DBresult.next()) {
int sID = DBresult.getInt("slrid");
String pNumber = DBresult.getString("pNumber");
sIDpNumberHashMap.put(sID , pNumber );
System.out.println("Output1"+ sID + "\t" + pNumber + "\n");
}
System.out.println("Output2" + "\n" + sIDpNumberHashMap);
While the Output1 is showing all the records(from the DB). The put command only takes the last value from the ResultSet in.
Output1:
502332262 101E2571G103
502332262 101E2571G103
502332262 116E3139P001
502332262 117E3640G025
502332262 314B7159G003
502332262 117E3640G025
Output2:
{502332262=117E3640G025}
How do I make the put command to iterate over the results from the ResultSet?
All your IDs are identical (502332262), and HashMap doesn't allow duplicate keys. That's the reason you see only one entry in the HashMap (containing the last value you put in the Map).
If you want to allow duplicates, consider a different collection to hold the data. For example, you can use an ArrayList<SomeClass> where SomeClass contains the two properties you read from the DB.
I might be late but I believe someone can get an idea from what I did.
Recently I had an almost similar challenge where I wanted to build dynamic query results (whatever select query just returns its JSON list and question would vary a lot and I can't write method per query so I had to come up with something everyone will be calling).
Below is my sample code:
public <T> List<T> findWithDynamicQuery(String query){
Connection conn = null;
PreparedStatement statement = null;
List<Object> mResults = new ArrayList<>();
try {
conn = //use your connection parameters;
} catch (SQLException e) {
e.printStackTrace(out);
return (List<T>) mResults;
}
try {
statement = conn.prepareStatement(query);
ResultSet result = statement.executeQuery();
ResultSetMetaData metaData = result.getMetaData();
int column = metaData.getColumnCount();
while (result.next()) {
HashMap<Object, Object> rows = new HashMap<>();
for(int i = 1; i <= column; i++){
rows.put(metaData.getColumnLabel(i), result.getObject(i));
}
mResults.add(rows);
}
result.close();
return (List<T>) mResults;
} catch (SQLException e) {
e.printStackTrace(out);
}finally{
if(statement != null){
try {
statement.close();
} catch (SQLException e) {
}
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
}
}
}
return (List<T>) mResults;
}
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.
The db tables that I am using are changing very often meaning new column can be add which will reflect my sql’s.
The solution that I was thinking is first “read” the meta data into some map and use it in order to retrieve the values something like this.
Read meta data:
public class Dynamic {
static public final Map<Integer, String> metadata = initMetaData();
HashMap<String, String> data = new HashMap<String, String>();
private static Map<Integer, String> initMetaData() {
Map<Integer, String> tmpMap = new HashMap<Integer, String>();
try {
Connection connection = DBConnection.getConnection();
try {
Statement stmt = connection.createStatement();
ResultSet result = stmt.executeQuery("SELECT * FROM TMP WHERE ROWNUM = 1");
for (int i = 1; i <= result.getMetaData().getColumnCount(); i++) {
tmpMap.put(new Integer(i), result.getMetaData().getColumnName(i));
}
} finally {
connection.close();
}
} catch (SQLException ex) {
…..
}
return Collections.unmodifiableMap(tmpMap);
}
public static String getColumnName(Integer index) {
return metadata.get(index);
}
And when running the sql:
public static void test()
try {
Connection connection = DBConnection.getConnection()
try {
Statement stmt = connection.createStatement();
ResultSet result = stmt.executeQuery("SELECT * FROM TMP where idx = 'R5'");
while (result.next()) {
Dynamic d = new Dynamic()
for (int i = 1; i <= Dynamic.metadata.size(); i++) {
d.setData(Dynamic.getColumnName(i),result.getString(Dynamic.getColumnName(i)));
}
}
In this approach I have two problems(that I notice):
1) I need to execute two loops
2) I don’t know which get function to use via resultset since the type can also change.
How can I overcome those problems ?
I would also appreciate to get some other suggestion maybe there is a simple why
Thanks
1) What is your alternative to the inner loop? How would you get the field values? Do you think there is a lot of overhead in looping over small number of integers?
2) You can get extra information about field data type from the same metadata where you get the field name and map the method names accordingly.
3) You should really create a map for multiple tables - table/fieldSeq/fieldType/methodName and maybe few extra details - you don't have to get them all dynamically all the time.