牵扯多张表的查询时,我们往往就要思考多表关联,表与表之间的关联关系通过那两个键来体现?实体类之间的属性嵌套,最终返回的结果集可能牵扯好几个实体类,这又要如何统一?
在mybatis的XML版,给我们提供了一种解决方案,可以通过定义ResultMap来定义返回结果集,再加上连接(JOIN)表操作就可很好的解决问题。
但当表的数量有很多而且实体类里属性关联越来越复杂时,这个ResultMap结果集以及SQL语句就会很复杂,并且很乱。
如果我们利用级联查询,就不一样,为什么这么说呢?
请看下面代码:
Order实体类: 对应表 t_order
SetMeal 实体类: 对应表 t_setmeal
CheckGroup实体类: 对应表 t_checkgroup
CheckItem 实体类: 对应表 t_checkitem
四个实体类间的关系通过下面三张表关联起来:
1.Order实体类中包含SetMeal的setmealId。
2.SetMeal与CheckGroup:
3.CheckGroup与CheckItem:
如果有这样一个需求,要查询关于Order类的SetMeal的详细信息,即包含CheckGroup集合,而CheckGroup又包含CheckItem集合,一般SQL语句我们会这么写:
在编写具体数据访问层时,遇到了一个问题,返回一行数据ResultMap集合可以写(用一个具体的对象来对应),多行数据呢?这样恐怕就不行了,
所以我们想到了利用级联查询,来嵌套调用具体DAO的方法实现五表的查询。
如下:
OrderDao利用@Many注解调用SetMealDao的selectGroupBySid查询出List<CheckGroup>集合。
@Mapper
public interface OrderDao {
//根据ID查询套餐详情(五表查询)
@Results(value = {
@Result(column = "id",property = "id"),
@Result(column = "ts.name",property = "name"),
@Result(column = "remark",property = "remark"),
//checkGroups集合
@Result(column = "id",property = "checkGroups",
many = @Many(select = "com.apesource.ressetmealservice.mapper.SetMealDao.selectGroupBySid"))
})
@Select("select * from t_setmeal where id=#{sid}")
SetMealDao利用@Many注解调用.CheckGroupDao的findCheckItemsByGroupId查询出List<CheckItem>集合。
@Mapper
public interface SetMealDao {
//根据套餐id查询检查组
@Results(value = {
@Result(column = "name",property = "name"),
@Result(column = "helpCode",property = "helpCode"),
@Result(column = "id",property = "checkItems",
many = @Many(select = "com.apesource.ressetmealservice.mapper.CheckGroupDao.findCheckItemsByGroupId"))
})
@Select("SELECT tc.* FROM t_checkgroup tc LEFT JOIN t_setmeal_checkgroup tsc ON tc.id=tsc.checkgroup_id " +
"WHERE tsc.setmeal_id=#{sid}")
List<CheckGroup> selectGroupBySid(int sid);
}
@Mapper
public interface CheckGroupDao {
//根据组ID查询所有检查项
@Select("SELECT tcm.* FROM t_checkitem tcm LEFT JOIN t_checkgroup_checkitem tcc ON tcm.id=tcc.checkitem_id WHERE tcc.checkgroup_id=#{gid}")
List<CheckItem> findCheckItemsByGroupId(int gid);
}
postman调用相应的控制层测试结果:
利用方法的完全限定名一级一级的调用不同的数据访问层方法,来达到多表查询的目的,这就是级联查询。