How to convert Time format in MySql to String in Java? - java

I am using hibernate to take out some records from my MySql database. The DepTime attribute in my table is of time format (hh:mm:ss). How can I convert it into string in Java? Following code is giving a type mismatch error at line 6.
List<?> dataList3 = DBOperation.getqpidfromAssessment(6);
if(dataList3.size()>0)
{
for (Iterator<?> iterator = dataList.iterator(); iterator.hasNext();) {
Route rt = (Route) iterator.next();
String depTime=rt.getDepTime();
double lt=rt.getLatitude();
log.debug("Lat : "+lat);
}
}

Use .toString() function to convert anydata into string in java.
String depTime=rt.getDepTime().toString();

Related

String Date in Named query generate ClassCastException

I am trying to create a named query for all the stringified arguments. This was how my stringified method was:
public Collection<Companypermcache> findExpiredPerms() {
String date = DateUtils.getSQLDate(DateUtils.getToday());
StringBuffer qbe = new StringBuffer("select cpc from Companypermcache cpc");
qbe.append(" where cpc.expire < '"+date+"'");
return super.findByQuery(qbe.toString());
}
I convert this to named query like below
String date = DateUtils.getSQLDate(DateUtils.getToday());
StringBuffer qbe = new StringBuffer("select cpc from Companypermcache cpc");
qbe.append(" where cpc.expire < :date");
return super.findByQuery(qbe.toString(),"date",date);
}
But this generates
java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Date
at org.hibernate.type.descriptor.java.JdbcTimestampTypeDescriptor.unwrap(JdbcTimestampTypeDescriptor.java:24)
at org.hibernate.type.descriptor.sql.TimestampTypeDescriptor$1.doBind(TimestampTypeDescriptor.java:48)
at org.hibernate.type.descriptor.sql.BasicBinder.bind(BasicBinder.java:74)
at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:253)
at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:248)
at org.hibernate.param.NamedParameterSpecification.bind(NamedParameterSpecification.java:52)
at org.hibernate.loader.hql.QueryLoader.bindParameterValues(QueryLoader.java:627) ...
Exception.
However If I update the named query like below I don't have any exception and everything looks good.
String date = DateUtils.getSQLDate(DateUtils.getToday());
DateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd");
Date edate = simpleDateFormat.parse(date);
StringBuffer qbe = new StringBuffer("select cpc from Companypermcache cpc");
qbe.append(" where cpc.expire < :date");
return super.findByQuery(qbe.toString(),"date",edate);
}
However I really did not understand the difference and and the need of parsing.I have many place in my project where I am using getSQLDate(), So I am concerned whether I want to parse all those dates?
In addition to that type for edate in my table is DATETIME
Why we need to parse the Date when we pass a date as argument to named query????

How to get data from SQL with sql2o?

I'm trying to get data from mySQL to List in java using sql2o lib.
But for some reason I just fail to understand how to use it properly (it looks like).
Here is the faulty code:
List<String> returning = new ArrayList<String>();
String date = "";
String playerList = "";
String playerCount = "";
String playerMax = "";
con.createQuery(sql)
.throwOnMappingFailure(true).addColumnMapping("date", date)
.addColumnMapping("playerList", playerList)
.addColumnMapping("playerCount", playerCount)
.addColumnMapping("playerMax", playerMax).executeAndFetch(String.class);
returning.add(date);
returning.add(playerList);
returning.add(playerCount);
returning.add(playerMax);
And here is error I get:
org.sql2o.Sql2oException: Could not map date to any property.
at org.sql2o.DefaultResultSetHandlerFactory.newResultSetHandler0(DefaultResultSetHandlerFactory.java:199)
at org.sql2o.DefaultResultSetHandlerFactory.access$200(DefaultResultSetHandlerFactory.java:17)
at org.sql2o.DefaultResultSetHandlerFactory$5.evaluate(DefaultResultSetHandlerFactory.java:160)
at org.sql2o.DefaultResultSetHandlerFactory$5.evaluate(DefaultResultSetHandlerFactory.java:156)
at org.sql2o.tools.AbstractCache.get(AbstractCache.java:49)
at org.sql2o.DefaultResultSetHandlerFactory.newResultSetHandler(DefaultResultSetHandlerFactory.java:173)
at org.sql2o.PojoResultSetIterator.<init>(PojoResultSetIterator.java:20)
at org.sql2o.Query$14.iterator(Query.java:547)
at org.sql2o.Query.executeAndFetch(Query.java:588)
at org.sql2o.Query.executeAndFetch(Query.java:574)
at lol.discordbot.database.QueryServerInfo.getCurrent(QueryServerInfo.java:31)
at lol.discordbot.command.Query.execute(Query.java:20)
at lol.discordbot.command.CommandsListener.onMessageReceived(CommandsListener.java:39)
I think you misunderstand what column mappings are. Column mappings are used to map column names to object-field names.
You should first create a data class to hold the result of your query. From your code above, I assume that you are trying to fetch players.
public class Player {
public String date;
public String playerList;
public String playerCount;
public String playerMax
}
(Consider to use better data types. Date for dates, int for counts, etc)
Then you can use sql2o to fetch data
List<Player> players = con.createQuery(sql).executeAndFetch(Player.class);
There is a much better way now.
.setAutoDeriveColumnNames(true)
Example
try (Connection con = sql2o.open()) {
List<Player> l = con.createQuery(sql)
.setAutoDeriveColumnNames(true)
.executeAndFetch(Player.class);
}
https://groups.google.com/g/sql2o/c/3H4XJIv-i04

