# ausgelesene Datei in Datenbank schreiben



## achillesat (20. Dez 2010)

Ich lasse eine Datei auslesen und diese ausgelesene Datei soll er automatisch in die Datenbank schreiben.
Bisher habe ich folgenden Quellcode vorliegen: 


```
public class MySQLConnection {

	private static MySQLConnection instance = null;
	private static Connection conn = null;

	// Hostname
	private static String dbHost = "....";

	// Port -- Standard: 3306
	private static String dbPort = "....";

	// Datenbankname
	private static String database = "....";

	// Datenbankuser
	private static String dbUser = ".....";

	// Datenbankpasswort
	private static String dbPassword = ".....";

	private MySQLConnection() {
		try {

			// Datenbanktreiber für ODBC Schnittstellen laden.
			// Für verschiedene ODBC-Datenbanken muss dieser Treiber
			// nur einmal geladen werden.
			Class.forName("com.mysql.jdbc.Driver").newInstance();

			// Es wird die JDBC-ODBC-Brücke verwendet.
			conn = DriverManager.getConnection("jdbc:mysql://" + dbHost + "/"
					+ database, dbUser, dbPassword);

		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("Treiber nicht gefunden");
		}
	}

	private static Connection getInstance() {
		if (conn == null)
			new MySQLConnection();
		return conn;
	}

	public static void getName() {
		conn = getInstance();

		if (conn != null) {
			// Anfrage-Statement erzeugen.
//			Statement query;
			try {
				
				Statement stmt = conn.createStatement();

				// Ergebnistabelle erzeugen und abholen.
				String sql = "INSERT INTO KUNDEN(NAME,STRASSE,ORT,LAND)"
						+ " VALUES ('Max Mustermann','Alleestr. 8', 'Thüringen', 'Deutschland')";
				stmt.executeUpdate(sql);

			} catch (SQLException e) {
				e.printStackTrace();

			}
		}
	}

}
```





```
public class Test {

	public static void main(String[] args) {
		Reader text1;
		Reader text2;
		try {
			text1 = new FileReader(
					"C:\\Dokumente und Einstellungen\\Alex\\Desktop\\Text1.txt");

			text2 = new FileReader(
					"C:\\Dokumente und Einstellungen\\Alex\\Desktop\\Values.txt");
			BufferedReader txt1 = new BufferedReader(text1);
			BufferedReader txt2 = new BufferedReader(text2);
			Map<String, String> map = new HashMap<String, String>();

			String keys = txt1.readLine();
			String values = txt2.readLine();

			String[] keysArray = keys.split(";");
			String[] valuesArray = values.split(";");

			for (int i = 0, length = keysArray.length; i < length; i++) {
				map.put(keysArray[i].trim(), valuesArray[i].trim());
			}

//			System.out.println(map);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

//		MySQLConnection.getName();

	}
}
```


Bisher gebe weise ich den Spalten Name,Strasse etc. den Wert manuell zu, aber ich aus einer XML Datei die Daten automatisch in die DB schreiben lassen.

Meine XML Datei sieht so aus: 
Text1: 
[XML]Name;Straße;Ort;Bundesland;Land;Alter;Geburtstdatum;Hobbys;[/XML]

Values: 
[XML]Max Mustermann;Meierstr.;45333 Berlin; ;Deutschland;20;22.3.1092;Fußball;
Meier Müller;Allestraße ;33333 Hamburg; ;Deutschland;20;22.4.1222;Fußball;
Claudia Heinemann;... ;4444 Hamburg; ;Deutschland;20;21.03.1322;Fußball;
Herr Müller;Heinamnnssr;434242 HHHH; ;Deutschland;20;21.3333;Fußball;[/XML]


----------



## XHelp (20. Dez 2010)

1. ist das keine xml datei.
2. Es fehlt eine Frage


----------



## VfL_Freak (20. Dez 2010)

Moin,

und was genau ist Deine Frage ???:L

Gruß
Klaus


----------



## achillesat (20. Dez 2010)

Ich möchte die Daten aus der Datei auslesen lassen und dann soll er die Daten automatisch erkennen und der z.B der Spalte "NAME" in der DB den Wert "Max Mustermann" aus der Datei geben...


----------



## XHelp (20. Dez 2010)

Das ist immer noch keine Frage...
Fang doch erstmal damit an, dass du die Datei ausliest und den inhalt z.B. auf die Konsole schreibst.


----------



## achillesat (21. Dez 2010)

Das die Datei ausgelesen wird und der Inhalt auf der Konsole ausgegeben wird habe ich schon gemacht. 
Gibt es irgendwelche bestimmten Befehle wie man den ausgelesenen Code automatisch in die DB schreiben lässt? 
Wenn ich zwei txt Dateien haben die so aussehen: 

[XML]Name;Straße;Ort;Bundesland;Land;Alter;Geburtstdatum;Hobbys;
[/XML]

[XML]Max Mustermann;Meierstr.;45333 Berlin; ;Deutschland;20;22.3.1092;Fußball;
Meier Müller;Allestraße ;33333 Hamburg; ;Deutschland;20;22.4.1222;Fußball;
Claudia Heinemann;... ;4444 Hamburg; ;Deutschland;20;21.03.1322;Fußball;
Herr Müller;Heinamnnssr;434242 HHHH; ;Deutschland;20;21.3333;Fußball;[/XML]


Bisher habe ich die Sachen manuell eingegeben 

```
try {
                
                Statement stmt = conn.createStatement();
 
                // Ergebnistabelle erzeugen und abholen.
                String sql = "INSERT INTO KUNDEN(NAME,STRASSE,ORT,LAND)"
                        + " VALUES ('Max Mustermann','Alleestr. 8', 'Thüringen', 'Deutschland')";
                stmt.executeUpdate(sql);
 
            } catch (SQLException e) {
                e.printStackTrace();
 
            }
```

