Mybatis XML vs Annotation

限于喜欢 提交于 2019-12-03 03:07:23
Junchen Liu

On top of Nested Join Mapping that Pitchers said, resultMap in XML format supports inheritance, which can not be achieved in annotation, you have do rewrite each time. Also the @Results annotation is a counterpart of the Mapper XML element <resultMap>. However, as of MyBatis 3.2.2 we can't give an ID for the @Results annotation. So unlike the <resultMap> XML element, we can't reuse the @Results declaration across different mapped statements. What this means is that you need to duplicate the @Results configuration even though it is the same. For example, see the following findStudentBy() and findAllStudents() methods:

@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();

Here the @Results configuration is same for both the statements, but we need to duplicate it. There is also a work around for this problem. We can create a Mapper XML file and configure the <resultMap> element and reference that resultMap using the @ResultMap annotation.

Define <resultMap> with 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 Using Annotations

In StudentMapper.java, reference the resultMap attribute StudentResult using @ResultMap.

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();

quote from Java-Persistence-with-MyBatis3

Yes,the documentation for Mybatis cautions that annotations can be much simpler and easier to read for smaller, simpler projects. However, annotations are limited compared to the XML configuration. If your project includes complex objects or a complex database structure, consider using the XML configuration instead of the Java annotations.

XML mapping is still required for the most advanced mappings like Nested Join Mapping in MyBatis.

Alexander Davliatov

There are plenty use cases when using .xml can be much more consice and cleaner approach. Say, you can create some Common.xml, define a bunch of queries, like

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

and reuse this code in your project.

Moreover, the template query can be defined, e.g.:

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

And then you can reference it via

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

This approach is less error-prone and much less copy/pasted. (you can have a look here).

Conditions, iterating, etc should also be mentioned, too.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!