Avoiding repeated `pst.setString(...)` when updating sql database with Java [duplicate] - java

Here is a method which displays Jobs from SQlite onto a table and sets them as labelText appropriately.
private void setLabelText() {
try {
String table_click0 = (table_job.getModel().getValueAt(row, 0).toString());
String sqlSt = "SELECT Employer.name, * FROM Job INNER JOIN Employer ON Job.employerID = Employer.employerID WHERE jobID='"+table_click0+"' ";
conn = JavaConnect.ConnectDB();
pst = conn.prepareStatement(sqlSt);
rs = pst.executeQuery();
if(rs.next()) {
descriptionArea.setText(rs.getString(5));
empTitLabel.setText(rs.getString(1)+" - "+rs.getString(4));
idLabel.setText("Job Reference: " + rs.getString(2));
typeLabel.setText("Job Type: " + rs.getString(6));
salaryLabel.setText("Salary: " + rs.getString(7));
benefitsLabel.setText("Benefits : " + rs.getString(8));
vacLabel.setText("Vacancies : " + rs.getString(9));
closeLabel.setText("Closing Date: " + rs.getString(10));
reqLabel.setText("Requirement : " + rs.getString(11));
placeLabel.setText("Placement : " + rs.getString(12));
applyToLabel.setText("Apply To: " + rs.getString(13));
statusLabel.setText("Job Status: "+rs.getString(14));
locLabel.setText("Location: "+rs.getString(16));
postedLabel.setText("Posted: "+rs.getString(15));
}
}
I want to be able to now allow users to select the Job (clicked row on table) to allow editing for update of data. So i provide a form to do that, instead of repeating lines such as descriptionArea.setText(rs.getString(5)); for Form textfields, is there a shorter way of doing this. or does each JTextfield have to be individually manipulated using textfieldName.setText(....) way, is there any tricks to do it shorter? any nice easy techniques to perhaps reuse the above code to minimise repetition.

You might want to look at the Apache Commons DbUtils, which uses Class Literals as Runtime-Type Tokens and ResultSetMetaData to simplify some of the more tedious parts of JDBC.

Despite JTextField being for editing you could use for displaying your results. You could change to editable whenever clicked.

Related

how to receive just one result from a query in a mysql database?

i´ve been using java to connect to a remote database in mysql, i´ve done a lot of diferents queries but today i´ve figured out that every time i wanted to look for a result, i have been always storing the result/s in a resulset,although in some cases my queries just have to return 0 or 1 result,that means that is not possible to receive an array of registers that meet the querie, so what kind of variable should i use to store JUST ONE RESULT?
Below i will post a portion of my code that describe the situation, it have to be understood that in the table "tareas", every register have a DIFFERENT title, like a PK.
Thanks in advance...
ps = c.prepareStatement("SELECT * FROM tareas WHERE titulo='" + title + "'");
rr = ps.executeQuery();
while (rr.next()) {
JOptionPane.showMessageDialog(null, "Titulo: " + rr.getString("titulo") + newline +
"Creador: " + rr.getString("nombre") + newline +
"Receptor: " + rr.getString("receptor") + newline +
"Tarea: " + nuevacadena(rr.getString("tarea")) + newline +
"fecha de creación:" + lafecha(rr.getString("fecha")));
}
Add a LIMIT; without that the JDBC driver may pre-fetch more than one row regardless of option 2 (which you can also do). That is,
ps = c.prepareStatement("SELECT * FROM tareas WHERE titulo='" + title + "' LIMIT 1");
and then change (for option 2)
while (rr.next())
to
if (rr.next())
Also, since you are using a PreparedStatement, you should bind your parameters instead of writing them literally into the query; for example,
ps = c.prepareStatement("SELECT * FROM tareas WHERE titulo=? LIMIT 1");
ps.setString(1, title);

How to insert all of the selected jcheckbox values into database

I have been trying to insert all of the selected jcheckbox values into a MySQL database but could not find any source. I want to do a program where teachers can select all of the courses (course code) taken by student and store them into the database column. I have tried appending all of the checkbox values into one string variable (code is given below) but don't know how to get all of the courses individually and insert them into database (since courses appear as a string). I have no idea how to do so. However it is also possible to append jcheckbox in jtable and then select all the rows (which are necessary) to insert into the database.
Please help me with one of the ways stated above. Help would be appreciated. Thank you.
if (jCheckBox1.isSelected()) {
GetAllValues += jCheckBox1.getText() + " ";
}
if (jCheckBox2.isSelected()) {
GetAllValues += jCheckBox2.getText() + " ";
}
if (jCheckBox3.isSelected()) {
GetAllValues += jCheckBox3.getText() + " ";
}
if (jCheckBox4.isSelected()) {
GetAllValues += jCheckBox4.getText() + " ";
}

Querying a MySQL database in Java, is it more efficient to specify which fields you require?

Is it more efficient to query a MySQL database in Java whilst specifying the fields in the query or more efficient to use the * wildcard?
My current code is
try (Statement statement = SQL.connection.createStatement()) {
try (ResultSet rs = statement.executeQuery("SELECT player_name, ip FROM " + SQL.database + "." + TableType.PlayerProfile.tableName + " WHERE ip='" + getPlayerIP(args[0]) + "' AND not(player_name='" + args[0] + "');")) {
if (!rs.isBeforeFirst()) {
sender.sendMessage("§7No accounts are associated with this player's ip");
} else {
sender.sendMessage("§7" + getServer().getOfflinePlayer(args[0]).getName() + "'s §lpossible §7alternative accounts:");
while (rs.next()) if (!args[0].equalsIgnoreCase(rs.getString("player_name"))) sender.sendMessage("§7" + getServer().getOfflinePlayer(rs.getString("player_name")).getName());
}
}
} catch (Exception exception) {
exception.printStackTrace();
}
So the query is
"SELECT player_name, ip FROM " + SQL.database + "." + TableType.PlayerProfile.tableName + " WHERE ip='" + getPlayerIP(args[0]) + "' AND not(player_name='" + args[0] + "');"
and then im using the Java code rs.getString("player_name") to get one of fields I need (I do the same for the ip field later)
Is this efficient or should I use the * wildcard instead of specifieng the fields I will be using with the Java code?
Of course it's more efficient to specify/reduce the fields you are trying to access. Less data to access by the RDBMS. Less Data to transfer via network in case you're trying to access a remote DB. Furthermore The * specifier does not guarantee the order of the returned fields. If your code is supposed to work with different DB Engines you may be surprised to see that the returned column #3 refers to a different content (been there done that). So even if you're trying to access the full width of a statement/table it is still saver to explicitly specify the cols you like to access.

Insert into database a scraped page containing double quotes with MySQL and Java

Imagine my page has a bunch of sections looking something like this (example page):
<div class="content">
</div>
My goal is to scrape the entire page into a MySQL DB entry. I currently do this like so:
//Declare SQL statement
String sql = "INSERT into rns " +
"(rns_pub_date, rns_headline, rns_link, rns_fulltext, constituent_id) values (\""+
rns.getRnsPubDate() + "\",\"" +
rns.getRnsHeadline() + "\",\"" +
rns.getRnsLink() + "\",\"" +
rns.getRnsFullText() + "\",\"" +
"(select constituent_id from constituent where constituent_name = " + rns.getRnsConstituentName() + "\")";
//SQL Statement Debug
Log.d(CLASS_NAME, "createRns. sqlStatement: " + sql);
//Initialize insertValues
insertValues = connect.prepareStatement(sql);
However, this falls over because there are multiple " marks in the page.
I can see a few options:
Escape the characters like this: '\"'
Replace the characters with: '"'
Remove all non-relevant data (the HTML) and save only the relevant data to the DB
I realise that there's also best practice with regards to preventing SQL injection. However this is a standalone system, so for the moment isn't an issue. Having said that if any answer can explain how to prevent that, I would prefer to implement that instead.
Edit 1:
Following on from #chrylis comment. This is what I have:
//Insert values into variables
String rns_pub_date = rns.getRnsPubDate();
String rns_headline = rns.getRnsHeadline();
String rns_link = rns.getRnsLink();
String rns_fulltext = rns.getRnsFullText();
String rns_constituent_name = rns.getRnsConstituentName();
//Prepare the SQL string
String sql = "INSERT into rns (rns_pub_date, rns_headline, rns_link, rns_fulltext,constituent_id) VALUES" + "(?,?,?,?,(select constituent_id from constituent where constituent_name = \"" + rns.getRnsConstituentName() + "\")";
//Prepare the statement
PreparedStatement prest = connect.prepareStatement(sql);
prest.setString(1, rns_pub_date);
prest.setString(2, rns_headline);
prest.setString(3, rns_link);
prest.setString(4, rns_fulltext);
prest.setString(5, rns_constituent_name);
However it provides this error:
Parameter index out of range (5 > number of parameters, which is 4).
Edit 2:
The insert was fixed by removing the escaped double quotes for the 5th parameter:
String sql = "INSERT into rns (rns_pub_date, rns_headline, rns_link, rns_fulltext, constituent_id) VALUES" + "(?,?,?,?,(select constituent_id from constituent where constituent_name = ?))";
Use PreparedStatement, there will be no need for escaping. Usage example is in API
It's not only a bad practice because of SQL injection, it's slow and inefficient, too, and has problems with quote characters. Use a parameterized query.

SQL error Too few parameters

I'm having an sql problem. I writing a java application on top of a Access database.
It's a search query for several fields and I know the error is in the part where I need to calculate the age of a person when he or she went missing. I'm returning a tablemodel in my method so i need to do the calculations in my query. My latest atempt to make it work is this:
public TableModel UpdateTable(String dossiernr, String naam, String voornaam,
String startleeftijd, String eindleeftijd, String dossierjaar, String geslacht)
{
TableModel tb = null;
String sql= "SELECT [Nr dossier],[Annee],[Nom],[Prenom],[Disparu le],[Ne le],[Sexe], DATEDIFF('yyyy',[Ne le],[Disparu le]) - iif(DATEADD('yyyy', DATEDIFF('yyyy',[Ne le],[Disparu le]),"
+ "[Ne le])>[Disparu le],1,0) AS Age FROM TotalTable "
+ "WHERE [Nr dossier] LIKE ? AND [Nom] LIKE ? AND [Prenom] LIKE ? AND [Annee] LIKE ? AND Age >= ? AND Age <= ? AND [Sexe] LIKE ?;";
try
{
PreparedStatement pstatement;
Connection connection = PersistentieController.getInstance().getConnection();
pstatement = initStatement(connection,sql);
pstatement.setString(1, "%" + dossiernr + "%");
pstatement.setString(2, "%" + naam + "%");
pstatement.setString(3, "%" + voornaam + "%");
pstatement.setString(4, "%" + dossierjaar + "%");
pstatement.setString(5, startleeftijd);
pstatement.setString(6, eindleeftijd);
pstatement.setString(7, "%" + geslacht + "%");
rs=pstatement.executeQuery();
tb = DbUtils.resultSetToTableModel(rs);
pstatement.close();
}//einde try
catch (SQLException e)
{
e.printStackTrace();
} //einde catch
return tb;
}
When i run it, i get following error:
java.sql.SQLException: [Microsoft][ODBC Microsoft Access Driver] Too few parameters. Expected 8.
I only work with 7 parameters and don't get why he's asking for 8.
Thanks
You count 7 parameters in your WHERE clause. Unfortunately, the Access db engine treats Age as another parameter in that situation, so it thinks you have 8 parameters instead of only 7.
To understand why, start with this query which runs without error with my Access database:
SELECT some_text AS foo
FROM tblFoo
WHERE some_text Is Not Null;
However, when attempting to use the alias instead of the field name in the WHERE clause, Access prompts me to supply a value for foo because it treats it as a parameter:
SELECT some_text AS foo
FROM tblFoo
WHERE foo Is Not Null;
Access limits your ability to re-use alias names later in a query. In certain cases, it will accept the alias, but yours is not one of those cases.
You could define the alias in a subquery. Then the db engine will recognize it correctly when you reference the subquery's alias in the parent query.
If possible, test your SQL statements directly in Access. If they fail, that effort will give you the best chance to determine why.

Categories

Resources