I am currently working on a Java project (on NetBeans) and I am struggling with a problem.
In fact, I have a jTable which contains several elements, which element has a jCheckBox in the second column and I would like to make a query to add the selected element (selected by the jCheckBox of course) in a table.
I can get the data that I want to add, but my query works only once. I have already check my loop but I don't where the problem comes from.
I let you see the code :
try {
// Getting id of the selected value in the jComboBox
String idParcours = oParcoursDAO.findIdParcours(jComboBoxParcours.getSelectedItem().toString());
int id = Integer.parseInt(idParcours);
// for each value in the jTable
for(int i=0; i <jTable2.getRowCount(); i++){
boolean isChecked = (Boolean)jTable2.getValueAt(i, 1);
String nomPoi = (String)jTable2.getValueAt(i, 0);
// if the value is selected
if(isChecked){
String IDPoi = oParcoursDAO.findIdPoi(nomPoi);
int idpoi = Integer.parseInt(IDPoi);
System.out.println("idpoi "+idpoi); // It works I saw as idpoi as I have choose
System.out.println("id "+id) // It works too
oParcoursDAO.addPoi(idpoi,id); // it works only once
}
}
}catch (SQLException ex) {
Logger.getLogger(ModificationParcoursJInternalFrame.class.getName()).log(Level.SEVERE, null, ex);
}
Thank you in advance for your help.
This is my statement
public void addPoi(int idPoi,int idParcours) throws SQLException{
String query = "INSERT INTO TB_POI_PARCOURS (id_poi,id_parcours) VALUES (?,?) ";
PreparedStatement preparedStatement = conn.prepareStatement(query);
preparedStatement.setInt(1,idPoi);
preparedStatement.setInt(2,idParcours);
preparedStatement.executeUpdate();
preparedStatement.close();
}
Why are you running one query per line? You can execute all of them in a single SQL using batch queries. It will require you to change the code but it will make it more efficient:
public void addPoi(Map<integer,Integer> poiMap) throws SQLException{
String query = "INSERT INTO TB_POI_PARCOURS (id_poi,id_parcours) VALUES (?,?) ";
PreparedStatement preparedStatement = conn.prepareStatement(query);
for(Integer idPoi:poiMap.keySet()) {
preparedStatement.setInt(1,idPoi);
preparedStatement.setInt(2,poiMap.get(idPoi));
preparedStatement.addBatch();
}
preparedStatement.executeBatch();
preparedStatement.close();
}
Of course the original method has to be changed accordingly.
Related
I have a JTable bound to MySQL. I already have done code to insert data.
But i don't know how to delete.
I have this sample delete method that works in other simple projects.
public String deleteItem(String name) {
String answer = "";
try {
Connection con = Connect.getConnection();
String sql = "Delete FROM item where name = ?";
PreparedStatement ps = con.prepareStatement(sql);
ps.setString(1, name);
ps.executeUpdate();
ps.close();
con.close();
answer = "OK";
} catch (Exception e) {
answer = e.toString();
}
return answer;
}
Even when I worked with an unbound table I have done this remove row from jtable that did well for me.
But now its a table bound to MySQL and I can't find a way to delete row... already searched on the internet. Found nothing.
PS: i'm using netbeans. i right-clicked jtable > bind > elements , to bind table.
Oh, I found a way!
First, I changed my deleteItem method, to delete by id
ItemDAO.java
public String deleteItem(int ID_item) {
String answer = "";
try {
Connection con = Connect.getConnection();
String sql = "Delete FROM item where ID_Item = ?";
PreparedStatement ps = con.prepareStatement(sql);
ps.setInt(1, ID_item);
ps.executeUpdate();
ps.close();
con.close();
answer = "OK";
} catch (Exception e) {
answer = e.toString();
}
return answer;
}
Then the action in delete button goes like this.
Form.java
private void btnDeleteActionPerformed(java.awt.event.ActionEvent evt) {
int column = 0; // get the first column which is ID_Item
int row = tableItem.getSelectedRow(); //get row selected by user
int value = (int) tableItem.getModel().getValueAt(row, column); // store ID_Item value
String answer = new ItemDAO().deleteItem(value); // call up deleteItem method
if(answer.equals("OK")) {
System.out.println("OK"); // just for test
itemList.clear(); // this is needed to update the bound table after Insert/Delete/Update etc
itemList.addAll(itemQuery.getResultList()); // same as above comment
}else{
System.out.println("ERROR"); // just for test.
}
Maybe isn't the most beautiful way to do it, but it works.
I have some problems to modify data from a table.
I need to update an entire column from a specific table and if there's no sufficient rows I need to insert more.
More exactly, the user will be able to modify data from interface, in a text area that contains current data from db.
I put all the text in a list, each line representing an element of the list.
In a certain column, I must go through each row and modify it with a list item. If there are more lines in the text area than number of rows in that table, I need to insert new ones, which will contain the remaining items from the list.
I would be grateful if someone could give me some help.
Thanks!
#FXML
public void modify() throws SQLException {
String col= selectNorme.getValue().toString();
String text=texta.getText();
List<String> l1notes= new ArrayList<>( Arrays.asList( text.split("\r\n|\r|\n") ));
Statement stmt=null;
String client = this.clientCombobox.getValue().toString();
String tab1Client= client+ "_" +this.selectLang1.getValue().toString();
String query="SELECT * FROM "+tab1Client+" WHERE ["+ selectNorme.getValue().toString()+ "]= "+col+"";
String sqlUpdate1= "UPDATE ["+tab1Client+"] SET ["+ this.selectNorme.getValue().toString() +"] = ?";
try {
Connection conn = dbConnection.getConnection();
PreparedStatement modif=conn.prepareStatement(sqlUpdate1);
int i=0;
if (rss.next()) {
stmt = conn.createStatement();
rss = stmt.executeQuery(query);
stmt.executeUpdate(sqlUpdate1);
modif.setString(1, l1notes.get(i));
i++;
modif.execute();
}
else {
PreparedStatement pstmt = conn.prepareStatement("INSERT INTO ["+this.clientCombobox.getValue().toString()+"_"+this.selectLang1.getValue().toString()+"] (["+ this.selectNorme.getValue().toString() +"]) values (?)" );
for (int row=i; row< l1notes.size(); row++)
{
pstmt.setString(1, l1notes.get(row));
pstmt.executeUpdate();
}
}
}
finally {
try {
if (conn !=null)
conn.close();
}
catch (SQLException se){
se.printStackTrace();
}
}
}
Here's my code for the addStudent:
#FXML
private void addStudent(ActionEvent event) {
// sql query to insert data into students at ID, first name, last name, email and DOB
String sqlInsert = "INSERT INTO students(id,fname,lname,email,DOB) VALUES (?,?,?,?,?)";
try {
Connection conn = dbConnection.getConnection();
PreparedStatement stmt = conn.prepareStatement(sqlInsert);
// add the data in the right column
stmt.setString(1, this.id.getText());
stmt.setString(2, this.firstname.getText());
stmt.setString(3, this.lastname.getText());
stmt.setString(4, this.email.getText());
stmt.setString(5, this.dob.getEditor().getText());
stmt.execute();
conn.close();
} catch(SQLException ex) {
ex.printStackTrace();
}
}
And here's my code for removeStudent:
#FXML
private void removeStudent(ActionEvent event) {
try {
// sql query to delete data from the database
String sqlRemove = "DELETE FROM students WHERE id = ?";
// open a connection to the database and use PreparedStatement to
// initialize the query.
Connection conn = dbConnection.getConnection();
PreparedStatement delete = conn.prepareStatement(sqlRemove);
// information needed to delete the row
delete.setString(1, selectStudent());
// execute and delete
delete.executeUpdate();
// close the connection
conn.close();
} catch (SQLException ex) {
ex.printStackTrace();
}
// update table after deleting
loadStudentData(event);
}
The picture above is the view of my table. I hit LoadData and my table values show up. I want to be able to click on a row(student) and hit Delete Student to remove it.
Helper method for removeStudent:
private String selectStudent() {
String result = "";
try {
String sqlSelect = "SELECT id FROM students";
Connection conn = dbConnection.getConnection();
ResultSet rs = conn.createStatement().executeQuery(sqlSelect);
result = rs.getString(1);
conn.close();
} catch (SQLException ex) {
ex.printStackTrace();
}
return result;
}
I'm pretty sure it has to do with when I "click" on a row, the id value for that isn't being held anywhere so when I hit "Delete" nothing is being given for it to Delete.
I don't know. Any advice would be awesome. :D
First edit: nothing is assigned to delete.setString(1, this.id.getText()). When I click on the row and hit delete, nothing is happening because there's nothing being assigned to id when I click on the row. The query string DOES work however when I physically give it an ID to delete. Also verified that the button does work; it prints out a lovely message for me with a good ol' System.out.println("expletive");
Second edit: Ok, so I updated the removeStudent code and now all I get is the string "null" returned. Nothing deletes. Nothing updates. Nothing is happening except I get "null" in the console.
Third edit: Getting closer! With the realization that the removeStudent isn't being given an ID to delete, I decided to create a private helper method that will do a SELECT query. Now, when I hit delete, it'll delete....but from the top, and not at where I want it selected. The code is above.
Fourth edit: Getting even closer! So, I figured out how to capture the row I click on within the table and I can delete......however, because of my sqlRemove command, I'm deleting by id so if I click on a row with index 3, then ONLY the row within the table that has an id of 3 will be deleted, nothing else. I gotta re-write how the sqlRemove command is worded.
I fixed it:
private String selectStudent() {
// initial value for result to return
String result = "";
// grab the index of the row selected on the table
int initial = studenttable.getSelectionModel().getSelectedIndex();
try {
// SELECT query to execute
String sqlSelect = "SELECT id FROM students";
Connection conn = dbConnection.getConnection();
ResultSet rs = conn.createStatement().executeQuery(sqlSelect);
// while there's a next row
while(rs.next()) {
// set temp to equal the id rs.next() is currently on
String temp = rs.getString("id");
// get the row id - 1 since we start at 0
int temp1 = rs.getRow() - 1;
// if temp1 is equal to the index we selected
if(temp1 == initial) {
// make it equal to result
result = temp;
}
}
// close the connection
conn.close();
} catch (SQLException ex) {
ex.printStackTrace();
}
// return the row to delete
return result;
}
What's going on is in the comments. I finally figured out how to pass the value from a selected row and compare it to a row. Once I get the correct row to pass, I give it to the delete function to remove.
After a day in a half.............but I love it, so. Yeah.
I am trying to insert some words to database and return newly inserted id or existing id if the word is already in the database.
I found that I can do this using PreparedStatement and including Statement.RETURN_GENERATED_KEYS. But PreparedStatement is terribly slow. I need to insert like 5000 words at once. Another way I could achieve it by running individual query in for loop:
public ArrayList<Integer> addWords(ArrayList<String[]> allTermsForTag) {
ArrayList ids = new ArrayList<Integer>();
ResultSet rs = null;
try{
Statement st = connection.createStatement();
for (String[] articleTerms: allTermsForTag) {
for(String term: articleTerms) {
String query = "WITH a AS (INSERT INTO tag (name) SELECT '"+term+"' WHERE NOT EXISTS (SELECT name FROM tag WHERE name = '"+term+"') " +
"RETURNING id) SELECT id FROM a UNION SELECT id FROM tag WHERE name = '"+term+"'";
rs = st.executeQuery(query);
while (rs.next())
{
int id = rs.getInt(1);
ids.add(id);
System.out.printf("id: "+id);
}
}
}
rs.close();
st.close();
}catch(SQLException e){
System.out.println("SQL exception was raised while performing SELECT: "+e);
}
return ids;
}
This does what I need nicely, but this is too slow as well.
Another method that I wrote uses executeBatch(), however, it does not return ids:
public ArrayList<Integer> addWords(ArrayList<String[]> allTermsForTag){
ResultSet rs = null;
ArrayList ids = new ArrayList<Integer>();
try{
Statement st = connection.createStatement();
for (String[] articleTerms: allTermsForTag) {
for(String term: articleTerms) {
String query = "WITH a AS (INSERT INTO tag (name) SELECT '"+term+"' WHERE NOT EXISTS (SELECT name FROM tag WHERE name = '"+term+"') " +
"RETURNING id) SELECT id FROM a UNION SELECT id FROM tag WHERE name = '"+term+"'";
st.addBatch(query);
}
st.executeBatch();
rs = st.getGeneratedKeys();
while (rs.next()) {
int id = rs.getInt(1);
ids.add(id);
}
}
st.close();
return ids;
}catch (SQLException e){
System.out.println("SQL exception was raised while performing batch INSERT: "+e.getNextException());
System.out.println("dub");
}
return null;
}
So the question is - how to get ids when using executeBatch() or if this is not possible, how to approach this problem? I need it to work as fast as possible, because there will be a lot of INSERT operations with large amount of data.
Thank you!
Set set = new HashSet();
try {
PreparedStatement ps = cn.prepareStatement("delete from myTable where... ",
Statement.RETURN_GENERATED_KEYS);
ps.setInt(1,200);
ps.setInt(2,262);
ps.setString(3, "108gf99");
ps.addBatch();
ps.setInt(1,200);
ps.setInt(2,250);
ps.setString(3, "hgfha");
ps.addBatch();
ps.executeBatch();
ResultSet rs = ps.getGeneratedKeys();
while (rs.next()){
set.addAll(Collections.singleton(rs.getLong(1)));
}
System.out.println(set);
} catch (SQLException e) {
e.printStackTrace();
}
executeBatch can return generated keys in the latest PgJDBC versions. See issue 195 and pull 204. You must use the prepareStatement variant that takes a String[] of returned column names.
However... take a step back here. The solution isn't loops. The solution is almost never loops.
In this case, you should almost certainly use COPY via the PgJDBC CopyManager API to COPY data into a TEMPORARY table. Then do an INSERT INTO ... SELECT ... RETURNING ... to insert the temp table's contents into the final table and return any generated fields. You can also do a SELECT to join on the temp table to return any that already exist. This is basically a bulk upsert or closely related bulk insert-if-not-exists.
If for some reason you can't do that, the next-best option is probably multi-valued INSERTs with large VALUES lists, but this requires some ugly dynamic SQL. Since you need existing values if the row already exists you'll probably need a writeable CTE too. So really, just use COPY and a query to do the table merge.
I am writing a java function to delete all data from MySQL table and then write new data in it. following is my function.
public void editsnack(ArrayList snames)
{
System.out.println("Snack Names "+snames);
Statement _snacksListStmt = null;
Statement _deleteTableDtataStmt = null;
try
{
_snacksListStmt = fCon.createStatement();
_deleteTableDtataStmt = fCon.createStatement();
int i=0;
for(i=0;i<snames.size();i++)
{
String _name = snames.get(i).toString();
String _deleteTableData ="TRUNCATE TABLE snacklist";
_deleteTableDtataStmt.executeUpdate(_deleteTableData);
String _snackListQuery ="insert into snacklist(snackName)values('"+_name+"')";
System.out.println("Query ");
System.out.println(_snackListQuery);
_snacksListStmt.executeUpdate(_snackListQuery);
}
}
Note that after deleting data successfully, these lines
System.out.println("Query ");
System.out.println(_snackListQuery);
are printing correct values, however values are not being stored in the table.
How can I solve this problem?
First of all, you're deleting all data for each item you are inserting.
So move the TRUNCATE code to before the for-loop
And see if you can sanitize the snack-names before adding them in the SQL, or they could cause sql-injections
Depending on if your connection is set on autoCommit or not you'd have to call fCon.commit() to commit your transaction.
Also you should always close your statements when you're done.
The problem is the delete query in the for loop, you are truncating the data after each insert. With your current logic only the last insert will reamin in the table and all other data will be truncated. Move the delete query outside of for loop and try:
String _deleteTableData ="TRUNCATE TABLE snacklist";
_deleteTableDtataStmt.executeUpdate(_deleteTableData);
for(i=0;i<snames.size();i++)
{
String _name = snames.get(i).toString();
String _snackListQuery ="insert into snacklist(snackName)values('"+_name+"')";
System.out.println("Query ");
System.out.println(_snackListQuery);
_snacksListStmt.executeUpdate(_snackListQuery);
}
Try code below..
public void editsnack(ArrayList snames)
{
System.out.println("Snack Names "+snames);
Statement _snacksListStmt = null;
Statement _deleteTableDtataStmt = null;
try
{
_snacksListStmt = fCon.createStatement();
_deleteTableDtataStmt = fCon.createStatement();
String _deleteTableData ="TRUNCATE TABLE snacklist";
_deleteTableDtataStmt.executeUpdate(_deleteTableData);
int i=0;
for(i=0;i<snames.size();i++)
{
String _name = snames.get(i).toString();
String _snackListQuery ="insert into snacklist (snackName) values ('"+_name+"')";
System.out.println("Query ");
System.out.println(_snackListQuery);
_snacksListStmt.executeUpdate(_snackListQuery);
}
}