# Speicherung von Daten aus Excel in Datenbank ohne doppelte Werte



## vector_ever (1. August 2013)

Hallo,

Ich habe eine Code um die Datein von Excel sofort in Datenbank zu speichern


```
CD_ID	Albumtitel	   Interpret	         Year                 Track	       Titel
----------------------------------------------------------------------------------------------
4711	Not That Kind	   Anastacia	         1999	             1	           Not That Kind
4710	Not That Kind	   Anastacia	         1999	             2	           I’m Outta Love
4713	Not That Kind	   Anastacia	         1999	             3	           Cowboys & Kisses
4722	Wish You Her      Pink Floyd	        1964	             1	           Shine On You Crazy Diamond
4713	Not That Kind	  Anastacia	        1999	             3	           Cowboys & Kisses
4711	Not That Kind	  Anastacia	        1999	             1	           Not That Kind
4712	Love me	          Sp.Girls	        1998	             1	           Viva for ever
4710	Not That Kind	  Anastacia	        1999	             2	           I’m Outta Love
4722	Wish You  Her     Pink Floyd	        1964	             1	           Shine On You Crazy Diamond
```

kann man hier bemerken die doppelte Werte in der Tabelle, das was ich nicht in meinem Datenbank speichern lassen

In meiner code benutze ich Zwei Arraylist, die erste um die Zellen zu speichern, die andere um die Zeilen zu speichern.

Ich  habe überlegt wenn ich Set anstatt von Arraylist benutze (mit Set keine  doppelte Werte)

Das aber konnte ich nicht genau wissen wie kann ich tun


```
import java.io.File;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Iterator;
 
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
 
public class Excel2DB3 {
 
 
	//static ArrayList cellArrayLisstHolder = new ArrayList();
 
	public static void main(String[] args) throws Exception{
 
		ArrayList dataHolder = readExcelFile(); 
		saveToDatabase(dataHolder);
	}
 
		public static ArrayList readExcelFile(){
 
		ArrayList dataSheet = new ArrayList();
 
	try {
 
	    FileInputStream file = new FileInputStream(new File("d:\\Songs.xls"));
 
	    //Get the workbook instance for XLS file 
	    HSSFWorkbook workbook = new HSSFWorkbook(file);
 
	    //Get first sheet from the workbook
	    HSSFSheet sheet = workbook.getSheetAt(0);
 
	    //Iterate through each rows from first sheet
	    Iterator<Row> rowIterator = sheet.iterator();
	    while(rowIterator.hasNext()) {
	        Row row = rowIterator.next();
 
	        //display from the first row 
	        if(row.getRowNum() > 0)
	        {
 
	        //For each row, iterate through each columns
	        Iterator<Cell> cellIterator = row.cellIterator();
 
	        ArrayList data = new ArrayList();
 
	        while(cellIterator.hasNext()) {
 
	            //Getting the cell contents
	            Cell cell = cellIterator.next();
 
	        data.add(cell);
	          }
 
	        dataSheet.add(data);
 
	        }
	        }
		    }catch (Exception e){e.printStackTrace(); 
		    }
		    return dataSheet;
		    }
 
 
		private static void saveToDatabase(Set dataHolder) {
	    	   String url = "jdbc:mysql://localhost:3306/songs";
	    	   String username = "root";
	    	   String password = "root";
	       Connection con = null;
	       String query = "insert into lieder values(?,?,?,?,?,?)";
	       PreparedStatement ps = null;
	       try {
	////////////////////////make connection withthe database ///////////////////////////////
	    	   Class.forName("com.mysql.jdbc.Driver");
	           con = DriverManager.getConnection(url, username, password);
 
	////////////////////////////////// Excute SQL statment:  ///////////////////////////////////////
 
	           ps = con.prepareStatement(query);
 
	           ArrayList cellStoreArrayList = null;
 
	       	//For inserting into database
	       	for (int i = 0; i < dataHolder.size(); i++) {
 
	       	    cellStoreArrayList = (ArrayList) ((ArrayList) dataHolder).get(i);
 
	       	       ps.setString(1,((HSSFCell)cellStoreArrayList.get(0)).toString());
	       	       ps.setString(2,((HSSFCell)cellStoreArrayList.get(1)).toString());
	       	       ps.setString(3,((HSSFCell)cellStoreArrayList.get(2)).toString());
	       	       ps.setString(4,((HSSFCell)cellStoreArrayList.get(3)).toString());
	       	       ps.setString(5,((HSSFCell)cellStoreArrayList.get(4)).toString());
	       	       ps.setString(6,((HSSFCell)cellStoreArrayList.get(5)).toString());
 
	       	     ps.executeUpdate();
 
	       	       }
 
	       } catch(Exception e) {
	    	   e.printStackTrace();
	       }
	       finally{
	    	   try{
 
	/////////////////////////////handle the results: ///////////////////////////////////
 
	       	   ResultSet rs = ps.executeQuery("SELECT * from lieder");
	           System.out.println(" Lieder :");
	           System.out.println(" ============== ");
 
	               while (rs.next()) {
	           		double s = rs.getDouble("CD_ID");
	           		String f = rs.getString("Albumtitel");
	           		String i = rs.getString("Interpret");
	           		double d = rs.getDouble("CREATED_DATE");
	           		double n = rs.getDouble("Track");
	           		String t = rs.getString("Titel"); 
	           		System.out.println(s + "   " + f + "             " + i + "        " + d + "      " + n + "   " + t);
	           }
	           ps.close();
	           con.close();
 
	           } catch(Exception ex) {
	                   System.err.print("Exception: ");
	                   System.err.println(ex.getMessage());
	           }
	}
}
}
```

