returning 2 different values - java

i'm working with java in eclipse.I am trying to take 2 variables from my database and write it to an excel.My only problem is returning 2 different values(an integer and a string) from db reader method and send it to excel writer method which are in different classes.
Here is my db reader class:
public class DbConnection {
public void createConnection(String choice) {
try {
String myDriver = "com.mysql.jdbc.Driver";
String db = "jdbc:mysql://localhost/digiturkschema";
Class.forName(myDriver);
Connection conn = DriverManager.getConnection(db, "root",
"*****");
Statement st = conn.createStatement();
switch (choice) {
case "write":
ResultSet rs = st.executeQuery("SELECT * FROM channelstable");
while (rs.next()) {
int channelId = rs.getInt("channelNo");
String channelName = rs.getString("channelName");
}
}
} catch (Exception exception) {
System.out.print(exception.getStackTrace());
}
}
}
I need to return "channelId" and "channelName" from this method to this method:
public class WritingToExcel {
public void Write() throws IOException {
try {
JFileChooser f = new JFileChooser();
f.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
f.showSaveDialog(null);
System.out.println(f.getCurrentDirectory());
System.out.println(f.getSelectedFile());
String direction = f.getSelectedFile().toString() + "\\DigiTurkKanalListesi.xls";
WritableWorkbook workbook = Workbook.createWorkbook(new File(direction));
WritableSheet sheet = workbook.createSheet("Kanal Listesi", 0);
Label label = new Label(0, 0, "A label record");
sheet.addCell(label);
Number number = new Number(2, 1, 3.1459);
sheet.addCell(number);
workbook.write();
workbook.close();
} catch (WriteException e) {
e.getStackTrace();
}
}}
I know that writingToExcel class is not completed and it's ok,i can finish it if i can take these two variables to this class.By the way i am using MVC pattern so i have a controller class between them.I can write it too if it's necessary.

