4Max/shutterstock.com

10. Januar 2015 / von Iryna Schmidt

Datenbank-

anbindung

mit MyBatis

Was ist MyBatis?

MyBatis ist ein Framework für die Datenbankanbindung, das durch seine Einfachheit besticht. Es unterstützt benutzerdefinierten SQL-Code, Stored Procedures sowie ein fortgeschrittenes Mapping von komplexen Joins und Objektgraphen.

Die SQL-Anweisungen werden vom Entwickler geschrieben und in XML-Dateien gespeichert. MyBatis erstellt daraus automatisch PreparedStatement und verbirgt dazugehörigen JDBC-Code. Die Ergebnisse der SQL-Abfragen werden automatisch in den Objekten abgebildet.

Das Framework kann ein eigenes Transaktionsmanagement für die Operationen an der Datenbank einsetzen oder ein externes von Spring, EJB CMT, etc. nutzen.

MyBatis abstrahiert also von solchen Details der Datenbankkommunikation wie Laden der Treiber, Instanziieren und Managen der Connection, Verwalten der Transaktionen, etc.

Man muss trotzdem im Kopf behalten, dass MyBatis ein leichtgewichtiger SQL-Mapper und kein ORM ist. Somit beinhaltet dieses Framework keine proprietäre Query-Sprache und generiert kein SQL. Genauso wenig befasst es sich mit der Identität der Objekte. MyBatis bildet keinen Objekt-Cache im Sinne von ORM-Mapping. Es cached die Ergebnisse von Abfragen, unabhängig davon ob die Objekte mit der jeweiligen Identität bereits im Speicher vorhanden sind.

Wann ist MyBatis sinnvoll?

Auf der Suche nach einem geeigneten Framework für eine Datenbankanbindung könnte MyBatis das Mittel der Wahl sein, wenn:

  • Die Projektsprache Java, .NET oder Ruby/Ruby on Rails ist
  • Man direkt auf SQL-Ebene arbeiten will und nur das Umwandeln in Objekte dem Framework überlassen will
  • Eine Trennung von Datenbankzugriffscode vom restlichen Applikationscode erwünscht ist
  • Zuordnung von Tabellen zu Klassen von der Geschäftslogik entkoppelt sein soll

Spring Integration

Um die Entwicklungs- und Integrationsarbeit zu vereinfachen, vertraut die Mehrzahl von Java-Projekten heutzutage auf Spring-Stack. Der Spring-Stack besteht aus einer großen Anzahl von Java-APIs und Open-Source-Frameworks, vereinheitlicht und erleichtert deren Nutzung.

Die Integration von MyBatis in ein Projekt unter Verwendung von Spring ist recht komfortabel. Spring verwaltet Mapper und Sessions von MyBatis, erlaubt die Nutzung von Spring-Transaktionen und befreit den Applikationscode von MyBatis-Abhängigkeiten durch den Einsatz von Spring-Injections.

Eine detaillierte MyBatis-Spring-Integration Anleitung ist unter folgendem Link zu finden: http://mybatis.github.io/spring/getting-started.html

MyBatis ohne Spring

MyBatis kann auch ohne Spring benutzt werden. Allerdings muss man dann Infrastruktur-Code selbst schreiben.

Dafür benötigt man eine Instanz von SqlSession in jeder Methode, die Zugriffe auf die Datenbank durchführt.

InputStream inputStream = Resources.getResourceAsStream("/mybatis-config.xml");
SqlSessionFactory factory = newSqlSessionFactoryBuilder().build(inputStream);
SqlSession session = factory.openSession();
MyDBObjectMapper mapper = session.getMapper(MyDBObjectMapper.class);

Damit bekommt man ein Objekt, dass das Mapper Interface bereits implementiert und die in myMapper.xml oder über Annotationen vordefinierten Methoden für den Datenbankzugriff beinhaltet.

Zum Beispiel eine vordefinierte Methode im XML-Mapper könnte so aussehen:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.mybatis.example.MyDBObjectMapper">
<select id="selectMyDBObject" parameterType="int" resultType="MyDBObject">
select * from MyDBObjectTable where id = #{id}
</select>
</mapper>

Oder über Annotationen:

public interface MyDBObjectMapper {
   @Select("select * from MyDBObjectTable where id = #{id}")
   MyDBObject selectMyDBObject(int id);
}

Aufruf der select-Methode würde dann lauten:

MyDBObject myDBObject = mapper.selectMyDBObject(id);

