Collecting all rows from a database - java

I'm trying to retrieve all the values stored in a database where it matches the sensor name.
The code runs however, it only outputs the final value in the database.
String info = "test info"
String sensorNameStr = "test sensor name";
String sensorValueStr = "test sensor value";
String selectSQL = "select sensorvalue from sensorUsage where "+
" sensorname = '" + sensorNameStr +
"' order by TimeInserted asc";
String retrievedSensorData = "no data available";
try {
PreparedStatement pst = conn.prepareStatement(selectSQL);
ResultSet rs = pst.executeQuery();
while (rs.next()) {
retrievedSensorData = rs.getString(1);
}
} catch (SQLException ex) {
System.out.println("Error in SQL " + ex.getMessage());
}
String json = "{\"sensor\": {\"" + sensorNameStr +
"\": \"" + retrievedSensorData + "\"}}";
System.out.println("DEBUG: json return: "+json);
Do I have to create a for loop so all values are returned and outputted on a webpage? As that's how I am viewing the data without manually going into the server. Also, if I do this, is it possible to only receive the last few inserted sensor values?
Help will be appreciated!

In your SQL query you retrieve only rows from column sensorvalue and all belong to specific sensorname. There are no other condition.
So it should be easy to make an Json with the Java EE API
// ...
JsonObject model = null;
try
{
// ...
ResultSet rs = stmt.executeQuery();
JsonArrayBuilder jsonArrayBuilder = Json.createArrayBuilder();
while(rs.next())
{
jsonArrayBuilder.add(rs.getString("sensorvalue"));
}
JsonObjectBuilder jsonObjectBuilder = Json.createObjectBuilder();
jsonObjectBuilder.add("sensorvalues", jsonArrayBuilder);
model = jsonObjectBuilder.build();
}
catch (Exception e)
{
System.out.println(e);
}
response.setContentType("application/json; charset=utf-8");
StringWriter stWriter = new StringWriter();
JsonWriter jsonWriter = Json.createWriter(stWriter);
jsonWriter.writeObject((JsonObject) model);
jsonWriter.close();
response.getWriter().append(stWriter.toString());
The output should be something like:
{"sensorvalues":["1","2"]}

Related

java ews service unable to work with multiple search filters

