2015-09-17 9 views
5

Ich habe das Buch und die Dokumentation über Mybatis gelesen, sowohl XML als auch Annotation tun, was ich will, aber von myBatis offizieller Website behaupten sie, XML sei ein besserer Weg Mappers zu machen, da Java Annotation Einschränkungen hat.Mybatis XML vs Annotation

Ich persönlich bevor Anmerkungen z

public interface PersonDAO { 

    String INSERT_PERSON = "insert into person (title,firstName,surName,jobTitle,dob,email,mobile,landPhone,fax,twitter,facebook,linkedin) VALUES (#{title},#{firstName},#{surName},#{jobTitle},#{dob},#{email},#{mobile},#{landPhone},#{fax},#{twitter},#{facebook},#{linkedin})"; 
    String UPDATE_PERSON = "update person set title=#{title},firstName=#{firstName},surName=#{surName},jobTitle=#{jobTitle},dob=#{dob},email=#{email},mobile=#{mobile},landPhone=#{landPhone},fax=#{fax},twitter=#{twitter},facebook=#{facebook},linkedin=#{linkedin} where id=#{id}"; 
    String GET_PERSON_BY_ID = "SELECT * FROM vw_person WHERE id = #{personId}"; 
    String DELETE_PERSON = "DELETE FROM person WHERE id = #{personId}"; 

    @Select(GET_PERSON_BY_ID) 
    public PersonVO doSelectPerson(long personId) throws Exception; 

    @Update(UPDATE_PERSON)@Options(flushCache = true, useCache = true) 
    public int doUpdatePerson(PersonVO vo) throws Exception; 


    @Insert(INSERT_PERSON)@Options(useGeneratedKeys = true, keyProperty = "id", flushCache = true) 
    public int doCreatePerson(PersonVO person) throws Exception; 

    @Delete(DELETE_PERSON)@Options(flushCache = true) 
    public int doDeletePerson(long personId) throws Exception; 

} 

Ich frage mich, was die Begrenzung ist? Nichts scheint mir offensichtlich zu sein.

+0

