"Exzessiv" dynamisches generieren

Status
Nicht offen für weitere Antworten.

lumo

Top Contributor
wusste nicht wie ich das sonst nennen soll...
habe eine template klasse wo einfach ein array von objekten drin ist... und diverse funktonen definiert sind, die die liste handeln

Code:
public class ClassTemplate {
	private Object[] data
	...
}

lade dann aus einer datenbank eine tabelle
dabei lese ich

1) namen aus (string[])
2) datentypen aus (String[])
3) daten aus verschiedensten typen

nach bearbeitung habe ich folgendes:
1) namen aus [columnNames] (string[])
2) datentypen [columnDataTypes] aus (Class[])
3) daten [daten aus dem ResultSet] aus verschiedensten typen als Object array[]


dazu habe ich mir schon eine klasse geschrieben, die die datentypen in classes umwandelt
also der string "text" aus sql liefert mir die klasse java.lang.String zurück.

Code:
public class DataTypeMapper {
	...
	public static Class getType(final String dataType) {
	   return typeMap.get(dataType);
	}
	...
}

wenn ich mir alles in die cmd ausgeben lasse, kommt schon alles korrekt zurück...

Code:
	// i is der index einer for-schleife, die mir alle result-zeilen durchgeht
	System.out.println("("+i+")"+this.columnNames[i]+" has type "
		+db.DataTypeMapper.getType(this.columnDataTypes[i])
		+" filled with data: ["+rs.getObject(this.columnNames[i]+"]");

mein problem ist nun...
wie kann ich dynamisch ein objekt vom typ xy generieren, ohne vorher zu wissen was xy ist?
so hab ichs versucht, klappt aber nicht

Code:
	Object value = rs.getObject(this.columnNames[i]);
	Object type = db.DataTypeMapper.getType(this.columnDataTypes[i]);
	type variable = new type(value);

wozu ich das machen will?
somit könnte ich ALLE meine tabellen mit einer funktion schon korrekt laden lassen und müsste nur noch die generierte klasse an die funktion übergeben, ohne für 101 Tabellen (so viele sinds in meinem fall) eigene Klassen zu schreiben... (würde mir somit ne menge arbeit sparen)
 
Die Lösung sollten in deinem Fall Generics sein.
Hier mal ein Beispiel:
Code:
public class genericArray<T> {
   private T[] data;
   ...
}

wenn du dann ein generisches Objekt anlegst einfach:
Code:
 genericArray bsp = new genericArray<String>();

Wenns das in deinen Code einbaust, solltes du dein Ziel erreichen.
Wenn nicht einfach wieder melden.
 
Mit iBatis zB kannst du dir aus einem DB Schema deine Dao Klassen generieren lassen, mit "exzessiven dynamischen gegerieren" geht das meistens schief.
 
erstmal danke an euch zwei für eure antworten

@mhauert, das genericArray ist nicht das, das was ich suche
@maki, hab mir die beschreibung von iBatis jetzt mal durchgelesen...
weiss nicht so genau obs das ist was ich realisieren will;

habe mittlerweile eine vereinfachung gemacht (zwei klassen weniger!) und einen "workaround" für das dynamische erstellen der der Types gemacht;
werde morgen weiter dran arbeiten, und dann meine (hoffentlich) lösung hier posten (glaub, dass das recht kompakt gelöst werden kann!)
 
@mhauert
bins jetzt noch einmal durchgegangen.
das mit den generics ist ne gute idee, hier aber nicht mal nötig.
werd jetzt die daten in ein Object packen, somit kann ich alle datentypen halten, und nicht nur ein spezielles.

dazu hab ich noch ne classe gecoded, die mir die informationen hält, wie die daten heissen, und welchen typ sie haben
hier mal der code zum XHeader (was mir die column headers der tabelle hält und damit den datentyp speichert)

Code:
import java.util.Map;
import java.util.HashMap;

public class XHeader {

	// Map to map the field names with tis datatypes
	private Map<String, String> typeMap;
	
	public XHeader() {
		typeMap = new HashMap<String, String>();
	}
	 
	public String get(final String _Name) {
	   return this.typeMap.get(_Name);
	}
	
	public String add(String _Name, String _Type) {
		return this.typeMap.put(_Name, _Type);
	}
	
	//@todo nicht vollständig -> datetime etc ergänzen
	public static Object getRealType(final String dataType, String value) {
		if (dataType.equalsIgnoreCase("varchar") ||
			dataType.equalsIgnoreCase("text")) {
			return value;
		}
		else if (dataType.equalsIgnoreCase("bit")) {
			return Boolean.parseBoolean(value);
		}
		else if (dataType.equalsIgnoreCase("int") ||
			dataType.equalsIgnoreCase("smallint")) {
			return Integer.parseInt(value);
		}
		else if (dataType.equalsIgnoreCase("real") ||
				dataType.equalsIgnoreCase("float")) {
			return Float.parseFloat(value);
		}
		else
			return null;
	}
}

die dazu gehörigen daten, die ich aus meinem resultset erhalte, geb ich in eine liste vom typ object
somit habe ich die dateninformationen (types, fieldnames) getrennt von den daten und halte die redundanz recht klein.
Code:
	private List<Object> objects = new ArrayList<Object>();

gleichzeitig hab ich immer die information welcher typ es ist bereit und kann über die funktion
Code:
	getValueOf(String columnname)
den korrekten wert bekommen...

liege ich falsch?
bitte um feedback

PS: werds jetzt noch fertig implementieren und dann testen und das ergebnis hier posten
 
habs mir jetzt nicht genau durchgelesen.
Aber reflection ist vielleicht auch ein gutes stichwort, dass du dir ansehen solltest. damit kannst du klassen anahnd des Typ Namens instanzieren.
 
hab mittlerweile wieder was geändert...

reflection sieht sehr interessant aus, konnte jetzt aber nicht sehen, wie ich da meine klassen erzeuge und werte zuweise... ev. hab ich das übersehn oder was falsch verstanden...

bin mir auch nicht sicher ob das schneller geht als meine 2 hashmaps
eine statische hier:
Code:
private static final Map<String, Class> typeMap;
	 
	static {
	    typeMap = new HashMap<String, Class>();
	    typeMap.put("varchar", String.class);
	    typeMap.put("text", String.class);
	    
	    typeMap.put("bit", boolean.class);

	    typeMap.put("int", int.class);
	    typeMap.put("smallint", int.class);
	    
	    typeMap.put("real", float.class);
	    typeMap.put("float", float.class);
	    // etc.
	    // typeMap.put("datetime", String.class);
	}

und eine dynamische wo ich die column-namen hab und dann dahinter den java datentyp.class

*grad.etwas.verwirrt.bin*
meld mich später nochmal, wenn die verwirrung weg is
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben