在使用mybatis的过程中,会用到关联查询,其中的一对一关联查询(如搜索所有订单,并关联查询出下该订单的用户信息,一个订单只能是某一个用户下的,也就是一对一关联查询)
1.第一个办法是直接生成一个含有订单信息和用户信心的实体类,可以不用association标签,直接使用select标签查询,然后自动将查询到的结果封装成这个新的实体类。这个方法会多生成一个新的实体类,有点不太妥
2.第二个方法是使用association标签,可以不生成新的实体类,减少项目的文件数量。但是association标签的使用方法也分为两种,下面分别讲述。
①同步查询
顾名思义,就是关联查询两张表的时候,通过sql语句和association标签中的属性配置,实现对两张表进行关联查询
<resultMap id="UserRoleMap" type="domain.User">
<id property="id" column="id"></id>
<result property="loginId" column="loginId"></result>
<result property="userName" column="userName"></result>
<result property="note" column="note"></result>
<association property="role" javaType="domain.Role">
<id property="id" column="roleId"></id>
<result property="roleName" column="roleName"></result>
</association>
</resultMap>
<select id="findAllUser" resultMap="UserRoleMap">
select * from t_user,t_role where t_user.roleId=t_role.id
</select>
这种方法可以理解为,纯通过select做到两张表的关联查询,然后将查询到的结果,根据不同的column名,对应到实体类中的不同属性。这个例子中,相当于User实体类中有long id,long loginId,String name,String note,Role role这五个属性,然后Role实体类中有long id,String roleName这两个属性。select语句通过查询两个表中返回的结果为
所以,我们需要做的是,将查询结果中的roleId(或第一个id,查询结果中第一个id是role表中的,应该改为roleId比较妥当)和roleName封装到Role中,将id,loginId,userName,roleId,note封装到User中。
②分步查询
将上面的这种方法拆分为两步实现,首先通过sql语句查询所有user表中的信息,然后再通过一个sql语句,根据user表中查询到的roleId到role表中查询相应id所对应的信息
但是这种方法也有个不足之处,就是相比于上一种方法,需要多创建一个roleDao的Mapper.xml
RoleDaoMapper.xml如下:
<mapper namespace="dao.RoleDao">
<!--sql-->
<select id="getRoleById" resultType="domain.Role">
注意嗷,这里直接将查询的结果封装为Role对象了
第一种方法是纯人工封装对象
select * from t_role where id=#{0}
</select>
</mapper>
此select标签的作用是根据传过来的id值,在role表中查询id对应的信息,并且!直接封装为Role对象!
UserDaoMapper.xml如下:
<mapper namespace="dao.UserDao">
<!--sql-->
<resultMap id="UserRoleMap" type="domain.User">
<id property="id" column="id"></id>
<result property="loginId" column="loginId"></result>
<result property="userName" column="userName"></result>
<result property="note" column="note"></result>
<!-- <association property="role" javaType="domain.Role">-->
<!-- <id property="id" column="roleId"></id>-->
<!-- <result property="roleName" column="roleName"></result>-->
<!-- </association>-->
<association property="role" select="dao.RoleDao.getRoleById" column="roleId"></association>
</resultMap>
<select id="findAllUser" resultMap="UserRoleMap">
select * from t_user
</select>
</mapper>
此处相较于上面第一种写法而言,只是改变了association标签内的参数,
此处相当于是直接使用dao.RoleDao.getRoleById的方法(后面的column意思是将roleId作为参数调用getRoleById方法)
经过getRoleById方法将结果查询出来以后,直接封装为Role对象,所以在此处不用再像第一次一样手动选择property和column进行封装
还有一点需要注意,这时的sql语句,已经成了直接查询t_user表
此sql语句的返回值只是每条t_user表中的数据,然后将role表的查询交给了association来做,
相当于进行了两次查询,第一次只查询user表,然后第二次是根据每一条roleId,查询role表。