SQL Queries mit Spring aus dem Java Quellcode auslagern

veröffentlicht am 04. Mai 2012

Wer häufiger mit Datenbanken arbeitet, kennt das Problem: längere SQL Queries werden in Java meist mit einem StringBuilder zusammengesetzt und sind schwieriger zu warten als ausgelagerte Queries (z.B. wenn man die Query einmal kopieren und direkt im Query Browser testen möchte). Heute habe ich eine ebenso einfache wie auch geniale Möglichkeit kennengelernt, um SQL Queries mit Spring auszulagern.

Vor einiger Zeit habe ich bereits beschrieben, wie man Properties mit dem PropertySourcesPlaceholderConfigurer von Spring einbinden kann. Diesen Mechanismus kann man auch dafür nutzen, um SQL Queries auszulagern.

Als Ausgangsbasis dient folgende SQL Query, die – soweit wie möglich – lesbar formatiert im Quellcode untergebracht wurde:

public class InlineSQLExample {

	public User getUser() {

		final StringBuilder sqlBuilder = new StringBuilder();
		sql.append(" SELECT ");
		sql.append(" 	* ");
		sql.append(" FROM ");
		sql.append(" 	users ");
		sql.append(" WHERE ");
		sql.append(" 	username = :username AND ");
		sql.append(" 	password = :password ");
		final String sql = sqlBuilder.toString();

		// do some db stuff here
	}
}

Die Query schreibt man nun in eine ganz normale Properties Datei im XML Format und vergibt einen aussagekräftigen und gleichzeitig eindeutigen Schlüssel:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
	<comment>This comment is optional</comment>
	<entry key="getUserQuery">
		SELECT
			*
		FROM
			users
		WHERE
			username = :username AND
			password = :password
	</entry>
</properties>

Unter der Annahme, dass die Properties Datei mit GetUserQuery.xml benannt worden ist und auf oberster Ebene im Classpath liegt, können die Einträge (im Beispiel nur ein Eintrag) aus der Properties Datei wie folgt über die Spring Konfigurationsdatei verfügbar gemacht werden:

<bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
	<property name="location" value="classpath:GetUserQuery.xml" />
</bean>

Die Query kann dann über die Annotation @Value in die entsprechende Klasse eingesetzt werden. Das obige Beispiel sieht dann so aus:

public class OutsourcedSQLExample {

	@Value("${getUserQuery}")
	private String sql;

	public User getUser() {
		// do some db stuff here
	}
}

Die Vorteile liegen klar auf der Hand: die SQL Queries können unkompliziert bearbeitet und kopiert werden, ohne das StringBuilder.append() Gerüst drum herum bauen zu müssen. Außerdem steigt die Lesbarkeit und damit auch Wartbarkeit immens.

Kommentare

Interessant, an diese Verwendungsart von Properties Files habe ich noch nie gedacht. Wie würdest du deinen Ansatz mit der Verwendung von MyBatis (http://www.mybatis.org) vergleichen? Oder mit jOOQ (http://www.jooq.org)

Kommentar #1 von Lukas Eder am 22. November 2013


Hallo Lukas,

jOOQ habe ich bisher noch nie verwendet, deshalb kann ich mit jOOQ keinen Vergleich anstellen. Bei MyBatis verwendet man natürlich XML Dateien zum Hinterlegen der Queries und Mappings. Ist für sehr komplexe Abfragen natürlich sehr nützlich. Ansonsten würde ich immer Hibernate oder das JPA vorziehen.

Gruß
Patrick

Kommentar #2 von Patrick am 23. November 2013


Hinterlasse einen Kommentar