I am using ews Exchange Service to Replicate emails from Inbox to some where in database. However i am using two search filters DateTimeReceived and Subject sampel cdoe is like below
SearchFilter.SearchFilterCollection search = new SearchFilter.SearchFilterCollection();
search.add(new SearchFilter.IsGreaterThanOrEqualTo(ItemSchema.DateTimeReceived, "02/01/2020"));
search.add(new SearchFilter.ContainsSubstring(ItemSchema.Subject,custno));
Once i run the code i found below error
microsoft.exchange.webservices.data.core.exception.service.remote.ServiceResponseException: The specified value is invalid for property.
Here is the Complete Code
public static String readmailbody(String custno, String user, String pwd, String domain) {
try {
//Connection conn = DriverManager.getConnection("jdbc:default:connection:");
Connection conn = DriverManager.getConnection("jdbc:oracle:thin:user/pass#host:port:sid");
ExchangeService service = new ExchangeService();
ExchangeCredentials credentials = new WebCredentials(user, pwd, domain);
service.setCredentials(credentials);
service.setUrl(new URI("https://host.domain.com/ews/Exchange.asmx"));
ItemView view = new ItemView(1);
view.getOrderBy().add(ItemSchema.DateTimeReceived, SortDirection.Descending);
view.setPropertySet(new PropertySet(BasePropertySet.IdOnly, ItemSchema.Subject,ItemSchema.DateTimeReceived));
//SearchFilter sfs = new SearchFilter.IsGreaterThanOrEqualTo(ItemSchema.DateTimeReceived,DateTime.now().dayOfMonth().toString());
//SearchFilter cust = new SearchFilter.ContainsSubstring(ItemSchema.Subject,custno);
SearchFilter.SearchFilterCollection search = new SearchFilter.SearchFilterCollection();
search.add(new SearchFilter.IsGreaterThanOrEqualTo(ItemSchema.DateTimeReceived, "02/01/2020"));
search.add(new SearchFilter.ContainsSubstring(ItemSchema.Subject,custno));
FindItemsResults<Item> findResults = service.findItems(WellKnownFolderName.Inbox,search,view);
String senderEmail = "";
String mailto = "";
StringBuilder emailbody=new StringBuilder();
for (Item item : findResults.getItems()) {
item.load();
if (item instanceof EmailMessage) {
senderEmail = "<b>From : </b>" + ((EmailMessage) item).getSender().getAddress();
mailto = "<b>To : </b>" + ((EmailMessage) item).getDisplayTo();
}
String mailcc = "<b>CC : </b>" + item.getDisplayCc();
String subject = "<b>Subject : </b>" + item.getSubject();
String sentdate = "<b>Sent : </b>" + item.getDateTimeSent().toString();
emailbody.append(senderEmail + "<br>" + sentdate + "<br>" + mailto + "<br>" + mailcc + "<br>" + subject + "<br>" + MessageBody.getStringFromMessageBody(item.getBody()));
String proc = "call xx_ews_exchange(?,?,?,?,?,?)";
CallableStatement pstmt = conn.prepareCall(proc);
pstmt.setString(1, senderEmail);
pstmt.setString(2, mailto);
pstmt.setString(3, mailcc);
pstmt.setString(4, subject);
pstmt.setString(5, emailbody.toString());
pstmt.setString(6, custno);
pstmt.executeUpdate();
pstmt.close();
System.out.println(emailbody.toString());
return "Success";
}
System.gc();
} catch (SQLException sqle) {
return "SQLException " + convertException(sqle);
} catch (ServiceLocalException sle) {
return "ServiceLocalException " + convertException(sle);
} catch (URISyntaxException urise) {
return "URISyntaxException " + convertException(urise);
} catch (Exception e) {
return "Other Exception " + convertException(e);
}
return "";
}
I want to add more parameters after that but for now i want to retrieve last email of each subject from the first day of current month.
In
search.add(new SearchFilter.IsGreaterThanOrEqualTo(ItemSchema.DateTimeReceived, "02/01/2020"));
The Date should be typed object not a String which is why the error is telling you that "The specified value is invalid for property".
You can use plain text if you use a QueryString instead of a SearchFilter https://learn.microsoft.com/en-us/exchange/client-developer/web-service-reference/querystring-querystringtype this would probably be more efficient for that type of query

How to add more `?` automatically in java in accordance with whatever amount of columns will be placed in the interface