Only take most recent line from CSV when a value appears twice

I'm working with a CSV file in Mule that could look something like the following:
ID|LastUpdated
01|01/12/2016 09:00:00
01|01/12/2016 09:45:00
02|01/12/2016 09:00:00
02|01/12/2016 09:45:00
03|01/12/2016 09:00:00
I'm trying to find a way of stripping out all duplicate occurrences of an ID value by taking only the most recent one, determined by the LastUpdated column. I'm trying to achieve this using DataWeave but have so far had no luck. I'm open to writing the logic in to a custom Java class but have limited knowledge of how to do that as well.
My desired output is something like the following:
ID|LastUpdated
01|01/12/2016 09:45:00
02|01/12/2016 09:45:00
03|01/12/2016 09:00:00
Any help or guidance would be appreciated.
Edit: it's worth noting that I expect the inbound file to be quite large (up to 000's of rows) so I need to be aware of performance in my solution
Edit: a solution using DataWeave can be found on the Mulesoft forum here.
If the dates/hours are always sorted into your CSV like in the example you gave the you can keep a reference on all your ID as keys into a Map and just update the value corresponding to the ids:
public static void main(String[] arg){
// I replace all the CSV reading by this list for the example
ArrayList<String> lines = new ArrayList<>();
lines.add("01|01/12/2016 09:00:00");
lines.add("01|01/12/2016 09:45:00");
lines.add("02|01/12/2016 09:00:00");
lines.add("02|01/12/2016 09:45:00");
lines.add("03|01/12/2016 09:00:00");
Iterator it = lines.iterator();
Map<String, String> lastLines = new HashMap<String, String>();
while (it.hasNext()) { // Iterator on the CVS lines here
String s = (String)it.next();
String id = s.substring(0, s.indexOf("|"));
String val = s.substring(s.indexOf("|") + 1 , s.length());
lastLines.put(id, val);
}
Iterator<String> keys = lastLines.keySet().iterator();
while (keys.hasNext()) {
String id = (String) keys.next();
System.out.println(id + "|" + lastLines.get(id));
}
}
This produce :
01|01/12/2016 09:45:00
02|01/12/2016 09:45:00
03|01/12/2016 09:00:00
If the CSV records can be in any order then you need to add a validation of the dates to keep only the most recent for each id.
private static final SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss");
public static void main(String... args) {
// I replace all the CSV reading by this list for the example
ArrayList<String> lines = new ArrayList<>();
lines.add("01|01/12/2016 09:45:00");
lines.add("01|01/12/2016 09:00:00");
lines.add("02|01/12/2016 09:00:00");
lines.add("02|01/12/2016 09:45:00");
lines.add("03|01/12/2016 09:00:00");
Iterator it = lines.iterator();
Map<String, String> lastLines = new HashMap<String, String>();
while (it.hasNext()) { // Iterator on the CVS lines here
String s = (String)it.next();
String id = s.substring(0, s.indexOf("|"));
String val = s.substring(s.indexOf("|") + 1 , s.length());
if(lastLines.containsKey(id)){
try{
Date storeDate = sdf.parse(lastLines.get(id));
Date readDate = sdf.parse(val);
if(readDate.getTime() > storeDate.getTime())
lastLines.put(id, val);
}catch(ParseException pe){
pe.printStackTrace();
}
}else{
lastLines.put(id, val);
}
}
Iterator<String> keys = lastLines.keySet().iterator();
while (keys.hasNext()) {
String id = (String) keys.next();
System.out.println(id + "|" + lastLines.get(id));
}
}
I'm not sure about the date format you are currently using. You may need to change the format of the parser"dd/MM/yyyy hh:mm:ss". You can find the related documentation here
Just saw this one and I believe #danw had asked this question on Mule forum too. There is a better way to achieve it with DataWeave.
Check out my answer on mule forum -
http://forums.mulesoft.com/questions/40897/only-take-most-recent-line-from-csv-when-a-value-a.html#answer-40975

Java ResultSet.getTimestamp() attaches millisecond to output

