一个员工的信息Employee,可能由多类信息组成,它们分别是BaseInfo, AddressInfo
而基本信息BaseInfo中又可能包含多类细分信息: 分别是EducationInfo,PrivateInfo, 同理AddressInfo又可能包含多类地址信息,如CountryInfo, ProvinceInfo
以此类推, 一个员工的信息可能由层次分明的复杂结构组成.
然而在日常开发中,经常看到的查询一个员工的信息却不是以这样的方式映射的,而是把所有这些信息的具体值统统映射到Employee这个顶层类的字段上,如下:
<select id="getById" resultType="com.xuejian.mybatis.vo.Employee">
SELECT
T.ID id,
T.NAME name,
T.AGE age,
T.PRIMARY_SCHOOL primarySchool,
T.MIDDLE_SCHOOL middleSchool,
T.COUNTRY_NAME,countryName,
T.COUNTRY_LANGUAGE countryLanguage,
T.PROVINCE_NAME provinceName,
T.PROVINCE_CULTURE privinceCulture
FROM SCOTT.EMPLOYEE_T T
WHERE T.ID=#{id}
</select>
当然这样映射可以查询出来, 没有任何问题,但是这种做法让Employee类含有它不应该含有的细节字段,如name, age这些私人信息应该在Employee下的BaseInfo下的PrivateInfo类中.
这样一来, Employee不仅臃肿,结构上不合理,而且一旦它的子字段想增加一个字段, Employee类为了映射需要同步增加一个一样的字段.
这显然是不合理的.
我们期望在映射时,查到结果就是那种自带层级结构的数据对象就好了,mybatis支持这种操作,只需要如下定义即可:
1. 首先我们根据数据的层级结构定义好具有层级结构的DTO类
2. 然后在映射时使用别名进行带结构的映射,通过"1层字段名.2层字段名.3层字段名"即可完成结构映射.如下:
<select id="getById" resultType="com.xuejian.mybatis.vo.Employee">
SELECT
T.ID id,
T.NAME "baseInfo.privateInfo.name",
T.AGE "baseInfo.privateInfo.age",
T.PRIMARY_SCHOOL "baseInfo.educationInfo.primarySchool",
T.MIDDLE_SCHOOL "baseInfo.educationInfo.middleSchool",
T.COUNTRY_NAME "addressInfo.countryInfo.countryName",
T.COUNTRY_LANGUAGE "addressInfo.countryInfo.countryLanguage",
T.PROVINCE_NAME "addressInfo.provinceInfo.provinceName",
T.PROVINCE_CULTURE "addressInfo.provinceInfo.privinceCulture"
FROM SCOTT.EMPLOYEE_T T
WHERE T.ID=#{id}
</select>
总结:
1. mybatis可以自动按DTO层级结构进行映射
2. 避免使用顶层类囊括所有它本层及其下层的所有字段信息, 既不符合数据结构需要,也容易产生超大类.
3. 使用嵌套映射特性, 可以避免在得到结果后还要创建子层对象,然后一一设置值.
4. 使用嵌套映射特性, 可以给前端同事一个带结构的数据, 数据更容易定位, 其含义也更容易理解