# Blätterfunktion implementieren



## paedubucher (10. Aug 2007)

Hallo allerseits

Ich habe eine Applikation, welche Daten in Apache Derby speichert. Nun zeige ich an einigen Orten in meiner Applikation Grids mit Datensätzen aus. Dort werden jeweils nur 20 Einträge angezeigt, der User kann dann weiterblättern. Im Moment werden beim Aufstarten der Maske (GWT-Maske im Browser) sämtliche Datensätze ausgelesen und über das Netzwerk an den Browser gesendet (Remote Procedure Call). Das ist nicht gerade performant.

Bei MySQL gibt es z.B. einen LIMIT-Parameter beim SELECT-Befehl. So kann ich immer nur z.B. 20 Datensätze auf einmal auslesen. Nun könnte ich z.B. ein folgendes Query erstellen:


```
SELECT * FROM foo WHERE id > ? LIMIT 20
```

So könnte ich z.B. immer die letzte ID übergeben, die in meinem Grid angezeigt wird.

Wie kann man sowas bei Apache Derby lösen? Der LIMIT-Operator scheint nämlich zu fehlen (kein SQL-Standard?). Gibt es dafür einen Ansatz, bei dem ich nicht immer die ganze Tabelle auslesen und dann die Einträge im Java-Code durchrattern muss?

Vielen Dank für die Hilfe!


----------



## André Uhres (10. Aug 2007)

LIMIT scheint ein MySQL feature zu sein und kein SQL Befehl.
Vielleicht solltest du versuchen, eine bessere Querystrategie zu finden.


----------



## paedubucher (10. Aug 2007)

Dass ich LIMIT nicht verwenden kann, ist mir klar. Darum brauche ich nun irgend etwas "ähnliches", dass die Anzahl der zurückgelieferten Datensätze auf einen bestimmten Wert einschränkt. Gibt es vielleicht eine JDBC-Lösung, der SQL-Standard kennt sowas offenbar nicht.


----------



## SlaterB (10. Aug 2007)

es muss doch eine SQL-Beschreibung für deine komische Datenbank geben?
nach grober google-Suche habe ich irgendwo 
(
http://www.tutego.com/blog/javainsel/2006/02/inselraus-die-datenbank-derby.html
)
'wie DB2' gelesen, und dort

SELECT 
FROM 
WHERE 
ORDER BY 
FETCH FIRST 3 ROWS ONLY;
gefunden

http://mysite.verizon.net/Graeme_Birchall/id1.html

-----------

Strohhalm: Hibernate verwenden, dort eine Query mit maxResults setzen und schauen was für SQL rauskommt


----------



## yajp (10. Aug 2007)

hi,
der Artikel hier beschäftigt sich mit Deinem Problem.
hth


----------



## paedubucher (10. Aug 2007)

yajp hat gesagt.:
			
		

> hi,
> der Artikel hier beschäftigt sich mit Deinem Problem.
> hth



Wunderbar, gleich oben auf Seite 2 wird auf die Methode setMaxRows(int rows) verwiesen, womit man einem (Prepared)Statement die Anzahl mitgeben kann.

Ich habe nun meine select()-Methode angepasst:


```
public List select(int fromId, int amount) {
 // SELECT * FROM tabelle WHERE id > fromId;
}
```

Beim Blättern übergebe ich einfach die ID des Datensatzes, der ganz am Ende angezeigt wird. So habe ich immer die Datensätze, die ich wirklich brauche.

Vielen Dank!


----------



## paedubucher (10. Aug 2007)

SlaterB hat gesagt.:
			
		

> es muss doch eine SQL-Beschreibung für deine komische Datenbank geben?



Apache Derby ist nicht komisch, die ist sogar in Java SE 6 standardmässig mit dabei (unter dem "Decknamen" JavaDB).



			
				SlaterB hat gesagt.:
			
		

> nach grober google-Suche habe ich irgendwo
> (
> http://www.tutego.com/blog/javainsel/2006/02/inselraus-die-datenbank-derby.html
> )
> ...



Naja, DB2 wäre doch etwas mit Kanonen auf Spatzen geschossen...



			
				SlaterB hat gesagt.:
			
		

> Strohhalm: Hibernate verwenden, dort eine Query mit maxResults setzen und schauen was für SQL rauskommt



Auch Hibernate ist wohl für mein mini-Tool übertrieben, intern wird wohl aber auch setMaxRows() verwenden.


----------



## SlaterB (10. Aug 2007)

musst du nicht auch noch nach id sortieren?
oder hast du das nur der Übersichtlichkeit halber weggelassen?

> Naja, DB2 wäre doch etwas mit Kanonen auf Spatzen geschossen... 

du sollst ja nicht DB2 verwenden, sondern nur schauen,  ob deren SQL-Syntax bei dir funktioniert 
aber dem Artikel nach gibts das ja leider nicht


----------



## André Uhres (10. Aug 2007)

paedubucher hat gesagt.:
			
		

> Dass ich LIMIT nicht verwenden kann, ist mir klar. Darum brauche ich nun irgend etwas "ähnliches",
> dass die Anzahl der zurückgelieferten Datensätze auf einen bestimmten Wert einschränkt..


Mit "bessere Querystrategie" meine ich natürlich nicht ein blosses Nachahmen von LIMIT.
Eine bessere Strategie müsste so aussehen, daß durch *logische* Eingrenzungen 
nicht zuviel Datensätze im ResultSet zurückkommen.
Beispiel:
Anstatt durch sämtliche Kunden der Datenbank zu blätter, 
könnte man durch die Kunden mit dem Namen "Schmit" blättern:
WHERE Name LIKE 'Schmit%'


----------



## semi (11. Aug 2007)

paedubucher hat gesagt.:
			
		

> ...
> Auch Hibernate ist wohl für mein mini-Tool übertrieben, intern wird wohl aber auch setMaxRows() verwenden.


Nein. Für Derby gibt es in Hibernate keine Unterstützung für LIMIT.

Auszug aus DerbyDialect
	
	
	
	





```
...
public boolean supportsLimit() {
   return false;
}

public boolean supportsLimitOffset() {
   return false;
}
...
```
Du wirst es so lösen müssen, wie André vorgeschlagen hat. Mit dem Datensatz anfangen, der dem letzten eingelesenen folgt (0 am Anfang) und setMaxRows verwenden.

z.B. (mit 0 als Id anfangen und dann mit der Id des letzten Datensatzes, den du eingelesen hast)
	
	
	
	





```
SELECT p.id, ...
FROM Person p
WHERE ...
  AND p.id > ?
ORDER BY p.id
```


----------