Nun möchte ich alle Zeilen auslesen lassen und die DB schreiben lassen. Automatisch passieren soll das er den Spalten (Name,Strasse,Ort,Land) automatisch die werte aus der txt Datei zuweisen soll. Ich weiß leider nicht wie das geht? Ich hab mal was mit einem PreparedStatement gelesen kann das sein?!


----------



## ARadauer (21. Dez 2010)

> Map<String, String> map = new HashMap<String, String>();
> 
> String keys = txt1.readLine();
> String values = txt2.readLine();


im Grunde ist eine Map Falsch, du liest aus txt1 die Struktur und aus txt2 die erste Zeile der Daten... aber was ist mit den anderen Zeilen?

Wenn schon dann brauchst du eine Liste mit Maps..

Aber egal sagen wir du machst mal eine Zeile in deiner Map dann kannst du dir zb so dein Insert Statement zusammenbauen...

(hab ich nicht getestet, kann falsch sein)


```
Map<String, String> map = new HashMap<String, String>();
      StringBuffer insertStr = new StringBuffer("INSERT INTO KUNDEN (");
      StringBuffer valuesStr = new StringBuffer("VALUES (");
      
      boolean first = false;
      for(String  key : map.keySet()){
         if(!first){
            insertStr.append(", ");
            valuesStr.append(", ");
         }            
         insertStr.append(key);
         valuesStr.append("'"+map.get(key)+"'");
         first = false;
      }

      String sql = insertStr.toString()+") "+valuesStr.toString()+")";
```



Noch eine andere Anmerkung zum Design: Lass MySQLConnection nur die Connection erzeugen und verwalten. Ich würde keine Datenbank Zugriffe in dieser Klasse machen. Dafür würde ich eine weitere Klasse schreiben. Schau dir vielelicht das DAO Pattern an. Du hast ein Kundenobjekt und du hat ein KundenDao das dir Kunden ließt, schreibt, updated, und deleted (CRUD). Diesem DAO gibst du von aussen beim Instanzieren die Connection von MYSqLConnection mit. warum?
Wenn du auf einaml 10 Objekte hast hast du 50 Methoden in MYSqLConnection die alles mögliche machen. Also sauber das ganze fachlich (unterschiedliche DAOs für die Fachobjekte) und technisch (MySQLConnection verbindet, DAO für Query aus) trenen.


----------



## henpara (21. Dez 2010)

Suchst du so etwas?

```
public String generateStatement(Datensatz p, int k) {
			String chd = "current timestamp";
			
			String statmt=null;
			

			if (//ZB Bedingung für Update statt Insert) { 
				
				statmt = updateStmt + 
				// Rest vom Statement abhängig von Spalten, die im String udateStmt           //gespeichert sein müssen
			} else if (//ggf nächster fall) { 
//statement zusammenbauen (mit ; beenden)
			} else if (//ggf nächster fall){
				statmt = updateStmt +
				//statement zusammenbauen (mit ; beenden)

			}
			return statmt;
		}
```

Das rufst du für jeden Datensatz auf, anschließend schreibst du den Befehl in eine Textdatei oder reihst alle Statements hintereinander und schickst ihn anschließend an die DB.


----------



## achillesat (21. Dez 2010)

Hab es nun fertig! Er wirft mir zwar jetzt eine Exception, weil ich Strings definiert habe, aber auch jeweils einmal int und date.



```
public static void InsertMap(Map<String, String> importmap) {
		conn = getInstance();

		if (conn != null) {
			// Anfrage-Statement erzeugen.
			// Statement query;
			try {
				PreparedStatement ps = conn
						.prepareStatement("INSERT INTO KUNDEN(NAME,STRASSE,ORT;LAND)\n"
								+ "Values(?,?");

				Statement stmt = conn.createStatement(
						ResultSet.TYPE_SCROLL_SENSITIVE,
						ResultSet.CONCUR_UPDATABLE);
				ResultSet rst = stmt.executeQuery("SELECT * FROM KUNDEN");
				rst.moveToInsertRow();

				for (Iterator<String> iterator = importmap.keySet().iterator(); iterator
						.hasNext();) {
					String key = iterator.next();
					String value = importmap.get(key);
					rst.updateString(key, value);

				}
```


```
com.mysql.jdbc.MysqlDataTruncation: Data truncation: Incorrect date value: '20' for column 'GEBURTSDATUM' at row 1
	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3591)
	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3525)
	at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1986)
	at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2140)
	at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2626)
	at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2111)
	at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2407)
	at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2325)
	at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2310)
	at com.mysql.jdbc.UpdatableResultSet.insertRow(UpdatableResultSet.java:903)
	at MySQLConnection.InsertMap(MySQLConnection.java:94)
	at Test.main(Test.java:48)
```


Im Internet hab ich bis jetzt nichts gefunden. In der TXT Datei und in der DB ist an der 6 Stelle ein DATE (Geburtsdatum) und an der 8 Stelle ein INT (Kundennummer), der Rest sind Strings. Kann mir da einer einen Tipp geben , mit was ich da lösen kann?? Hab bei goolge nach "automatisches typenerkennung" gegoogelt.


----------



## henpara (21. Dez 2010)

Übliches Problem. Das Datum muss richtig "formatiert" sein damit es die Datenbank als solches erkennt.
das heißt zB muss es vom Format TT-MM-JJJJ sein.

Du schaust am besten auf deiner DB, was die unter "Date-Format" versteht und formatierst den String in java so, daß er den Anforderungen gerecht wird.

mfG


----------