I have a table timestamptest with a single column timestamp of type timestamp without time zone.
I inserted a value to this table :
insert into timestamptest values('2015-09-08 13:11:11')
The timestamp does not contain any millisecond value.
On selecting this data in pgAdmin, it is displayed same as above.
But when I fetch this data using jdbc connection, the value displayed is with milliseconds.
Class.forName("org.postgresql.Driver");
Connection lConnection = null;
lConnection = DriverManager.getConnection(
"jdbc:postgresql://localhost:5432/postgres","postgres", "Password#123");
String lQuery = "select * from timestamptest";
Statement lStatement = lConnection.createStatement();
ResultSet lResultSet = lStatement.executeQuery(lQuery);
while(lResultSet.next()) {
System.out.println(lResultSet.getTimestamp(1));
}
Output : 2015-09-08 13:11:11.0
The desired output is 2015-09-08 13:11:11
It can be achieved by using SimpleDateFormat :
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(lResultSet.getTimestamp(1).getTime())
Can it be possible without using SimpleDateFormat? Is there any other way by which the result set itself gives me in the desired format?
What I need is that the statement
lResultSet.getTimestamp(1)
directly gives me the output 2015-09-08 13:11:11.
Its not possible. Since ResultSet.getTimestamp(1) return class that extends java.sql.TimeStamp. Returning class based on Database driver. And also we cant change the toString implementation of that.
Yes you can - but you're not going to like it.
class MyTimestamp extends Timestamp {
public MyTimestamp(long time) {
super(time);
}
public MyTimestamp(Timestamp ts) {
this(ts.getTime());
}
#Override
public String toString() {
String s = super.toString();
return s.substring(0, s.lastIndexOf("."));
}
}
public void test() {
System.out.println("Hello");
Timestamp t = new Timestamp(System.currentTimeMillis());
System.out.println(t);
System.out.println(new MyTimestamp(t));
}

How do I parse a column from a CSV string using jackson CsvMapper or another csv parser?

I have a Java method that receives a CSV string of values and an integer index to reference which column in the CSV string to parse. The method returns the value associated with the integer index in the CSV string.
For example if I have a CSV string with a header and a second row with values defined as:
String csvString = "Entry #,Date Created,Date Updated, IP Address
165,8/22/13 14:46,,11.222.33.444";
and the integer index received by the method was 1, I'd expect the method to return the string "165"
And if the integer index received by the method was 2, I'd expect the method to return the string "8/22/13 14:46"
etc,...
I don't want to just split up the CSV string by commas as that could get ugly and I'm sure that there is a CSV parser that already does some parsing like this. From my Google searches it sounds like OpenCSV or the Jackson CsvMapper can do this.
I've been playing with the com.fasterxml.jackson.dataformat.csv.CsvMapper libary to parse out the appropriate column of this CSV string and here's what I have so far:
int csvFieldIndex (this is the integer index passed into my method)
String csvString = "Entry #,Date Created,Date Updated, IP Address
165,8/22/13 14:46,,11.222.33.444";
CsvSchema csvSchema = CsvSchema.emptySchema().withHeader();
ObjectReader mapper = new CsvMapper().reader(Map.class).with(csvSchema);
MappingIterator<Map<String, Object>> iter = null;
iter = mapper.readValues(csvString);
while (iter.hasNext()) {
Map<String, Object> row = iter.next();
System.out.Println("row= " + row.toString());
}
But this iterator gives me all the csv values which is not what what I want; I just want the one value associated with my integer index.
Here's the output I get when I run this snippet of code:
row= {Entry #=165, Date Created=8/22/13 14:46, Date Updated=, IP Address=11.222.33.444}
Is there a way I can use the Jackson CsvMapper to do this?
======== UPDATE: ========
Based on feedback from keshlam I was able to parse a column from a CSV with the following code:
CsvSchema csvSchema = CsvSchema.emptySchema().withHeader();
ObjectReader mapper = new CsvMapper().reader(Map.class).with(csvSchema);
MappingIterator<Map<String, Object>> iter = null;
iter = mapper.readValues(csvString);
// iterate over whole csv and store in a map
Map<String, Object> row = null;
while (iter.hasNext()) {
row = iter.next();
}
// now put the set of field names (keys) from this map into an array
String[] csvKeysArray = row.keySet().toArray(new String[0]);
int j = 0;
// loop over this array of keys and compare with csvFieldIndex
for (int i = 0; i < csvKeysArray.length; i++) {
// increment j by 1 since array index starts at 0 but input index starts at 1
j = i + 1;
if (j == csvFieldIndex) {
csvValue = row.get(csvKeysArray[i]).toString();
}
}
return csvValue;
If I'm following what you're asking, and understanding your code correctly (I've never used that CsvMapper), change the final loop to
while (iter.hasNext()) {
Map<String, Object> row = iter.next();
System.out.Println("Entry #= " + row.get("Entry #");
}
If you want to access the columns numerically rather than by name (why?), set up a mapping from number to column name and use that to retrieve the key you pass to the get() operation.

Categories