I'm currently scraping some scores from a HTML page and then inputting them into a SQL database.
The scores are being parsed using Jsoup into an ArrayList. From here I'm converting the ArrayList to a String to allow it to be parsed into a VARCHAR field in the db. Although I can't seem to work out how to edit the for loop I have to insert all the values at once.
Here is my current code:
Document doc = Jsoup.connect(URL).timeout(5000).get();
for (Element table : doc.select("table:first-of-type")) //selects first table
{
for (Element row : table.select("tr:gt(0)")) { //selects first table cell
Elements tds = row.select("td");//selects row
List1.add(tds.get(0).text());
List2.add(tds.get(1).text());
List3.add(tds.get(2).text());
}
}
PreparedStatement stmt = conn.prepareStatement("INSERT INTO Scores (Home, Score, Away) VALUES (?,?,?)");
String[] List1str = new String[List1.size()];
List1str = List1.toArray(List1str);
for (String s : List1str) {
stmt.setString(1, s);
stmt.setString(2, "test");
stmt.setString(3, "test");
stmt.executeUpdate();
}
for (int i = 0; i < dtm.getRowCount(); i++) {
for (int j = 0; j < dtm.getColumnCount(); j++) {
Object o = dtm.getValueAt(i, j);
System.out.println("object from table is : " + o);
pst.setString(j + 1, (String) o);
}
pst.executeUpdate();
pst.clearParameters();
}
Related
I have an hashmap with a key and value (Array of integers) HashMap<key, array> and I would like to retrieve data from a sql table with a column that matches the values in array stored in a hashmap
I can do this in two ways one getting all the data from table and iterating through hashmap and other being iterating through hashmap and applying the where clause in each iteration which makes n calls to database.
Is there an efficient way to do this other than the above ?
Use a PreparedStatement to set up a query having an IN condition in the WHERE clause. This snippet should give you the general idea:
values = new int[]{1,2,3,4,5};
String query =
"SELECT film_id, title\n"
+ "FROM film\n"
+ "WHERE film_Id IN (";
for (int i = 0; i < values.length; ++i) {
if (i > 0) {
query += ",";
}
query += "?";
}
query += ")";
try {
Connection conn = DriverManager.getConnection("db-url", "user", "pwd");
PreparedStatement stmt = conn.prepareStatement(query);
for (int i = 0; i < values.length; ++i)
stmt.setInt(i+1, values[i]);
ResultSet rs = stmt.executeQuery();
while (rs.next()){
// process results
}
} catch (Exception ex) {
ex.printStackTrace();
}
I want to be able to select any row, just 1 row specifically and edit its data.
The data is in a SQL Table.
I am using tableview with scenebuilder 2.
The Problem: The row I select does not update with new fields. Not sure If it recognizes the selection.
Code is posted Below
Sorry if I am not being fully clear, I will be happy to explain further if needed
Connection c;
data = FXCollections.observableArrayList();
for (int i = 0; i < rs.getMetaData().getColumnCount(); i++) {
//We are using non property style for making dynamic table
final int j = i;
TableColumn col = new TableColumn(rs.getMetaData().getColumnName(i + 1));
col.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<ObservableList, String>, ObservableValue<String>>() {
public ObservableValue<String> call(TableColumn.CellDataFeatures<ObservableList, String> param) {
return new SimpleStringProperty(param.getValue().get(j).toString());
}
});
tableview.getColumns().addAll(col);
System.out.println("Column [" + i + "] ");
}
/********************************
* Data added to ObservableList *
********************************/
while (rs.next()) {
//Iterate Row
ObservableList<String> row = FXCollections.observableArrayList();
for (int i = 1; i <= rs.getMetaData().getColumnCount(); i++) {
//Iterate Column
row.add(rs.getString(i));
}
System.out.println("Row [1] added " + row);
data.add(row);
}
//FINALLY ADDED TO TableView
tableview.setItems(data);
c.close();
} catch (Exception e) {
e.printStackTrace();
System.out.println("Error on Building Data");
}
////SELECT A ROW AND EDIT
String a =(String)tableview.getSelectionModel().getSelectedCells().toString();
String query = "UPDATE Frontdesk SET CustomerName = ? , Zip = ? , Make =? , Model=? , PhoneNumber =? WHERE CustomerName =? ";
PreparedStatement preparedStmt = c.prepareStatement(query);
preparedStmt.setString(1, txtCus);
preparedStmt.setString(2, txtzi);
preparedStmt.setString(3, txtMod);
preparedStmt.setString(4, txtMak);
preparedStmt.setString(5, txtPun);
preparedStmt.setString(6, a);
preparedStmt.executeUpdate();
This is a screenshot of the application:
I have a class it retrieve number of rows from database but here i return result set object to servlet class and based on those rows i need to display in table when i retrieve table it shows single row only but when i execute same query it shows in Database having two rows may be i didn't return result set object properly can anyone help me to retrieve all the all records from database.
Servlet :
WorkAreaClass wa=new WorkAreaClass();
ResultSet resultSet = wa.workarea(User);
if(resultSet.next())
{
table(resultSet,out);
}
You're calling if(resultSet.next()) before you start to iterate the resultset. After that you'll be on the first row. Then when you enter your while(rs.next()) loop, the cursor is moved to the second row.
You can convert the while loop into a do-while and it won't skip the first row.
Suppose #kayaman solution is correct.
Simply your table should be like this.
public int table( ResultSet rs, PrintWriter out)throws Exception
{
int rowcount=0;
out.println("<P ALIGN='center'><TABLE BORDER=1>");
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();
// table header
out.println("<TR>");
for (int i = 0; i < columnCount; i++) {
out.println("<TH>" + rsmd.getColumnLabel(i + 1) + "</TH>");
}
out.println("</TR>");
// the data
do {
rowcount++;
out.println("<TR>");
for (int i = 0; i < columnCount; i++) {
out.println("<TD>" + rs.getString(i + 1) + "</TD>");
}
out.println("</TR>");
} while(rs.next());
out.println("</TABLE></P>");
return rowcount;
}
You need to use JDBCRowSet https://docs.oracle.com/javase/tutorial/jdbc/basics/jdbcrowset.html
here is short demo:
Statement stmt = con.createStatement(
ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE);
ResultSet rs = stmt.executeQuery("select * from COFFEES");
JdbcRowSetImpl jdbcRs = new JdbcRowSetImpl(rs);
public cntctus()
{
column names for JTable
String column[]= { "Name","Position","Phone"};
rows for JTable
Object [][]row = {
{"Prof. Renu Vig", "Director", "+123456"},
{"Mr. Sukhbir singh", "Assistant Professor", "+9123568989"},
{"Ms. shaweta", "BI teacher","9468645"}
};
table = new JTable(row,column);
TableModel tm = table.getModel();
java.sql.Connection con=null;
try {
Class.forName("com.mysql.jdbc.Driver");
con=DriverManager.getConnection("jdbc:mysql://localhost:3306/training","root","");
try{
java.sql.Statement stmt =con.createStatement();
String maketable = "CREATE TABLE if not exists contacttable(Name Varchar(25),Position Varchar(20),Phone Varchar(20))";
stmt.executeUpdate(maketable);
System.out.print("table created ");
//insert into table contacttable query
PreparedStatement pstmt=con.prepareStatement("INSERT into contacttable select distinct values(?,?,?)");
get some TableModel that will contain the data
for (int i = 0; i < tm.getRowCount(); i++) {
for (int j = 0; j < tm.getColumnCount(); j++) {
Object o = tm.getValueAt(i, j);
System.out.println("object from table is : " +o);
k=j+1;
pstmt.setString(k, (String)o);
}
pstmt.executeUpdate();
}
}
catch(SQLException s)
{
System.out.println(s);
}
}
catch(Exception e)
{
e.printStackTrace();
}
I want to insert this whole object into database.in short how to insert jtable data into databse.?? please help.
error is: you have an error in your sql syntax at line 1 ('"prof. renu vig, "director"...
In the event that you want to have multiple rows on your prepared statement, you could just take what you have now and add a call to pstmt.addBatch() inside the outer loop, and outside the inner loop (the loops which iterate over the JTable, IE add batch once per row). Then after you have iterated over the whole table call pstmt.executeBatch().
A word to the wise though, if you are generating keys on insert, the drivers must also support returning multiple keys on batch inserts, or you will probably just get the first key generated back instead of all of them. Alternatively you could execute the statement each iteration of the outer loop (IE once per row), making sure to call .clearParamters() after each execution. You will want to reuse the preparedStatement for performance reasons.
Your insert statement is also screwed up. Its just going to be INSERT INTO contacttable VALUES(?,?,?). Get rid of the select distinct stuff.
It will probably look like this when its done:
String column[]= { "Name","Position","Phone"};
Object [][]row = {
{"Prof. Renu Vig", "Director", "+123456"},
{"Mr. Sukhbir singh", "Assistant Professor", "+9123568989"},
{"Ms. shaweta", "BI teacher","9468645"}
};
JTable table = new JTable(row,column);
TableModel tm = table.getModel();
java.sql.Connection con=null;
try
{
Class.forName("com.mysql.jdbc.Driver");
con=DriverManager.getConnection("jdbc:mysql://localhost:3306/training","root","");
java.sql.Statement stmt =con.createStatement();
String maketable = "CREATE TABLE if not exists contacttable(Name Varchar(25),Position Varchar(20),Phone Varchar(20))";
stmt.executeUpdate(maketable);
System.out.print("table created ");
PreparedStatement pstmt=con.prepareStatement("INSERT INTO contacttable VALUES(?,?,?)");
for (int i = 0; i < tm.getRowCount(); i++) {
for (int j = 0; j < tm.getColumnCount(); j++) {
Object o = tm.getValueAt(i, j);
System.out.println("object from table is : " +o);
pstmt.setString(j+1, (String)o);
}
pstmt.executeUpdate();
pstmt.clearParameters();
}
}
catch (Exception e) {
e.printStackTrace();
}
The Only one change You have to do with your Code i.e
for (int i = 0; i < tm.getRowCount(); i++) {
for (int j = 0; j < tm.getColumnCount(); j++) {
Object o = tm.getValueAt(i, j);
System.out.println("object from table is : " +o);
pstmt.setObject(j+1, o);
it will send your actual JTable data into your Database file.
i am sure. it will work work.
i have an exemple with jpa i hope that it help you
try{
TableModel tm= table.getModel();
for (int i = 0; i < tm.getRowCount(); i++) {
Object NumeroCin=tm.getValueAt(i, 0);
Object Nomprenom=tm.getValueAt(i, 1);
Object Tel =tm.getValueAt(i, 2);
Object Adresse =tm.getValueAt(i, 3);
Object DateNaissance=tm.getValueAt(i, 5);
Object Sexe=tm.getValueAt(i, 4);
Etudiant e=new Etudiant();
e.setAdresse((String) Adresse);
e.setDateNaissance((String) DateNaissance);
e.setNomprenom((String) Nomprenom);
e.setNumeroCin((String) NumeroCin);
e.setSexe( (String) Sexe );
e.setTel((String) Tel);
Ajouterobjet(e);
}}}
catch (Exception e) {
e.printStackTrace();
}
public void Ajouterobjet(Object o)
{
EntityTransaction tx=entityManager.getTransaction();
tx.begin();
entityManager.persist(o);
tx.commit();
}
The code below displays the tuples of an specific table. How can I turn this into dynamic code? So the user would enter the name of the table, then the rows and column names in addition to the content of the table are displayed.
* Keep in mind that res.getInt and res.getString need to be specified as they are. In a dynamic model, I wouldn't need to know the number, type, and name of the columns. *
public void displayTableA()
{
//Connection already established
Statement st = conn.createStatement();
ResultSet res = st.executeQuery("SELECT * FROM A");
System.out.println("A_code: " + "\t" + "A_name: ");
while (res.next()) {
int r = res.getInt("A_code");
String s = res.getString("A_name");
System.out.println(r + "\t\t" + s);
}
conn.close();
}
Direct answer: The query is just a string. You can build it up from user inputs. Like read the name of the table into a variable, say "String tablename", then
String query="select * from " + tablename;
Then you run the query to get the result set:
ResultSet rs=st.executeQuery(query);
Then get the meta data for the result set:
ResultSetMetaData meta=rs.getMetaData();
Then loop through the columns getting their names:
for (int x=1;x<=meta.getColumnCount();++x)
{
String columnName=meta.getColumnName(x);
... do whatever you want with this column name ...
}
(Note the columns are numbered starting from 1, not 0.)
As to the data itself, if you're just dumping it out, you don't need to know the type. Just do getString on everything. Every data type can be converted to a string. Well, if you have blobs or images you might want to check for those. There's a ResultSetMetaData function to get the column type, I think it's getType or something like that. Check the javadocs.
That said, why do you want to do this? If you're building some sort of tool to be used by developers to do ad hoc queries, okay fine. But I would be extremely cautious about exposing something like this to end users. (a) They would be unlikely to understand the data, and (b) You'd be creating a huge security hole, users could see ANY data in the system. You could potentially wrap this in checks to limit the users to what they're authorized to see, but it's a lot of work to get that right. It's a lot easier to say "here's what you are allowed to see" then to try to say "here's what you're not allowed to see".
public void displayTable(String table)
{
//Connection already established
Statement st = conn.createStatement();
ResultSet res = st.executeQuery("SELECT * FROM " + table);
ResultSetMetaData rsmd = res.getMetaData();
while (res.next()) {
for(int ii = 1; ii <= rsmd.getColumnCount(); ii++) {
// get type
int type = rsmt.getColumnType(ii);
String value = null;
switch (type) {
case Types.VARCHAR: value = res.getString(ii); break;
}
// print value.
System.out.print(rsmd.getColumnName(ii) + ": " + value);
}
}
conn.close();
}
If you want print a ResultSet in a dynamic query converting a instance of ResultSet in String:
public static String toString(ResultSet rs) throws SQLException {
StringBuilder sb = new StringBuilder();
ResultSetMetaData metaData = rs.getMetaData();
int columnCount = metaData.getColumnCount();
Map<Integer, Integer> sizeMap = new HashMap<>();
for (int column = 1; column <= columnCount; column++) {
int size = Math.max(metaData.getColumnDisplaySize(column), metaData.getColumnName(column).length());
sizeMap.put(column, size);
sb.append(StringUtils.rightPad(metaData.getColumnName(column), size));
sb.append(' ');
sb.append(' ');
}
sb.append('\n');
for (int column = 1; column <= columnCount; column++) {
sb.append(StringUtils.rightPad("", sizeMap.get(column), '-'));
sb.append(' ');
sb.append(' ');
}
while(rs.next()) {
sb.append('\n');
for (int columnIndex = 1; columnIndex <= columnCount; columnIndex++) {
String str = rs.getString(columnIndex);
if (str == null) {
str = "(null)";
}
sb.append(StringUtils.rightPad(str, sizeMap.get(columnIndex)));
sb.append(' ');
sb.append(' ');
}
}
return sb.toString();
}
For print something like that:
user_id user_code date_update
------------ -------------------- -------------------
01006393 00989573 2011-09-29 19:23:46
00984742 20192498 2011-12-21 00:00:00
This method use Commons Lang 3
Note: You should use this with care for avoid memory errors. You can change the sb.append with System.out.print or System.out.println