mybatis
Ich möchte kurz beschreiben, wie man mit mybatis auf RDBMS zugreifen kann.
Zunächst benötigt man folgende JARs:
mybatis.jar (Aktuell ist dies mybatis-3.0.2.jar)
derby.jar (Oder den JDBC-Treiber für eine andere DB)
Und schon kann es losgehen. Ach halt, eine sehr einfache Datenbank wird noch benötigt. Hier der DDL-Code für eine einfache Tabelle
Und wir pflegen noch ein paar Daten bereit
mybatis verbindet SQL-Befehle mit Java-Objekten über XML-Dateien.
mybatis erfordert eine Konfigurationsdatei in der beschrieben, wie auf die DB zugegriffen werden soll. Hier mal eine Demo-Datei
In der Datei db.properties stehen die Zugangsdaten für die Datenbank drin. Dies vereinfacht das Ändern, weil man nicht in der ganzen XML-Datei suchen muss
dbDriver=org.apache.derby.jdbc.EmbeddedDriver
dbUrl=jdbc:derby:testdb
dbUser=
dbPassword=
Im Beispiel wird nur eine Mapper-Datei (Person.xml) eingebunden, aber davon kann es beliebig viele geben:
Hier erkennt man schon eine select-Abfrage, die alle Datensätze aus der Tabelle liest. Über resultType wird eine Java-Klasse angegeben auf die die Reesultat-Spalten gemapped werden. Sofern nichts anderes angegeben, mapped mybatis Spalten auf namensgleiche Attribute der Java-Klasse. Also legen wir die Klasse Person an:
Und nun ein einfacher Aufruf:
Die Initialisierung von mybatis ist eigentlich immer gleich und muss natürlich nur einmal gemacht werden. Danach sehen Benutzungen immer so aus:
Man´erkennt auch, dass der Befehl "selectAllPersons" aus Person.xml aufgerufen wird. Dieser SQL-Befehl selektiert ja alle Records aus der Tabelle und mapped diese auf Java-Person-Objekte. Und da es mehrere Einträge gibt, rufen wir selectList auf.
Eigentlich alle Dateien, die von mybatis gelesen werden sollen, müssen über den ClassPath erreichbar sein. Hilfreich finde ich auch, wenn mybatis gute Logging-Informationen ausgibt. Wird log4j im Classpath gefunden, wird mit folgender log4j.properties alles geloggt.
log4j.rootLogger=DEBUG,stdout
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %d{DATE} %5p [%t] (%F\:%L) - %m%n
log4j.logger.com.ibatis=DEBUG
log4j.additivity.com.ibatis = false
log4j.additivity.java.sql = false
Und wenn es dann ausgeführt wird, sieht man:
9 Aug 2011 15:00:20,131 DEBUG [main] (Log4jImpl.java:27) - Created connection 21868771.
09 Aug 2011 15:00:20,131 DEBUG [main] (Log4jImpl.java:27) - ooo Connection Opened
09 Aug 2011 15:00:20,553 DEBUG [main] (Log4jImpl.java:27) - ==> Executing: select id,vorname,nachname from person
09 Aug 2011 15:00:20,553 DEBUG [main] (Log4jImpl.java:27) - ==> Parameters:
09 Aug 2011 15:00:20,600 DEBUG [main] (Log4jImpl.java:27) - <== Columns: ID, VORNAME, NACHNAME
09 Aug 2011 15:00:20,600 DEBUG [main] (Log4jImpl.java:27) - <== Row: 0, Turtle, Tortois
09 Aug 2011 15:00:20,600 DEBUG [main] (Log4jImpl.java:27) - <== Row: 1, Angela, Merkel
[ID:0, vorname:Turtle, nachname:Tortois]
[ID:1, vorname:Angela, nachname:Merkel]
09 Aug 2011 15:00:20,616 DEBUG [main] (Log4jImpl.java:27) - xxx Connection Closed
09 Aug 2011 15:00:20,616 DEBUG [main] (Log4jImpl.java:27) - Returned connection 21868771 to pool.
Neben select können natürlich auch insert, update, delete in Transaktionen (commit,rollback) ausgeführt werden. Ich finde es insbesondere sehr angenehm, dass man genau weiss, welcher Befehl da gegen die DB abgesetzt wird. Und häufig ist die erste Frage von DBA's, wie ein Programm schneller laufen könnte, doch immer: "Zeig mal Dein SQLl". Dies kann nun umgesetzt werden. Genauso einfach kann halt der optimierte SQL-Befehl schnell probiert werden. Meine Erfahrung mit anderen Frameworks ist, dass einfache Dinge auch einfach gehen, man aber oft die Schraube sucht an der man stellen muss, damit das Framework den SQL-Befehl absetzt, den man gerne abgesetzt hätte und in mybatis sofort hinschreiben kann. Zudem ist mybatis extrem einfach einzusetzen. Das Einrichten und Nutzen geht innerhalb von 5 Minuten!
mybatis hat also Vor- und Nachteile. Vorteil ist: Ich weiss genau mit welchem SQL-Befehl gearbeitet wird, weil ich ihn selbst hingeschrieben habe. Nachteil: Ich muss SQL-Befehle hinschreiben und kein Franework generiert dies für mich.
Zunächst benötigt man folgende JARs:
mybatis.jar (Aktuell ist dies mybatis-3.0.2.jar)
derby.jar (Oder den JDBC-Treiber für eine andere DB)
Und schon kann es losgehen. Ach halt, eine sehr einfache Datenbank wird noch benötigt. Hier der DDL-Code für eine einfache Tabelle
1 2 3 4 5 6 CREATE TABLE person (id INT NOT NULL, vorname VARCHAR(200), nachname VARCHAR(200), PRIMARY KEY (id) )
1 2 INSERT INTO person(id,vorname,nachname) VALUES(0,'Turtle', 'Tortois') INSERT INTO person(id,vorname,nachname) VALUES(1,'Angela', 'Merkel')
mybatis erfordert eine Konfigurationsdatei in der beschrieben, wie auf die DB zugegriffen werden soll. Hier mal eine Demo-Datei
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <properties resource="database/db.properties"></properties> <environments default="development"> <environment id="development"> <transactionManager type="JDBC" /> <dataSource type="POOLED"> <property name="driver" value="${dbDriver}" /> <property name="url" value="${dbUrl}" /> <property name="username" value="${dbUser}" /> <property name="password" value="${dbPassword}" /> </dataSource> </environment> </environments> <mappers> <mapper resource="database/Person.xml" /> </mappers> </configuration>
dbDriver=org.apache.derby.jdbc.EmbeddedDriver
dbUrl=jdbc:derby:testdb
dbUser=
dbPassword=
Im Beispiel wird nur eine Mapper-Datei (Person.xml) eingebunden, aber davon kann es beliebig viele geben:
1 2 3 4 5 6 7 <?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="Person"> <select id="selectAllPersons" resultType="Person"> select id,vorname,nachname from person </select> </mapper>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 public class Mybatis { public static void main(String[] args) { try { Reader reader = Resources.getResourceAsReader("database/SqlMapConfig.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder() .build(reader); SqlSession sqlSession = sqlSessionFactory.openSession(); try { @SuppressWarnings("unchecked") List<Person> listPersons = sqlSession .selectList("Person.selectAllPersons"); for (Person person : listPersons) { System.out.println(person); } } finally { sqlSession.close(); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
Code:
SqlSession sqlSession = sqlSessionFactory.openSession(); try // Etwas tun } finally sqlSession.close();
Eigentlich alle Dateien, die von mybatis gelesen werden sollen, müssen über den ClassPath erreichbar sein. Hilfreich finde ich auch, wenn mybatis gute Logging-Informationen ausgibt. Wird log4j im Classpath gefunden, wird mit folgender log4j.properties alles geloggt.
log4j.rootLogger=DEBUG,stdout
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %d{DATE} %5p [%t] (%F\:%L) - %m%n
log4j.logger.com.ibatis=DEBUG
log4j.additivity.com.ibatis = false
log4j.additivity.java.sql = false
Und wenn es dann ausgeführt wird, sieht man:
9 Aug 2011 15:00:20,131 DEBUG [main] (Log4jImpl.java:27) - Created connection 21868771.
09 Aug 2011 15:00:20,131 DEBUG [main] (Log4jImpl.java:27) - ooo Connection Opened
09 Aug 2011 15:00:20,553 DEBUG [main] (Log4jImpl.java:27) - ==> Executing: select id,vorname,nachname from person
09 Aug 2011 15:00:20,553 DEBUG [main] (Log4jImpl.java:27) - ==> Parameters:
09 Aug 2011 15:00:20,600 DEBUG [main] (Log4jImpl.java:27) - <== Columns: ID, VORNAME, NACHNAME
09 Aug 2011 15:00:20,600 DEBUG [main] (Log4jImpl.java:27) - <== Row: 0, Turtle, Tortois
09 Aug 2011 15:00:20,600 DEBUG [main] (Log4jImpl.java:27) - <== Row: 1, Angela, Merkel
[ID:0, vorname:Turtle, nachname:Tortois]
[ID:1, vorname:Angela, nachname:Merkel]
09 Aug 2011 15:00:20,616 DEBUG [main] (Log4jImpl.java:27) - xxx Connection Closed
09 Aug 2011 15:00:20,616 DEBUG [main] (Log4jImpl.java:27) - Returned connection 21868771 to pool.
Neben select können natürlich auch insert, update, delete in Transaktionen (commit,rollback) ausgeführt werden. Ich finde es insbesondere sehr angenehm, dass man genau weiss, welcher Befehl da gegen die DB abgesetzt wird. Und häufig ist die erste Frage von DBA's, wie ein Programm schneller laufen könnte, doch immer: "Zeig mal Dein SQLl". Dies kann nun umgesetzt werden. Genauso einfach kann halt der optimierte SQL-Befehl schnell probiert werden. Meine Erfahrung mit anderen Frameworks ist, dass einfache Dinge auch einfach gehen, man aber oft die Schraube sucht an der man stellen muss, damit das Framework den SQL-Befehl absetzt, den man gerne abgesetzt hätte und in mybatis sofort hinschreiben kann. Zudem ist mybatis extrem einfach einzusetzen. Das Einrichten und Nutzen geht innerhalb von 5 Minuten!
mybatis hat also Vor- und Nachteile. Vorteil ist: Ich weiss genau mit welchem SQL-Befehl gearbeitet wird, weil ich ihn selbst hingeschrieben habe. Nachteil: Ich muss SQL-Befehle hinschreiben und kein Franework generiert dies für mich.
Kommentare 5
Kommentare
-
@Select("SELECT * FROM person") finde ich cooler als das mapping per XML in dem Fall :PVeröffentlicht: 12.08.2011 um 23:21 von eRaaaa
-
Veröffentlicht: 13.10.2011 um 18:33 von turtle
-
bringt leider immer Fehler:
Wenn man danach googelt, sieht man, dass andere das gleiche berichten. Hat hier jemand das auch mal gehabt und kann mir sagen, warum das nicht geht?Zitat:java.io.IOException: Could not find resource SqlMapConfig.xml
at org.apache.ibatis.io.Resources.getResourceAsStream(Resources.java:104)
at org.apache.ibatis.io.Resources.getResourceAsStream(Resources.java:91)
at org.apache.ibatis.io.Resources.getResourceAsReader(Resources.java:149)Veröffentlicht: 17.04.2012 um 14:04 von cipherwar
-
Fehler gefunden. Es liegt in der Art, wie in MyBatis korrekterweise Pfade zu adressieren sind. In meinem Falle hätte es so sein müssen:
1
String resource = "com/susanne/model/SqlMapConfig.xml";
Der Vollständigkeithalber für andere Leidensgenossen die dazugehörige Konfigurationsdatei:
Zitat:<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="com/susanne/model/db.properties"></properties>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/susanne/model/searches.xml" />
<mapper resource="com/susanne/model/options.xml" />
</mappers>
</configuration>Veröffentlicht: 17.04.2012 um 14:47 von cipherwar
-
Veröffentlicht: 10.06.2012 um 11:37 von turtle









