背景:
假设有一张table_meta表记录表的主要信息和一张table_col记录着每个表的列信息
需求是分页查询table_meta的数据,但是还要展示table_meta在table_col中对应的部分信息
问题出现:
例如主表有7条数据,每个主表的数据在详情表有2条详情数据,使用left join 查询的时候在数据库会查询到14条信息,此时的分页明显是不正确的,因为主表只有7条,分页也应该是在7条里面分页
解决方法:
1.先分页查询主表信息,再查询明细表信息
1.使用mybatis或mybatis-plus单次查询
ps:这里我使用mybatis-plus 其实都一样只是节省一些分页的计算
结果:
@Resource
private TableMetaService tableMetaService;
@Resource
private TableColService tableColService;
@Test
public void aa(){
Page<TableMeta> page = tableMetaService.lambdaQuery()
.exists(String.format("SELECT 1 FROM table_col b WHERE table_meta.`table_name`=b.`table_name` AND b.col_name = %s","'sex'"))
.page(new Page<>(1, 5));
page.getRecords().forEach(item->{
item.setCols(tableColService.lambdaQuery().eq(TableCol::getTableName,item.getTableName()).list());
});
System.out.println(page.getTotal());
System.out.println(page.getPages());
System.out.println(page.getCurrent());
System.out.println(page.getSize());
System.out.println(page.getRecords());
}
2.使用mybatis的resultMap语法
1.tableMetaMapper
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.lowcode.model.TableMeta;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
/**
* <p>
* 表信息 Mapper 接口
* </p>
*
* @author wjj
* @since 2024-06-24
*/
public interface TableMetaMapper extends BaseMapper<TableMeta> {
IPage<TableMeta> pageTableMeta(IPage<TableMeta> page,@Param("colName")String colName);
}
tableMetaMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lowcode.mapper.TableMetaMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.lowcode.model.TableMeta">
<id column="table_name" property="tableName" />
<result column="table_desc" property="tableDesc" />
<result column="create_date" property="createDate" />
<result column="update_date" property="updateDate" />
<collection property="cols" ofType="com.lowcode.model.TableCol" column="{tableName=table_name}"
select="com.lowcode.mapper.TableColMapper.finByTableNameAndColName" >
</collection>
</resultMap>
<select id="pageTableMeta" resultMap="BaseResultMap">
select * from table_meta a
<where>
<if test="colName !=null and colName != ''">
EXISTS(SELECT 1 FROM table_col b WHERE a.`table_name`=b.`table_name` AND b.col_name = #{colName})
</if>
</where>
</select>
</mapper>
tableColMapper
import com.lowcode.model.TableCol;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* <p>
* 列信息 Mapper 接口
* </p>
*
* @author wjj
* @since 2024-06-27
*/
public interface TableColMapper extends BaseMapper<TableCol> {
List<TableCol> finByTableNameAndColName(@Param("tableName")String tableName,@Param("colName")String colName);
}
tableColMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lowcode.mapper.TableColMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.lowcode.model.TableCol">
<id column="col_name" property="colName" />
<result column="col_desc" property="colDesc" />
<result column="table_name" property="tableName" />
<result column="create_date" property="createDate" />
<result column="update_date" property="updateDate" />
</resultMap>
<select id="finByTableNameAndColName" resultType="com.lowcode.model.TableCol">
select * from table_col
<where>
<if test="tableName !=null and tableName !=''">
and table_name = #{tableName}
</if>
</where>
</select>
</mapper>
结果:
@Resource
private TableColMapper tableColMapper;
@Resource
private TableMetaMapper tableMetaMapper;
@Test
public void bb(){
IPage<TableMeta> tableMetaIPage = tableMetaMapper.pageTableMeta(new Page<>(1, 5),"sex");
System.out.println(tableMetaIPage.getTotal());
System.out.println(tableMetaIPage.getPages());
System.out.println(tableMetaIPage.getCurrent());
System.out.println(tableMetaIPage.getSize());
System.out.println(tableMetaIPage.getRecords());
}
解析

3.总结
1.共同点:
都是先分页查询主表的数据,然后根据主表的每条数据去一条条查询明细数据
2.不用点:
第一种方法 书写简单 需要依赖mp
第二种方法 书写稍微复杂不需要依赖mp