wo und wie kann ich diese abschnitt mit Set bearbeiten?


----------



## vector_ever (1. August 2013)

Ok eine Idee ist, um von ArrayList zu Set zu konvertieren

deshalb  (ArrayList dataSheet)die drin die Ganze Attributen von Datasheet enthält (mit doppelte Werte) wird in Set gesetzt, dann nicht mehr doppelte Werte

```
Set set = new TreeSet(dataSheet);
```

aber es ist geben Fehler durch Ausführung:

```
Exception in thread "main" java.lang.ClassCastException: java.util.ArrayList cannot be cast to java.lang.Comparable
	at java.util.TreeMap.compare(Unknown Source)
	at java.util.TreeMap.put(Unknown Source)
	at java.util.TreeSet.add(Unknown Source)
	at java.util.AbstractCollection.addAll(Unknown Source)
	at java.util.TreeSet.addAll(Unknown Source)
	at java.util.TreeSet.<init>(Unknown Source)
	at Mysql.Excel2DB4.readExcelFile(Excel2DB4.java:73) --> refer to Set set = new TreeSet(dataSheet);
```

Ideen?


----------



## Writtscher (2. August 2013)

Bei mir klappt der Code. Ich habe natürlich die Datenbank weggemockt und durch einfache print lines ersetzt und die Ausgabe ist korrekt.


```
CD_ID	Albumtitel	Interpret	Year	Track	Titel
4711.0	Not That Kind	Anastacia	1999.0	1.0	Not That Kind
4710.0	Not That Kind	Anastacia	1999.0	2.0	I’m Outta Love
4712.0	Not That Kind	Anastacia	1999.0	3.0	Cowboys & Kisses
4713.0	Wish You Her	Pink Floyd	1964.0	1.0	Shine On You Crazy Diamond
4722.0	Freak of Nature	Anastacia	1999.0	1.0	Paid my Dues
```


```
public class Excel2DB3 {
    private final static Database database = new Database();

    public static void main(String[] args) throws Exception{
        List<List<Cell>> dataHolder = readExcelFile();
        saveToDatabase(dataHolder);
    }

    public static List<List<Cell>> readExcelFile(){
        List<List<Cell>> dataSheet = new ArrayList<>();
        try {
            FileInputStream file = new FileInputStream(new File("d:\\songs.xls"));
            HSSFWorkbook workbook = new HSSFWorkbook(file);
            HSSFSheet sheet = workbook.getSheetAt(0);
            Iterator<Row> rowIterator = sheet.iterator();
            while(rowIterator.hasNext()) {
                Row row = rowIterator.next();
                if(row.getRowNum() > 0)
                {
                    Iterator<Cell> cellIterator = row.cellIterator();
                    List<Cell> data = new ArrayList<>();
                    while(cellIterator.hasNext()) {
                        Cell cell = cellIterator.next();
                        data.add(cell);
                    }
                    dataSheet.add(data);
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return dataSheet;
    }


    private static void saveToDatabase(List<List<Cell>> dataHolder) {
        try {
            for (int i = 0; i < dataHolder.size(); i++) {
                List<Cell> cellStoreArrayList = dataHolder.get(i);
                database.newRow(cellStoreArrayList.get(0).toString(),
                        cellStoreArrayList.get(1).toString(),
                        cellStoreArrayList.get(2).toString(),
                        cellStoreArrayList.get(3).toString(),
                        cellStoreArrayList.get(4).toString(),
                        cellStoreArrayList.get(5).toString());
            }
            database.printRows();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
}
```


```
public class Database {
    private final List<List<String>> rows = new ArrayList<>();

    public Database() {
        List<String> firstRow = new ArrayList<>();
        firstRow.add("CD_ID\tAlbumtitel\tInterpret\tYear\tTrack\tTitel");
        rows.add(firstRow);
    }
    public void newRow(String first, String second, String third, String fourth, String fifth, String sixth) {
        List<String> newRow = new ArrayList<>();
        newRow.add(first + "\t" + second +"\t" + third + "\t" + fourth + "\t" + fifth + "\t" + sixth);
        rows.add(newRow);
    }

    public void printRows() {
        for (List<String> row : rows) {
            for (String s : row) {
                System.out.println(s);
            }
        }

    }
}
```

Jetzt zu deinem Code: 

"readExcelFile()" liefert eine Liste zurück und diese gibst du in eine Methode die ein Set als Parameter übernimmt? Das geht doch nicht, es kompiliert nicht mal. Dieser Code "cellStoreArrayList = (ArrayList) ((ArrayList) dataHolder).get(i);", wieso? 

Ich glaube dir fehlt es einfach an den Grundlagen von Java. Klar probierst du viel aus aber bevor ein Rennfahrer auf die Rennstrecke kann, muss er trotzdem erstmal in die Fahrschule. Ich hoffe du verstehst was ich meine. 

Also nochmal, bei mir funktioniert der Code so wie er ist, wieso er bei dir falsch ist weiß ich nicht. Debuggen hilft aber das willst du ja nicht. Somit hat sich das für mich erledigt.


----------



## HonniCilest (2. August 2013)

Ich gehe davon aus, dass du tatsächlich nur vermeiden möchtest einen Titel doppelt in einer Datenbank zu haben. Dafür geben Datenbanken aber bereits ein einfaches Mittel her: Primärschlüssel.
Primärschlüssel kann eine oder mehrere Spalten sein. Angenommen du definierst den Titel mit dem Interpret als Primärschlüssel, dann würde die Datenbank nur reagieren, wenn beide Werte gleich sind und nicht etwa nur der Interpret oder der Titel.

In deinem Code würde es sich vermutlich als SQLException äußern, auf welche du nur reagieren musst bzw. eben nichts tust außer mit den anderen Elementen weiterzumachen.


----------



## Writtscher (2. August 2013)

HonniCilest hat gesagt.:


> Ich gehe davon aus, dass du tatsächlich nur vermeiden möchtest einen Titel doppelt in einer Datenbank zu haben. Dafür geben Datenbanken aber bereits ein einfaches Mittel her: Primärschlüssel.
> Primärschlüssel kann eine oder mehrere Spalten sein. Angenommen du definierst den Titel mit dem Interpret als Primärschlüssel, dann würde die Datenbank nur reagieren, wenn beide Werte gleich sind und nicht etwa nur der Interpret oder der Titel.
> 
> In deinem Code würde es sich vermutlich als SQLException äußern, auf welche du nur reagieren musst bzw. eben nichts tust außer mit den anderen Elementen weiterzumachen.



Finde den Ansatz nicht gut, dass bei SqlException wegen Primärschlüssel Verletzung einfach weitergemacht wird. Hier in dem Fall besonders. Besser ist es die Ursache zu behandeln nicht den Exception. Ich kann mir nämlich nicht vorstellen, dass das PreparedStatement oder der darunterliegende Code falsch arbeitet. Mit einfachem Debuggen ists bestimmt schnell behoben.


----------



## HonniCilest (2. August 2013)

Die Ursache für die Exception oben ist einfach, dafür braucht man keinen Debugger. dataSheet enthält wiederum verschiedene ArrayLists und diese sind nicht Compareable. Das Set benötigt aber Comparable Elemente um die natürliche Reihenfolge herzustellen und doppelte Einträge zu löschen.

Warum sollte eine Exception in diesem Fall schlecht sein? Der Türsteher sagt einfach nur "Nein du kommst hier nicht rein, nächster Bitte." Writtscher kann so bei seinen ArrayLists bleiben.

Ansonsten müsste er einen Comperator schreiben oder ähnliches.

Edit: Der Weg mit der Exception hätte natürlich den Vorteil, dass man bestimmte Elemente definieren kann, die nicht gleich sein dürfen, d.h. wenn gewollt wäre es möglich einen Titel nur 1x aufzuführen unabhängig, ob er auf dem Interpretenalbum ist oder auf eine Various Artists Disc.

Wenn wirklich alles gleich sein soll dann würde ich es hiermit probieren:

```
if dataSheet.contains(data) { datasheet.add(data); }
```


----------



## Writtscher (2. August 2013)

Der Türstehervergleich zieht nicht, denn ein Türsteher wäre eher eine Überprüfung also 

```
if türsteher.hältFürAngebracht(mich) { disko.add(mich); }
```

Eine Exception ist ein Fehler und muss behandelt werden. Exception sind ein Zeichen das etwas falsch oder fehlerhaft ist. Aber ich will mich jetzt nicht darum streiten. Jeder hat seine eigenen Prinzipien. 

Der Threadersteller meint aber, er habe ein Problem, weil die Datensätze in der Datenbank doppelt sind, obwohl seine Excelliste diese Einträge nur einmal hat. Das bedeutet für mich, dass irgendwo ein Bug ist. Also würde ich mich jetzt auf die Suche machen (debuggen) wieso die Einträge in dem Sheet nicht doppelt und in der Liste auf einmal mehrmals auftreten. Einfach mal zusagen: Och Gott dann sind sie nun mal doppelt drin, obwohl sie nur einmal drin sein dürfen. Ich ignoriere einfach die Datensätze die falsch sind. Ist grob fahrlässig. Ich will gar nicht wissen was passiert wenn ein anderer Entwickler diesen Code reviewn würde.


----------



## HonniCilest (2. August 2013)

> Der Threadersteller meint aber, er habe ein Problem, weil die Datensätze in der Datenbank doppelt sind, obwohl seine Excelliste diese Einträge nur einmal hat.



Aha, das habe ich nämlich nicht so verstanden, dann wäre es natürlich etwas anderes. Ich hatte es so verstanden, dass die Excel bereits die Einträge mehrmals hat.

Ok anderer Vergleich 


```
try {
   Fluggast.geheDurchMetalldetektor();
} catch (WaffeGefundenException e) {
   Zollbeamter.schlageAlarmWegen(Fluggast);
   // nächster Fluggast
}
```

Auch wenn hier vorher eine Prüfung erfolgte, ob er ein Ticket hat, von außen ok zu sein scheint, vielleicht sogar grob abgetastet wurde, ein Mensch ist ;-) schlägt der Zutritt in den nächsten Bereich des Flughafens fehl.


----------



## Writtscher (2. August 2013)

HonniCilest hat gesagt.:


> Aha, das habe ich nämlich nicht so verstanden, dann wäre es natürlich etwas anderes. Ich hatte es so verstanden, dass die Excel bereits die Einträge mehrmals hat.



Ok dann haben wir aneinander vorbeigeredet, passiert =). Sein Excelsheet ist:


```
CD_ID	Albumtitel	  Interpret   created Track   Titel
--------------------------------------------------------------------------
4711	Not That Kind	Anastacia	1999	1	Not That Kind
4710	Not That Kind	Anastacia	1999	2	I’m Outta Love
4712	Not That Kind	Anastacia	1999	3	Cowboys & Kisses
4722	Wish You Her    Pink Floyd	1964	1	Shine On You Crazy Diamond
4713	Freak of Nature	Anastacia	1999	1	Paid my Dues
```

Das erfährst du zwei Threads vorher, dort hat er das selbe Problem nochmal. Weiß nicht wieso er zwei Threads braucht. Würde Excel doppelt haben, dann auf jeden Fall vorher mit contains überprüfen und nur dann in die Liste aufnehmen.


