How can refresh a ResultSet in Java - mysql

I want to use a MySQL with JDBC in a loop, because I have to poll a table frequently for new data which comes in from other clients. But even if I close the ResultSet, the connection and the statement, is the old result at the next round still there. I cannot get a new result, unless I restart the program. What is my mistake?
I condensed the code for the necessary.
import java.sql.*;
public class Eventmgr {private static String in_text;
private static String in_typ;
private static Connection connection;
private static String URL = "jdbc:mysql://xxx.xxx.x.x:3306/xxxx";
private static String username = "xxx";
private static String password = "xxx";
public static void start() throws SQLException {
while(loop_count > 0) {
if (loop == false) {
loop_count = loop_count -1;}
connection = DriverManager.getConnection(URL, username, password);
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery("select id, nummer, text, typ from inbox order by id asc limit 1") ;
while(rs.next()) {
in_id = rs.getString("id");
in_nummer = rs.getString("nummer");
in_text = rs.getString("text");
in_typ = rs.getString("typ");}
connection.close();
stmt.close();
rs.close();
System.out.println("still running");
}
}
}
Anybody has an idea what my problem is?
Thanks in advance

I am stupid, and it was my mistake...
The problem is. I check on the variable "in_id" and if there is no new result "while(rs.next())" dont deliver a new value, so I need to reset that variable with "in_id = null;" at the end of the loop.
Now it works...

Related

how can i connect to my database sql in a java class method and called it in another class?