I'm trying to create an api so I can use it to whatever project I need to create. I'm still new to java so I'm sorry in advance for the wrong codes. Anyways, I've got here this code that has the CRUD statements (except for Read/Retrieve).
import java.sql.*;
public class KitApiNew {
public static void main(String[] args) throws SQLException {
Connection dbConnection = null;
PreparedStatement PSInsert = null;
PreparedStatement PSUpdate = null;
PreparedStatement PSDelete = null;
PreparedStatement PSStatement = null;
String DBTable = "fruits";
String DBColumnSet = "fruit";
String DBID = "23";
String DBColumnSingle = "fruit";
String DBChoice ="insert";
String DBCS = "";
String insertTable = "INSERT INTO " + DBTable + "(" +DBColumnSet+ ")" + "VALUES" + "(?)";
String updateTable = "UPDATE " + DBTable + " SET " + DBColumnSingle + " = ?" + " WHERE id = ?";
String deleteTable = "DELETE FROM " + DBTable + " WHERE id = ?";
String statementTable = "INSERT INTO fruits(fruit) VALUES('grapes')";
try{
dbConnection = getDBConnection();
dbConnection.setAutoCommit(false);
if(DBChoice.equals("insert")){
//for insert
PSInsert = dbConnection.prepareStatement(insertTable);
PSInsert.setString(1, "Orange");
PSInsert.executeUpdate();
dbConnection.commit();
}
if(DBChoice.equals("update")){
//for update
PSUpdate = dbConnection.prepareStatement(updateTable);
PSUpdate.setString(1, "Apple");
PSUpdate.setString(2, DBID);
PSUpdate.executeUpdate();
dbConnection.commit();
}
if(DBChoice.equals("delete")){
//for delete
PSDelete = dbConnection.prepareStatement(deleteTable);
PSDelete.setString(1, DBID);
PSDelete.executeUpdate();
dbConnection.commit();
}
if(DBChoice.equals("statement")){
//for statement
PSStatement = dbConnection.prepareStatement(statementTable);
PSStatement.executeUpdate();
dbConnection.commit();
}
System.out.println("Success!");
}catch(SQLException e){
System.out.println("Error occured " + e.toString());
dbConnection.rollback();
}
finally{
if(PSInsert !=null){
PSInsert.close();
}
if(PSUpdate != null){
PSUpdate.close();
}
if(dbConnection != null){
dbConnection.close();
}
}
}
private static Connection getDBConnection(){
Connection con = null;
try{
Class.forName("com.mysql.jdbc.Driver");
}catch(ClassNotFoundException e){
System.out.println("Error 1 : " + e.getMessage());
}
try{
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/bongbong","root","");
}catch(SQLException e){
System.out.println("Error 2 : " + e.getMessage());
}
return con;
}
}
Oh by the way,
The values of the variables are currently temporary. I'll be changing them later to whatever they're going to be catching. I'm referring to these:
String DBTable = "fruits";
String DBColumnSet = "fruit";
String DBID = "23";
String DBColumnSingle = "fruit";
String DBChoice ="insert";
String DBCS = "";
and this
String statementTable = "INSERT INTO fruits(fruit) VALUES('grapes')";
Problem
What I really need help from is with the ? thing from the first code I posted after the VALUES word inside the String insertTable. I want it so that when I place a column amount in my interface then it'll add more ? in accordance with what was inputted (I also want it to add another PSInsert.setString(n, "value") with n+1 in accordance with the column amount inputted if it's possible). Can anyone tell me how to? I'm really new to java and I'm still a student studying at his best.
I want it to add those ? thing because what if I add more columns or if I use another table with more columns other than my fruits table. (I want it so that whatever I'm going to place in DBColumnSet --with columns separated by comma --will also relate to how many ? are going to be placed).
Oh by the way, it's a general api so I can't provide an interface.

how can we see output without rectangular boxes

i have created a table in data base which consists of telugu data .when i am trying to retrieve telugu data by using eclipse in java i am getting out with rectangular boxes .
code :
try {
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/sloka?useUnicode=yes&characterEncoding=UTF-8", "root", "");
st = con.createStatement();
} catch (Exception e) {
System.out.print("error:" + e);
}
public void getData() {
try {
String query = "select * from eesavyasa ";
rs = st.executeQuery(query);
System.out.print("records from database");
while (rs.next()) {
String name1 = new String(rs.getBytes("firstcolumn"), "UTF-8");
String name2 = new String(rs.getBytes("secondcolumn"), "UTF-8");
String name3 = new String(rs.getBytes("thirdcolumn"), "UTF-8");
String name4 = new String(rs.getBytes("fourthcolumn"), "UTF-8");
System.out.println(name1);
System.out.println(name2);
System.out.println(name3);
System.out.println(name4);
}
} catch (Exception ex) {
System.out.print(ex);
}
}
we have used collation utf-8 for db ,table,for all but we are getting output in rectangular boxes
kindly respond as soon as possible
It would be fixed after executing below sql after connected to mysql
SET NAMES utf8

Collection value is not getting iterated in passed Query?

Below is my Code..
while(obt.hasNext()){
try{
Object itrvalue = obt.next();
String sql2 ="select entryDt,Student_Name,Class_Div_Name,ReceiptNo from test where ReceiptNo = '"+itrvalue+"'";
System.out.println("Receipt No --"+itrvalue);
stat = con.prepareStatement(sql2);
rs=stat.executeQuery();
rs.next();
Date datevalue = rs.getDate(1);
String name = rs.getString(2);
String CDN = rs.getString(3);
String RNO = rs.getString(4);
System.out.println("Date is ---"+datevalue);
System.out.println("Student Name ---"+name);
System.out.println("Coloumn Div No ---"+CDN);
System.out.println("Receipt No ---"+RNO);
rs.close();
}
catch(Exception ex){};
}
Output : -
Receipt No --S00000001234
Date is ---2013-06-10
Student Name ---ABC XYZ
Coloumn Div No ---VI - C
Receipt No ---S00000001234
Receipt No --S00000001234
Receipt No --S00000001235
Receipt No --S00000001236
Receipt No --S00000001237
Receipt No --S00000001238
Receipt No --S00000001239
Every iteration value's are getting changed. But in Current SQL query it's getting passed only 1st value remaining iteration values are getting displayed, but not getting passed in SQL Query. As per output you can see I have received data only S00000001234 and I want same details of all Receipt No.
You may have raised an exception. Try this code instead:
String sql2 = "select entryDt,Student_Name,Class_Div_Name,ReceiptNo from test where ReceiptNo = ?";
PreparedStatement stat = con.prepareStatement(sql2);
try {
while (obt.hasNext()) {
try {
Object itrvalue = obt.next();
System.out.println("Receipt No --" + itrvalue);
stat.setObject(1, itrvalue);
rs = stat.executeQuery();
rs.next();
Date datevalue = rs.getDate(1);
String name = rs.getString(2);
String CDN = rs.getString(3);
String RNO = rs.getString(4);
System.out.println("Date is ---" + datevalue);
System.out.println("Student Name ---" + name);
System.out.println("Coloumn Div No ---" + CDN);
System.out.println("Receipt No ---" + RNO);
rs.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
} finally {
if (stat != null) {
stat.close();
}
}

Getting better Pefromance using BLOB, on JAVA

My question is not related to how to do something, it's more of how to help improve performance. I apologize for the long post, but I thought since this is about performance, that i should post all details about what I'm doing to see if anyone can help.
I have to make a program that gets info from 2 different databases, creates a metadata, its corresponding BLOB(pdf file) and zips it.
The metadata file is only created if the BLOB object was found in the database. I have managed to do so, but problem is sometimes I might have up to 80k results on my query and it may take as long as 20 hours to do so, which is ridiculous considering each blob object is no larger than 100 KB.
I have a transactional database (lets call it TEQ8P) where all the ID's and the info for the metadata is stored. I queried the data by date and status (which sucks but i don't have any other filter, that was the requirement)
TEQ8P.openConnection();
Boolean flag = TEQ8P.ExecuteQuery("select tr.legaltransnumber, cc.country_code, tr.transnumber, tr.postingdate, tr.transdate from EQUATE.transheader tr inner join companycode_country cc on tr.tocompanycode = cc.company_code where tr.transtype = 'IC' and tr.transdate between to_date(" + date + ", 'DD/MM/YYYY') and to_date(" + nextday + ", 'DD/MM /YYYY')");
public Boolean ExecuteQuery(String query) {
Statement stmt;
ResultSet rs = null;
try {
stmt = connection.createStatement();
rs = stmt.executeQuery(query);
if(!rs.isBeforeFirst())
return false;
rowset = new CachedRowSetImpl();
rowset.populate(rs);
metadata = rs.getMetaData();
rs.close();
stmt.close();
return true;
} catch (SQLException e) {
HLog.error(e.getMessage());
e.printStackTrace();
return false;
//System.out.println(query);
}
finally
{
closeConnection();
}
}
I am using JAVA 1.5 (per requirement again) so I downloaded the cachedrowsetimp jar from oracle, so once I finish querying data I save it to memory and close the connection.
After that I start moving through the cachedrowset and query every ID on the Warehouse DB. I can't do a select "where in" because there is no way to tell if all id's will be found and an "in" would only return the items that it finds, and I wouldn't know which items it didn't find. But if you have any suggestion please!
So I use preparedStatement to use bind variables on ORACLE and start writing the blob object.
My first question, is there a better way to write blob files? A faster way?
if(flag)
{
String Query = "select wh.transnumber, wh.image from EQUATEWH.legalimage wh where wh.transnumber = ?";
WEQ8I.openConnection();
WEQ8I.setPreparedStmt(Query);
WEQ8I.WriteBlobs(PDF, TEQ8P.getRowsSet(), IC_FILE);
WEQ8I.closePrepStmt();
WEQ8I.closeConnection();
FileUtils.createZip(prop.getProperty("ZIPDIR_IC"), lsize, prop.getProperty("ZIPNAME_IC"));
public void WriteBlobs(String path, CachedRowSetImpl set, IMP_File IC_FILE)
{
ResultSet rs = null;
try
{
while(set.next())
{
pstmt.setString(1, set.getString(3));
rs = pstmt.executeQuery();
if(!rs.isBeforeFirst())
{
System.out.println("invoice " + set.getString(3) + "was not found on W database");
ErrorFile.writeErrorFile(set.getString(3));
}
else
{
//getting the name of the PDF file, if no ID use legaltransnumber
String ID = set.getString(1);
if(ID == null)
{
ID = set.getString(3);
}
while(rs.next())
{
FileOutputStream fos = null;
try
{
Blob blob = rs.getBlob(2);
InputStream is = blob.getBinaryStream();
fos = new FileOutputStream(path + ID + ".pdf");
int i = 0;
while ((i = is.read()) != -1)
{
fos.write(i);
}
fos.close();
is.close();
IC_FILE.fillIMPFile("IC", ID, set.getString(3), set.getString(2), set.getString(5));
}catch (Exception e)
{
e.printStackTrace();
ErrorFile.writeErrorFile(set.getString(3));
}
}
}
rs.close();
}
IC_FILE.writeFile();
} catch (SQLException e)
{
System.out.println("Problem when trying to create Record: " + path);
HLog.error(e.getMessage());
e.printStackTrace();
try
{
ErrorFile.writeErrorFile(set.getString(3));
}catch (Exception ex)
{
ex.printStackTrace();
HLog.error(e.getMessage());
}
}
}
If the query found a result for that ID on the WarehouseDB AND the image is not null (meaning it won't go to the null exception), I create the metadafile which is the IC_FILE.
the IC_FILE does not write a file, it saves everything into memory and when it finishes it writes the file, I thought this could help improve performance since it wouldn't have to do I/O operations on every file, just once, using IC_FILE.writefile().
To create the metadatafile, I also have to (per requirement again) get the container name from a file. to retrieve the container name I have to use 3 fields from the Transactional database, concatenate them and search for them in that file.
this is how I create the IMP file, first to get data from each record:
public void fillIMPFile(String type, String ID, String ID2, String companyCode, String date)
{
date = date.substring(0, 10);
date = date.replace("-", "/");
date = date.substring(5, 7) + "/" + date.substring(8, 10) + "/" + date.substring(0, 4);
String Name = prop.getProperty("NAME");
String info = prop.getProperty(type);
String DOS = Name + info + ID + ".";
String NOTES = Name + " " + info + " ";
info += getContainer(companyCode, date, type);
if(type.equals("IC"))
{
String desc = prop.getProperty("DESC_PDF");
DOS += "pdf";
NOTES += desc + " " + ID + " " + ID2;
buffer += info + "\t" + date + "\t" + date + "\t" + DOS + "\t" + NOTES + "\t"
+ NOTES + "\t" + ID2;
}
To get the containers I use the properties object, but I guess there might be better choices? a hash map maybe?
public String getContainer(String companyCode, String Date, String type)
{
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
Date = sdf.format(cal.getTime());
//mal siempre pondra 2012
String data = type + companyCode + Date;
String container = containers.getProperty(data);
if(container == null)
{
data = type + "WW" + Date;
container = containers.getProperty(data);
}
return container;
}
finaly to write the file:
public void writeFile()
{
try
{
FileWriter fw = new FileWriter(File, true);
BufferedWriter bw = new BufferedWriter(fw);
bw.write(buffer);
bw.close();
}catch (IOException e)
{
e.printStackTrace();
HLog.error(e.getMessage());
}
}
thanks!!
Daniel
fixed...using bind variables and creating more than 1 container file for each year

Categories