groovy und couchdb - berlin expert...
TRANSCRIPT
18.04.2011
Groovy und CouchDB
Ein traumhaftes Paar
Thomas Westphal
Herzlich Willkommen
Thomas Westphal
► Software Engineer @ adesso AG
► Projekte, Beratung, Schulung
► www.adesso.de
18.04.2011 Groovy und CouchDB2
Agenda
►Warum?
►Groovy
► CouchDB
► 4 Wege
►Was haben wir davon?
18.04.2011 Groovy und CouchDB3
Warum?
18.04.2011 Groovy und CouchDB4
► Ausdrucksschwacher Code
► Altlasten in Java
► RDBMS
Ausgangsbasis
18.04.2011 Groovy und CouchDB5
Groovy
Wie?
Ausgangsbasis
18.04.2011 Groovy und CouchDB6
CouchDBDaten
Arten von Daten
18.04.2011 Groovy und CouchDB7
Strukturiert
► Beispiel Kommentar
Unstrukturiert
► Beispiel Kommentar
► Beispiel Umfragen
Strukturierte Daten
18.04.2011 Groovy und CouchDB8
class Artikel {
String titel
String text
Map<String, Kommentar> kommentare
}
class Kommentar {
String email
String text
Date erstellungsZeitpunkt
}
Beispiel Kommentar
Unstrukturierte Daten
18.04.2011 Groovy und CouchDB9
Beispiel Umfragen
def formulardaten1 = [
formularName: 'Umfrage1'‚
name: 'Westphal'‚
vorname: 'Thomas'
]
def formulardaten2 = [
formularName: 'Testformular2'‚
kanal: '1'‚
nutzer: [
name: 'Westphal'‚
vorname: 'Thomas']
]
Groovy
18.04.2011 Groovy und CouchDB10
Was ist Groovy?
Groovy
… ist eine dynamische Sprache für die JVM.
► Elemente aus Sprachen wie Python, Ruby und Smalltalk
► Java-ähnliche Syntax
► seit 2003
► aktuelle Version 1.7.8
► http://groovy.codehaus.org
18.04.2011 Groovy und CouchDB11
Groovy
Dynamisch
► optionale Typisierung (Keyword def)
► Skriptfähigkeit
► Meta-Programmierung (Meta Object Protocol)
► AST-Transformation
Java Plattform
► läuft auf jeder JVM
► Zugriff auf jegliche Java-Bibliotheken (Jakarta Commons, JUnit)
► Zugriff von Java auf Groovy-Objekte
18.04.2011 Groovy und CouchDB12
Groovy
Features (Auswahl):
► Expressive Syntax
► Native Schreibweise für Listen und Maps
► Builder (HTTPBuilder, JsonGroovyBuilder)
► GPath
► Grails
18.04.2011 Groovy und CouchDB13
CouchDB
18.04.2011 Groovy und CouchDB14
Was ist
CouchDB?
CouchDB
… ist eine dokumentenorientierte Datenbank.
► Cluster of unreliable commodity hardware Data Base
► seit 2005
► aktuelle Version 1.0.2
► http://couchdb.apache.org
18.04.2011 Groovy und CouchDB15
CouchDB
Ein anderer Weg!
18.04.2011 Groovy und CouchDB16
JSON:
{„rechnungsnummer“: 19881,„rechnungsbetrag“: 35.75,„kunde“: {„name“: „Firma Pahl & Co.“,„adresse“: {„ort“: „Braunschweig“,„strasse“: „Kaiserstr. 19“
}}
}
Reale Daten Reale Dokumente
CouchDB
Ein anderer Weg!
18.04.2011 Groovy und CouchDB17
Adresse 2:
...„adresse“: {
„ort“: „Halle/Saale“„postfach“: „0815“
}...
Schemafrei
Adresse 1:
...„adresse“: {„ort“: „Braunschweig“„strasse“: „Kaiserstr. 19“
}...
CouchDB
Zugriff!
18.04.2011 Groovy und CouchDB18
POST
GET
PUT
DELETE
REST-HTTP-Schnittstelle
Create
Read
Update
Delete
CouchDB
Zugriff!
18.04.2011 Groovy und CouchDB19
REST-HTTP-Schnittstelle
Die Datenbank für Rechnungen erstellen:
curl -X PUT http://127.0.0.1:5984/rechnungen
Antwort:
{"ok":true}
CouchDB
Zugriff!
19.04.2011 Groovy und CouchDB20
REST-HTTP-Schnittstelle
Eine Rechnung erstellen:
curl -X POST http://127.0.0.1:5984/rechnungen -H 'Content-Type: application/json‘ -d '{"rechnungsnummer": 19881, ...}'
Antwort:
{"ok":true,"id":"a6fb0ae60611d87ced0c0dd6b30c023c","rev":"1-8dd617694443d5dfc6b55a9e57a8a4d3"}
CouchDB
Zugriff!
19.04.2011 Groovy und CouchDB21
REST-HTTP-Schnittstelle
Die Rechnung abrufen:
curl -X GET http://127.0.0.1:5984/rechnungen/a6fb0ae60611d87ced0c0dd6b30c023c
Antwort:
{"_id":"a6fb0ae60611d87ced0c0dd6b30c023c","_rev":"1-8dd617694443d5dfc6b55a9e57a8a4d3","rechnungsnummer":19881,...}
CouchDB
Zugriff!
19.04.2011 Groovy und CouchDB22
REST-HTTP-Schnittstelle
Eine Rechnung ändern:
curl -X PUT http://127.0.0.1:5984/rechnungen/a6fb0ae60611d87ced0c0dd6b30c023c -d '{"_id":"a6fb0ae60611d87ced0c0dd6b30c023c","_rev":"1-8dd617694443d5dfc6b55a9e57a8a4d3","rechnungsnummer": ... }'
Antwort:
{"ok":true,"id":"a6fb0ae60611d87ced0c0dd6b30c023c","rev":"2-06d624eadf589bd8d2eaf99af36641af"}
CouchDB
Zugriff!
19.04.2011 Groovy und CouchDB23
REST-HTTP-Schnittstelle
Eine Rechnung löschen: So nicht!
curl -X DELETE http://127.0.0.1:5984/rechnungen/a6fb0ae60611d87ced0c0dd6b30c023c
Antwort:{"error":"conflict","reason":"Document update conflict."}
Eine Rechnung löschen:
curl -X DELETE http://127.0.0.1:5984/rechnungen/a6fb0ae60611d87ced0c0dd6b30c023c?rev=2-06d624eadf589bd8d2eaf99af36641af
Antwort:{"ok":true,"id":"a6fb0ae60611d87ced0c0dd6b30c023c","rev":"3-1fd850455664ff9c32fec6b9bbd4545c"}
CouchDB
Zugriff? Views!
18.04.2011 Groovy und CouchDB24
Query-Engine
► = Ansichten
► MapReduce
► JavaScript
► Ergebnis: Schlüssel-Werte Paare
► temporäre Views
► permanente Views = Designdokumente
CouchDB
Zugriff? Views!
19.04.2011 Groovy und CouchDB25
Query-Engine
Rechnungen filtern und nach Rechnungsnummer sortieren:
function(doc) {if (doc.rechnungsnummer) {emit({"rechnungsnummer":doc.rechnungsnummer}, doc);
}}
CouchDB
Zugriff? Views!
19.04.2011 Groovy und CouchDB26
Query-Engine
Rechnungen filtern und nach Rechnungsnummer sortieren:
curl -X GET http://localhost:5984/rechnungen/_design/rechnungen/_view/alle
Antwort:
{"total_rows":3,"offset":0,"rows":[ {"id":"a6fb0ae60...","key":{"rechnungsnummer“...}},{"id":"a6fb0ae60...","key":{"rechnungsnummer“...}}, {"id":"a6fb0ae60...","key":{"rechnungsnummer"...}}]}
CouchDB
Zugriff? Views!
19.04.2011 Groovy und CouchDB27
Query-Engine
Rechnungen filtern mit Parameter (Browser):
http://localhost:5984/rechnungen/_design/rechnungen/_view/alle?key={rechnungsnummer:19882}
Antwort:{"total_rows":3,"offset":1,"rows":[{"id":"a6fb0ae606...78","key":{"rechnungsnummer“...}}]}
CouchDB
Zugriff? Views!
19.04.2011 Groovy und CouchDB28
Query-Engine
Rechnungen und Artikel in getrennten Dokumenten - alle Rechnungen mit
deren Artikel (JOIN) anzeigen:
function(doc) {if (doc.rechnungsnummer && !doc.artikelnummer) {// Dies ist eine Rechnungemit({"rechnungsnummer":doc.rechnungsnummer}, doc);
}if (doc.rechnungsnummer && doc.artikelnummer) {// Dies ist ein Artikelemit({"rechnungsnummer":doc.rechnungsnummer,
"artikelnummer":doc.artikelnummer}, doc);}
}
4 Wege
18.04.2011 Groovy und CouchDB29
4 Wege
18.04.2011 Groovy und CouchDB30
jcouchdb Groovy GrailsEktorp
4 Wege
18.04.2011 Groovy und CouchDB31
jcouchdb Groovy GrailsEktorp
jcouchdb
… ist ein Java 5 CouchDB Treiber.
► für dynamische Daten und POJOs
► nutzt die svenson JSON Bibliothek
► aktuelle Version 1.0.1
► http://code.google.com/p/jcouchdb
18.04.2011 Groovy und CouchDB32
jcouchdb
jcouchdb
Kontakt!
18.04.2011 Groovy und CouchDB33
org.jcouchdb.db.Database
Verbindung zur CouchDB herstellen:
def couchDb = new Database(‘localhost’, ‘artikel’)
public class Kommentar extends org.jcouchdb.document.BaseDocument {
private String email;private String text;private Date erstellungsZeitpunkt;
@org.svenson.JSONProperty(value = "type", readOnly = true)public String getType() {
return Kommentar.class.getSimpleName();}
public String getEmail() { return email; }...
}
jcouchdb
Java: Strukturierte Daten
18.04.2011 Groovy und CouchDB34
Beispiel Kommentare
Kommentar kommentar1 = new Kommentar();kommentar1.setEmail("[email protected]");kommentar1.setText("Reaktion 1");...
Map<String, Kommentar> kommentare = new HashMap<String, Kommentar>();kommentare.put("kommentar1", kommentar1);kommentare.put("kommentar2", kommentar2);
Artikel artikel = new Artikel();artikel.setTitel("Java und jcouchdb");artikel.setText("Objekte mit Java und jcouchdb in die CouchDb speichern...");artikel.setKommentare(kommentare);
couchDb.createDocument(artikel);
jcouchdb
Java: Strukturierte Daten
18.04.2011 Groovy und CouchDB35
Beispiel Kommentare
Artikel artikel = new Artikel(titel: "Groovy und jcouchdb",text: "Objekte mit Groovy und jcouchdb in die CouchDb speichern...",kommentare: [
kommentar1: new Kommentar(email: "[email protected]", text: "Reaktion 1"),
kommentar2: new Kommentar(email: "[email protected]", text: "Reaktion 2")
])
couchDb.createDocument(artikel)
jcouchdb
Groovy: Strukturierte Daten
18.04.2011 Groovy und CouchDB36
Beispiel Kommentare
Map<String, String> kommentar1 = new HashMap<String, String>();kommentar1.put("email", "[email protected]");kommentar1.put("text", "Reaktion 1");...
Map<String, Map<String, String>> kommentare = new HashMap<String, Map<String, String>>();
kommentare.put("kommentar1", kommentar1);kommentare.put("kommentar2", kommentar2);
Map<String, Object> artikel = new HashMap<String, Object>();artikel.put("titel", "Java und jcouchdb");artikel.put("text", "Maps mit Java und jcouchdb in die CouchDb speichern...");artikel.put("kommentare", kommentare);
couchDb.createDocument(artikel);
jcouchdb
Java: Unstrukturierte Daten
18.04.2011 Groovy und CouchDB37
Beispiel Kommentare
couchDb.createDocument([titel: "Groovy und jcouchdb",text: "Maps mit Groovy und jcouchdb in die CouchDb speichern...",kommentare: [
kommentar1: [email: "[email protected]", text: "Reaktion 1"],kommentar2: [email: “[email protected]", text: "Reaktion 2"]
]])
jcouchdb
Groovy: Unstrukturierte Daten
18.04.2011 Groovy und CouchDB38
Beispiel Kommentare
4 Wege
18.04.2011 Groovy und CouchDB39
jcouchdb Groovy GrailsEktorp
4 Wege
18.04.2011 Groovy und CouchDB40
jcouchdb Groovy GrailsEktorp
Ektorp
… ist eine Java Persistenz API für CouchDB.
► für dynamische Daten und POJOs
► nutzt die Jackson JSON Bibliothek
► aktuelle Version 1.1.1
► http://code.google.com/p/ektorp
18.04.2011 Groovy und CouchDB41
Ektorp
Ektorp
Kontakt!
18.04.2011 Groovy und CouchDB42
org.ektorp.CouchDbConnector
Verbindung zur CouchDB herstellen:
def httpClient = new StdHttpClient.Builder().host(‘localhost’).port(5984).build()
def instance = new StdCouchDbInstance(httpClient)
CouchDbConnector couchDb = new StdCouchDbConnector(‘artikel’, instance)
@org.codehaus.jackson.annotate.JsonIgnoreProperties( ['id', 'revision'] )@org.codehaus.jackson.map.annotate.JsonSerialize(include=Inclusion.NON_NULL)class Kommentar {
@org.codehaus.jackson.annotate.JsonProperty("_id")String id
@org.codehaus.jackson.annotate.JsonProperty("_rev")String revision
String emailString textDate erstellungsZeitpunktString type = Kommentar.class.getSimpleName()
}
Ektorp
Groovy: Strukturierte Daten
18.04.2011 Groovy und CouchDB43
Beispiel Kommentare
Kommentar kommentar1 = new Kommentar();kommentar1.setEmail("[email protected]");kommentar1.setText("Reaktion 1");
...
Map<String, Kommentar> kommentare = new HashMap<String, Kommentar>();kommentare.put("kommentar1", kommentar1);kommentare.put("kommentar2", kommentar2);
Artikel artikel = new Artikel();artikel.setTitel("Java und Ektorp");artikel.setText("Objekte mit Java und Ektorp in die CouchDb speichern...");artikel.setKommentare(kommentare);
couchDb.create(artikel);
Ektorp
Java: Strukturierte Daten
18.04.2011 Groovy und CouchDB44
Beispiel Kommentare
Artikel artikel = new Artikel(titel: "Groovy und Ektorp",text: "Objekte mit Groovy und Ektorp in die CouchDb speichern...",kommentare: [
kommentar1: new Kommentar(email: "[email protected]", text: "Reaktion 1"),
kommentar2: new Kommentar(email: "[email protected]", text: "Reaktion 2")
])
couchDb.create(artikel)
Ektorp
Groovy: Strukturierte Daten
18.04.2011 Groovy und CouchDB45
Beispiel Kommentare
Map<String, String> kommentar1 = new HashMap<String, String>();kommentar1.put("email", "[email protected]");kommentar1.put("text", "Reaktion 1");...
Map<String, Map<String, String>> kommentare = new HashMap<String, Map<String, String>>();
kommentare.put("kommentar1", kommentar1);kommentare.put("kommentar2", kommentar2);
Map<String, Object> artikel = new HashMap<String, Object>();artikel.put("titel", "Java und Ektorp");artikel.put("text", "Maps mit Java und Ektorp in die CouchDb speichern...");artikel.put("kommentare", kommentare);
couchDb.create(artikel);
Ektorp
Java: Unstrukturierte Daten
18.04.2011 Groovy und CouchDB46
Beispiel Kommentare
couchDb.create([titel: "Groovy und Ektorp",text: "Maps mit Groovy und Ektorp in die CouchDb speichern...",kommentare: [
kommentar1: [email: "[email protected]", text: "Reaktion 1"],kommentar2: [email: “[email protected]", text: "Reaktion 2"]
]])
Ektorp
Groovy: Unstrukturierte Daten
18.04.2011 Groovy und CouchDB47
Beispiel Kommentare
4 Wege
18.04.2011 Groovy und CouchDB48
jcouchdb Groovy GrailsEktorp
4 Wege
18.04.2011 Groovy und CouchDB49
jcouchdb Groovy GrailsEktorp
HTTPBuilder
… ist ein Groovy Modul für HTTP-basierende Dienste.
► bietet einen RESTClient
► bietet Builder und Parser für JSON
► nutzt Apache's HttpClient Bibliothek
► aktuelle Version 0.5.1
► http://groovy.codehaus.org/modules/http-builder/home.html
18.04.2011 Groovy und CouchDB50
HTTPBuilder
Kontakt!
18.04.2011 Groovy und CouchDB51
groovyx.net.http.RESTClient
Verbindung zur CouchDB herstellen:
def couchDb = new RESTClient(‘http://localhost:5984’)
class Kommentar {
String emailString textDate erstellungsZeitpunktString type = Kommentar.class.getSimpleName()
}
HTTPBuilder
Groovy: Strukturierte Daten
18.04.2011 Groovy und CouchDB52
Beispiel Kommentare
Artikel artikel = new Artikel(titel: ‘Groovy und HTTPBuilder’,text: ‘Objekte mit Groovy und HTTPBuilder in die CouchDb speichern...’,kommentare: [
kommentar1: new Kommentar(email: ‘[email protected]’, text: ‘Reaktion 1’),
kommentar2: new Kommentar(email: ‘[email protected]’, text: ‘Reaktion 2’)
])
def response = couchDb.post(path: ‘artikel’,contentType: JSON, requestContentType: JSON,body: artikel)
HTTPBuilder
Groovy: Strukturierte Daten
19.04.2011 Groovy und CouchDB53
Beispiel Kommentare
def response = couchDb.put(path: "artikel/${uuid}", contentType: JSON, requestContentType: JSON,body: [
titel: 'Groovy und HTTPBuilder',text: 'Maps mit Groovy und HTTPBuilder in die CouchDb speichern...',kommentare: [
kommentar1: [ email: ‘[email protected]', text: 'Reaktion 1' ],kommentar2: [ email: ‘[email protected]', text: 'Reaktion 2' ]
]])
HTTPBuilder
Groovy: Unstrukturierte Daten
18.04.2011 Groovy und CouchDB54
Beispiel Kommentare
4 Wege
18.04.2011 Groovy und CouchDB55
jcouchdb Groovy GrailsEktorp
4 Wege
18.04.2011 Groovy und CouchDB56
jcouchdb Groovy GrailsEktorp
Grails CouchDB Plugin
… ist ein Grails Plugin für CouchDB.
► bietet GORM-Funktionalität
► nutzt die jcouchdb Bibliothek
► aktuelle Version 0.9.0
► http://www.grails.org/plugin/gorm-couchdb
18.04.2011 Groovy und CouchDB57
CouchDB Plugin
Grails CouchDB Plugin
Kontakt!
18.04.2011 Groovy und CouchDB58
Konfigurationsdatei
Datei DataSource.groovy:
couchdb {host = "localhost"port = 5984database = "artikel"username = ""password = ""
}dataSource {
configClass = CouchDomainConfiguration.class}
@grails.plugins.couchdb.CouchEntity(type='kommentar')class Kommentar {
String emailString textDate erstellungsZeitpunkt
static constraints = {}
}
Grails CouchDB Plugin
Grails: Strukturierte Daten
18.04.2011 Groovy und CouchDB59
Beispiel Kommentare
def kommentarInstance = new Kommentar(params)kommentarInstance.save(flush: true)
Grails CouchDB Plugin
Grails: Strukturierte Daten
18.04.2011 Groovy und CouchDB60
Beispiel Kommentare
► Speichern und Löschen:kommentarInstance.save( flush: true)kommentarInstance.delete(flush: true)
► Zusätzliche Felder:def id = kommentarInstance.iddef version = kommentarInstance.version
► Auslesen:def instance = Kommentar.get(id)def instanceList = Kommentar.list(params)def instanceTotal = Kommentar.count()
Grails CouchDB Plugin
Grails: Strukturierte Daten
18.04.2011 Groovy und CouchDB61
Beispiel Kommentare
4 Wege
18.04.2011 Groovy und CouchDB62
jcouchdb Groovy GrailsEktorp
4 Wege
18.04.2011 Groovy und CouchDB63
jcouchdb Groovy GrailsEktorp
Grails + strukturierte Daten
CouchDB + Groovy
jcouchdb und Ektorp
jcouchdb und Ektorp
jcouchdb
► CouchDB Plugin
► auch ohne Treiber möglich
► flexibel durch Annotations
► Out-of-the-Box CRUD
► CouchdDBUpdater
Groovy und CouchDB
18.04.2011 Groovy und CouchDB64
Was haben wir davon?
Groovy und CouchDB
► starke Ausdrucksmöglichkeiten in Groovy
> Listen und Maps
> JSON
> Groovy-Objekte
18.04.2011 Groovy und CouchDB65
Was haben wir davon?
Verständlich!
Groovy und CouchDB
► sehr einfacher Zugriff auf die CouchDB
> viele Wege
> einfaches JSON-Format
► Dokumente passen besser zu OOP und realen Objekten
18.04.2011 Groovy und CouchDB66
Was haben wir davon?
Einfach!
Groovy und CouchDB
► CouchDB ist
> schemalos
> sehr einfach replizierbar
18.04.2011 Groovy und CouchDB67
Was haben wir davon?
Flexibilität!
18.04.2011 Groovy und CouchDB68
Groovy und CouchDB
Einfachheitermöglicht den Blick für das
Wesentliche
Was haben wir davon?
18.04.2011 Groovy und CouchDB69
Vielen Dank für Ihre Aufmerksamkeit.
Relax!
Wir suchen Sie als
Software-Architekt (m/w)
Projektleiter (m/w)
Senior Software Engineer (m/w)