As #Ascalonian said, you can use Map or HashMap.
for example:
Map<Integer, String> channelInfo = new HashMap<Integer, String>();
You can also (but should not):
Create a new class with the values you need and return that class. (You will be doing extra work which you don't really need to.)
Create setter methods for those variables and use it before calling the method to write to excel. (requires caution as you can end up with undesired values if you mess the code)

There are multiple options
ArrayList<Objects> : During Iterating the resultSet prepare temporary List say tempList insert items into tempList and then after each iteration add tempList to Main List , Since ArrayList is a sequential list. So, insertion and retrieval order is the same. So you can return this from your dbReader() method .Then use them wherever you want
Your Arraylist will look like this
[ [1,Channel 1] , [2,Channel 2] , [3,Channel 3] ]
Map if order is important prefer LinkedHashMap if order is not your primary concern then opt for HashMap

Related

Objects getting copied by reference and replacing all items in ArrayList

I understand that people have faced this issue before and I have gone through the previous posts.
I have an arrayList and I'm trying to add objects to it. During every add call, the same object reference is being copied. Though I have used the 'new' operator and am creating new objects. This is something basic and has worked previously when I create the object again during each iteration.
Any help is much appreciated.
Here is my code.
public List<Actor> readAllActors()
{
String selectMovie = "SELECT * from ACTOR;";
List<Actor> listOfActors = new ArrayList<Actor>();
try {
statement = conn.prepareStatement(selectMovie);
results = statement.executeQuery(selectMovie);
Actor a = new Actor();
while (results.next())
{
a = getActorFromResult(results);
listOfActors.add(new Actor(a.getId(), a.getFirstName(), a.getLastName(), a.getDateOfBirth()));
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return listOfActors;
}
private Actor getActorFromResult(ResultSet results) throws SQLException {
// TODO Auto-generated method stub
int id = results.getInt("id");
String fname = results.getString("firstName");
String lname = results.getString("lastName");
String dob = results.getString("dateOfBirth");
Actor actor = new Actor(id, fname, lname, dob );
return actor;
}
I have tried printing the object in each iteration. It is fetching the right row from the table.. the new Actor() seems to have no effect in creating a new object reference!!
Your code is fine and can't pass the same reference all the time. You can check it via a == check of your listed objects.
You could refactor you code to
results = statement.executeQuery(selectMovie);
while (results.next())
{
listOfActors.add(getActorFromResult(results));
}
as you're creating a new Actor and thus a new object with an own reference after fetching the result set. This will also make the code clearer here.
Also return new Actor(id, fname, lname, dob ); will do the job in your result method. You're not using the self-descriptive local variable anyways.
I suspect your problem lies in your database. Try querying it with a database tool.
try to change that line
listOfActors.add(new Actor(a.getId(), a.getFirstName(), a.getLastName(), a.getDateOfBirth()));
to that
listOfActors.add(getActorFromResult(results));
and delete line
a = getActorFromResult(results);
Your references are for sure not the same, please check it in debugger.

ArrayList method return

I'm working in a project with DB. There are a method that collect info from the DB and set the info in ArrayList:
public ArrayList<Director> listAll(){
ArrayList<Director>list = new ArrayList<Director>();
Director direc = new Director();
int cont=0;
String sql = "select * from director;";
try{
ResultSet res = objBBDD.sentencia.executeQuery(sql);
while(res.next()){
direc.setCode(res.getInt("CODE"));
direc.setName(res.getString("NAME"));
direc.setNationality(res.getString("NATIONALITY"));
direc.setOscar(res.getInt("OSCAR"));
list.add(direc);
// THIS IS USE TO CONFIRM IF IT WORKS ///////////////////////////////////////
// JOptionPane.showMessageDialog(null,"Code:"+list.get(cont).getCode()+"Nombre"+list.get(cont).getName());
// cont++;
}
}catch (SQLException e) {
e.printStackTrace();
}
return list;
}
I use JOptionPane.showMessageDialog to see if I get info from DB and is added correctly to de ArrayList, and it's works.
Now the ArrayList back the invoker class, this is the method:
private void stackArray(){
ArrayList<Director>arrayDir = new ArrayList<Director> ();
ArrayList<Director>arrayDir = conexion.listAll();
// JOptionPane.showMessageDialog(null,"Code:"+arrayDir.get(0).getCode()+"Name"+arrayDir.get(0).getName());
// JOptionPane.showMessageDialog(null,"Code:"+arrayDir.get(1).getCode()+"Name"+arrayDir.get(1).getName());
// JOptionPane.showMessageDialog(null,"Code:"+arrayDir.get(2).getCode()+"Name"+arrayDir.get(2).getName());
}
Again I use the JOptionPane.showMesageDialog to show the first three positions, but it's not work, the problem, as far as I've seen, is all the positions have the same object saved (exactly the last).
Summarizing the ArrayList have the same object (last in DB), there are no problems at run or compile.
I don't know if I write something bad, or just a noob fail.
the problem, as far as I've seen, is all the positions have the same
object saved (exactly the last).
You are changing value of same instance Director. Thats why, you seen the last value of Director object. You should create new instance of Director with iteration of while loop.
ResultSet res = objBBDD.sentencia.executeQuery(sql);
while(res.next){
Director direc = new Director();// Declare Director instance here.
.....
list.add(direc);
}

compare two arrayList and stock the result in a thirth arrayList

i want compare 2 arrayList when i stock in them the result of a class java of telnet
this class it's to telnet about a router and gives all of interfaces of this routers then stock them in the arrayList
so i stock the interfaces for the router1 in myData1 and the second in myData2
and i will compare if the interface of the first aray it's the same in the second just add one of them in the array of result myData
but it gives me anthing the code
public class Test {
public static void main(String[] args) {
Connection conn = null;
try {
conn = DriverManager.getConnection("jdbc:mysql://localhost/mohammedia", "root", "123456");
String sql = "SELECT * FROM router;";
Telnet_Interface telnet = new Telnet_Interface();
Telnet_Interface telnet1 = new Telnet_Interface();
Telnet_Interface telnet2 = new Telnet_Interface();
PreparedStatement prest = conn.prepareStatement(sql);
ResultSet res=prest.executeQuery();
while(res.next()){
telnet1.Config(res.getString(1), "user", "passwd", res.getString(1));
telnet2.Config(res.getString(2), "user", "passwd", res.getString(2));
}
ArrayList myData=new ArrayList();
ArrayList myData1=telnet1.getMyData();
ArrayList myData2=telnet2.getMyData();
boolean bool=false;
for(int i=0;i<myData1.size();i++)
{
for(int j=0;j<myData2.size();j++)
{
if (myData2.get(j).equals(myData1.get(i)))
{
bool=true;
//System.out.print("sdfsd");
}
if(!bool)
{
myData.add(myData2.get(j));
//System.out.print("sdsd");
}
}
}
for(int x=0;x<myData.size();x++)
{
System.out.print(myData.get(x));
}
} catch (SQLException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
what's the problem ??
thank you
You can just use ArrayList.retainAll method like this
list1.retainAll(list2)
after this method list1 will containt only the data which are available in list2.
(Not an answer) Separate all. Use logging and handle the exceptions.
If it is not a kind of dictionary attack, first do the SQL retrieving users with passwords.
Close result set, statement and connection.
Check the results.
Then get the telnet data.
Check the results.
Then do the comparison.
I hope you can see the deleted answer of #StinePike; he basically proposes list1.retainAll(list2) to remove all element in list1 that occur in list2.
I think you want to do the following. Outcommented is non-looping alternative.
// Add all myData2 and myData1 elements but not twice to myData.
// (1) Add myData2
myData.addAll(myData2);
// (2) Add myData1 when not in myData2
//myData1.removeAll(myData1);
//myData.addAll(myData1);
for (int i = 0; i < myData1.size(); i++)
{
boolean found = false;
for (int j = 0; j < myData2.size(); j++)
{
if (myData2.get(j).equals(myData1.get(i)))
{
found = true;
break;
}
}
if (!found)
{
myData.add(myData1.get(i));
}
}

Single thread writing to different database with different connection parameters

I am working on a project in which I have three tables in a different database with different schemas. So that means I have three different connection parameters for those three tables to connect using JDBC-
Let's suppose-
For Table1-
Username:- A
Password:- B
URL: C
Columns-
ID1 String
Account1 String
For Table2-
Username:- P
Password:- Q
URL:- R
Columns-
ID2 String
Account2 String
For Table3-
Username:- T
Password:- U
URL:- V
Columns-
ID3 String
Account3 String
And I am supposed to insert in all the three tables or any one of them using JDBC.
Below are the three use cases I have-
From the command prompt if suppose I am passing Table1 only, then I am suppose to insert only in Table1 columns by making connection to
Table1.
And if I am passing Table1, Table2 from the command prompt then I am suppose to insert in both Table1 and Table2 columns by making
connection to Table1 and Table2.
And if I am passing Table1, Table2 and Table3 then I am suppose to enter in all the three tables using there respective connection
parameter
I am not able to understand how to write code for the above particular scenario in such a cleaner way so that it can be extended in near future as well if I come up with four tables. I can have a one constant file which can store the SQL that needs to be executed for any of the three tables and some other constant thing as well.
public static void main(String[] args) {
}
class Task implements Runnable {
private Connection dbConnection = null;
private PreparedStatement preparedStatement = null;
public Task() {
}
#Override
public void run() {
dbConnection = getDbConnection();
//prepare the statement and execute it
}
}
private Connection getDBConnection() {
Connection dbConnection = null;
Class.forName(Constants.DRIVER_NAME);
dbConnection = DriverManager.getConnection( , , );
return dbConnection;
}
Can anyone provide some thoughts on this how should I proceed forward?
Note:-
Column in each table will differ a lot. Like in some tables, column can be 10 and in some other table, column can be 20.
Create databases.properties file with content like this:
# Table 1
table1.url: jdbc:mysql://localhost:3306/garden
table1.user: gardener
table1.password: shavel
table1.table: fruits
table1.column.id: fruitID
table1.column.color: fruitColor
table1.column.weight: fruitWeight
# ... More fruit columns here ...
# Table 2
table2.url: jdbc:mysql://otherhost:3306/forest
table2.user: forester
table2.password: axe
table2.table: trees
table2.column.id: treeID
table2.column.height: treeHeight
# ... More tree columns here ...
# ... More tables here ...
Then do something like this:
public static void main (String [] args)
{
Properties databasesProperties = new Properties ();
databasesProperties.load ("databases.properties");
for (String arg: args)
{
String url = databasesProperties.get (arg + ".url");
String user = databasesProperties.get (arg + ".user");
String password= databasesProperties.get (arg + ".password");
String table = databasesProperties.get (arg + ".table");
String columnPrefix = arg + ".column."
Map <String, String> columns = new HashMap <String, String> ();
for (String key: databasesProperties.stringPropertyNames ())
{
if (key.startsWith (columnPrefix))
columns.put (
key.substring (columnPrefix.length ()),
databasesProperties.get (key));
}
doInsert (url, user, password, table, columns);
}
}
Later you can always add more tables into your databases.properties file.
Save your Database properties in a class file DBPropery.java.
final class DBProperty
{
static String[] urls = {
"C",
"R",
"V"
}; //You can add more URLs here.
static String[] driver= {
"Driver1",
"Driver2",
"Driver3"
};//You can add more drivers string
static String[] table = {
"Table1",
"Table2",
"Table3"
};//You can add more table names here According to URLs mentioned in urls array.
static String[] user = {
"A",
"P",
"T"
};//You can add more user names here according to URls mentioned in urls array.
static String[] pwd = {
"B",
"Q",
"U"
};//You can add more Password here according to URls mentioned in urls array.
static String[] queries = {
"Query for Table1",
"Query for Table2",
"Query for Table3",
};//You can add more queries here for more tables according to URls mentioned in urls array.
static int[] columns ={
2,
2,
2
};//You can change the column numbers according to need . 0th index belongs to Table1 , 1 to table2....so on.
//If you add more tables , add corresponding columns count to next index.
static String[] columnValues ={
"1^John",
"34^Vicky",
"65^Ethen"
};//String at each index represents a row in corresponding table in table[] array. each column is seperated by delimiter "^".
}
Make all Changes in DBProperty.java file.
Then proceed with following class file
import java.sql.*;
import java.util.*;
class MultiTableInsert implements Runnable
{
Map<String,Integer> columnsInTable;
Map<String,String> tableDriver;
Map<String,String> rowForTable;
Map<String,String> queryForTable;
Map<String,String> urlForTable;
Map<String,String> userForTable;
Map<String,String> pwdForTable;
String[] tables ;
public MultiTableInsert(String... tables)//Loading all Database Settings here..
{
this.tables = tables;
columnsInTable = new LinkedHashMap<String,Integer>();
rowForTable = new LinkedHashMap<String,String>();
tableDriver = new LinkedHashMap<String,String>();
urlForTable = new LinkedHashMap<String,String>();
userForTable= new LinkedHashMap<String,String>();
pwdForTable = new LinkedHashMap<String,String>();
for (int i = 0 ; i < DBProperty.urls.length ; i++ )
{
try
{
tableDriver.put(DBProperty.table[i],DBProperty.driver[i]);
queryForTable.put(DBProperty.table[i],DBProperty.queries[i]);
columnsInTable.put(DBProperty.table[i],DBProperty.columns[i]);
rowForTable.put(DBProperty.table[i],DBProperty.columnValues[i]);
urlForTable.put(DBProperty.table[i],DBProperty.urls[i]);
userForTable.put(DBProperty.table[i],DBProperty.user[i]);
pwdForTable.put(DBProperty.table[i],DBProperty.pwd[i]);
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
}
#Override
public void run()
{
insertIntoTable(tables);
}
private void insertIntoTable(String... tables)
{
for (String tble : tables )
{
Connection con = null;
PreparedStatement pStmt = null;
try
{
Class.forName(tableDriver.get(tble));
con = DriverManager.getConnection(urlForTable.get(tble),userForTable.get(tble),pwdForTable.get(tble));
pStmt = con.prepareStatement(queryForTable.get(tble));
int columns = columnsInTable.get(tble);
String sRow = rowForTable.get(tble);
StringTokenizer tokenizer = new StringTokenizer(sRow,"^");
for (int i = 0; i < columns ; i++)
{
pStmt.setString(i+1,(String)tokenizer.nextElement());
}
pStmt.execute();
}
catch (Exception ex)
{
ex.printStackTrace();
}
finally
{
try
{
con.close();
}catch (Exception ex){}
try
{
pStmt.close();
}catch (Exception ex){}
}
}
}
public static void main(String[] args)
{
int length = args.length;
int THREAD_COUNTS = 10;//Number of threads you want to start.
switch (length)
{
case 0:
System.out.println("Usage: javac MultiTableInsert Table1/Table2/Table3 <Table1/Table2/Table3> <Table1/Table2/Table3>");
System.exit(0);
case 1:
for (int i = 0 ; i < THREAD_COUNTS ; i++)
{
MultiTableInsert mti = new MultiTableInsert(args[0]);
Thread th = new Thread(mti,"Thread"+i);//Create New Thread
th.start(); //Start Thread
}
break;
case 2:
for (int i = 0 ; i < THREAD_COUNTS ; i++)
{
MultiTableInsert mti = new MultiTableInsert(args[0],args[1]);//Create New Thread
Thread th = new Thread(mti,"Thread"+i); //Start Thread
th.start();
}
break;
default:
for (int i = 0 ; i < THREAD_COUNTS ; i++)
{
MultiTableInsert mti = new MultiTableInsert(args[0],args[1],args[2]);//Create New Thread
Thread th = new Thread(mti,"Thread"+i); //Start Thread
th.start();
}
break;
}
}
}

Iterartor - How to traverse for specific records

I have executed a query using JDBC and traversing the resultset I have stored all fields in List in java.
List<String> dataList=new ArrayList<String>();
while(res.next())
{
dataList.add(res.getString(1));
dataList.add(res.getString(2));
dataList.add(res.getString(3));
dataList.add(res.getString(4));
dataList.add(res.getString(5));
dataList.add(res.getString(6));
dataList.add(res.getString(7));
}
Iterator<String> it= dataList.iterator();
As I have added directly into list so how can I get this 7 fields while traversing the iterator.
Means:
while(it.hasNext())
{
String f1=it.next();
}
Like wise everytime I want 7 fields at a time
and next 7, next 7....... so on
Using this while loop how can I get those 7 fields (one row in table having 7 field) at a time.
I get little bit confuse here. Please help me.
Thanks
What you want to do is actually create another object that stores all seven of the values.
Then create a list of these entries so that you can access one row at a time, which is what I think you are asking.
First create a class for the row.
private static class Entry {
String[] row;
public Entry ( ResultSet r ) {
row = new String [ 7 ];
for (int i = 1; i <= 7; i++) {
row[i] = r.getString(i);
}
}
}
Using that, you can then create a list of Entry objects.
List<Entry> entryList = new ArrayList <Entry> ();
while(res.next())
{
entryList.add ( new Entry ( res ) );
}
Then, you can go ahead and loop through entryList and get any specific entry you would want.
Of course, if you have specific values, it might be wise to create instance variables of type String for Entry rather than an array of Strings.
By that I mean you could do this:
private static class Entry {
String column1; // rather than name column1 use what the column semantically represents
String column2;
// ...
public Entry ( ResultSet r ) {
column1 = r.getString(1);
// ...
}
This way, you can also calls like r.getInt(i) for certain columns which have an different type other than String.
Good luck!
I think your List declaration should be
List<Any DAO Object> instead of List<String>
While fetching from resultset, create a DAO object, add all fetched data into that object and then add that object into the list.
Then you can iterate and get each DAO object at each iteration.
You can use DatabaseMetaData class,
private static final String DRIVER = "com.mysql.jdbc.Driver";
private static final String URL = "jdbc:mysql://localhost/testdb";
private static final String USERNAME = "root";
private static final String PASSWORD = "";
public static void main(String[] args) throws Exception {
Class.forName(DRIVER);
Connection connection = DriverManager.getConnection(URL, USERNAME, PASSWORD);
DatabaseMetaData metadata = connection.getMetaData();
ResultSet resultSet = metadata.getColumns(null, null, "users", null);
while (resultSet.next()) {
String name = resultSet.getString("COLUMN_NAME");
String type = resultSet.getString("TYPE_NAME");
int size = resultSet.getInt("COLUMN_SIZE");
System.out.println("Column name: [" + name + "]; type: [" + type + "]; size: [" + size + "]");
}
connection.close();
}

Categories

Resources