myBatis3之SQL映射的XML文件(resultMap元素之七)
-----------
高级结果映射之discriminator元素(鉴别器)
<discriminator javaType="int" column="draft"> <case value="1" resultType="DraftPost"/> </discriminator>
有时一个单独的数据库查询也许返回很多不同(但是希望有些关联)数据类型的结果集。鉴别器元素就是被设计来处理这个情况的,还有包括类的继承层次结构。鉴别器非常容易理解,因为它的表现很像 Java 语言中的switch语句。 定义鉴别器指定了column和javaType属性。列是MyBatis查找比较值的地方。JavaType是需要被用来保证等价测试的合适类型(尽管字符串在很多情形下都会有用)。比如:
<resultMap id="vehicleResult" type="Vehicle"> <id property=”id” column="id"/> <result property="vin" column="vin"/> <result property="year" column="year"/> <result property="make" column="make"/> <result property="model" column="model"/> <result property="color" column="color"/> <discriminator javaType="int" column="vehicle_type"> <case value="1" resultMap="carResult"/> <case value="2" resultMap="truckResult"/> <case value="3" resultMap="vanResult"/> <case value="4" resultMap="suvResult"/> </discriminator> </resultMap>
在这个示例中,MyBatis会从结果集中得到每条记录,然后比较它的vehicle类型的值。如果它匹配任何一个鉴别器的实例,那么就使用这个实例指定的结果映射。换句话说,这样做完全是剩余的结果映射被忽略(除非它被扩展,这在第二个示例中讨论)。如果没有任何一个实例相匹配,那么 MyBatis 仅仅使用鉴别器块外定义的结果映射。所以,如果carResult按如下声明:
<resultMap id="carResult" type="Car"> <result property=”doorCount” column="door_count"/> </resultMap>
那么只有doorCount属性会被加载。这步完成后完整地允许鉴别器实例的独立组,尽管和父结果映射可能没有什么关系。这种情况下,我们当然知道 cars 和 vehicles 之间有关系,如 Car是一个 Vehicle 实例。因此,我们想要剩余的属性也被加载。我们设置的结果映射的简单改变如下。
<resultMap id="carResult" type="Car" extends=”vehicleResult”> <result property=”doorCount” column="door_count" /> </resultMap>
现在vehicleResult和carResult的属性都会被加载了。
尽管曾经有些人会发现这个外部映射定义会多少有一些令人厌烦之处。因此还有另外一种语法来做简洁的映射风格。比如:
<resultMap id="vehicleResult" type="Vehicle"> <id property=”id” column="id" /> <result property="vin" column="vin"/> <result property="year" column="year"/> <result property="make" column="make"/> <result property="model" column="model"/> <result property="color" column="color"/> <discriminator javaType="int" column="vehicle_type"> <case value="1" resultType="carResult"> <result property=”doorCount” column="door_count" /> </case> <case value="2" resultType="truckResult"> <result property=”boxSize” column="box_size" /> <result property=”extendedCab” column="extended_cab" /> </case> <case value="3" resultType="vanResult"> <result property=”powerSlidingDoor” column="power_sliding_door" /> </case> <case value="4" resultType="suvResult"> <result property=”allWheelDrive” column="all_wheel_drive" /> </case> </discriminator> </resultMap>
要记得这些都是结果映射,如果你不指定任何结果,那么 MyBatis 将会为你自动匹配列和属性。所以这些例子中的大部分是很冗长的,而其实是不需要的。也就是说,很多数据库是很复杂的,我们不太可能对所有示例都能依靠它。