Logischerweise liegen transaktionale Steuermechanismen wie commit und rollback sowie das Schließen der SqlSession in der Verantwortung des Entwicklers.

Der Einsatz von MyBatis ohne Spring ist sinnvoll, wenn …

  • das Spring-Framework keinen zusätzlichen Nutzen für das Projekt bringen würde und nur für die Integration von MyBatis benötigt wäre oder
  • im Projekt kein Spring eingesetzt werden darf oder
  • man die Kontrollebehalten möchte und eigenem Code mehr vertraut als der „Spring-Magic“.

MyBatis Caching

MyBatis verfügt über einen lokalen und einen Second-Level-Cache.

Der lokale Cache ist immer verfügbar und kann nicht abgeschaltet werden. Das ist im Wesentlichen eine Map mit SQL-Statements und dazugehöriger Ergebnis-Liste von Java Objekten. Dieser Cache kann über Parameter (vgl. localCacheScope) so konfiguriert werden, dass er entweder nach jedem SQL- Statement gelöscht wird oder am Ende jeder Transaktion.

Der Second-Level-Cache ist optional und wird, wenn verfügbar, immer als erstes ausgewertet. Im Unterschied zum lokalen Cache stehen die Objekte aus dem Second-Level-Cache mehreren Transaktionen zur Verfügung. Der Second-Level-Cache kann den Zugriff auf read-only Data optimieren. Über den Parameter readOnly kann man erzwingen, dass immer eine Kopie des Objekts gecached wird.

Objektcaching funktioniert nur für die Objekte vom Typ Serializable.

DB Migration mit MyBatis Generator

Für die Migration zwischen Datenbanken hat MyBatis einen flexiblen und leicht konfigurierbaren Generator entwickelt, der als Ant-Task oder Maven-Plugin in ein Continuous Build Environment integriert werden kann.

Der Generator scannt die Datenbanktabellen und generiert Artefakte für den Zugriff darauf. Das verringert den anfänglichen Aufwand in Bezug auf Erzeugen der Objekte und Konfigurationsdateien für die Datenbankkommunikation.

Zu den automatisch erzeugten Dateien gehören:

  • Die der Struktur der Tabellen entsprechenden Java POJOs (Plain Old Java Object). Die Hierarchie dieser Objekte kann konfiguriert werden (z.B. als single domain object für jede Tabelle).
  • Optional kann der Generator Java-Klassen für den Zugriff auf POJOs generieren.
  • MyBatis-kompartible SQL Mapper: Das sind XML Dateien, die SQL-Code für einfache CRUD (Create, Retrieve, Update, Delete) Operationen enthalten. Je nach Tabellenstruktur werden verschiedene Varianten von diesen Operationen generiert.

Somit liefert der Generator ein gutes Gerüst für den Zugriff auf die Quell- und Zieldatenbank. Höchstwahrscheinlich wird man an diesen Dateien noch einige Erweiterungen vornehmen wollen. So muss man zum Beispiel Joins und Stored Procedures weiterhin selber in die XML Datei schreiben. Dabei sind folgende Punkte wichtig:

Die XML-Dateien werden beim jedem neuen Lauf des MyBatis-Generators gemerged. Nur die im letzten Lauf generierten XML-Elemente werden überschrieben, die in benutzerdefinierten Elementen stehende Erweiterungen bleiben unverändert.

Das gilt nicht für die Java-Klassen. Nur wenn der Generator über ein Eclipse-Plugin in die Umgebung angebunden ist, können die Java-Dateien automatisch gemerged werden. Anderenfalls muss der Entwickler die Dateien bei jedem neuen Lauf per Hand mergen.

http://mybatis.github.io/generator/quickstart.html

Fazit

Der unschlagbare Vorteil von MyBatis Framework ist die Einfachheit und Zeitersparnis. Es gibt kaum einen schnelleren Weg, die Kommunikation mit der Datenbank aufzubauen.

Aus meiner Sicht lohnt es sich MyBatis für Projekte einzusetzen, in denen man eine kleine Datenhaltung hat und nur wenige SQL-Queries selbst schreiben muss. Anderes gesagt, MyBatis ist genau dann eine attraktive Alternative zu einem ORM-Framework, wenn die Features eines ausgereiften ORM nicht benötigt werden.

Autor

Iryna Schmidt
Iryna Schmidt
Weitere Artikel

Das könnte Sie auch interessieren