I would like to put all the data from the following sql in a map( because this sql is called many times and instead of going to db everytime ),
but I am wondering how to implement the <= for the timestamp
EDIT:
I am using Oracle, just updated the tags, however, I am using PreparedStatement in java which caches queries, without being recompiled, but our program doesn’t have a cache solution to cache the data from the table. going to the db and getting the data is taking 2 ms roundtrip, but getting the data from the HashMap would take a nano second. This query is being executed around 20,000 times and we would like to load all the data initially and put it inside the Hashmap.
END OF EDIT.
SELECT ar
FROM table1
WHERE fk_col1 = ?
AND timestamp_col <= ?
ORDER BY date DESC
The way I did is as follows: but I am not sure, the timestamp_col in equals and hashCode is right. Could you suggest the modifications?
public class Table1Key
{
private String fk_col1;
private java.sql.Timestamp timestamp_col;
//setters and getters here.
//implementing hashCode and equals.
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((fk_col1 == null) ? 0 : fk_col1.hashCode());
result = prime * result
+ ((timestamp_col == null) ? 0 : timestamp_col.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Table1Key other = (Table1Key) obj;
if (fk_col1 == null) {
if (other.fk_col1 != null)
return false;
} else if (!fk_col1.equals(other.fk_col1))
return false;
if (timestamp_col == null) {
if (other.timestamp_col != null)
return false;
} else if (!timestamp_col.equals(other.timestamp_col))
return false;
return true;
}
}
…
private Map<Table1Key, String> map = Functions.getHashMapInstance();
public class Functions {
...
public static <K,V> HashMap<K,V> getHashMapInstance() {
return new HashMap<K,V>();
}
}
So, I would populate the map like the following:
private void populateMap() throws SQLException {
try {
ps = conn.prepareStatement(table1Sql);
ps.setFetchSize(20000);
ResultSet rs = ps.executeQuery();
while(rs.next()) {
Table1Key rdk = new Table1Key();
String ar = rs.getString(1);
rdk.setFk_col1(rs.getString(2));
rdk.setTimestampCol(rs.getTimestamp(3));
if(actualRateMap.get(rdk) == null) {
actualRateMap.put(rdk, ar);
}
}
} catch (SQLException e) {
e.printStackTrace();
throw e;
} finally {
ps.close();
}
}
//set the key here.
Table1Key tk = new Table1Key();
tk.setFk_col1(col1);
tk.setTimestampCol(timestamp);
String ar = actualRateMap.get(tk);
//My main concern here is .. this will work if the sql has timestamp_col = ?, but what if the timestamp_col is < than what is present in the map?
if(actualRate != null) {
Logger.info("Actual Rate:"+actualRate);
}
HashMapdoesn’t do the job for your case, rather TreeMap can help.a): RangeMap solution
Guava RangeMap is designed to handle such case:
Of course, ‘fk_coll’ is problem. so you could define
Map<String/*fk_coll*/, RangeMap<java.sql.Timestamp, String>>to handle the case.b): TreeMap solution
and
handles ‘fk_coll’.
plus: evict is a problem in any cache case.