一對一
在SysUser 類中增加SysRole字段双仍。
1、sql語句將role.role_name映射到role.roleName上苞轿。
2、還可以在XML 映射文件中配置結(jié)果映射瑟俭。
<resultMap id="userRoleMap" type ="SysUser"〉
<id property="id" column="id"/>
<result property="userName" column="use_name"/>
<result property="userPassword" column="user_password" />
<result property="role.id" column ="role_id"/>
<result property="role.roleName" column="role_name"/>
<result property="role.createTime" column="role_create_time" jdbcType="TIMESTAMP"/>
</resultMap>
為了避免不同表中存在相同的列契邀,如create_time, 在它前面增加了"role_"前綴。
3椭迎、MyBatis是支持resultMap繼承田盈,因此可以簡化上面的resultMap配置
<resultMap id= "userRoleMap" extends= "userMap" type= "SysUser">
<result property= "role.id" column="role_id "/>
<result property= "role.roleName" column= "role_name"/>
<result property= "role.createTime" column ="role_create_time" jdbcType= "TIMESTAMP"/>
</resultMap>
4允瞧、使用resultMap的association標簽配置
<resultMap id= "userRoleMap" extends= "userMap" type= "SysUser">
<association property="role" columnPrefix="role_" javaType="SysRole">
<result property= "id" column="role_id "/>
<result property= "roleName" column= "role_name"/>
<result property= "createTime" column ="create_time" jdbcType= "TIMESTAMP"/>
</association>
</resultMap>
association標簽的屬性property對應(yīng)實體類中的屬性名述暂,必填項。另外我們還配置了columnPrefix="role_"畦韭,在寫SQL的時候艺配,和sys_role表相關(guān)的查詢列的別名都要有"role_"前綴,在內(nèi)部result配置column時转唉,需要去掉前綴。sql:r.id role_id, r.role_name role_role_name, r.create_time role_create_time麦轰。
5款侵、使用association 配置時還可以使用resultMap 屬性配置成一個已經(jīng)存在的resultMap
<resultMap id= "roleMap" type = "SysRole">
<id property="id" column="id"/>
<result property="roleName" column= "role_name"/>
<result property="createTime" column="create_time" jdbcType = "TIMESTAMP"/>
</resultMap>
<resultMap id="userRoleMap" extends= "userMap" type="SysUser">
<association property="role" columnPrefix="role_" resultMap="roleMap"/>
</resultMap>
MyBatis 默認會給 roleMap 添加當前命名空間的前綴侧纯,代碼如下,test.mybatis.simple.mapper.UserMapper.roleMap。目前的 roleMap 是寫在UserMapper.xml中的茂蚓,其實更合理的位置應(yīng)該是在RoleMapper.xml中聋涨。將roleMap移動到RoleMapper.xml中后晾浴,這里的userRoleMap就不能簡單地指定為roleMap了脊凰,而是要修改為以下的樣子狸涌。
<resultMap id="userRoleMap" extends= "userMap" type="SysUser">
<association property="role" columnPrefix="role_" resultMap="test.mybatis.simple.mapper.RoleMapper.roleMap"/>
</resultMap>
上面的情況都是一種情況最岗,這種方式的好處是減少數(shù)據(jù)庫查詢次數(shù),減輕數(shù)據(jù)庫的壓力懒豹。缺點是由于要在應(yīng)用服務(wù)器上將結(jié)果映射到不同的類上脸秽,因此也會增加應(yīng)用服務(wù)器的壓力蝴乔。當一定會使用到嵌套結(jié)果,并且整個復(fù)雜的SQL執(zhí)行速度很快時片酝,建議使用這種方法挖腰。
還可以利用簡單的SQL 通過多次查詢轉(zhuǎn)換為我們需要的結(jié)果曙聂,最后會將結(jié)果組合成一個對象。
<resultMap id = "userRoleMapSelect" extends = "userMap" type= "SysUser">
<association property="role" column="{id=role_id}" select="test.mybatis.simple.mapper.RoleMapper.selectRoleById" />
</resultMap>
<select id="selectUserAndRoleByIdSelect" resultMap="userRoleMapSelect">
select u.id, u.user_name, u.user_password, u.user_email, u.user_info,u.head_img, u.create_time,
ur.role_id
from sys_user u
join sys_user_role ur on u.id = ur.user_id
where u.id= #{id}
</select>
association 屬性 select :另一個查詢的id, MyBatis 會額外執(zhí)行這個查詢断国。
column :列名(或別名)稳衬,將主查詢中列的結(jié)果作為嵌套查詢的參數(shù)坐漏,配置方式如 column = {propl=coll , prop2=col2}。
fetchType :數(shù)據(jù)加載方式街夭,可選值為lazy 和eager,分別為延遲加載和積極加載呈枉,這個配置會覆蓋全局的lazyLoadingEnabled 配置埃碱。
問題:如果主查詢結(jié)果不是1條數(shù)據(jù),而是N條數(shù)據(jù)啃憎,那就會出現(xiàn)N+1問題辛萍。主SQL 會查詢一次,查詢出N 條結(jié)果名党,這N條結(jié)果要各自執(zhí)行一次查詢传睹,那就需要進行N次查詢欧啤。
解決辦法:fetchType="lazy"
<resultMap id = "userRoleMapSelect" extends = "userMap" type= "SysUser">
<association property="role" column="{id=role_id}"
select="test.mybatis.simple.mapper.RoleMapper.selectRoleById" fetchType="lazy"/>
</resultMap>
<select id="selectUserAndRoleByIdSelect" resultMap="userRoleMapSelect">
select u.id, u.user_name, u.user_password, u.user_email, u.user_info,u.head_img, u.create_time,
ur.role_id
from sys_user u
join sys_user_role ur on u.id = ur.user_id
where u.id= #{id}
</select >