How to run progress bar while executing the mysql query in java? - java

I want to delete duplicate record in my database table, and I do it in java by using this query
String sql = "DELETE e1 FROM tweet_after_preprocessing e1, tweet_after_preprocessing e2 WHERE e1.tweet = e2.tweet AND e1.tweet_after_preprocessing_id > e2.tweet_after_preprocessing_id"
The problem is when there are so many records in my database table, the process will take so long, and make my program look not curently running.
and I want to use progress bar to show progress of the executing, how can I do that?. I don't now the maximum and the minimum value, so how can i accessing the progress bar?.

You can create an indeterminate progress bar by setting the property indeterminate to true: JProgressBar.html#setIndeterminate().
Also it is wise to not execute long lasting work in the EDT but use a different thread for this.

The problem is that you're doing all your work on the EDT, which is blocking your GUI. You need to do the loading on another Thread, so your GUI can still update, display, and respond to user input.
Once you have the work on another thread, then from that thread, you can post updates to the EDT using the SwingUtilities.invokeLater() method.
You could also look into the SwingWorker class, which handles some of that for you.
Recommended reading: http://docs.oracle.com/javase/tutorial/uiswing/concurrency/

Excellent question.
Jenkins uses the time of the last build to guess how long the current build will take to run. So for example if the last time a build ran it took 10 minutes, and it is 5 minutes into a current build it will show that it is 50% complete.
You can do something similar. Maybe query the DB first to see how many items need to be deleted and have a table of how long it will take for the amount of items being deleted and how many items are in the table.

Related

Implementing a refreshing table with threads

I'm doing a Swing application where in one of its forms, I have a table which I want to update periodically. I first thought of using a Timer, but the task may be time consuming and it may freeze the GUI. Then, I thought of using a SwingWorker, but it is designed to be executed once, and I need to execute this task periodically (every two or three minutes) while the form is open.
In this form's code I have implemented three methods: acceptNew(), which runs a quick UPDATE query, listRequests(), which runs some queries to fill an ArrayList with all the records; and manipulateTable(), which compares the table model with the ArrayList and updates/inserts the records.
In short, acceptNew() does a quick task, listRequests() does another task which its completion time depends of the number of records in the DB, and manipulateTable() updates the GUI. I need to call these three methods periodically without freezing the GUI.
You can use SwingWorker's publish to emit the new state of listRequests() that you call manipulateTable() in the process method and sleep inbetween.
Or just create and submit a new SwingWorker that updates it once every time from a Timer.

How to create JProgressBar for executeUpdate()

