【mysql】 mybatis实现 主从表 left join 1:n 一对多 分页查询 主表从表都有查询条件 【mybatis】count 统计+JSON查询
mybatis实现 主从表 left join 1:n 一对多 分页查询 主表从表都有查询条件+count
需求:
========================================
1.主从表数据 是 1:m
2.主从表各自都有查询条件
3.最后查询结果 需要分页,并统计总数
注意:
=======================================
1.查询的分页,必须在数据库做,否则分页没有意义
解决方法:
注意 下面的入参中 [第一页的10条]
pageNum=0 PageSize=10
实际入参应该是处理过的
pageNum = pageNum*10
pageSize = 10
##############################有对应实体接收查询结果的情况下################################
1.mapper.xml应该这么写
<resultMap type="com.lsrsjava.daywork.domain.week.自定义Bean" id="myResultMap">
<id column="id" property="id"/>
<!--一堆的主表 属性-->
<result column="userId" property="userId"/>
<result column="userName" property="userName"/>
<result column="userImg" property="userImg"/> <!--子表对应的属性 封装在list中 即接收了 主表对子表的 1:N -->
<collection property="listData" javaType="com.lsrsjava.daywork.domain.week.子表Bean" columnPrefix="slaveTable_">
<id column="id" property="id"/>
<result column="rowId" property="rowId"/>
<result column="colName" property="colName"/>
<result column="val" property="val"/>
</collection>
</resultMap> <select id="pageFind" resultMap="myResultMap" parameterType="com.lqjava.daywork.api.beans.WorksheetDataSaveBean"> SELECT
base.id,
t.id slaveTable_id,
t.row_id slaveTable_rowId,
t.col_name slaveTable_colName,
t.val slaveTable_val
FROM
(
SELECT
*
FROM
worksheet_data_${dataId}
WHERE
-- 此处之后加 主表的 where查询条件拼接 LIMIT #{pageNum}, #{pageSize}
) base
LEFT JOIN
worksheet_data_table_data t
ON
base.id = t.row_id
WHERE
<!-- 此处之后加 子表单的 where查询拼接 -->
</select>
2.mapper.java应该这么写
List<自定义的Bean> pageFind(WorksheetDataSaveBean queryBean);
############################### 不确定返回字段类型[即表中属性是动态的,没有对应实体的情况下]###################################
1.mapper.xml中应该这么写
[下面的示例中:因为我不确定返回的字段,所以用HashMap直接接收查询结果后 自己处理的结果集]
<select id="pageFind" resultType="java.util.HashMap" parameterType="com.lsrjava.daywork.api.beans.WorksheetDataSaveBean">
SELECT
base.*,
t.id slaveTable_id,
t.row_id slaveTable_rowId,
t.col_name slaveTable_colName,
t.val slaveTable_val
FROM
(
SELECT
*
FROM
worksheet_data_${dataId}
WHERE
-- 此处之后加 主表的 where查询条件拼接
LIMIT #{pageNum}, #{pageSize}
) base
LEFT JOIN
worksheet_data_table_data t
ON
base.id = t.row_id
WHERE
<!-- 此处之后加 子表单的 where查询拼接 -->
</select>
2.mapper.java应该这么写
List<Map<String,String>> pageFind(WorksheetDataSaveBean queryBean);
===================================count=============================================
count 是什么?count就是页面的 总共total条数
1.mapper.xml应该这么写
<select id="count" parameterType="com.lqjava.daywork.api.beans.WorksheetDataSaveBean" resultType="java.lang.Long">
SELECT
count( DISTINCT base.id ) count
FROM
worksheet_data_${dataId} base
LEFT JOIN
worksheet_data_table_data c
ON
c.row_id = base.id
-- 拼接条件的地方 </select>
2.mapper.java应该这么写
Long count(WorksheetDataSaveBean queryBean);
====================================附录,完整的 分页+left join+count+不确认返回列+Map接收+mybatis标签嵌套+json字段查询+字符串转日期+字符串转数值+结果集封装处理========================================
需求:
1.数据表 列是动态的多列,因此不确定查询返回是哪些列【因此使用Map接收】
2.主表一行 关联 子表的多行 【因此需要left join】
3.对于主表和子表的所有列,需要提供查询功能【因此需要使用mybatis标签拼接查询条件】
4.主表是正常数据,子表是JSON数据存储【因此需要提供有关JSON字段查询处理的操作】
5.查询出的List<Map>结果集 size=主size*子size 【因此,结果集需要将子表数据封装进主表数据集 java处理】
6.上述结果集条数不能作为分页查询的count统计,返回总页码【因此需要额外count()查询,以返回正确的total】
代码参考:
1.Mapper.xml【一个page查询 一个count查询】
<select id="pageFind" resultType="java.util.HashMap" parameterType="com.lqjava.daywork.api.beans.WorksheetDataSaveBean">
SELECT
base.*,
u.name create_by_name,
u2.name update_by_name,
t.id slaveTable_id,
t.row_id slaveTable_rowId,
t.col_name slaveTable_colName,
t.val slaveTable_val
FROM
(
SELECT
d.*
FROM
worksheet_data_${dataId} d
<!-- 此处之后加 主表的 where查询条件拼接 -->
<where>
<if test="list != null">
<foreach collection="list" item="item" index="index" separator="AND" open="(" close=")">
<choose>
<when test='item.cname.contains("date")'>
<choose>
<when test='item.operator.contains("between") and item.endValue != null'>
DATE_FORMAT(${item.cname} , ${item.dateFormat} ) BETWEEN DATE_FORMAT( #{item.value}, ${item.dateFormat} ) AND DATE_FORMAT( #{item.endValue}, ${item.dateFormat} )
</when>
<otherwise>
DATE_FORMAT( ${item.cname}, ${item.dateFormat} ) = DATE_FORMAT( #{item.value}, ${item.dateFormat} )
</otherwise>
</choose>
</when>
<when test='item.cname.contains("input-number")'>
<choose>
<when test='item.operator.contains("between") and item.endValue != null'>
CAST(${item.cname} AS DECIMAL) BETWEEN #{item.value} AND #{item.endValue}
</when>
<otherwise>
CAST(${item.cname} AS DECIMAL) = #{item.value}
</otherwise>
</choose>
</when>
<when test='item.cname.contains("checkbox") or item.cname.contains("select")'>
<if test="item.valueList != null">
<choose>
<when test=' "OR".equals(item.reOperator) '>
<foreach collection="item.valueList " item="v" index="i" separator="OR" open="(" close=")">
FIND_IN_SET( #{v},${item.cname} )
</foreach>
</when>
<otherwise>
<foreach collection="item.valueList " item="v" index="i" separator="AND" open="(" close=")">
FIND_IN_SET( #{v},${item.cname} )
</foreach>
</otherwise>
</choose>
</if>
</when>
<when test='item.cname.contains("dept-user") or item.cname.contains("dept-base")'>
<if test="item.valueList != null">
<choose>
<when test=' "OR".equals(item.reOperator) '>
<foreach collection="item.valueList " item="v" index="i" separator="OR" open="(" close=")">
<choose>
<when test='item.operator.contains("like") '>
${item.cname} -> '$[*].name' like '%${v}%'
</when>
<otherwise>
JSON_CONTAINS( ${item.cname} ->'$[*].name' , '"${v}"', '$')
</otherwise>
</choose>
</foreach>
</when>
<otherwise>
<foreach collection="item.valueList " item="v" index="i" separator="AND" open="(" close=")">
<choose>
<when test='item.operator.contains("like") '>
${item.cname} -> '$[*].name' like '%${v}%'
</when>
<otherwise>
JSON_CONTAINS( ${item.cname} ->'$[*].name' , '"${v}"', '$')
</otherwise>
</choose>
</foreach>
</otherwise>
</choose>
</if>
</when>
<otherwise>
<choose>
<when test='item.operator.contains("like") '>
${item.cname} like '%${item.value}%'
</when>
<otherwise>
${item.cname} = #{item.value}
</otherwise>
</choose>
</otherwise>
</choose>
</foreach>
</if>
</where>
LIMIT #{pageNum}, #{pageSize}
) base
LEFT JOIN
(SELECT * from worksheet_data_table_data where data_id = #{dataId}) t
ON
base.id = t.row_id
LEFT JOIN
dept_user u
ON
base.create_by = u.id
LEFT JOIN
dept_user u2
ON
base.update_by = u2.id
<!-- 此处之后加 子表单的 where查询拼接 -->
<where>
<if test="slaveList != null">
<foreach collection="slaveList" item="item" index="index" separator="AND" open="(" close=")">
t.col_name = #{item.tableName}
AND
<choose>
<when test='item.cname.contains("date")'>
<choose>
<when test='item.operator.contains("between") and item.endValue != null'>
STR_TO_DATE(val -> '$.${item.cname}','"%Y-%m-%d %H:%i:%s"') between #{item.value} AND date_add(#{item.endValue}, interval 1 day)
</when>
<otherwise>
STR_TO_DATE(val -> '$.${item.cname}','"%Y-%m-%d %H:%i:%s"') between #{item.value} AND date_add(#{item.value}, interval 1 day)
</otherwise>
</choose>
</when>
<when test='item.cname.contains("input-number")'>
<choose>
<when test='item.operator.contains("between") and item.endValue != null'>
CAST(val -> '$."${item.cname}"' AS DECIMAL) BETWEEN #{item.value} AND #{item.endValue}
</when>
<otherwise>
CAST(val -> '$."${item.cname}"' AS DECIMAL) = #{item.value}
</otherwise>
</choose>
</when>
<when test='item.cname.contains("checkbox") or item.cname.contains("select")'>
<if test="item.valueList != null">
<choose>
<when test=' "OR".equals(item.reOperator) '>
<foreach collection="item.valueList " item="v" index="i" separator="OR" open="(" close=")">
val -> '$.${item.cname}' like '%,${v},%'
</foreach>
</when>
<otherwise>
<foreach collection="item.valueList " item="v" index="i" separator="AND" open="(" close=")">
val -> '$.${item.cname}' like '%,${v},%'
</foreach>
</otherwise>
</choose>
</if>
</when>
<when test='item.cname.contains("dept-user") or item.cname.contains("dept-base")'>
<if test="item.valueList != null">
<choose>
<when test=' "OR".equals(item.reOperator) '>
<foreach collection="item.valueList " item="v" index="i" separator="OR" open="(" close=")">
val -> '$."${item.cname}"' like '%${v}%'
</foreach>
</when>
<otherwise>
<foreach collection="item.valueList " item="v" index="i" separator="AND" open="(" close=")">
val -> '$."${item.cname}"' like '%${v}%'
</foreach>
</otherwise>
</choose>
</if>
</when>
<otherwise>
<choose>
<when test='item.operator.contains("like") '>
val -> '$.${item.cname}' like '%${item.value}%'
</when>
<otherwise>
JSON_CONTAINS( val ->'$.${item.cname}' , '"${item.value}"', '$')
</otherwise>
</choose>
</otherwise>
</choose>
</foreach>
</if>
</where>
</select>
<select id="count" parameterType="com.lqjava.daywork.api.beans.WorksheetDataSaveBean" resultType="java.lang.Long">
SELECT
count( DISTINCT base.id ) count
FROM
worksheet_data_${dataId} base
LEFT JOIN
(SELECT * from worksheet_data_table_data where data_id = #{dataId}) c
ON
c.row_id = base.id
<!-- 主表 + 子表 查询条件拼接 -->
<where>
<if test="list != null">
<foreach collection="list" item="item" index="index" separator="AND" open="(" close=")">
<choose>
<when test='item.cname.contains("date")'>
<choose>
<when test='item.operator.contains("between") and item.endValue != null'>
DATE_FORMAT(${item.cname} , ${item.dateFormat} ) BETWEEN DATE_FORMAT( #{item.value}, ${item.dateFormat} ) AND DATE_FORMAT( #{item.endValue}, ${item.dateFormat} )
</when>
<otherwise>
DATE_FORMAT( ${item.cname}, ${item.dateFormat} ) = DATE_FORMAT( #{item.value}, ${item.dateFormat} )
</otherwise>
</choose>
</when>
<when test='item.cname.contains("input-number")'>
<choose>
<when test='item.operator.contains("between") and item.endValue != null'>
CAST(${item.cname} AS DECIMAL) BETWEEN #{item.value} AND #{item.endValue}
</when>
<otherwise>
CAST(${item.cname} AS DECIMAL) = #{item.value}
</otherwise>
</choose>
</when>
<when test='item.cname.contains("checkbox") or item.cname.contains("select")'>
<if test="item.valueList != null">
<choose>
<when test=' "OR".equals(item.reOperator) '>
<foreach collection="item.valueList " item="v" index="i" separator="OR" open="(" close=")">
FIND_IN_SET( #{v},${item.cname} )
</foreach>
</when>
<otherwise>
<foreach collection="item.valueList " item="v" index="i" separator="AND" open="(" close=")">
FIND_IN_SET( #{v},${item.cname} )
</foreach>
</otherwise>
</choose>
</if>
</when>
<when test='item.cname.contains("dept-user") or item.cname.contains("dept-base")'>
<if test="item.valueList != null">
<choose>
<when test=' "OR".equals(item.reOperator) '>
<foreach collection="item.valueList " item="v" index="i" separator="OR" open="(" close=")">
<choose>
<when test='item.operator.contains("like") '>
${item.cname} -> '$[*].name' like '%${v}%'
</when>
<otherwise>
JSON_CONTAINS( ${item.cname} ->'$[*].name' , '"${v}"', '$')
</otherwise>
</choose>
</foreach>
</when>
<otherwise>
<foreach collection="item.valueList " item="v" index="i" separator="AND" open="(" close=")">
<choose>
<when test='item.operator.contains("like") '>
${item.cname} -> '$[*].name' like '%${v}%'
</when>
<otherwise>
JSON_CONTAINS( ${item.cname} ->'$[*].name' , '"${v}"', '$')
</otherwise>
</choose>
</foreach>
</otherwise>
</choose>
</if>
</when>
<otherwise>
<choose>
<when test='item.operator.contains("like") '>
${item.cname} like '%${item.value}%'
</when>
<otherwise>
${item.cname} = #{item.value}
</otherwise>
</choose>
</otherwise>
</choose>
</foreach>
</if>
<if test="slaveList != null">
AND
<foreach collection="slaveList" item="item" index="index" separator="AND" open="(" close=")">
c.col_name = #{item.tableName}
AND
<choose>
<when test='item.cname.contains("date")'>
<choose>
<when test='item.operator.contains("between") and item.endValue != null'>
STR_TO_DATE(val -> '$.${item.cname}','"%Y-%m-%d %H:%i:%s"') between #{item.value} AND date_add(#{item.endValue}, interval 1 day)
</when>
<otherwise>
STR_TO_DATE(val -> '$.${item.cname}','"%Y-%m-%d %H:%i:%s"') between #{item.value} AND date_add(#{item.value}, interval 1 day)
</otherwise>
</choose>
</when>
<when test='item.cname.contains("input-number")'>
<choose>
<when test='item.operator.contains("between") and item.endValue != null'>
CAST(val -> '$."${item.cname}"' AS DECIMAL) BETWEEN #{item.value} AND #{item.endValue}
</when>
<otherwise>
CAST(val -> '$."${item.cname}"' AS DECIMAL) = #{item.value}
</otherwise>
</choose>
</when>
<when test='item.cname.contains("checkbox") or item.cname.contains("select")'>
<if test="item.valueList != null">
<choose>
<when test=' "OR".equals(item.reOperator) '>
<foreach collection="item.valueList " item="v" index="i" separator="OR" open="(" close=")">
val -> '$.${item.cname}' like '%,${v},%'
</foreach>
</when>
<otherwise>
<foreach collection="item.valueList " item="v" index="i" separator="AND" open="(" close=")">
val -> '$.${item.cname}' like '%,${v},%'
</foreach>
</otherwise>
</choose>
</if>
</when>
<when test='item.cname.contains("dept-user") or item.cname.contains("dept-base")'>
<if test="item.valueList != null">
<choose>
<when test=' "OR".equals(item.reOperator) '>
<foreach collection="item.valueList " item="v" index="i" separator="OR" open="(" close=")">
val -> '$."${item.cname}"' like '%${v}%'
</foreach>
</when>
<otherwise>
<foreach collection="item.valueList " item="v" index="i" separator="AND" open="(" close=")">
val -> '$."${item.cname}"' like '%${v}%'
</foreach>
</otherwise>
</choose>
</if>
</when>
<otherwise>
<choose>
<when test='item.operator.contains("like") '>
val -> '$.${item.cname}' like '%${item.value}%'
</when>
<otherwise>
JSON_CONTAINS( val ->'$.${item.cname}' , '"${item.value}"', '$')
</otherwise>
</choose>
</otherwise>
</choose>
</foreach>
</if>
</where>
</select>
2.Mapper.java
List<Map<String,String>> pageFind(WorksheetDataSaveBean queryBean); Long count(WorksheetDataSaveBean queryBean);
3.入参数据结构
public class WorksheetDataSaveBean {
private Long dataId;
private Long rowId;
private List<WorksheetData> list; //入参集合
private List<WorksheetData> resultList;//结果列集合 要返回哪些列信息
private List<WorksheetData> slaveList;//子表单查询条件
private Integer pageNum = 0;
private Integer pageSize = 10;
public class WorksheetData {
public static final Integer DATE_UNIT_SECOND = 1;
public static final Integer DATE_UNIT_MINUTE = 2;
public static final Integer DATE_UNIT_HOUR = 3;
public static final Integer DATE_UNIT_DAY = 4;
public static final Integer DATE_UNIT_MONTH = 5;
public static final Integer DATE_UNIT_YEAR = 6;
public static final String RELATED_OPERATOR_AND = "AND";
public static final String RELATED_OPERATOR_OR = "OR";
private Long id;
private String cname;
private String value;
private String tableName;//子表单cname 对应的子表单列 在主表单中的列名 例如:table_0 table_1
private String operator = "equals";//操作符 [equals] / [between and] / [like] /
private String reOperator = RELATED_OPERATOR_AND;//查询条件[条件内] 关联符 AND(默认) OR 提供给select/checkbox/dept-user/dept-base使用
private String endValue;//区间操作 结束区间值 提供给date/input-number 字段使用
private Integer dateUnit = DATE_UNIT_DAY;// 按秒、分、时、天(默认)、月、年 提供给date字段查询使用
private String dateFormat;
private List<String> valueList;//对checkbox、select 提供多值查询功能
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getCname() {
return cname;
}
public void setCname(String cname) {
this.cname = cname;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
initValueList();
}
public String getOperator() {
return operator;
}
public void setOperator(String operator) {
this.operator = operator;
}
public String getEndValue() {
return endValue;
}
public void setEndValue(String endValue) {
this.endValue = endValue;
}
public String getTableName() {
return tableName;
}
public void setTableName(String tableName) {
this.tableName = tableName;
}
public String getReOperator() {
return reOperator;
}
public void setReOperator(String reOperator) {
this.reOperator = reOperator;
}
public Integer getDateUnit() {
return dateUnit;
}
public void setDateUnit(Integer dateUnit) {
this.dateUnit = dateUnit;
initDateFormat();
}
public String getDateFormat() {
return dateFormat;
}
public void setDateFormat(String dateFormat) {
this.dateFormat = dateFormat;
}
public List<String> getValueList() {
return valueList;
}
public void setValueList(List<String> valueList) {
this.valueList = valueList;
}
private String initDateFormat(){
dateFormat = "'%Y-%m-%d %H:%i:%S'";
switch (dateUnit){
case 1:dateFormat = "'%Y-%m-%d %H:%i:%S'";break;
case 2:dateFormat = "'%Y-%m-%d %H:%i'";break;
case 3:dateFormat = "'%Y-%m-%d %H'";break;
case 4:dateFormat = "'%Y-%m-%d'";break;
case 5:dateFormat = "'%Y-%m'";break;
case 6:dateFormat = "'%Y'";break;
default:dateFormat = "'%Y-%m-%d'";
}
return dateFormat;
}
private void initValueList(){
List<String> list = null;
if (this.cname.contains("select")
|| this.cname.contains("checkbox")
|| this.cname.contains("dept-user")
|| this.cname.contains("dept-base")){
String[] split = this.value.split(",");
list = Arrays.asList(split);
}
this.valueList = list;
}
}
4.controller
@RequestMapping(value = "/pageFindTableData",method = RequestMethod.POST,name="表单数据分页全字段查询")
public PageResultBean<Map<String, Object>> pageFindTableData(@RequestBody WorksheetDataSaveBean bean){
PageResultBean<Map<String, Object>> res = new PageResultBean<>(); Long dataId = bean.getDataId();
int pageNum = bean.getPageNum();
int pageSize = bean.getPageSize();
pageNum = pageNum * pageSize;
bean.setPageNum(pageNum); /**
* 1.表名验证 + 列名验证
*/ if (dataId != null){
String tableName = DDLCreater.TABLE_NAME+dataId;
//表名验证
String exist = mapper.checkTableExist(tableName);
if(StringUtils.isNotBlank(exist)){ //列名验证
boolean flag = true;
List<WorksheetData> paramList = bean.getList();
if (paramList != null && paramList.size() > 0){
flag = checkColName(dataId,paramList,true);
} /**
* 2.区分主表子表查询条件 + DB查询 + 组装结果集
*/
if (flag){ //主子拆分
diffSlaveList(bean); //DB查询
List<Map<String, String>> maps = tableDataMapper.pageFind(bean); //组装结果
WorksheetPageFindMap map = new WorksheetPageFindMap();
List<Map<String, Object>> result = map.dealMap(maps);
//返回
res.initTrue(result,tableDataMapper.count(bean)); }else {
res.initFalse("列名不合法");
}
}else {
res.initFalse("数据表不存在");
}
}else {
res.initFalse("必填参数缺失");
}
return res;
}
检查表是否存在的sql
<select id="checkTableExist" resultType="java.lang.String" parameterType="java.lang.String">
SELECT
table_name
FROM
information_schema.TABLES
WHERE
table_name = #{tableName};
</select>
列名检查 以及 区分主表和子表的查询条件[因为主表是正常数据,子表是JSON数据,查询方式不同,因此需要区分处理]
/**
* 列名合法性检查
* [并处理 列名 加上``符号]
*
* =======处理列名注意=======
* 只有主表单字段 需要处理列名
* 子表单查询字段 列名无需处理【json中查询 字段不能带 ``查询】
*
*
* @param dataId dataId
* @param paramList 入参列名集合
* @param includeSlaveTable 是否包含子表单列
* @return 列名是否合法
*/
private boolean checkColName(Long dataId,List<WorksheetData> paramList,boolean includeSlaveTable){ int size = paramList.size();
WorksheetColBase check = new WorksheetColBase();
check.setDataid(dataId);
check.setState(includeSlaveTable ? null: 0);
List<WorksheetColBase> byDataIdCheckList = mapper.findByDataId(check); for (WorksheetData data : paramList) {
String colName = data.getCname();
String tableName = data.getTableName(); for (WorksheetColBase worksheetColBase : byDataIdCheckList) {
if (colName.equals(worksheetColBase.getColName())){
String tableColName = worksheetColBase.getTableColName();
if (tableName == null){
if (tableName == tableColName){ //处理列名
data.setCname("`"+colName+"`"); size--;
}
}else {
if (tableName.equals(tableColName)){
size--;
}
}
}
} } return size == 0 ? true : false;
} /**
* 区分 子表单 查询条件 和 主表查询条件
* @param bean
*/
private void diffSlaveList(WorksheetDataSaveBean bean){
List<WorksheetData> list = bean.getList(); //入参查询集合
if (list != null ){
List<WorksheetData> slaveList = new ArrayList<>(); //子表单查询集合 for (int i = 0; i < list.size(); i++) {
WorksheetData data = list.get(i);
String tableName = data.getTableName();
if (tableName != null){
slaveList.add(data);
list.remove(data); i--;
}
} bean.setSlaveList(slaveList);
} }
组装数据集的工具类
public class WorksheetPageFindMap {
private Map<Long,Map<String,Object>> resultMap = new HashMap<>();
private Long rowId;//行ID
private Map<String,Object> rowMap;//行Map
private List<Map<String,String>> slaveList;//子表单List
private Map<String,String> slaveMap;//子表单Map
public List<Map<String, Object>> dealMap(List<Map<String,String>> list){
for (Map<String, String> oldMap : list) {
rowMap = new HashMap<>();
slaveMap = new HashMap<>();
Set<String> keySet = oldMap.keySet();
for (String key : keySet) {
String value = String.valueOf(oldMap.get(key));
if (key.equals("id")){
rowId = Long.valueOf(value);
init();
append(key,rowId);
}else {
if (key.contains("slaveTable_")){
dealSlaveMap(key.split("slaveTable_")[1],value);
}else {
if (key.contains("date")){
value = value.split("\\.")[0];
}
append(key,value);
}
}
}
dealSlaveList();
}
List<Map<String, Object>> resultList = new ArrayList<>();
for (Map<String, Object> stringObjectMap : resultMap.values()) {
resultList.add(stringObjectMap);
}
return resultList;
}
//初始化行方法
private void init(){
Map<String, Object> oldRowMap = resultMap.get(rowId);
if (oldRowMap != null){
List<Map<String,String>> oldSlaveList = (List) oldRowMap.get("table");
if (oldSlaveList != null){
if (rowMap.get("table") == null){
slaveList = new ArrayList<>();
}
slaveList.addAll(oldSlaveList);
append("table",slaveList);
}
}
resultMap.put(rowId,rowMap);
}
//行数据追加方法
private void append(String key,Object value){
rowMap.put(key,value);
}
//子表单集合 初始化
private void dealSlaveMap(String key,String value){
slaveMap.put(key,value);
}
//子表单List 处理
private void dealSlaveList(){
//说明有子表单数据
if (slaveMap.size() > 0 ){
slaveList = (List) rowMap.get("table");
if (slaveList == null){
slaveList = new ArrayList<>();
append("table",slaveList);
}
slaveList.add(slaveMap);
}
}
}
最后conut ,拿到total,一起返回结果即可


返回结果集

【mysql】 mybatis实现 主从表 left join 1:n 一对多 分页查询 主表从表都有查询条件 【mybatis】count 统计+JSON查询的更多相关文章
- Mysql-单个left join 计算逻辑(一对多问题)
BUG背景: 我们有一个订单表 和 一个 物流表 它们通过 订单ID 进行一对一的关系绑定.但是由于物流表在保存订单信息的时候没有做判断该订单是否已经有物流信息,这就变成同一个订单id在物流表中存在多 ...
- mysql驱动表与被驱动表及join优化
驱动表与被驱动表 先了解在join连接时哪个表是驱动表,哪个表是被驱动表:1.当使用left join时,左表是驱动表,右表是被驱动表2.当使用right join时,右表时驱动表,左表是驱动表3.当 ...
- MySQL优化--表之间JOIN的关键字ON和Where (01)
1. Join关键字,就是把多个表连接起来 而on和where都是条件,但是针对的对象不一样 1.1. 关键字 On是指怎样把两个表连接起来,如: on a.name = b.name 是一行一行的比 ...
- mysql 5.7主从安装和配置
本文主要介绍mysql 5.7主从复制,转载请注明出处 下载地址 模块 版本 下载地址 mysql 5.7 https://dev.mysql.com/downloads/mysql/ libaio( ...
- MySQL架构之 主从+ProxySQL实现读写分离
准备服务器: docker run -d --privileged -v `pwd`/mysql_data:/data -p 3001:3306 --name mysql5-master --host ...
- 0104探究MySQL优化器对索引和JOIN顺序的选择
转自http://www.jb51.net/article/67007.htm,感谢博主 本文通过一个案例来看看MySQL优化器如何选择索引和JOIN顺序.表结构和数据准备参考本文最后部分" ...
- MYSQL管理之主从同步管理
原文地址:MYSQL管理之主从同步管理 作者:飞鸿无痕 MYSQL管理之主从同步管理 MYSQL主从同步架构是目前使用最多的数据库架构之一,尤其是负载比较大的网站,因此对于主从同步的管理也就显得非常重 ...
- 工作随笔——mysql子查询删除原表数据
最近在开发的时候遇到一个mysql的子查询删除原表数据的问题.在网上也看了很多方法,基本也是然并卵(不是写的太乱就是效率太慢). 公司DBA给了一个很好的解决方案,让人耳目一新. DELETE fb. ...
- 【MySQL】MySQL中针对大数据量常用技术_创建索引+缓存配置+分库分表+子查询优化(转载)
原文地址:http://blog.csdn.net/zwan0518/article/details/11972853 目录(?)[-] 一查询优化 1创建索引 2缓存的配置 3slow_query_ ...
随机推荐
- XGBoost 引入 - 提升树
认识提升树 这个boosting 跟 Adaboost 不同. Adaboost 是通过上一轮的误差率来动态给定一下轮样本不同的权重来学习不同的模型. 现在的方式, 更多是基于残差 的方式来训练. 一 ...
- A simple introduction to Three kinds of Delegation of Kerberos
1.What is Delegation? Just like the name. Delegation is that a server pretend to behalf of a user an ...
- PAT 乙级 1048.数字加密 C++/Java
题目来源 本题要求实现一种数字加密方法.首先固定一个加密用正整数 A,对任一正整数 B,将其每 1 位数字与 A 的对应位置上的数字进行以下运算:对奇数位,对应位的数字相加后对 13 取余——这里用 ...
- S3C2440_LCD控制器
1.LCD控制器主要有两方面的功能: 1)从framebuffer中取出某个像素的数据: 2)配合其他信号,一起将这个数据发送给LCD 不管是2440,还是其他型号的ARM芯片.它们的LCD控制器的功 ...
- windows 运行库与dll文件
Windows 10包含版本 win10家庭版win10专业版win10教育版win 10企业版 Windows 7包含6个版本分别为Windows 7 Starter(初级版)Windows 7 H ...
- plv8 rpm包创建
以下是从一个三方rpm构建,获取到的rpm 包制作spec,主要是学习下pg 扩展rpm 包的打包 rpm src 包 下载地址 https://fedora.pkgs.org/29/fedora-x ...
- ABP abp zreo 老版本 支持dotnet framework 4.0
下载了个abp zreo的老版本,module-zero-template-1.5.1, 只有这个版本支持.net framework4.0,其它都依赖.net framework 4.5和4.6去了 ...
- [RN] React Native 自定义导航栏随滚动渐变
React Native 自定义导航栏随滚动渐变 实现效果预览: 代码实现: 1.定义导航栏 NavPage.js import React, {Component} from 'react'; im ...
- Linux/Unix 多线程通信
线程间无需特别的手段进行通信,因为线程间可以共享数据结构,也就是一个全局变量可以被两个线程同时使用. 不过要注意的是线程间需要做好同步,一般用 mutex. 可以参考一些比较新的 UNIX/Linux ...
- Java 读取和写入文本文件
package test_java; import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStre ...