mybatis记录随便(四)一对一映射实现方式
在RBAC权限系统设计过程中,假设一个用户只有一个角色(当然实际系统并非如此)
序号 | 表名 | 对应实体 | 对应数据库接口 | 对应mapper | 备注 |
1 | sys_user | SysUser | UserMapper.java | UserMapper.xml | 用户表 |
2 | sys_role | SysRole | RoleMapper.java | RoleMapper.xml | 角色表 |
在SysUser实体添加角色属性SysRole
SysUser.java
SysRole.java
一、自动映射处理一对一映射
查询sql中通过别名让Mybatis自动将值匹配到对应的字段上,简单的别名如user_name匹配到userName,除此之外还支持复杂的属性映射,可以多层嵌套,例如将role.role_name映射到roleName上。
在UserMapper.xml添加select,如下
注意上述方法中sys_role查询列的别名都是"role."前缀,通过这种方式将role的属性都映射到了SysUser的role属性上。
在UserMapper.java接口中添加对应查询接口,如下
一对一映射查询完成,当前查询返回的SysUser实例包含起对应的SysRole内容。
二、使用resultMap配置一对一映射
在 UserMapper.xml 中增加如下的 resultMap 配置。
也可以通过resultMap的extends属性优化写法,如下
这种配置和上一节自动映射方式相似的地方在于,role中的 property 配置部分使用"role."前缀。在 column 部分,为了避免不同表中存在相同的列,所有可能重名的列都增加了"role"前缀。使用这种方式配置的时候,还需要在查询时设置不同的别名。
在SysUserMapper.xml添加查询selectUserAndRoleByid2
在UserMapper.java接口中添加对应查询接口,如下
三、使用resultMap的association标签配置一对一映射
在 resultMap 中,association标签用于和一个复杂的类型进行关联,即用于一对一的关联配置 。
修改userRole标签如下
association常用标签包含以下属性:
property :对应实体类中的属性名,必填项。
javaType : 属性对应的 Java 类型 。
resultMap : 可以直接使用现有的 resultMap ,而不需要在这里配置。
columnPrefix :查询列的前缀,配置前缀后,在子标签配置result 的.column时可以省略前缀。
association可以配置已经存在的resultMap进而优化提取公共代码,如下在UserMapper.xml
当前userRoleMap定义在UserMapper.xml,合理的方式应该定义在RoleMapper.xml,对应将association引用resultMap的地方修改为对应的全路径即可(MyBatis默认会给roleMap添加当前命名空间的前缀)。
resultMap="com.chl.mapper.RoleMapper.userRoleMap"
在UserMapper.xml添加查询标签
三、使用association标签的嵌套查询
association 标签的嵌套查询常用的属性如下:
select :另一个映射查询的 id, MyBatis 会额外执行这个查询获取嵌套对象的结果。
column :列名(或别名),将主查询中列的结果作为嵌套查询的 参数,配置方式如column={propl=coll , prop2=col2}, propl 和 prop2 将作为嵌套查询的参数。
fetchType :数据加载方式,可选值为 lazy 和 eager,分别为延迟加载和积极加载,这个配置会覆盖全局的 lazyLoadingEnabled 配置。
在UserMapper.xml创建resultMap和select
【说明】关联查询中已经去掉和sys_role相关的,角色信息由selectRoleById来查询,这个查询定义在RoleMapper.xml中。
【说明】当使用fetchType配置lazy时,为了阻止在查询时调用setter方法还需在mybatis-config.xml进行如下配置,
当该参数设置为 true 时,对任意延迟属性的调用会使带有延迟加载属性的对象完整加载,反之,每种属性都将按需加载。这个参数默认为 true ,所以当查询sys_user 过后并给 SysUser 对象赋值时,会调用该对象其他属性的setter方法,这也会触发上述规则,导致本该延迟加载的属性直接加载
在RoleMapper.xml定义select
配置完成。
【其他说明】有些时候还是需要在触发某方法时将所有的数据都加载进来,而我们己经将 aggressiveLazyLoading 设置为 false ,这种情况又该怎么解决呢?
MyBatis 仍然提供了参数 lazyLoadTriggerMethods 帮助解决这个问题,这个参数的含义是,当调用配置中的方法时,加载全部的延迟加载数据。
默认值为 ” eqals , clone ,hashCode,toString ” 。因此在使用默认值的情况下,只要调用其中一个方法就可以实现加载调用对象的全部数据。
开发工作着,生活快乐着,留下总结,相互交流,共同进步