My little application uploads table to a database .
Connection ....
...
...
PreparedStatement ps ...
ps.executeUpdate() ; // this takes a while so I want to create a progress bar
How can I track progress of ps.executeUpdate() ? Can anybody post a java code to do that ? I need to create a progress bar
(My database is Teradata)
You can leverage the Performance Monitor and Performance Control (PMPC) Open APIs using SQL to monitor the progress of a session as it executes a SQL Statement in Teradata 13 and higher.
Get Completed Steps, Host, RunVProcNo for all sessions running as user:
SELECT HostID
, RunVProcNo
, ReqStepsCompletedCnt
FROM TABLE(MonitorSession(-1,'{username}', 0)) AS T2;
You can always obtain the current session for a given connection by running:
SELECT SESSION;
With the Session Number in hand you can isolate the number of records returned by the previous MonitorSession() call.
Get Total Number of Steps for SQL being executed:
SELECT MAX(StepNum) AS TotalNumSteps
FROM TABLE(MonitorSQLSteps({Host},{Session},{RunVProcNo)) AS T1;
With those two statements you should be able to track how something is progressing to update a progress bar in the application. `
There are several possibilities to display "something is happening". But the problem is, you have no progress indicator or listener on a database statement.
"A direct tracking of progress in the database management system is not possible." Regarding this I was corrected by the other answerer. So there are possibilities to track the progress but these are very database specific. So this is also a way to go if you have only TeraData in mind.
So here are some other possibilities to produce some kind of process feedback:
Slice your update in multiple steps (n) (if it is possible). You know how many steps you have to go, that would be your 100 percent. Every step should increase your progressbar by 100/n percent.
This splitting of your SQL is not always a way to go. Therefore you could display a work in progress indicator (an indetermined one).
You could guess the time to process and build a progressbar on that value, like windows does on file copy.
In every case your database processing should happen in a worker thread (different from EDT), but for sure you are aware of that.

How to Display a Database data in jtextarea by using time delay?

int time = 0;
time++; // set by 1second
int countdata = 0; // countdata queried by table shows the numbers of table values
rs = stmt.executeQuery("SELECT ID,test From Table");
StringBuilder strBuilder = new StringBuilder();
while (rs.next()) {
strBuilder.append(rs.getString(0)).append(" ").append(rs.getString(1));
strBuilder.append("\n");
if(time <= countdata){
// this is my idea but i dont know how to fetch the data each row
}
jtextarea.setText(strBuilder.toString());
}
the output is like this:
// time 1 seconds
test1
// time 2 seconds
test2
// time 3 reconds
test3
//until it reach the last data of table
please help
i want to fetch data by every 1 second until it reach the last value. the time is fix by 1 second delay. every 1 second shows the row of data.
You have two basic choices (there are others, but lets keep it simple...)
Basically, you want to perform the query in some kind of background thread but ensure that the updates to the UI are carried out within the context of the Event Dispatching Thread...
This ensures that while the query is taking place, the UI remains responsive to the user and to won't make it look like your application has crashed...
You Could...
Use a Swing Timer to schedule a call back every n milliseconds. The benefit of this is that it the callback is triggered within the context of the Event Dispatching Thread.
The drawback is that the callback is triggered within the context of the Event Dispatching Thread.
The main problem I see is you don't want to be querying the database from the context of the EDT as this will prevent it from performing updates to the UI and remaining responsive to the user while the processing is occurring.
Now you could spawn another Thread at this stage, but the problem is, the time it takes to complete the query may be more than the time allocated between updates, meaning that it would be possible for last query to still be running when the next one is triggered. You also run into issues with having to synchronise updates to the UI manually, while not especially difficult, why would you want to make life more difficult ;)
Take a look at How to Use Swing Timers and Concurrency in Swing for more details
You Could...
Use a SwingWorker. This will allow you to perform the query in a background thread while providing you with functionality to send updates back to the Event Dispatching Thread so the UI can be updated properly.
The drawback with this is that the SwingWorker doesn't have timer concept of it's own, but, you could simply use Thread.sleep.
Now, depending on whether you want regular updates; ie they MUST occur every second, exactly, or delayed updates; ie they must occur every second AFTER the last update will depend on how you use this, but what this means is you gain control.
Basically what this means is, you can ensure that only one query is been executed at a time and control the amount of time before the next one.
Take a look at Worker Threads and SwingWorker for more details

constantly check database [duplicate]

I'm using JDBC, need to constantly check the database against changing values.
What I have currently is an infinite loop running, inner loop iterating over a changing values, and each iteration checking against the database.
public void runInBG() { //this method called from another thread
while(true) {
while(els.hasElements()) {
Test el = (Test)els.next();
String sql = "SELECT * FROM Test WHERE id = '" + el.getId() + "'";
Record r = db.getTestRecord(sql);//this function makes connection, executeQuery etc...and return Record object with values
if(r != null) {
//do something
}
}
}
}
I'm think this isn't the best way.
The other way I'm thinking is the reverse, to keep iterating over the database.
UPDATE
Thank you for the feedback regarding timers, but I don't think it will solve my problem.
Once a change occurs in the database I need to process the results almost instantaneously against the changing values ("els" from the example code).
Even if the database does not change it still has to check constantly against the changing values.
UPDATE 2
OK, to anyone interested in the answer I believe I have the solution now. Basically the solution is NOT to use the database for this. Load in, update, add, etc... only whats needed from the database to memory.
That way you don't have to open and close the database constantly, you only deal with the database when you make a change to it, and reflect those changes back into memory and only deal with whatever is in memory at the time.
Sure this is more memory intensive but performance is absolute key here.
As to the periodic "timer" answers, I'm sorry but this is not right at all. Nobody has responded with a reason how the use of timers would solve this particular situation.
But thank you again for the feedback, it was still helpful nevertheless.
Another possibility would be using ScheduledThreadPoolExecutor.
You could implement a Runnable containing your logic and register it to the ScheduledExecutorService as follows:
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(10);
executor.scheduleAtFixedRate(myRunnable, 0, 5, TimeUnit.SECONDS);
The code above, creates a ScheduledThreadPoolExecutor with 10 Threads in its pool, and would have a Runnable registered to it that will run in a 5 seconds period starting immediately.
To schedule your runnable you could use:
scheduleAtFixedRate
Creates and executes a periodic action that becomes enabled first after the given initial delay, and subsequently with the given period; that is executions will commence after initialDelay then initialDelay+period, then initialDelay + 2 * period, and so on.
scheduleWithFixedDelay
Creates and executes a periodic action that becomes enabled first after the given initial delay, and subsequently with the given delay between the termination of one execution and the commencement of the next.
And here you can see the advantages of ThreadPoolExecutor, in order to see if it fits to your requirements. I advise this question: Java Timer vs ExecutorService? too in order to make a good decision.
Keeping the while(true) in the runInBG() is a bad idea. You better remove that. Instead you can have a Scheduler/Timer(use Timer & TimerTask) which would call the runInBG() periodically and check for the updates in the DB.
u could use a timer--->
Timer timer = new Timer("runInBG");
//Taking an instance of class contains your repeated method.
MyClass t = new MyClass();
timer.schedule(t, 0, 2000);
As you said in the comment above, if application controls the updates and inserts then you can create a framework which notifies for 'BG' thread or process about change in database. Notification can be over network via JMS or intra VM using observer pattern or both local and remote notifications.
You can have generic notification message like (it can be class for local notification or text message for remote notifications)
<Notification>
<Type>update/insert</Type>
<Entity>
<Name>Account/Customer</Name>
<Id>id</Id>
<Entity>
</Notification>
To avoid a 'busy loop', I would try to use triggers. H2 also supports a DatabaseEventListener API, that way you wouldn't have to create a trigger for each table.
This may not always work, for example if you use a remote connection.
UPDATE 2
OK, to anyone interested in the answer I believe I have the solution now. Basically the solution is NOT to use the database for this. Load in, update, add, etc... only whats needed from the database to memory. That way you don't have to open and close the database constantly, you only deal with the database when you make a change to it, and reflect those changes back into memory and only deal with whatever is in memory at the time. Sure this is more memory intensive but performance is absolute key here.

java (jdbc, ms sql server) how to get an indication that my query was executed?

My application does queries to database (non-queries too).
I show to the user indeterminate progressbar while transaction.
The problem is that I don't know when to close the progressbar, because I have no indication or signal object of query completion.
If your queries are taking so long that you need a progress bar, I'd recommend taking a hard look at your database to see how you can speed them up.
Since a database operation blocks, you know it's done when you return.
The progress bar suggests that you need some kind of polling mechanism to check a metric that indicates how much you have to do and how many have been done. Since you don't give any details, I can only guess what those might be.
But an AJAX call in your JSP to poll and update the progress bar is most likely what you need.

Categories

Resources