I am trying to create an event using the code below in java. However after I give it the input needed I check the database to find all of the fields containing null values. what should I do? Thank you in advance.
public void CreateEvent(User U){
try{
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
String d;
//getting inputfrom the user
System.out.print("Event Name \n");
d = inFromUser.readLine();
EventName = d;
System.out.println("Kindly Provide the start date(Format dd/MM/yyyy HH:mm)");
//parsing date from user using SimpleDateFormat
date = sdf.parse(inFromUser.readLine());
startDate = date.toString();
System.out.println("Kindly Provide the end date(Format dd/MM/yyyy HH:mm)");
date = sdf.parse(inFromUser.readLine());
d = date.toString();
endDate = d;
System.out.println("Where is the event:");
d = inFromUser.readLine();
Location= d ;
System.out.println("Description");
d = inFromUser.readLine();
Description= d;
//Get creator UserName
Creator = U.FullName;
MyJDBC.Insert(TableName, Fields, Values);
}
catch (IOException ex) {//catch the exception
ex.printStackTrace();
}
catch (ParseException e) {
e.printStackTrace();
}
}
values is this
String Values= "'"+EventName+"','"+Location +"','"+Description+"','"+startDate+"','"+endDate+"','"+Creator+"'";
this is JDBC insert method
public void Insert(String TableName,String Fields, String Values){
try {
conn = DriverManager.getConnection(DB_URL, USER, PASS);
stmt = conn.createStatement();
String sql = "INSERT INTO " + TableName+ " (" +Fields+ ") VALUES ("+ Values+ ")" ;
stmt.execute(sql);
System.out.println("Successfully inserted record into database");
stmt.close();
}
catch(SQLException se){
se.printStackTrace();
}
}
The code sample is not complete. Yet, what can be seen, is that you collect some variables like EventName and Location and later on you send values to the insert method, but that values is never filled.
Your updated question proves that: String in Java is immutable, you cannot change it after creation. Values will not be evaluated again, after the assignment has been done.
At the time you assign it, all variables used to fill it are null.
To solve your problem now, assign values right before you call the insert-method.
To improve your program, write a class DAO with a method saveEvent() that takes an EventVO as parameter.
The EventVO contains all the collected values as properties.
The save method will create the sql neccessary to insert or update the event.
Also: The java language has the convention, that variables name are lower case, you should stick to that.
Related
How can I query data from my database and assign it to an array of strings? In this attempt I noticed I would receive an out of bounds error before I included the resultSet.next() call since it seems that ResultSet starts at 0 and is not called like a list / array (meaning you can access the contents with its index).
public String[][] retrieveNameAndLocation() {
final String table = "customers";
try {
ResultSet resultSet = statement.executeQuery(
"SELECT " +
"first_name," +
"location" +
" FROM " + table
);
resultSet.next();
final String[] names = (String[]) (resultSet.getArray(1).getArray());
final String[] location = (String[]) (resultSet.getArray(2)).getArray();
final String[][] nameAndCountry = {names, location};
resultSet.close();
return nameAndCountry;
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
Anyways the above code resulted in a SQLFeatureNotSupportedException. My next attempt was to simply call the the columns by name since I noticed it was an option inside of getArray, however that also resulted in the not supported exception.
public String[][] retrieveNameAndLocation() {
final String table = "customers";
try {
ResultSet resultSet = statement.executeQuery(
"SELECT " +
"first_name," +
"location" +
" FROM " + table
);
resultSet.next();
final String[] names = (String[]) (resultSet.getArray("first_name").getArray());
final String[] location = (String[]) (resultSet.getArray("location")).getArray();
final String[][] nameAndCountry = {names, location};
resultSet.close();
return nameAndCountry;
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
I am not really sure why I need to include resultSet.next() because it seems like it's just broken since why would they include an option to query columns if they forced you to loop through the indexes?
I think you misunderstand the purpose of method getArray. Some DBMSs, like Oracle, have "array" data types. Hence the getArray method – to query a database table column whose type is an array type. I have no experience with MySQL but it appears that it does not have an array type. Hence the JDBC driver for MySQL does not need to implement the getArray method and that's why you get the SQLFeatureNotSupportedException.
You need to iterate through the ResultSet and build up your array. However since you usually don't know how many rows there are in a ResultSet, I usually use a List and then, if required, convert it to an array because when you declare an array you need to know its size.
I would also define a record and declare a List of records.
(Note that below code is not compiled and not tested since I don't have your database and I can't simulate it since the code in your question is not a minimal, reproducible example.)
public record NameAndCountry(String name, String location) {
public static java.util.List<NameAndCountry> retrieveNameAndLocation() {
final String table = "customers";
try {
ResultSet resultSet = statement.executeQuery(
"SELECT " +
"first_name," +
"location" +
" FROM " + table
);
java.util.List<NameAndCountry> list = new java.util.ArrayList<>();
while (resultSet.next()) {
String name = resultSet.getString(1);
String location = resultSet.getString(2);
NameAndCountry row = new NameAndCountry(name, location);
list.add(row);
}
} catch (SQLException e) {
e.printStackTrace();
}
return list;
}
}
I wrote a small program to retrieve records in my email queue table to process and send email. While using JDBC to achieve this, as shown below:
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);
}
The above works fine since it retrieve email records where the status is pending and pass the subject, content, recipient, etc to sendemail method and done.
I wanted to achieve the same goal but using JPA persistence instead. So I wrote this method:
public Object getrecords() {
try {
String sql = "select p.id,p.user,p.subject,p.recipient,p.content from Emailqueue p where " +
"status='Pending'";
List<Object[]> resList =(List<Object[]>) em.createQuery(sql).getResultList();
if (resList == null) {
throw new Exception("Error with selection query.");
}
if (resList.size() > 0) {
return resList;
}
// msg = "Setting <" + name + "> not found.";
return null;
} catch (Exception e) {
msg = CoreUtil.wrapMsg(CoreUtil.FUNC_ERROR,
this.getClass().getName(), "get(" + "Pending" + ")", e.getMessage());
return null;
}
}
It has no issue retrieving the records and size in the table. And I called this method in the email(). Something like:
Object records = ejbCon.getSettingsFacade().getrecords();
From here, I can't figure how do I loop the records, to get each of the value in each field. For example, if there's 2 pending email records, I should need to retrieve each of its content, subject, recipient, etc and pass to sendemail method.
Also, retrieving these records is already taxing to my program since it takes long time to close the application compared to using JDBC (it's faster and I guess more efficient?).
So, I also need to consider the performance by doing using this method.
Edit
I should have clarified this better to explain what I'm trying to achieve.
So I have that email queue table in this form:
id user subject content recipient status
1 user1 test example abc#example.com Pending
2 user2 test2 example cde#example.com Pending
So before this, I was using resultset in JDBC to obtain each individual field values for id:1 and pass them to the send method, and proceed with id:2 and do the same, an iteration. Now I want to achieve the same way by using the object I retrieve but I can't specify which fields value it's able to get. So I am stuck.
There are many ways to achieve your desired result but the easiest way you can do is to create a parameterized constructor in your Emailqueue class and change your query to
String sql = "select NEW
Emailqueue(p.id,p.user,p.subject,p.recipient,p.content) from Emailqueue p
where " +
"p.status='Pending'";
List<Emailqueue> resList =(List<Emailqueue>)
em.createQuery(sql).getResultList();
this way you can normally iterate over List using foreach loop.
If i understood what is your correctly needs, Try to loop your resList.
And i recommend to you don't get Object type.
List<Emailqueue> resList = em.createQuery(sql, Emailqueue.class).getResultList();
for (Emailqueue email : resList) {
String subject = email.getSubject();
// something do.
}
Here the simple way to get data based on query.
If you are using Entity Manager for query and use HQL, u can just simply return the class data. here is the sample :
TypedQuery q = man.createQuery("SELECT u FROM YourTable u WHERE u.col1 =:col1 and u.col2 =:col2", YourCalss.class)
.setParameter("col1", col1)
.setParameter("col2", col2);
result = q.getResultList();
If you want with custom result, then u can modify the current class of entity into another class.
List<CustomClass> result = null;
EntityManager man = PersistenceUtilities.getEntityManagerFactory().createEntityManager();
try {
TypedQuery q = man.createQuery("SELECT NEW " + CustomClass.class.getCanonicalName() + "(u.col1,u.col2) "
+ "FROM YourTable as u ", CustomClass.class);
if (q.getResultList().size() > 0) {
result = q.getResultList();
}
} catch (Throwable t) {
Main.logger.error(t.getMessage());
} finally {
man.close();
}
return result;
I am having some trouble in returning the NEXT record within the database, my code currently only returns the last record entered. I have tried creating an instance of a List/ArrayList, tried adding statements to my createStatement(); and just tried everything. I've searched the web, however, I always seem to get the last value returned. I was hoping as to whether someone could help me out. I am using .Swing and this is all executed within an ActionListener.
Essentially I want this function to get the next record in the database. As opposed to returning the last record.
nextEmployee.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Connection connection = null;
Statement statement = null;
try {
Class.forName("org.sqlite.JDBC");
connection = DriverManager.getConnection("jdbc:sqlite:employeeDatabase.sqlite");
connection.setAutoCommit(false);
System.out.println("Read operation - database successfully opened");
statement = connection.createStatement(ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY);
ResultSet resultset = statement.executeQuery( "SELECT * from employees" );
while (resultset.next()) {
ArrayList<Employee> selectAllEmployees = new ArrayList<Employee>();
String id = resultset.getString("id");
String name = resultset.getString("name");
String email = resultset.getString("email");
String gender = resultset.getString("gender");
String dob = resultset.getString("dob");
String Address = resultset.getString("address");
String Postcode = resultset.getString("Postcode");
String NIN = resultset.getString("NIN");
String JobTitle = resultset.getString("JobTitle");
String StartDate = resultset.getString("StartDate");
String Salary = resultset.getString("Salary");
idTextField.setText(id);
nameTextField.setText(name);
genderTextField.setText(gender);
dobTextField.setText(dob);
addressTextField.setText(Address);
postcodeTextField.setText(Postcode);
ninTextField.setText(NIN);
jobtitleTextField.setText(JobTitle);
startdateTextField.setText(StartDate);
salaryTextField.setText(Salary);
emailTextField.setText(email);
}
resultset.close();
statement.close();
connection.close();
} catch ( Exception e1 ) {
System.err.println( e1.getClass().getName() + ": " + e1.getMessage() );
System.exit(0);
}
}});
Thank you for your time and effort.
One of two things is happening. Either:
You have a bug in the code which populates the database, so you think you have rows A, B, and C in the database, but in fact you only have row C
Or:
Your code as listed populates your controls with the contents of row A, then it repeats to populate the exact same controls with contents of row B, and then the exact same controls once more with the contents of row C. So, naturally, the values you are left with are the values of the last row.
It helps to think precisely what it is that you are trying to do, precisely what is happening, precisely what you expected to happen instead, and most importantly, what makes you believe that the code should do that which you expect it to do rather than what it actually does.
i have been trying a lot of syntax but i can't figured it out.
I want to display "Invoice number" from my databases to the text field (The field "invoice" from table "transaksi" is already filled with number) But it won't show anything. Here's my code :
private void InvoiceActionPerformed(java.awt.event.ActionEvent evt) {
ResultSet aa = null;
try {
koneksi objKoneksi = new koneksi();
Connection kon = objKoneksi.bukaKoneksi();
Statement stat = kon.createStatement();
String query ="select invoice from transaksii";
String res = aa.getString(query);
Invoice.setText(res);
}
catch (SQLException e) {}
}
Note : - Invoice is Former JTextField1.
- transaksii = name of my table.
- invoice = name of the field.
Thank you. English is not my native language.
You did not execute the query. The value of aa is null and you might be getting a NullPointerException.
String query ="select invoice from transaksii";
aa=stat.executeQuery(query);
if(aa.next())
String res = aa.getString("invoice");
Note: Its not a good practice to have an empty catch because you would then end up without knowing about the exception like now. You should do e.printStackTrace(); in catch block.
There is only 1 problem in your original code. The result set that has returned in the line aa = stat.executeQuery(query); is presently at the a position before the 1st result returned. So When you call aa.getString it is not going to return any thing as it is before the 1st result. Also the ResultSet.getString takes a parameter of int or a parameter of String representing the column name. But in your case you have passed the query as the parameter.
So the corrected code should be if you only want to return the 1st item of the ResultSet would be :
private void InvoiceActionPerformed(java.awt.event.ActionEvent evt) {
ResultSet aa = null;
try {
koneksi objKoneksi = new koneksi();
Connection kon = objKoneksi.bukaKoneksi();
Statement stat = kon.createStatement();
String query ="select invoice from transaksii";
aa = stat.executeQuery(query);
String res = "";
if(aa.next()){ // checks and moves it to 1st position
res = aa.getString("invoice"); //column name of the column
}
Invoice.setText(res);
}catch(SQLException e){
e.printStackTrace();
}finally{
//The closing of connection, statement and resultset.
}
}
I m getting except1 on running this code.Please see if there is any mistake within the try block....
Try
{
pst=con.prepareStatement("SELECT Name,Roll,Semester,Address,Phoneno," +
"E-mailId,Gender,DOB,Result FROM stud WHERE Roll = ?");
pst.setString(1,s2);
ResultSet rs=pst.executeQuery();
while(rs.next())
{
s2=rs.getString("Roll");
String s1=rs.getString("Name");
String s3=rs.getString("Semester");
String s4=rs.getString("Address");
String s5=rs.getString("Phoneno");
String s6=rs.getString("E-mailId");
String s7=rs.getString("Gender");
String s8=rs.getString("DOB");
String s9=rs.getString("Result");
t1.setText(s1);
t2.setText(s2);
t3.setText(s3);
t4.setText(s4);
t5.setText(s5);
t6.setText(s6);
t7.setText(s7);
t8.setText(s8);
t9.setText(s9);
}
con.commit();
con.close();
}
catch(SQLException e2)
{
System.out.println("except1");
}
caveat: my Java is rusty -
don't know if field names can contain hypens, depends on the database
print the exact exception that you're getting
why are you doing a commit on a SELECT?
Make Sure data type of "Roll" Atrribute in Database is Character(n).
if it is integer/number then use this
pst.setInt(1,Integer.parseInt(s2));
Make sure you use VARCHAR data type for all attributes in database. If it is not the case then change your code according to these data types.
And print exception stack trace (e2.printStackTrace()) in catch block for getting exact reason for the exception.
Thanks
Try
{
pst=con.prepareStatement("SELECT Name,Roll,Semester,Address,Phoneno," +
"E-mailId,Gender,DOB,Result FROM stud WHERE Roll = ?");
pst.setString(1,s2);
string s2 = '123123'; //pass the required value to Query
ResultSet rs=pst.executeQuery();
while(rs.next())
{
//String s2=rs.getString("Roll");
String s1=rs.getString("Name");
String s3=rs.getString("Semester");
String s4=rs.getString("Address");
String s5=rs.getString("Phoneno");
String s6=rs.getString("E-mailId");
String s7=rs.getString("Gender");
String s8=rs.getString("DOB");
String s9=rs.getString("Result");
t1.setText(s1);
t2.setText(s2);
t3.setText(s3);
t4.setText(s4);
t5.setText(s5);
t6.setText(s6);
t7.setText(s7);
t8.setText(s8);
t9.setText(s9);
}
con.commit(); // use commit only when you are doing create/update operations
con.close();
}
catch(SQLException e2)
{
System.out.println("Error Information");
e2.printStackTrace();// this method display the error information
}