i'm trying to create a desktop application using corba and java swing for graphical interface.
As you know , in CORBA we have to make the principal methods like: connecting to the database ,calculations... in the server ,so i have created a method in a server class for connecting to the database.
The java class method is the one shown bellow:
public void connect_db(){
// TODO Auto-generated method stub
JTextField txtUsername = FrameLogin.txtUsername;
JPasswordField pwd= FrameLogin.pwd;
JLabel lblLoginMessage= FrameLogin.lblLoginMessage;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
Connection conn =(Connection)DriverManager.getConnection("jdbc:mysql://localhost:3306/utilisateurs","root", "Mrayhana123");
Statement stm = conn.createStatement();
String sql="select * from etudiant where username='"+txtUsername+"' and pwd='"+pwd+"'";
ResultSet result = stm.executeQuery(sql);
if(result.next()){
lblLoginMessage.setText("you are connected");
lblLoginMessage.setForeground(Color.GREEN);
}
else {
lblLoginMessage.setText("Incorrect username or password!");
lblLoginMessage.setForeground(Color.RED);
}
} catch(Exception e){
//System.out.println("not connected to database");
e.printStackTrace();
}
}
And i have called it in the client class which contain the graphical interface by the following way:
public static JTextField txtUsername;
public static JPasswordField pwd;
public static JLabel lblLoginMessage = new JLabel("");
pnlBtnlogin.addMouseListener(new MouseAdapter() {
#Override
String username = txtUsername.getText();
String pwd= pwd.getText();
try {
SraCorbaImpl sci = new SraCorbaImpl();
sci.connect_db();
} catch(Exception e1){
//System.out.println("not connected to database");
e1.printStackTrace();
}
But the result always shows me Incorrect username or password! even though I type a username and a password which are in the database.
THANK YOU FOR HELPING ME
According to your comment, I understand that you are successfully connecting to the database but your query is not returning any rows.
If the code in your question is your actual code, then you are passing a JTextField to your [SQL] query and not the text of the JTextField. Likewise with the password. You are passing the JPasswordField and not the actual password.
Try the below code.
public void connect_db(){
JTextField txtUsername = FrameLogin.txtUsername;
JPasswordField pwd= FrameLogin.pwd;
JLabel lblLoginMessage= FrameLogin.lblLoginMessage;
try {
// Class.forName("com.mysql.cj.jdbc.Driver"); <- not required
Connection conn =(Connection)DriverManager.getConnection("jdbc:mysql://localhost:3306/utilisateurs","root", "Mrayhana123");
Statement stm = conn.createStatement();
String sql="select * from etudiant where username='"+txtUsername.getText()+"' and pwd='"+pwd.getText()+"'"; // Change here.
ResultSet result = stm.executeQuery(sql);
if(result.next()){
lblLoginMessage.setText("you are connected");
lblLoginMessage.setForeground(Color.GREEN);
}
else {
lblLoginMessage.setText("Incorrect username or password!");
lblLoginMessage.setForeground(Color.RED);
}
} catch(Exception e){
//System.out.println("not connected to database");
e.printStackTrace();
}
Because you are using string concatenation, the toString of JTextField is being inserted into your SQL string.
Consider using a PreparedStatement instead.
String sql="select * from etudiant where username=? and pwd=?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, txtUsername.getText());
ps.setString(2, pwd.getText());
In that case, if you omit the .getText(), the code will not compile.

Insert int from class to database (mysql)

I have two classes, from which I want one int number (first code) inserted into a database. The only thing I found so far is with a prepared statement, but I want the int from "freeparking" inserted into the database (second code) every hour. I have prepared a sleep thread already, which lets my second code initiate every full hour. But I am not sure how to insert the integer with my database. Thanks for your help in advance!
private void setFreieparkplätze(int freeparking) {
this.freeparking = freeparking;
}
int freeparking = vehiclenumber.getParking();
}
static Connection connection = null;
static String databaseName = "";
static String url = "jdbc:mysql://localhost:3306/tiefgarage?autoReconnect=true&useSSL=false" + databaseName;
static String username = "";
static String password = "";
public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException, SQLException {
Class.forName("com.mysql.jdbc.Driver").newInstance();
connection = DriverManager.getConnection(url, username, password);
**PreparedStatement ps = connection.prepareStatement("INSERT Into parkinglot(Numbers) VALUES (?)");** // ???
int status = ps.executeUpdate();
if (status != 0) {
System.out.println("Database connected");
System.out.println("Record was inserted");
}
I repeat my comment as answer to make it visible to anyone.
The query to add an integer in a db shoould be like:
INSERT Into parkinglot(Numbers) VALUES ("+ getFreeparking() +");
Note that Numbers (table column) has to be integer type and getFreeparking() is just a getter for freeparking int variable.

Does h2 have a query/clause similar to the WHERE IN in MySQL?

My code currently goes as follows:
public List<DeviceOrganizationMetadataHolder> getChildrenByParentId(List<String> parentIds) throws DeviceOrganizationDAOException {
List<DeviceOrganizationMetadataHolder> children = new ArrayList<>();
Connection conn;
PreparedStatement stmt = null;
ResultSet rs = null;
DeviceOrganizationMetadataHolder deviceMetadataHolder;
String[] data = parentIds.toArray(new String[parentIds.size()]);
try {
conn = this.getConnection();
String sql = "SELECT * FROM DEVICE_ORGANIZATION_MAP WHERE DEVICE_PARENT IN (?)";
stmt = conn.prepareStatement(sql);
data = parentIds.toArray(data);
stmt.setObject(1, data);
rs = stmt.executeQuery();
while (rs.next()) {
deviceMetadataHolder = this.loadOrganization(rs);
children.add(deviceMetadataHolder);
}
} catch (SQLException e) {
throw new DeviceOrganizationDAOException("Error occurred for device list with while retrieving children.", e);
} finally {
DeviceManagementDAOUtil.cleanupResources(stmt, rs);
return children;
}
}
However even though in the unit tests I try to pass an array with parentIds, the return remains null.
What I can gauge from this is one of the following:
The array data isn't getting properly read, therefore the output is coming as null.
WHERE IN is not supported by h2 or else there is a different implementation that needs to be used instead.
Where am I going wrong in this?
EDIT - There was a similar duplicate question that was tagged. While it suggested using a StringBuilder and a loop, I was looking for an answer stating how it could be done in a cleaner way using the query itself.
Try setting the parameter as a list instead of an array, ie replace
stmt.setObject(1, data);
with
stmt.setObject(1, Arrays.asList(data));
Figured it out.
There was an issue posted on the h2database GitHub about this exact problem. Followed the suggested edits and it worked!
Code after edits is as follows:
public List<DeviceOrganizationMetadataHolder> getChildrenByParentId(List<String> parentIds) throws DeviceOrganizationDAOException {
List<DeviceOrganizationMetadataHolder> children = new ArrayList<>();
Connection conn;
PreparedStatement stmt = null;
ResultSet rs = null;
DeviceOrganizationMetadataHolder deviceMetadataHolder;
Object[] data = parentIds.toArray();
try {
conn = this.getConnection();
String sql = "SELECT * FROM DEVICE_ORGANIZATION_MAP WHERE DEVICE_PARENT IN (SELECT * FROM TABLE(x VARCHAR = ?))";
stmt = conn.prepareStatement(sql);
stmt.setObject(1, data);
rs = stmt.executeQuery();
while (rs.next()) {
deviceMetadataHolder = this.loadOrganization(rs);
children.add(deviceMetadataHolder);
}
} catch (SQLException e) {
throw new DeviceOrganizationDAOException("Error occurred for device list with while retrieving children.", e);
} finally {
DeviceManagementDAOUtil.cleanupResources(stmt, rs);
return children;
}
}
As you can see, I've used an Object array for data instead and added an additional query inside the main query.
Followed the instructions given in the GitHub issue to a tee and it worked flawlessly.

Displaying Database records to JTable in JAVA swing

I am trying to display the database records in the Jtable but i m not getting the code right. I m using IDE netbeans and database is mysql. I can see the panel and the scroll pane but the table is not displayed. I think something is wrong in the table properties or dont know if its invisible.
My code is as follows:
try{
panel_paylist.setVisible(true);
String dbUrl = "jdbc:mysql://localhost/hostel";
String dbClass = "com.mysql.jdbc.Driver";
Class.forName("com.mysql.jdbc.Driver");
Connection conn=DriverManager.getConnection(dbUrl,"root","17121990");
System.out.println("Connected!!!!");
MainScreen obj = new MainScreen(conn);
String[] columnNames = {"First Name",
"Last Name",
"Amount Recvd.",
"Date","Cheque/cash","cheque no","Balance Amt.","Total Amt.",
"Vegetarian"};
ResultSet rs = null;
Statement sql= null;
ArrayList<Object[]> data = new ArrayList<>();
String query="SELECT firstname,lastname, amountreceivd,dte,creditcashcheque,cheque_no,balance_amt, totalamount,Remark FROM payment;";
sql = con.createStatement();
sql.executeQuery(query);
rs = sql.getResultSet();
while(rs.next()){
Object[] row = new Object[]{rs.getString(1),
rs.getString(2),
rs.getInt(3),
rs.getString(4),
rs.getString(5),
rs.getString(6),
rs.getInt(7),
rs.getInt(8),
rs.getString(9)};
data.add(row);
}
Object[][] realData = data.toArray(new Object[data.size()][]);
table_paylist= new JTable(realData, columnNames);
scroll_paylist= new JScrollPane(table_paylist);
table_paylist.setPreferredScrollableViewportSize(new Dimension(800, 200));
table_paylist.setFillsViewportHeight(true);
panel_paylist.setLayout(new BorderLayout());
panel_paylist.add(scroll_paylist, BorderLayout.CENTER);
}
catch(Exception e)
{
}
please help
first of all you are missing port number of localhost.
change
"jdbc:mysql://localhost/hostel"
to
"jdbc:mysql://localhost:3306/hostel";
second point dont use semicolon(;) at the end of sql string. i. e. remove semicolon from
"SELECT firstname,lastname, amountreceivd,dte,creditcashcheque,cheque_no,balance_amt, totalamount,Remark FROM payment;"
and you can also try this one
public DefaultTableModel PlayList() throws ClassNotFoundException,SQLException,ParseException
{
String[] columnNames = {"First Name","Last Name","Amount Recvd.","Date","Cheque/cash","cheque no","Balance Amt.","Total Amt.","Vegetarian"};
DefaultTableModel dtm = new DefaultTableModel(columnNames , 0);
dtm.setColumnCount(9);
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:8080/hostel","root","17121990");
PreparedStatement ps1 = null;
ResultSet rs1 = null;
try
{
Class.forName("com.mysql.jdbc.Driver");
ps1=conn.prepareStatement("SELECT firstname,lastname,mountreceivd,dte,creditcashcheque,cheque_no,balance_amt,totalamount,Remark FROM payment");
rs1 = ps1.executeQuery();
while(rs1.next())
{
dtm.addRow(new Object[]{rs1.getString(1)
rs.getString(2),
rs.getInt(3),
rs.getString(4),
rs.getString(5),
rs.getString(6),
rs.getInt(7),
rs.getInt(8),
rs.getString(9)});
}
}
finally
{
rs1.close();
ps1.close();
conn.close();
}
return dtm;
}
now use PlayList() method as a argument of your jtable's setmodel method;
i. e. jtable.setmodel(PlayList());
Use rs2xml third party Jar file to display query results.This is very helpful

Am I Using JDBC Connection Pooling?

I am trying to determine if I am actually using JDBC connection pooling. After doing some research, the implementation almost seems too easy. Easier than a regular connection in fact so i'd like to verify.
Here is my connection class:
public class DatabaseConnection {
Connection conn = null;
public Connection getConnection() {
BasicDataSource bds = new BasicDataSource();
bds.setDriverClassName("com.mysql.jdbc.Driver");
bds.setUrl("jdbc:mysql://localhost:3306/data");
bds.setUsername("USERNAME");
bds.setPassword("PASSWORD");
try{
System.out.println("Attempting Database Connection");
conn = bds.getConnection();
System.out.println("Connected Successfully");
}catch(SQLException e){
System.out.println("Caught SQL Exception: " + e);
}
return conn;
}
public void closeConnection() throws SQLException {
conn.close();
}
}
Is this true connection pooling? I am using the connection in another class as so:
//Check data against database.
DatabaseConnection dbConn = new DatabaseConnection();
Connection conn;
ResultSet rs;
PreparedStatement prepStmt;
//Query database and check username/pass against table.
try{
conn = dbConn.getConnection();
String sql = "SELECT * FROM users WHERE username=? AND password=?";
prepStmt = conn.prepareStatement(sql);
prepStmt.setString(1, user.getUsername());
prepStmt.setString(2, user.getPassword());
rs = prepStmt.executeQuery();
if(rs.next()){ //Found Match.
do{
out.println("UserName = " + rs.getObject("username") + " Password = " + rs.getObject("password"));
out.println("<br>");
} while(rs.next());
} else {
out.println("Sorry, you are not in my database."); //No Match.
}
dbConn.closeConnection(); //Close db connection.
}catch(SQLException e){
System.out.println("Caught SQL Exception: " + e);
}
Assuming that it's the BasicDataSource is from DBCP, then yes, you are using a connection pool. However, you're recreating another connection pool on every connection acquirement. You are not really pooling connections from the same pool. You need to create the connection pool only once on application's startup and get every connection from it. You should also not hold the connection as an instance variable. You should also close the connection, statement and resultset to ensure that the resources are properly closed, also in case of exceptions. Java 7's try-with-resources statement is helpful in this, it will auto-close the resources when the try block is finished.
Here's a minor rewrite:
public final class Database {
private static final BasicDataSource dataSource = new BasicDataSource();
static {
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/data");
dataSource.setUsername("USERNAME");
dataSource.setPassword("PASSWORD");
}
private Database() {
//
}
public static Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
}
(this can if necessary be refactored as an abstract factory to improve pluggability)
and
private static final String SQL_EXIST = "SELECT * FROM users WHERE username=? AND password=?";
public boolean exist(User user) throws SQLException {
boolean exist = false;
try (
Connection connection = Database.getConnection();
PreparedStatement statement = connection.prepareStatement(SQL_EXIST);
) {
statement.setString(1, user.getUsername());
statement.setString(2, user.getPassword());
try (ResultSet resultSet = preparedStatement.executeQuery()) {
exist = resultSet.next();
}
}
return exist;
}
which is to be used as follows:
try {
if (!userDAO.exist(username, password)) {
request.setAttribute("message", "Unknown login. Try again.");
request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
} else {
request.getSession().setAttribute("user", username);
response.sendRedirect("userhome");
}
} catch (SQLException e) {
throw new ServletException("DB error", e);
}
In a real Java EE environement you should however delegate the creation of the DataSource to the container / application server and obtain it from JNDI. In case of Tomcat, see also for example this document: http://tomcat.apache.org/tomcat-6.0-doc/jndi-resources-howto.html
Doesn't seem like it's pooled. You should store the DataSource in DatabaseConnection instead of creating a new one with each getConnection() call. getConnection() should return datasource.getConnection().
Looks like a DBCP usage. If so, then yes. It's already pooled. And here is the default pool property value of the DBCP.
/**
* The default cap on the number of "sleeping" instances in the pool.
* #see #getMaxIdle
* #see #setMaxIdle
*/
public static final int DEFAULT_MAX_IDLE = 8;
/**
* The default minimum number of "sleeping" instances in the pool
* before before the evictor thread (if active) spawns new objects.
* #see #getMinIdle
* #see #setMinIdle
*/
public static final int DEFAULT_MIN_IDLE = 0;
/**
* The default cap on the total number of active instances from the pool.
* #see #getMaxActive
*/
public static final int DEFAULT_MAX_ACTIVE = 8;
As a follow up to BalusC's solution, below is an implementation that I can be used within an application that requires more than one connection, or in a common library that would not know the connection properties in advance...
import org.apache.commons.dbcp.BasicDataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.concurrent.ConcurrentHashMap;
public final class Database {
private static final ConcurrentHashMap<String, BasicDataSource> dataSources = new ConcurrentHashMap();
private Database() {
//
}
public static Connection getConnection(String connectionString, String username, String password) throws SQLException {
BasicDataSource dataSource;
if (dataSources.containsKey(connectionString)) {
dataSource = dataSources.get(connectionString);
} else {
dataSource = new BasicDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl(connectionString);
dataSource.setUsername(username);
dataSource.setPassword(password);
dataSources.put(connectionString, dataSource);
}
return dataSource.getConnection();
}
}