----------



## vector_ever (2. August 2013)

Zuerst, vielen Dank für die Antwort



> du in eine Methode die ein Set als Parameter übernimmt? Das geht doch nicht, es kompiliert nicht mal. Dieser Code "cellStoreArrayList = (ArrayList) ((ArrayList) dataHolder).get(i);", wieso?



Zweitens: Keine Ahnung wie ich son gemacht habe, na mir klar das ist ein großer Fehler, aber wahrscheinlich habe wollte es komplett mit Set anstatt arryList und vergessen noch mal zu arraylist zurück zu bearbeiten.

aber deine code hat nichts mit Mysql zu tun, und speichert keine Datei in Datenbank(obwohl das nicht Problem ist)
Aber ich bin die Code ausgeführt, aber trotzdem zeigt doppelte Werte


```
CD_ID	Albumtitel	Interpret	Year	Track	Titel
4711.0	Not That Kind	Anastacia	1999.0	1.0	Not That Kind
4710.0	Not That Kind	Anastacia	1999.0	2.0	I’m Outta Love
4713.0	Not That Kind	Anastacia	1999.0	3.0	Cowboys & Kisses
4722.0	Wish You Her	Pink Floyd	1964.0	1.0	Shine On You Crazy Diamond
4713.0	Not That Kind	Anastacia	1999.0	3.0	Cowboys & Kisses
4711.0	Not That Kind	Anastacia	1999.0	1.0	Not That Kind
4712.0	Love me	        Sp.Girls	998.0	1.0	Viva for ever
4710.0	Not That Kind	Anastacia	1999.0	2.0	I’m Outta Love
4722.0	Wish You Her	Pink Floyd	1964.0	1.0	Shine On You Crazy Diamond
```

Ps: ich habe deine code bearbeitet und ArrayList anstatt List benutzet


----------



## vector_ever (3. August 2013)

Jetzt mir klar, dass ich irgendwie   hashcode() und equal() methoden benutzen muss.


```
@Override
   public boolean equals(Object obj){  
  
        if(!(obj instanceof myClass))  
            return false;  
  
        return (attribute== ((myClass) obj1).getAttribute());   
    }  
  
  
    @Override
    public int hashCode(){  
  
        return  attribute.hashCode();    
    }
```

Aber das Problem ich weiß nicht wie es bearbeiten kann, was werden "myClass" und "attribute" sein ?


----------



## Writtscher (5. August 2013)

Equals and hashcode tutorial (3 sekunden googlen):

http://javarevisited.blogspot.com/2011/10/override-hashcode-in-java-example.html

Edit: Equals und hashcode wird dir nicht viel bringen, denn du iterierst über eine List von Cells und holst von diesen Cells den Value als String raus
**
*

```
ps.setString(6,((HSSFCell)cellStoreArrayList.get(5)).toString());
```


Weiß also nicht von was du equals und hashcode überschreiben möchtest.


----------



## vector_ever (5. August 2013)

> Equals and hashcode tutorial (3 sekunden googlen):
> 
> http://javarevisited.blogspot.com/20...a-example.html


danke, immer noch, aber das Problem nicht mit wie man Equals und hashcode Methoden benutzen kann, sonst wie kann ich die mit Poi Bibliothek von Apache  um Excel Datei zu lesen



> Weiß also nicht von was du equals und hashcode überschreiben möchtest



das weiß ich nicht auch nicht

```
@Override
   public boolean equals(Object obj){  
  
        if(!(obj instanceof myClass))  
            return false;  
  
        return (attribute== ((myClass) obj1).getAttribute());   
    }  
  
  
    @Override
    public int hashCode(){  
  
        return  attribute.hashCode();    
    }
```

Also weiß nicht was sindmy class und die attribute 
mein Zeil ist lese jede Zeile von excel Datei und addiere in Arraylist, danach Konvertier diese ArrayList zu HashSet und die doppelte werte zu ignorieren, danach Konvertier zurück nochmal zu Arraylist um in anderen Methode zu benutzen.

Jetzt bei Benutzung HashSet braucht man Equal und Hashcode Methoden zu bearbeiten.

hier habe ich diese Class selbst nicht erzeugt um genau wissen, welche Attributen zu vergleichen


----------

