Mysql Java Update Query - java

I have a listener that listens a button and takes 3 texts fields from input to execute an update query. I want to execute the update but in the query to pass my local variables(name,city,salary).
What can i do this?
public void actionPerformed(ActionEvent arg0) {
final String name;
final String city;
final String salary;
name = (textFieldName.getText());
city = (textFieldCity.getText());
salary = (textFieldSalary.getText());
System.out.println(salary);
try {
Statement s = connection.createStatement();
s.executeUpdate("INSERT INTO users (name,city,salary) VALUES (name, city,salary)");

I'd go with a PreparedStatement
PreparedStatement s = connection.prepareStatement("INSERT INTO users (name,city,salary) VALUES (?, ?, ?)");
s.setString(1, name);
s.setString(2, city);
s.setString(3, salary);
boolean res = s.execute();
This approach is a bit better, quoting will be automatically managed and will prevent simple SQL Injection.

Related

JDBC inserting variables to database

I'm passing my method InsertQuery variables from another method which are entered by the user via Scanner.
How do I fill in the iName, iType etc. into my iQuery so that I can insert them into my DB?
public void InsertQuery (String iName, String iType, int health_Problem, Date date2, String aRemind, String docName, String docType, String docAdress)
{
final String url = "jdbc:mysql://localhost/ehealthdb?serverTimezone=UTC";
final String DBUSER = "root";
final String DBPSWD = "root";
try {
Connection con = DriverManager.getConnection(url,DBUSER,DBPSWD);
Statement stmt = con.createStatement();
String iQuery = "INSERT into appointment"
+ "(ID, PatientID, Insurance_Name, Insurance_Type, Health_Problem, Appointment_Date, Appointment_Remind, Doctor_Name,Doctor_Type,Doctor_Adress)"
+ "values ('1','1',,'Gesetzlich','5','15.01.2020','1 Week','Musterarzt','Hausarzt','Musterstraße')";
stmt.executeUpdate(iQuery);
} catch (Exception e) {
System.out.println("Something went wrong #InsertQuery");
}
}
The easiest approach would probably be to use a PreparedStatement:
public void insertQuery
(String iName, String iType, int healthProblem, Date date2, String aRemind, String docName, String docType, String docAddress)
throws SQLException {
final String url = "jdbc:mysql://localhost/ehealthdb?serverTimezone=UTC";
final String DBUSER = "root";
final String DBPSWD = "root";
try (Connection con = DriverManager.getConnection(url,DBUSER,DBPSWD);
PreparedStatement stmt = con.prepareStatement(
"INSERT into appointment" +
"(ID, PatientID, Insurance_Name, Insurance_Type, Health_Problem, Appointment_Date, Appointment_Remind, Doctor_Name, Doctor_Type, Doctor_Adress) " +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)")) {
stmt.setString(1, iName);
stmt.setString(2, iType);
stmt.setInt(3, healthProblem);
stmt.setTimestamp(4, new Timestamp(date2.getTime()));
stmt.setString(5, aRemind);
stmt.setString(6, docName);
stmt.setString(7, docType);
stmt.setString(8, docAddress);
stmt.executeUpdate();
}
}
Don't use a statement, use a PreparedStatement. Otherwise, you get hacked.
More generally, JDBC is a tricky beast and not a particularly nice API. For fairly good reasons - it is designed to be the lowest common denominator, and it is more focused on exposing all the bells and whistles of all databases in existence, than in giving you, programmer who wants to interact with a database, a nice experience.
Try JDBC or JOOQ.
Your exception handling is also wrong. If you catch an exception, either handle it, or make sure you throw something. Logging it, (or worse, printing it) definitely does not count. Add throws to your method signature. If that's not possible (and it usually is possible, try that first), throw new RuntimeException("Uncaught", e) is what you want. not e.printStackTrace(), or even worse, what you did: You just tossed out all relevant information. Don't do that.
The recommended approach is to use PreparedStatement which solves the following two important problems apart from many other benefits:
It helps you protect your application from SQL Injection.
You will not have to enclose the text values within single quotes yourself.
Typical usage is as shown below:
String query = "INSERT INTO appointment(ID, PatientID, Insurance_Name, Insurance_Type, Health_Problem) VALUES (?, ?, ?, ?, ?)";
try (PreparedStatement pstmt = con.prepareStatement(query)) {
//...
pstmt.setString(1, id);
pstmt.setString(2, patientId);
pstmt.setString(3, insuranceName);
//...
pstmt.executeUpdate();
} catch(SQLException e) {
e.printStackTrace();
}
Note that for each ?, you will have to use pstmt.setXXX. Another thing you need to understand is that in the method call, pstmt.setString(1, Id), 1 refers to the first ? and not the first column in your table.
Some other important points:
I have used try-with-resources statement which is an easier and recommended way to close the resources after the program is finished with it. Learn more about it from Oracle's tutorial on it.
Always follow Java naming conventions e.g. Insurance_Name should be named as insuranceName.
I used this way and it is working greatly
for iName
public void InsertQuery (String iName, String iType, int health_Problem, Date date2, String aRemind, String docName, String docType, String docAdress)
{
final String url = "jdbc:mysql://localhost/ehealthdb?serverTimezone=UTC";
final String DBUSER = "root";
final String DBPSWD = "root";
try {
Connection con = DriverManager.getConnection(url,DBUSER,DBPSWD);
Statement stmt = con.createStatement();
String iQuery = "INSERT into appointment"
+ "(ID, PatientID, Insurance_Name, Insurance_Type, Health_Problem, Appointment_Date, Appointment_Remind, Doctor_Name,Doctor_Type,Doctor_Adress)"
+ "values ('1','1',,'"+iName+"','5','15.01.2020','1 Week','Musterarzt','Hausarzt','Musterstraße')";
stmt.executeUpdate(iQuery);
} catch (Exception e) {
System.out.println("Something went wrong #InsertQuery");
}
}

Parameter index out of range (1 > number of parameters, which is 0). output when attempting to save information to database

I created a small program where the user must input data into text fields and select options from combo boxes. I created a database using XAMPP and created the corresponding tables for the program through the web browser.
The database is called activitydb and the table that's responsible for storing the data from the program is called userdata.
The first column in the table is called UserID and is an int that auto increments every time a new entry is added.
The rest are all varchars with varying maximum lengths.
This is currently the source code of the program:
Connection con = null;
Statement st = null;
try {
// activitydb = database name
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/activitydb?zeroDateTimeBehavior=convertToNull", "root", "");
st = con.createStatement();
// userdata = table name
String sqlconn = "INSERT INTO userdata (UserID, LastName, FirstName, MiddleName, Email, Sex, HomeAddress, City, CPUBrand, ComputerType, HardwareSpecs, GPUBrand, GPUType, GPUVRAM)";
PreparedStatement prdStmt = con.prepareStatement(sqlconn);
// Input of variable data into corresponding database table
// First table will be declared as null as it is an Integer designed with an Auto Increment
prdStmt.setString(1, null);
prdStmt.setString(2, jTextLastName.getText());
prdStmt.setString(3, jTextFirstName.getText());
prdStmt.setString(4, jTextMiddleName.getText());
prdStmt.setString(5, jTextEmail.getText());
prdStmt.setString(6, jComboBoxSex.getSelectedItem().toString());
prdStmt.setString(7, jTextHomeAddress.getText());
prdStmt.setString(8, jTextCity.getText());
prdStmt.setString(9, jComboBoxCPUBrand.getSelectedItem().toString());
prdStmt.setString(10, jComboBoxComputerType.getSelectedItem().toString());
prdStmt.setString(11, jComboBoxHardwareSpecs.getSelectedItem().toString());
prdStmt.setString(12, jComboBoxGPUBrand.getSelectedItem().toString());
prdStmt.setString(13, jComboBoxGPUType.getSelectedItem().toString());
prdStmt.setString(14, jComboBoxGPUVRAM.getSelectedItem().toString());
// Do this if something goes wrong
} catch (SQLException err) {
// Print error message to console for diagnosis
System.out.println(err.getMessage());
}
For the combo boxes, I've used getSelectedItem().toString() to have the data found inside stored as a String.
Clicking the button will make the program do nothing but print this in the console:
Parameter index out of range (1 > number of parameters, which is 0).
You are missing the place holders ? to put the values, your query should be :
String sqlconn = "INSERT INTO userdata (UserID, LastName, FirstName, MiddleName," +
" Email, Sex, HomeAddress, City, CPUBrand, ComputerType, HardwareSpecs," +
" GPUBrand, GPUType, GPUVRAM) " +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";

jdbcTemplate.update for auto incremented and unique ID field

I have an EMPLOYEE table that has 4 fields; ID, NAME, AGE, SALARY. ID is unique and auto-increment.
Below is the code to insert a row in the table, using Spring's JDBCTemplate. Please suggest, how can I auto increment ID field.
String sql = "insert into employee values (?,?,?,?)"
jdbcTemplate.update( sql, ID, bean.getName(), bean.getAge(), bean.getSalary())
I see, you tag your question Oracle, use Oracle sequence then.
String sql = "insert into Employee values (id_seq.nextval, ?, ?, ?)";
jdbcTemplate.update(sql, bean.getName(), bean.getAge(), bean.getSalary());
Ref: How to create Sequence in Oracle.
Just add following code to your domain:
Ref: http://docs.spring.io/spring/docs/2.5.x/reference/jdbc.html#jdbc-auto-genereted-keys
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
final String INSERT_SQL = "insert into my_test (name) values(?)";
final String name = "Rob";
KeyHolder keyHolder = new GeneratedKeyHolder();
jdbcTemplate.update(
new PreparedStatementCreator() {
public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
PreparedStatement ps =
connection.prepareStatement(INSERT_SQL, new String[] {"id"});
ps.setString(1, name);
return ps;
}
},
keyHolder);

How to dynamically assign values to a PreparedStatement?

Current Scenario:
String query= "select emp_role from emp where emp_id = ?";
String query= "select address.phone_no from address, emp where address.address_id=emp.address_id and emp.emp_id = ?";
PreparedStatement prepatedStatement = connection.prepareStatement(query);
prepatedStatement.setInt(1, empId);
ResultSet rs = prepatedStatement.executeQuery();
Expected Scenario:
When I have queries with multiple inputs like the ones mentioned below
String query= "select emp_role from emp where emp_id = ? and emp_plan = ?";
String query= "select emp_id,emp_name from (select emp_id,emp_name from emp_1 where emp_1_id = ?)union(select emp_id,emp_name from emp_2 where emp_2_id = ?)";
I need to have a generic prepatedStatement logic to do this.
Take a look at - How to create a prepared statement dynamically - and re-use the query
This logic works fine but I still have to set values to map explicitly.
There is no automatic way of doing the things but you could improve it with something like:
List<String> empParameters = getMeParameters();//may be factory here?
ResultSet rs = getResultSet(.....);
......
private ResultSet getResultSet(PreparedStatement prepatedStatement, List<String> empParameters) {
int i = 0;
for (String empParameter : empParameters) {
prepatedStatement.setInt(i++, empParameter);
}
return prepatedStatement.executeQuery();
}

Looking Pattern for UPDATE SQL in Java

I am looking the best coding pattern for the below update SQL table with prepared statement in Java.
SQL Table name is table1 and attr1, att2, att3, att4, attr5 and .... in table1.
Currently my pseudo
If (want to update att1 only) {
PreparedStatement pst = Connection.prepareStatement("UPDATE table1 SET attr1 = ?");
} else if (want to update attr1 & attr2 only) {
PreparedStatement pst = Connection.prepareStatement("UPDATE table1 SET attr1 = ?, attr2 = ?");
} else if (want to update attr1 & attr2 & attr3) {
PreparedStatement pst = Connection.prepareStatement("UPDATE table1 SET attr1 = ?, attr2 = ?, attr3 = ?");
} else if (want to udpate attr1 & attr3) {
PreparedStatement pst = Connection.prepareStatement("UPDATE table1 SET attr1 = ?, attr3 = ?");
} ......
.... else {
Bad Request
}
This above code will make more complex with WHERE SQL condition. I don't like this if - else if - else pattern here because
very hard to maintain.
Yes, I know other options are dynamically generate UPDATE SQL query and use ORM solution.
I believe dynamically generate SQL UPDATE Query logic would become complex.
Please provide any other pattern OR solution which can fit best here.
You could just write one update statement to update all non-key fields and call that each time.
public class MyThing {
private long uniqueID;
private String attr1;
private String attr2;
private String attr3;
// ++ rest of attriutes, getters and setters
}
public MyThing getMyThing(long uniqueID) {
// code to retrieve MyThing from table1, poulating all attributes
}
public void updateMyThing(MyThing myThing) {
PreparedStatement pst = Connection.prepareStatement
(" UPDATE table1 SET attr1 = ?, attr2 = ?, attr3 = ?, attr4 = ?, attr5 = ?" +
" WHERE id = ? );
pst.SetString(1, myThing.getAttr1());
pst.SetString(2, myThing.getAttr2());
pst.SetString(3, myThing.getAttr3());
pst.SetString(4, myThing.getAttr4());
pst.SetString(5, myThing.getAttr5());
pst.SetString(6, myThing.getId());
// etc.
}
So retrieve a MyThing object from the DB. Update whatever attributes you want then call the update method. All attributes updated whether they have changed or not

Categories

Resources