Lesen Sie diesen Beitrag, um zu erfahren, welche Annotationen auf [Xml-Konfiguration versus Annotation-basierte Konfiguration] beschränkt sind (http://stackoverflow.com/a/183401/1793718). Soweit es myBatis betrifft, sagt die [Dokumentation] (https://mybatis.github.io/mybatis-3/getting-started.html), dass XML-Mapping immer noch für die fortgeschrittensten Zuordnungen benötigt wird. Ein Beispiel dafür ist die Verschachtelte Join-Zuordnung. – Lucky

+0

Lesen Sie auch diese verwandte Frage zu [Mybatis-Annotationen in komplexen Anwendungen] (http://stackoverflow.com/questions/15352242/mybatis-annotations-in-complex-applications) – Lucky

Antwort

7

Oben auf Nested Join Mapping, dass Pitchers sagte, resultMap im XML-Format unterstützt die Vererbung, die in Annotation nicht erreicht werden kann, müssen Sie jedes Mal neu schreiben. Auch die Annotation @Results ist ein Gegenstück zum Mapper-XML-Element <resultMap>. Ab MyBatis 3.2.2 können wir jedoch keine ID für die @Results Annotation vergeben. Im Gegensatz zum XML-Element <resultMap> können wir die Deklaration @Results nicht für verschiedene zugeordnete Anweisungen verwenden. Das bedeutet, dass Sie die Konfiguration @Results duplizieren müssen, obwohl sie identisch ist. Zum Beispiel finden Sie in den folgenden findStudentBy() und findAllStudents() Methoden:

@Select("SELECT * FROM STUDENTS WHERE STUD_ID=#{studId}") 
@Results({ 
    @Result(id=true, column="stud_id", property="studId"), 
    @Result(column="name", property="name"), 
    @Result(column="email", property="email"), 
    @Result(column="addr_id", property="address.addrId") 
}) 
Student findStudentById(int studId); 

@Select("SELECT * FROM STUDENTS") 
@Results({ 
    @Result(id=true, column="stud_id", property="studId"), 
    @Result(column="name", property="name"), 
    @Result(column="email", property="email"), 
    @Result(column="addr_id", property="address.addrId") 
}) 
List<Student> findAllStudents(); 

Hier die @Results Konfiguration sowohl für die Aussagen gleich ist, aber wir müssen es duplizieren. Es gibt auch eine Arbeit für dieses Problem. Wir können eine Mapper-XML-Datei erstellen und das <resultMap>-Element konfigurieren und unter Verwendung der @ResultMap-Annotation auf resultMap verweisen.

Definieren Sie <resultMap> mit ID StudentResult in StudentMapper.xml.

<mapper namespace="com.mybatis3.mappers.StudentMapper"> 
    <resultMap type="Student" id="StudentResult"> 
    <id property="studId" column="stud_id"/> 
    <result property="name" column="name"/> 
    <result property="email" column="email"/> 
    <result property="phone" column="phone"/> 
    </resultMap> 
</mapper> 

SQL Mappers Annotations

In StudentMapper.java Mit Bezug das resultMap Attributs StudentResult@ResultMap verwenden.

public interface StudentMapper 

@Select("SELECT * FROM STUDENTS WHERE STUD_ID=#{studId}") 
@ResultMap("com.mybatis3.mappers.StudentMapper.StudentResult") 
Student findStudentById(int studId); 

@Select("SELECT * FROM STUDENTS") 
@ResultMap("com.mybatis3.mappers.StudentMapper.StudentResult") 
List<Student> findAllStudents(); 

Zitat von Java-Persistenz-mit-MyBatis3

+0

Die Wiederverwendung von '@ Results' ist heutzutage tatsächlich möglich. Wenn Sie eine 'id' mit den' @ Results' angeben, können Sie von '@ ResultMap' darauf verweisen. Siehe [Dokumente] (http://www.mybatis.org/mybatis-3/java-api.html#Mapper_Annotations) und [gitlab-Problem] (https://github.com/mybatis/mybatis-3/issues/ 155). – Stim

3

Ja, die Dokumentation für MyBatis warnt, dass Annotationen für kleinere, einfachere Projekte einfacher und einfacher zu lesen sind. Anmerkungen sind jedoch im Vergleich zur XML-Konfiguration begrenzt. Wenn Ihr Projekt komplexe Objekte oder eine komplexe Datenbankstruktur, enthält, sollten Sie die XML-Konfiguration anstelle der Java-Anmerkungen verwenden.

XML-Mapping erforderlich ist nach wie vor für die am weitesten fortgeschrittenen Mappings wie Nested Mapping Join in Mybatis.

+1

Ich bin sicher, Annotation kann eine verschachtelte Join-Zuordnung erreichen, isn ' t? – user5324782

1

Es gibt viele Fälle, bei der Verwendung von .xml kann viel mehr consice und sauberer Ansatz. Say, können Sie einige Common.xml erstellen, definieren eine Reihe von Anfragen, wie

<sql id="inStmt"> 
    IN 
    <foreach item="id" collection="ids" separator="," open="(" close=")"> 
     #{id} 
    </foreach> 
</sql> 

und diesen Code in Ihrem Projekt wiederverwenden.

Darüber hinaus kann die Vorlagenabfrage definiert werden, z.B.:

<sql id="selectDistinct"> 
    SELECT DISTINCT(${column}), #{param} 
    FROM ${entityTable} 
</sql> 

Und dann kann man es über

<include refid="Common.selectDistinct"> 
     <property name="column" value="id"/> 
     <property name="entityTable" value="some_table"/> 
</include> 

Dieser Ansatz ist weniger fehleranfällig und viel weniger Kopieren/Einfügen verweisen. (Sie können einen Blick here werfen).

Bedingungen, Iteration usw. sollten ebenfalls erwähnt werden.