da es eine groovy-dsl einführung war, haben wir ein wichtiges prinzip der softwareentwicklung, nämlich die trennung von model und view, vernachlässigt. (zum erzeugen des create-statements hatten wir die create-funktionen im Table- und ColumnModel.) das möchten wir in diesem artikel nachholen.
unser beispiel:
angenommen sie entwickeln eine datenbankanwendung mit hunderten von tabellen und eine anforderung ist, dass die anwendung mit unterschiedlichen datenbanken läuft. mit unserer bisherigen lösung müssten wir für jeden datenbankdialekt eine eigene create-funktion implementieren. da wir unser model aber nicht mit noch mehr code überfrachten wollen, wählen wir einen anderen weg: groovy-temples. (anmerkung: wir gehen der einfachheit halber davon aus, dass es eine reine sql-anwendung ist und kein orm-framework verwendet wird)
groovy besitzt ein template framework, und mit der SimpleTemplateEngine wird es uns leicht gemacht, vorlagen für die create-statements je datenbank-typ zu erstellen und damit die create-statements zu generieren.
class ColumnModel {
/**
* Tabelle, zu der diese Column gehört
*/
TableModel table
/**
* name der column
*/
String name
/**
* datentyp
*/
String datatype
/**
* not null
*/
boolean notnull
}
einem groovy-template werden daten übergeben, die innerhalb des templates verwendet werden können.
in unserem fall übergeben wir ein TableModel-objekt mit dem namen "table". (code siehe weiter unten).
im template selbst können wir groovy-code ausführen:
- ${xxx}: mit dieser syntax wird der wert, den xxx liefert, im template ausgegeben
- <% xxx %>: hiermit wird xxx als groovy-code ins template eingebettet
zum besseren verständnis verwenden wir in unserem ersten template beide varianten.
unser template ist folgendermaßen strukturiert:
das template-code wurde nur zwecks erklärungen in mehrere zeilen aufgeteilt. würden wir das template wie hier verwenden kämen zu viele zeilenumbrüche zustande, da alle zeilenumbrüche auserhalb von groovy-code ausgegeben werden.
daher zusammenfassend unser endgültiges MySql-template (gespeichert in der datei MySql.tpl):
dazu bietet uns groovy mit der SimpleTemplateEngine die einfachste möglichkeit.
hier die nötigen schritte:
def engine = new SimpleTemplateEngine()
anmerkung: der einfachheit halber kann man die createTempate() und build() - schritte zusammenfassen:
für unser beispiel ergibt sich damit:
def builder = new TableBuilder();
def table = builder.table("test") {
column "id", datatype: "int", notnull: true
column "name", datatype: "text"
}
// Ausgabe
def engine = new SimpleTemplateEngine()
// Ausgabe für MySql
def template = engine.createTemplate(new File('MySql.tpl')).
make([table: table])
println "MySql-Statement:"
println template.toString()
// Ausgabe für Oracle
template = engine.createTemplate(new File('Oracle.tpl')).
make([table: table])
println "Oracle-Statement:"
println template.toString()
hier das erzielte ergebnis:
Oracle-Statement:
create table test (
id int not null,
name clob
);
create table test (
id int not null,
name text
);
danke für ihre aufmerksamkeit,
wir feuen uns über kommentare und anregungen.
Georgy:
Die einfachste (aber auch unsicherste) Variante ist:
1. Datei (z.B. "test.tab") mit der Tabellendefinition wie vorgeschlagen erstellen
2. Test.groovy so abwandeln:
builder = new TableBuilder(); // darf nicht mehr mit def definiert werden!
def tabledef = (new File('test.tab')).text // liest die Tabellendefinition
def table = evaluate("builder.$tabledef") // führt den Build-Prozess aus
// danach weiter mit der Ausgabe
erstellt von erich konicek, 01.04.2010 11:20 (vor 4 monat)
Wie kann man das Beispiel so umprogrammieren, dass die Informationen aus einer Datei gelesen werden. Das heißt, ich möchte einfach eine Datei haben, wo Folgendes steht:
table("test") {
column "id", datatype: "int", notnull: true
column "name", datatype: "text"
}
Die möchte ich dann in meinem Script laden und daraus die create-Anweisung generieren.
erstellt von Georgy, 31.03.2010 16:57 (vor 4 monat)