Only getting first row from table in jdbc - java

I only get the first row from table, from a JDBC call.
Below is my code
import java.util.*;
import java.sql.*;
public class TrainManagementSystem {
public ArrayList <Train> viewTrain (String coachType, String source, String destination){
Connection myCon = null;
PreparedStatement myStat = null;
ResultSet myRes = null;
ArrayList<Train> result = new ArrayList<>();
try{
myCon = DB.getConnection();
myStat = myCon.prepareStatement("select * from train where source = ? and destination = ? and ? > 0");
myStat.setString(1, source);
myStat.setString(2, destination);
myStat.setString(3, coachType);
myRes = myStat.executeQuery();
while(myRes.next()){
int train_number = myRes.getInt("train_number");
String train_name = myRes.getString("train_name");
String source1 = myRes.getString("source");
String destination1 = myRes.getString("destination");
int ac1 = myRes.getInt("ac1");
int ac2 = myRes.getInt("ac2");
int ac3 = myRes.getInt("ac3");
int sleeper = myRes.getInt("sleeper");
int seater = myRes.getInt("seater");
System.out.println(myRes.getString("train_name"));
Train train = new Train(train_number, train_name, source1, destination1, ac1, ac2, ac3, sleeper, seater);
result.add(train);
return result;
}
}catch(Exception e){
System.out.println(e);
}
return result;
}
}
I only get the first row in result set in JDBC. The query is not retrieving the second row.
I have attached my entries in table.
When giving input as
Why is it not going to next row? When I try removing coachtype and only search for train between Howrah and Dehradun, it gives me result Dehradun Mail whereas the result should add Doon Express as well.

Because you have a return result; inside your while loop.
Move it line down outside of the loop

Related

Make custom code to reduce number of repetitive lines

I have to get 'tags' from the database and store them in an array so I could check if my document contains them. Due to the number of tag categories (customers, system_dependencies, keywords) I have multiple arrays to compare my document with. Is there an easy way to simplify and make my code look nicer?
This is my approach but it looks terrible with all the repetitive for loops.
ArrayList<String> KEYWORDS2 = new ArrayList<String>();
ArrayList<String> CUSTOMERS = new ArrayList<String>();
ArrayList<String> SYSTEM_DEPS = new ArrayList<String>();
ArrayList<String> MODULES = new ArrayList<String>();
ArrayList<String> DRIVE_DEFS = new ArrayList<String>();
ArrayList<String> PROCESS_IDS = new ArrayList<String>();
while (resultSet2.next()) {
CUSTOMERS.add(resultSet2.getString(1));
}
sql = "SELECT da_tag_name FROM da_tags WHERE da_tag_type_id = 6";
stmt = conn.prepareStatement(sql);
resultSet2 = stmt.executeQuery();
while (resultSet2.next()) {
SYSTEM_DEPS.add(resultSet2.getString(1));
}
while (resultSet.next()) {
String da_document_id = resultSet.getString(1);
String file_name = resultSet.getString(2);
try {
if(file_name.endsWith(".docx") || file_name.endsWith(".docm")) {
System.out.println(file_name);
XWPFDocument document = new XWPFDocument(resultSet.getBinaryStream(3));
XWPFWordExtractor wordExtractor = new XWPFWordExtractor(document);
//Return what's inside the document
System.out.println("Keywords found in the document:");
for (String keyword : KEYWORDS) {
if (wordExtractor.getText().contains(keyword)) {
System.out.println(keyword);
}
}
System.out.println("\nCustomers found in the document:");
for (String customer : CUSTOMERS) {
if (wordExtractor.getText().contains(customer)) {
System.out.println(customer);
}
}
System.out.println("\nSystem dependencies found in the document:");
for (String systemDeps : SYSTEM_DEPS) {
if (wordExtractor.getText().contains(systemDeps)) {
System.out.println(systemDeps);
}
}
System.out.println("Log number: " + findLogNumber(wordExtractor));
System.out.println("------------------------------------------");
wordExtractor.close();
}
As you can see there are 3 more to come and this doesn't look good already. Maybe there's a way to compare all of them at the same time.
I have made another attempt at this creating this method:
public void genericForEachLoop(ArrayList<String> al, POITextExtractor te) {
for (String item : al) {
if (te.getText().contains(item)) {
System.out.println(item);
}
}
}
Then calling it like so: genericForEachLoop(MODULES, wordExtractor);
Any better solutions?
I've got two ideas to shorten this: first of all you can write a general for-loop in a separate method that has an ArrayList as a parameter. Then you pass it each of your ArrayLists successively, which would mean that at least you do not have to repeat the for-loops. Secondly, you can create an ArrayList of type ArrayList and store your ArrayLists inside it. Then you can iterate over the whole thing. Only apparent disadvantage of both ideas (or a combination of them) would be, that you need to name the variable for your query string alike for the search of each ArrayList.
What you could do is use a Map and an enum like this:
enum TagType {
KEYWORDS2(2), // or whatever its da_tag_type_id is
CUSTOMERS(4),
SYSTEM_DEPS(6),
MODULES(8),
DRIVE_DEFS(10),
PROCESS_IDS(12);
public final daTagTypeId; // this will be used in queries
TagType(int daTagTypeId) {
this.daTagTypeId = daTagTypeId;
}
}
Map<TagType, List<String>> tags = new HashMap<>();
XWPFDocument document = new XWPFDocument(resultSet.getBinaryStream(3));
XWPFWordExtractor wordExtractor = new XWPFWordExtractor(document);
for(TagType tagType : TagType.values()) {
tags.put(tagType, new ArrayList<>()); // initialize
String sql = String.format("SELECT da_tag_name FROM da_tags WHERE da_tag_type_id = %d", tagType.daTagTypeId); // build query
stmt = conn.prepareStatement(sql);
resultSet2 = stmt.executeQuery();
while(resultSet2.next()) { // fill from DB
tags.get(tagType).add(.add(resultSet2.getString(1)));
}
System.out.println(String.format("%s found in the document:", tags.get(tagType).name());
for (String tag : tags.get(tagType)) { // search in text
if (wordExtractor.getText().contains(tag)) {
System.out.println(keyword);
}
}
}
But at this point I'm not sure you need those lists at all:
enum TagType {
KEYWORDS2(2), // or whatever its da_tag_type_id is
CUSTOMERS(4),
SYSTEM_DEPS(6),
MODULES(8),
DRIVE_DEFS(10),
PROCESS_IDS(12);
public final daTagTypeId; // this will be used in queries
TagType(int daTagTypeId) {
this.daTagTypeId = daTagTypeId;
}
}
XWPFDocument document = new XWPFDocument(resultSet.getBinaryStream(3));
XWPFWordExtractor wordExtractor = new XWPFWordExtractor(document);
for(TagType tagType : TagType.values()) {
String sql = String.format("SELECT da_tag_name FROM da_tags WHERE da_tag_type_id = %d", tagType.daTagTypeId); // build query
stmt = conn.prepareStatement(sql);
resultSet2 = stmt.executeQuery();
System.out.println(String.format("%s found in the document:", tags.get(tagType).name());
while(result2.next()) {
String tag = resultSet2.getString(1);
if (wordExtractor.getText().contains(tag)) {
System.out.println(keyword);
}
}
}
This given I don't know where those resultSet is declared and initialised, nor where that resultSet2 is initialised.
Basically you just fetch tags for each type from DB and then directly search them in the text without storing them at first and then re-iterating the stored ones... I mean that's what the DB is there for.

Calculating Document Frequency in HashMap java

I'm trying to achieve counting TF-IDF in java with DB as the corpus of document. I have done calculating the Term Frequency store in hashmap, but i have a problem, how can i calculate the document frequency each term? eg. the term "president" occurs in which document id? and how many it occurs in other document? i have 3 documents in DB for training, im stuck here, any advice? and thanks for helping, here is my code:
try{
Map <String,Integer> kamus = new HashMap<String, Integer>();
k.Koneksi();
String sql = "select * from data_berita";
Statement n = k.koneksi.createStatement();
ResultSet res = n.executeQuery(sql);
while(res.next()){
int id = res.getInt("id");
String konten = res.getString("konten");
String f = konten.replaceAll("[-?/<>_+=!##%&*.“”‘’()$·,';:{}|\"]", "").toLowerCase();
String [] array = f.split("\\s+");
for(String s : array){
int fl = 1;
k.Koneksi();
String sq = "Select * from StopWord";
Statement stat = k.koneksi.createStatement();
ResultSet rs = stat.executeQuery(sq);
while(rs.next()){
if(s.equals(rs.getString("Stopword"))){
fl=0;
}
}
if (fl!=0){
if(kamus.containsKey(s)){
kamus.put(s, kamus.get(s)+1);
}
else{
kamus.put(s, 1);
}
}
}
for(Map.Entry<String,Integer> en : kamus.entrySet()){
String d = en.getKey();
Integer s = en.getValue();
System.out.println(d+" "+s);
}
and this is the result of term frequency(not all):
alliance=1, president=3, suzhou=3, unloading=1, attended=1, liquefied=1, bright=1

getting values from Database to JLabel

i have a table in the database of 4rows and 4columns. each column holds a different data.
now i want to retrieve all the data in the database and put them on JLabel on another form. i.e
in my Database i have.
packageName.....monthlyFee..... YearlyFee....... TotalFee
Regular......................150..................300....................450
Gold.........................300...................400..................700
..... ..... .... ....
now i have a form that i have put 4 empty JLabels in four rows but how do i retrieve the values from the database and place each value in the appropriate Label?.
This is what i've done but i still cant get around it. im stuck.
Thank you anyone.
public void getPrices()
{
String srt ="SELECT * FROM program_tbl";
try
{
con.connect();
ps = con.con.prepareStatement(srt);
rs = ps.executeQuery();
ResultSetMetaData data = rs.getMetaData();
int colums = data.getColumnCount();
while(rs.next())
{
Vector rows = new Vector();
for (int i = 1; i < colums; i++)
{
rows.addElement(rs.getObject(i));
}
.....................................................................
If you want to get this data as a string then you could probably try something like:
Vector<String> rows = new Vector<String>();
while(rs.next()) {
String rowEntry = rs.getString("packageName") +
rs.getString("monthlyFee") +
rs.getString("yearlyFee") +
rs.getString("totalFee") +
rows.add(rowEntry);
}
If not String, but an object to use later, then you can create a class:
public class MyObject {
private String packageName;
private int monthlyFee;
private int yearlyFee;
private int totalFee;
public MyObject (String name, int monthlyFee, int yearlyFee, int totalFee) {
this.packageName = name;
this.monthlyFee = monthlyFee;
this.yearlyFee = yearlyFee;
this.totalFee = totalFee;
}
/*Setters
*And
*Getters*/
}
And then use it as:
Vector<MyObject> rows = new Vector<MyObject>();
while (rs.next()) {
MyObject obj = new MyObject(rs.getString("packageName")
, rs.getInt("montlyFee")
, rs.getInt("yearlyFee")
, rs.getInt("totalFee")
);
rows.add(obj)
}
So say we now have a vector with String values - Vector<String> rows;
now i would like to create those JLabels.
JLabel[] myLabels = new JLabel[v.size()];
for(int i=0; i<rows.size(); i++) {
as[i] = new JLabel(rows.get(i));
}
And now we have an array of JLabels ready to be put to applet.
Don't use a JLabel. There is no way you can easily format the data so that you get tabular data.
Instead you should be using a JTable. Read the section from the Swing tutorial on How to Use Tables for more information. You can also search the forum for examples of using a JTable with a ResultSet.

Load database Field Values to A JCombobox

How to load values from an Oracle db to a JComboBox to make it easier for the user To Choose from I Have tried this:
Connection dbcon = null;
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
dbcon = DriverManager.getConnection("
jdbc:oracle:thin:#localhost:1521:XE", "USERNAME", "PASSWORD");
Statement st = dbcon.createStatement();
String combo = "Select EMP_IDNUM from employees";
ResultSet res = st.executeQuery(combo);
while(res.next()){
String ids = res.getString("EMP_IDNUM");
String [] str = new String[]{ids};
cboId = new JComboBox(str);
}
} catch (Exception d) {
System.out.println(d);
}
This is Only getting me the first Value Into the JComboBox cboID. What Is the Best way to Load the entire Field Data (EMP_IDNUM) into the Jcombobox??
String [] str = new String[]{ids};
It means your String array is having only one ids value which you have loaded String ids = res.getString("EMP_IDNUM");
if(rs.getRow()>0){
String [] str = new String[res.getRow()];
int i=0;
while(res.next()){
str[i++] = res.getString("EMP_IDNUM");
}
}
JComboBox jcb = new JComboBox(str);
Instead of array you can use Vector also to create JComboBox.
you can use this code:
Vector v = new Vector();
while(res.next()){
String ids = res.getString("EMP_IDNUM");
v.add(ids)
}
JComboBox jcb = new JComboBox(v);
In this code you create a Vector with your Strings, and then invoke directly the JComboBox(Vector items) constructor of JComboBox
there are three important areas
a) close all JDBC Objects in the finally block, because these Object aren't, never GC'ed
try {
} catch (Exception d) {
System.out.println(d);
} finally {
try {
st.close()
res.close()
dbcon.close()
} catch (Exception d) {
//not important
}
}
b) don't to create any Objects inside try - catch - finally, prepare that before
meaning cboId = new JComboBox(str);
c) put all data from JDBC to the ComboBoxModel, prepare that before

replaceAll() method using parameter from text file

i have a collection of raw text in a table in database, i need to replace some words in this collection using a set of words.
i put all the term to be replace and its substitutes in a text file as below
min=admin
lelet=lambat
lemot=lambat
nii=nih
ntu=itu
and so on.
i have successfully initiate a variabel of File and Scanner to read the collection of the term and its substitutes.
i loop all the dataset and save the raw text in a string
in the same loop
i loop all the term collection and save its row to a string name 'pattern', and split the pattern into two string named 'term' and 'replacer'
in this loop i initiate a new string which its value is the string from the dataset modified by replaceAll(term,replacer)
end loop for term collection
then i insert the new string to another table in database
end loop for dataset
i do it manualy as below
replaceAll("min","admin")
and its works but its really something to code it manually for almost 2000 terms to be replace it.
anyone ever face this kind of really something..
i really need a help now desperate :(
package sentimenrepo;
import javax.swing.*;
import java.sql.*;
import java.io.*;
//import java.util.HashMap;
import java.util.Scanner;
//import java.util.Map;
/**
*
* #author herman
*/
public class synonimReplaceV2 extends SwingWorker {
protected Object doInBackground() throws Exception {
new skripsisentimen.sentimenttwitter().setVisible(true);
Integer row = 0;
File synonimV2 = new File("synV2/catatan_kata_sinonim.txt");
String newTweet = "";
DB db = new DB();
Connection conn = db.dbConnect("jdbc:mysql://localhost:3306/tweet", "root", "");
try{
Statement select = conn.createStatement();
select.executeQuery("select * from synonimtweet");
ResultSet RS = select.getResultSet();
Scanner scSynV2 = new Scanner(synonimV2);
while(RS.next()){
row++;
String no = RS.getString("no");
String tweet = " "+ RS.getString("tweet");
String published = RS.getString("published");
String label = RS.getString("label");
clean2 cleanv2 = new clean2();
newTweet = cleanv2.cleanTweet(tweet);
try{
Statement insert = conn.createStatement();
insert.executeUpdate("INSERT INTO synonimtweet_v2(no,tweet,published,label) values('"
+no+"','"+newTweet+"','"+published+"','"+label+"')");
String current = skripsisentimen.sentimenttwitter.txtAreaResult.getText();
skripsisentimen.sentimenttwitter.txtAreaResult.setText(current+"\n"+row+"original : "+tweet+"\n"+newTweet+"\n______________________\n");
skripsisentimen.sentimenttwitter.lblStat.setText(row+" tweet read");
skripsisentimen.sentimenttwitter.txtAreaResult.setCaretPosition(skripsisentimen.sentimenttwitter.txtAreaResult.getText().length() - 1);
}catch(Exception e){
skripsisentimen.sentimenttwitter.lblStat.setText(e.getMessage());
}
skripsisentimen.sentimenttwitter.lblStat.setText(e.getMessage());
}
}catch(Exception e){
skripsisentimen.sentimenttwitter.lblStat.setText(e.getMessage());
}
return row;
}
class clean2{
public clean2(){}
public String cleanTweet(String tweet){
File synonimV2 = new File("synV2/catatan_kata_sinonim.txt");
String pattern = "";
String term = "";
String replacer = "";
String newTweet="";
try{
Scanner scSynV2 = new Scanner(synonimV2);
while(scSynV2.hasNext()){
pattern = scSynV2.next();
term = pattern.split("=")[0];
replacer = pattern.split("=")[1];
newTweet = tweet.replace(term, replacer);
}
}catch(Exception e){
e.printStackTrace();
}
System.out.println(newTweet+"\n"+tweet);
return newTweet;
}
}
}
update
ive just realize that the code actually works but only for the first row in database, the second row and so on stand still. here is i update the newest code i ve build
public class synonimReplaceV2 extends SwingWorker {
protected Object doInBackground() throws Exception {
new skripsisentimen.sentimenttwitter().setVisible(true);
Integer row = 0;
String newTweet = "";
DB db = new DB();
Connection conn = db.dbConnect("jdbc:mysql://localhost:3306/tweet", "root", "");
try{
Statement select = conn.createStatement();
select.executeQuery("select * from synonimtweet limit 2,10");
ResultSet RS = select.getResultSet();
FileReader readSyn = new FileReader("synV2/catatan_kata_sinonim.txt");
BufferedReader buffSyn = new BufferedReader(readSyn);
while(RS.next()){
row++;
String no = RS.getString("no");
String tweet = " "+ RS.getString("tweet");
String published = RS.getString("published");
String label = RS.getString("label");
String pattern = "";
while((pattern=buffSyn.readLine())!=null){
String patternTerm = pattern.split("=")[0];
String patternSubs = pattern.split("=")[1];
tweet = tweet.replaceAll("\\s"+patternTerm, patternSubs);
}
try{
Statement insert = conn.createStatement();
insert.executeUpdate("INSERT INTO synonimtweet_v2(no,tweet,published,label) values('"
+no+"','"+tweet+"','"+published+"','"+label+"')");
String current = skripsisentimen.sentimenttwitter.txtAreaResult.getText();
skripsisentimen.sentimenttwitter.txtAreaResult.setText(current+"\n"+row+"original : "+tweet+"\n"+newTweet+"\n______________________\n");
skripsisentimen.sentimenttwitter.lblStat.setText(row+" tweet read");
skripsisentimen.sentimenttwitter.txtAreaResult.setCaretPosition(skripsisentimen.sentimenttwitter.txtAreaResult.getText().length() - 1);
}catch(Exception e){
skripsisentimen.sentimenttwitter.lblStat.setText(e.getMessage());
}
}
}catch(Exception e){
skripsisentimen.sentimenttwitter.lblStat.setText(e.getMessage());
// System.out.println(e.getMessage());
}
Thread.sleep(100);
return row;
}
}
Opening the synonym file and iterating over 2,000 lines for every row in your ResultSet is a bit wasteful.
Load your synonyms into an in-memory Map once, keyed by unique misspelt term, then do a lookup on the map for every row in your result set, and replace as necessary.
Let us use both solutions to build a single solution for you:
First, you create a HashMap with all your keys:
public static HashMap<String, String> getMap() {
//your version would read from the file
HashMap<String,String> myMap=new HashMap<String,String>();
myMap.put("min", "admin");
myMap.put("lelet", "lambat");
myMap.put("lemot", "lambat");
myMap.put("nii", "nih");
myMap.put("ntu", "itu");
return(myMap);
}
Second, you create a pattern that contains all the keys in your hashmap:
public static String getPattern(HashMap<String,String> mapReplacement) {
String pattern="";
for (String s : mapReplacement.keySet()) {
if (!pattern.isEmpty()) {
pattern=pattern+"|";
}
pattern=pattern+s;
}
return(pattern);
}
Next, you can create a cleanTweet method that uses both structures you created:
public static String cleanTweet(String tweet, Pattern pattern,HashMap<String, String> myMap) {
String newTweet=tweet;
Matcher matcher = pattern.matcher(newTweet);
int start=0;
while (matcher.find()) {
String key=matcher.group();
String replacement=myMap.get(key);
if (replacement!=null) {
newTweet=newTweet.replace(key, replacement );
}
}
return(newTweet);
}
This might require some tweaking to perfect (I onyl tested a few cases), but the point is that you are going to iterate a single time in your keys and then iterate only on your tweets.
I hope it helps.
I didn't try, but it seems to me that you've almost got it - just replace this line:
newTweet = tweet.replace(term, replacer);
with this:
tweet = tweet.replaceAll(term, replacer);
As you're not using newTweet any more, return tweet:
return tweet;
You should also delete the newTweet declaration.
Also, you shouldn't read Scanner to read lines. Use FileReader instead.
thanks folks
i ve found the answer why the code is not working,
the txt file containing terms and its substitutes should be initiated each time the program read a row from database.
the code would be like this
public class synonimReplaceV2 extends SwingWorker {
protected Object doInBackground() throws Exception {
new skripsisentimen.sentimenttwitter().setVisible(true);
Integer row = 0;
String newTweet = "";
DB db = new DB();
Connection conn = db.dbConnect("jdbc:mysql://localhost:3306/tweet", "root", "");
try{
Statement select = conn.createStatement();
select.executeQuery("select * from synonimtweet limit 2,10");
ResultSet RS = select.getResultSet();
while(RS.next()){
row++;
FileReader readSyn = new FileReader("synV2/catatan_kata_sinonim.txt");
BufferedReader buffSyn = new BufferedReader(readSyn);
String no = RS.getString("no");
String tweet = " "+ RS.getString("tweet");
String published = RS.getString("published");
String label = RS.getString("label");
String pattern = "";
while((pattern=buffSyn.readLine())!=null){
String patternTerm = pattern.split("=")[0];
String patternSubs = pattern.split("=")[1];
tweet = tweet.replaceAll("\\s"+patternTerm, patternSubs);
}
try{
Statement insert = conn.createStatement();
insert.executeUpdate("INSERT INTO synonimtweet_v2(no,tweet,published,label) values('"
+no+"','"+tweet+"','"+published+"','"+label+"')");
String current = skripsisentimen.sentimenttwitter.txtAreaResult.getText();
skripsisentimen.sentimenttwitter.txtAreaResult.setText(current+"\n"+row+"original : "+tweet+"\n"+newTweet+"\n______________________\n");
skripsisentimen.sentimenttwitter.lblStat.setText(row+" tweet read");
skripsisentimen.sentimenttwitter.txtAreaResult.setCaretPosition(skripsisentimen.sentimenttwitter.txtAreaResult.getText().length() - 1);
}catch(Exception e){
skripsisentimen.sentimenttwitter.lblStat.setText(e.getMessage());
}
}
}catch(Exception e){
skripsisentimen.sentimenttwitter.lblStat.setText(e.getMessage());
// System.out.println(e.getMessage());
}
Thread.sleep(100);
return row;
}
}
but im actually want to apply the code in which rlinden made above, but cant figure it out how to call the cleanTweet function.

Categories