I am writing a program that acts as a service and picks up emails from the email queue table, processes them and sends them out. Here is something along how I did it, and it does work fine.
MySqlConnect con = new MySqlConnect();
public PreparedStatement preparedStatement = null;
public Connection con1 = con.connect();
//pick up queue and send email
public void email() throws Exception {
try {
while(true) {
String sql = "SELECT id,user,subject,recipient,content FROM emailqueue WHERE status='Pending' ";
PreparedStatement statement = con1.prepareStatement(sql);
ResultSet rs = statement.executeQuery();
while (rs.next()) {
String subject = rs.getString("subject");
String recipient = rs.getString("recipient");
String content = rs.getString("content");
String id = rs.getString("id");
String username = rs.getString("user");
String emailStatus = "DONE";
String errormsg = sendEmail(recipient, subject, content, id,username);
if (!errormsg.equals("")) {
emailStatus = "FAILED";
}
TerminalLogger.printMsg("Status : " + emailStatus);
}
statement.close();
rs.close();
}
} catch(Exception e) {
e.printStackTrace();
TerminalLogger.printMsg("Exception: "+e.toString());
}
con1.close();
Thread.sleep(2000);
}
Now, I am clearly using JDBC to obtain the result set in the loop and process them as shown. Of course, I also need to specify my database connection in MySqlConnect.java properties. While all this works perfectly fine, I was wondering is there another way of achieving the same goal without using JDBC, i.e. specifying the connection properties?
I was thinking of Java Persistence. I am new to this.
Edit
I have been told to use JPA to achieve this and I have written it in this way:
public void email() throws Exception {
try {
while(true) {
String sql = "select p.id,p.user,p.subject,p.recipient,p.content from Emailqueue p where " +
"status='Pending'";
List<Object[]> list = em.createQuery(sql).getResultList();
for (Object[] obj : list) {
System.out.println(obj[0]);
System.out.println(obj[1]);
System.out.println(obj[2]);
System.out.println(obj[3]);
System.out.println(obj[4]);
}
}
} catch(Exception e) {
e.printStackTrace();
TerminalLogger.printMsg("Exception: " + e.toString());
}
From here, I would pass the parameters I want to the method. Is this way feasible?
Edit 2
Did it a bit different like below:
String id = ejbCon.getSettingsFacade().getid();
String username = ejbCon.getSettingsFacade().getUser();
String subject = ejbCon.getSettingsFacade().getSubject();
String recipient = ejbCon.getSettingsFacade().getRecipient();
String content = ejbCon.getSettingsFacade().getContent();
String errormsg = sendEmail(recipient, subject, content, id,username);
public String getContent() {
try {
String sql="Select content FROM emailqueue WHERE status='Pending'";
if (em == null) {
throw new Exception("could not found subject");
}
return (String) em.createNativeQuery(sql).getSingleResult();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
Just a bit idea of how the method looks like, the other methods follow the same concept.
List<EmailQueue> emailList = em.createQuery(sql).getResultList();
for (EmailQueue obj : emailList) {
String emailStatus = "DONE";
String errormsg=sendEmail(obj.getRecipient(), obj.getSubject, obj.getContent(),obj.getId(),obj.getUsername());
if (!errormsg.equals("")) {
emailStatus = "FAILED"
}
TerminalLogger.printMsg("Status : " + emailStatus);
}
}
Before using JPA ,you must read about it WHY JPA
As discussed in the comments above, Spring Batch and Spring JPA is a good choice for your use-case,
you can follow and study about on the internet and follow the official document
Spring JPA tutorial link
Spring Batch tutorial link
Happy Learning, Hope more users would suggest other good options that you can choose from and apply to your use-case post evaluating their pros and cons
Related
I am connecting my Java Program to a database stored in the program folder, and I am having users answer quiz questions and I want the results to be stored in the database. The Update statement is not working, and I don't know if it's a problem with the actual statement or the database connection.
I've tried creating a new database with the same tables and reconnecting to that database, but nothing seems to be working.
//database connection class
public class databaseConnection {
public static Connection dbConnector() {
try {
Class.forName("org.sqlite.JDBC");
Connection conn = DriverManager
.getConnection("jdbc:sqlite:D:\\Users\\mariammahmoud\\eclipse-workspace\\ia_2019_final\\testjava.db");
return conn;
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e);
return null;
}
}
}
public class student {
public static final String DB_NAME = "testjava.db";
public static final String TABLE_STUDENTS = "students";
public static final String COLUMN_NAME = "name";
public static final String COLUMN_GRADE = "grade";
public static final String COLUMN_RESULTS = "results";
public static final String COLUMN_EVENTS = "events";
public static final String COLUMN_USERNAME = "username";
public void main() {
try {
String user_name = login_student.sendQuiz();
Connection conn = databaseConnection.dbConnector();
ArrayList<String> results = new ArrayList<String>(15);
instructions();
questions(results);
results.trimToSize();
System.out.println("Here are the events that you should consider competing in:");
System.out.println(results);
String separator = ",";
int total = results.size() * separator.length();
for (String finalResults : results) {
total += finalResults.length();
}
StringBuilder sb = new StringBuilder(total);
for (String finalResults : results) {
sb.append(separator).append(finalResults);
}
String resultsDatabase = sb.substring(separator.length());
String sql = "UPDATE students SET events = ? WHERE username = " +user_name;
PreparedStatement myStmt = conn.prepareStatement(sql);
myStmt.setString(1, resultsDatabase);
myStmt.executeUpdate();
} catch (SQLException e) {
System.out.println("Something went wrong:" + e.getMessage());
e.printStackTrace();
}
}
I expected the update statement to update the testjava.db database, but everything is staying the same. What should I do? Thank you in advance!
Your problem is that while you wisely used a prepared statement in your code for the update, you never actually used it for the username column in the WHERE clause. Hence, the query you are executing currently won't be interpreted as comparing some input against username. Rather, the username value will be interpreted as a column. Try this version:
String resultsDatabase = sb.substring(separator.length());
String sql = "UPDATE students SET events = ? WHERE username = ?";
PreparedStatement myStmt = conn.prepareStatement(sql);
myStmt.setString(1, resultsDatabase);
myStmt.setString(2, user_name);
myStmt.executeUpdate();
Note that you could have just tried the following:
String sql = "UPDATE students SET events = ? WHERE username = '" + user_name + "'";
But, please bind a value to a ? placeholder instead, as I have suggested above. One benefit of using statements is that it frees you from having to worry about how to escape your data in the query.
first time posting so sorry if my question is slightly strange.
So I have a project in school that requires us to create java classes using netbeans that open up a window with three options, check stock, purchase item and update stock.
We had a class called stockdata that held the details of 5 different items for us to use in our three classes to check, purchase and update items. The latest stage of our coursework requires us to create a derby database and enter the items into a table.
I have done this with no issues but I am having a problem getting the items from the table back into my classes to use. We were given the following code but I can't get it to work, even using the commented hints.
package stock;
// Skeleton version of StockData.java that links to a database.
// NOTE: You should not have to make any changes to the other
// Java GUI classes for this to work, if you complete it correctly.
// Indeed these classes shouldn't even need to be recompiled
import java.sql.*; // DB handling package
import java.io.*;
import org.apache.derby.drda.NetworkServerControl;
public class StockData {
private static Connection connection;
private static Statement stmt;
static {
// standard code to open a connection and statement to an Access database
try {
NetworkServerControl server = new NetworkServerControl();
server.start(null);
// Load JDBC driver
Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
//Establish a connection
String sourceURL = "jdbc:derby://localhost:1527/"
+ new File("UserDB").getAbsolutePath() + ";";
connection = DriverManager.getConnection(sourceURL, "use", "use");
stmt = connection.createStatement();
} // The following exceptions must be caught
catch (ClassNotFoundException cnfe) {
System.out.println(cnfe);
} catch (SQLException sqle) {
System.out.println(sqle);
} catch (Exception e) {
System.out.println(e);
}
}
// You could make methods getName, getPrice and getQuantity simpler by using an auxiliary
// private String method getField(String key, int fieldNo) to return the appropriate field as a String
public static String getName(String key) {
try {
// Need single quote marks ' around the key field in SQL. This is easy to get wrong!
// For instance if key was "11" the SELECT statement would be:
// SELECT * FROM Stock WHERE stockKey = '11'
ResultSet res = stmt.executeQuery("SELECT * FROM Stock WHERE stockKey = '" + key + "'");
if (res.next()) { // there is a result
// the name field is the second one in the ResultSet
// Note that with ResultSet we count the fields starting from 1
return res.getString(2);
} else {
return null;
}
} catch (SQLException e) {
System.out.println(e);
return null;
}
}
public static double getPrice(String key) {
// Similar to getName. If no result, return -1.0
return 0;
}
public static int getQuantity(String key) {
// Similar to getName. If no result, return -1
return 0;
}
// update stock levels
// extra is +ve if adding stock
// extra is -ve if selling stock
public static void update(String key, int extra) {
// SQL UPDATE statement required. For instance if extra is 5 and stockKey is "11" then updateStr is
// UPDATE Stock SET stockQuantity = stockQuantity + 5 WHERE stockKey = '11'
String updateStr = "UPDATE Stock SET stockQuantity = stockQuantity + " + extra + " WHERE stockKey = '" + key + "'";
System.out.println(updateStr);
try {
stmt.executeUpdate(updateStr);
} catch (SQLException e) {
System.out.println(e);
}
}
// close the database
public static void close() {
try {
connection.close();
} catch (SQLException e) {
// this shouldn't happen
System.out.println(e);
}
}
}
Sorry if this seems a stupid question but I am fairly new to Java and was making good progress until this roadblock.
Thanks in advance!
Alex
Searching for "java sql" on Google delivers this link: https://docs.oracle.com/javase/tutorial/jdbc/basics/processingsqlstatements.html
From a connection you can create a statement (you can find this in the link and in your code) , then fetch a result set and loop over that with rs.next(). That should get your started.
Of course you have to make sure that the driver and database are there/running, just saying...
Here netbeans has nothing to do with database. This is a Java-based integrated development environment(IDE) that will help you to reduce syntactic error.
public void dataAccess(){
try {
String connectionUrl = "suitable connection url as per your database";
Connection con = null;
Statement stmt = null;
ResultSet rs = null;
Class.forName("JDBC driver name as per your database");
con = DriverManager.getConnection(connectionUrl, userName, password);
String SQL = "SQL query as per your criteria";
stmt = con.createStatement();
rs = stmt.executeQuery(query);
while (rs.next()) {
// look into ResultSet api and use method as per your requirement
}
rs.close();
}
catch (Exception e) {
//log error message ;
}
}
I'm getting this error even though I am not trying to edit the table/column:
com.ibm.db2.jcc.am.SqlSyntaxErrorException: The operation failed because the operation is not supported with the type of the specified table. Specified table: "DASH103985.wajihs". Table type: "ORGANIZE BY COLUMN". Operation: "WITH RS".. SQLCODE=-1667, SQLSTATE=42858
#MultipartConfig
public class DemoServlet extends HttpServlet {
private static Logger logger = Logger.getLogger(DemoServlet.class.getName());
private static final long serialVersionUID = 1L;
#Resource(lookup="jdbc/db2")DataSource dataSource;
private String getDefaultText() {
TweetsCombined = new String(" ");
try {
// Connect to the Database
Connection con = null;
try {
System.out.println("Connecting to the database");
} catch (SQLException e) {
TweetsCombined = "first" +e;
}
// Try out some dynamic SQL Statements
Statement stmt = null;
try {
stmt = con.createStatement();
String tableName = "wajihs";// change table name here to one
// chosen in the first website
String columnName = "msgBody";// msgBody is where the tweets
// are stored
String query = "SELECT * FROM \"" + tableName + "\"";
ResultSet rs = stmt.executeQuery(query);
while (rs.next()) {
content = rs.getString(columnName) + ". ";
if (content.toLowerCase().contains("RT".toLowerCase())
|| content.toLowerCase().contains("Repost: ".toLowerCase())) {
// do nothing
}
else {
TweetsCombined.concat(content);
}
}
// Close everything off
// Close the Statement
stmt.close();
// close
con.commit();
// Close the connection
con.close();
} catch (Exception e) {
TweetsCombined = "second" +e;
System.out.println(e.getMessage());
}
} catch (Exception e) {
TweetsCombined = "third" + e;
System.out.println(e);
}
return TweetsCombined;
}
As I explained here, dashDB, with its BLU Acceleration features, has certain limitations compared to DB2 without BLU Acceleration. In your case it is that you can only run queries with the CS isolation level against column-organized tables.
Either change your connection configuration to use CS isolation level or create your table(s) while explicitly specifying ORGANIZE BY ROW.
So I'm quite new to Java and Derby. I'm using both with my Flex app on Tomcat 7.
When I make a call to Java from Flex the login function works fine but my getUserByUsername function does not.
public Boolean loginUser(String username, String password) throws Exception
{
Connection c = null;
String hashedPassword = new String();
try
{
c = ConnectionHelper.getConnection();
PreparedStatement ps = c.prepareStatement("SELECT password FROM users WHERE username=?");
ps.setString(1, username);
ResultSet rs = ps.executeQuery();
if(rs.next())
{
hashedPassword = rs.getString("password");
}
else
{
return false;
}
if(Password.check(password, hashedPassword))
{
return true;
}
else
{
return false;
}
}
catch (SQLException e)
{
e.printStackTrace();throw new DAOException(e);
}
finally
{
ConnectionHelper.closeConnection(c);
}
}
public User getUserByUsername(String username) throws DAOException
{
//System.out.println("Executing DAO.getUserByName:" + username);
User user = new User();
Connection c = null;
try
{
c = ConnectionHelper.getConnection();
PreparedStatement ps = c.prepareStatement("SELECT * FROM users WHERE username = ?");
ps.setString(1, username);
ResultSet rs = ps.executeQuery();
while(rs.next())
{
user.setId(rs.getInt("id"));
user.setUsername(rs.getString("username"));
user.setPassword(rs.getString("password"));
user.setTeam(rs.getString("team"));
user.setScore(rs.getInt("score"));
}
}
catch (SQLException e)
{
e.printStackTrace();
throw new DAOException(e);
}
finally
{
ConnectionHelper.closeConnection(c);
}
return user;
}
The stack I get in Flex is useless as far as I can tell:
Flex Message (flex.messaging.messages.ErrorMessage) clientId = 8EB6D37B-7E0B-01B0->AA55-457722B9036C correlationId = A39E574F-CFC6-51FE-6CBE-451AF329E2F8 destination >= service messageId = 8EB6DF4C-650B-BDD7-7802-B813A61C8DC8 timestamp = >1401318734645 timeToLive = 0 body = null code = Server.Processing message = >services.DAOException : java.sql.SQLException: Failed to start database >'/Applications/blazeds/tomcat/webapps/testdrive/WEB-INF/database/game_db', see the next >exception for details. details = null rootCause = ASObject(23393258)>>{message=java.sql.SQLException: Failed to start database >'/Applications/blazeds/tomcat/webapps/testdrive/WEB-INF/database/game_db', see the next >exception for details., suppressed=[], localizedMessage=java.sql.SQLException: Failed to >start database '/Applications/blazeds/tomcat/webapps/testdrive/WEB->INF/database/game_db', see the next exception for details., cause=java.sql.SQLException} >body = null extendedData = null
My first thought was that it was just an error in my function (maybe someone else will notice it) but I've been looking through it for a couple hours and I can't see anything.
After that I thought maybe Derby had a problem with concurrent connections. I saw somewhere that Embedded JDBC can only handle one connection so I changed the driver from Embedded to Client which once again resulted in the login function working and the other an error saying the url in the connection was null. Any thoughts? Thanks ahead of time for any ideas.
EDIT:
package services;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.net.URLDecoder;
public class ConnectionHelper
{
private String url;
private static ConnectionHelper instance;
public String getUrl()
{
return url;
}
private ConnectionHelper()
{
try
{
Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance();
String str = URLDecoder.decode(getClass().getClassLoader().getResource("services").toString(),"UTF-8");
str= str.substring(0, str.indexOf("classes/services"));
if ( str.startsWith("file:/C:",0)){
str=str.substring(6);
}
else{
str=str.substring(5);
}
url = "jdbc:derby:" + str + "database/game_db";
System.out.println("Database url "+url);
}
catch (Exception e)
{
e.printStackTrace();
}
}
public static ConnectionHelper getInstance()
{
if (instance == null)
instance = new ConnectionHelper();
return instance;
}
public static Connection getConnection() throws java.sql.SQLException
{
return DriverManager.getConnection(getInstance().getUrl());
}
public static void closeConnection(Connection c)
{
try
{
if (c != null)
{
c.close();
}
}
catch (SQLException e)
{
e.printStackTrace();
}
}
}
There is NO problem with multiple connections in embedded mode. Full stop.
That said, what you may have come across, is that only one jvm process can access the Derby database files at a time. But that jvm may well have 1000s of threads each with their own connection to Derby (resources permitting, of course).
I'm using flex, Java and sql server for webmapping application and i'm trying to fill my combobox from database, but i just get results like this [Object Object] [Object Object] [Object Object] [Object Object] instead of getting the correct values of the fields, this is the code, i think all is right but it doesn't work !!! can you help be to find what i'm messing !!
so first this is the code of my class, it selects a column (Intitule Chapitre) from database
public class RapportDao {
public Connection conectar(){
Connection cn = null;
String connectionUrl = "jdbc:sqlserver://localhost\\SQLEXPRESS;databaseName=mabase;user=sa;password=sa;";
try
{
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
cn = DriverManager.getConnection(connectionUrl);
}
catch(Exception ex)
{
System.out.println("Error : " + ex.getMessage());
}
return cn;
}
public ArrayList<Rapport> Selection() {
Connection conn = conectar();
ArrayList<Rapport> list = null;
if (conn!=null){
try{
Rapport pr = null;
String a;
list = new ArrayList<Rapport>();
String sql = "select IntituleChap from Rapport";
Statement st = conn.createStatement();
ResultSet rs=st.executeQuery(sql);
while (rs.next())
{
a=rs.getString("IntituleChap");
pr = new Rapport();
pr.setIntituleChap(a);
list.add(pr);
}
}
catch(SQLException e ) {
// System.out.print(e.getMessage());
System.out.println("Error = " + e.getMessage());
}
}else
{
}
return list;
}
}
and this is my actionscript code for combobox
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:esri="http://www.esri.com/2008/ags"
minWidth="1000" minHeight="700" applicationComplete="application1_applicationCompleteHandler(event)">
<fx:Script>
<![CDATA[
import spark.components.ComboBox;
private function getTypeprojetResult(event : ResultEvent):void
{
//Alert.show(""+event.result);
}
protected function application1_applicationCompleteHandler(event:FlexEvent):void
{
RemoteRapportDao.Selection()
}
]]>
<fx:Declarations>
<s:RemoteObject id="RemoteRapportDao"
destination="RapportDaoDest"
fault="onFault(event)">
<s:method name="Selection" result="getTypeprojetResult(event);"/>
</s:RemoteObject>
</fx:Declarations>
<s:ComboBox id="cmb" x="10" y="13" width="162" labelField="IntituleChap" dataProvider="{RemoteRapportDao.Selection.lastResult}" />
RemoteRapportDao : is the id RemoteObject
Selection() : my method on the service
any one could help me ?
It's very likely to having issue with representing the results from the query correctly, and therefore the labelField is not trigered correctly with the combo box object.
I would suggest to create a data model representing the results, which would not only great improve readability of the code, but will help you aswell with such no-go issues.
possible example of a data model ( just for a testing purposes ).
package myTopLevelPackage.myPackage
{
public class ComboBoxItemDataModel
{
public var intituleChap: String;
public function ComboBoxItemDataModel( o : Object )
{
super();
this.intituleChap = o[ 'IntituleChap' ];
trace( JSON.encode( o ) );
// use this or other suitable method to see actually how Your object looks like, in order to set the object property correctly in the assignment above.
}
}
}
Please note that I have switched using capital character for a variable IntituleChap to intituleChap.
it works, thank you all for your help, i just should use ArrayCollection instead of arraylist.
public ArrayCollection Selection() {
Connection conn = conectar();
ArrayCollection list = new ArrayCollection();
if (conn!=null){
try{
Rapport pr = null;
String a;
list = new ArrayList<Rapport>();
String sql = "select IntituleChap from Rapport";
Statement st = conn.createStatement();
ResultSet rs=st.executeQuery(sql);
while (rs.next())
{
a=rs.getString("IntituleChap");
pr = new Rapport();
pr.setIntituleChap(a);
list.add(pr);
}
}
catch(SQLException e ) {
// System.out.print(e.getMessage());
System.out.println("Error = " + e.getMessage());
}
}else
{
}
return list;
}
thank you all :)