【mysql】 mybatis实现 主从表 left join 1:n 一对多 分页查询 主表从表都有查询条件 【mybatis】count 统计+JSON查询

摘要:
--对应于子表的属性被封装在列表中,它接收1:N--˃SELECTbase.id,t。idslaveTable_ id,t。row_ idslaveTable_ rowId,t。col_ nameslaveTable_ colName,t。valslaveTable_valFROMbaseLEFTJOIN工作表_data_table_datatONbase.id=t。row_ idWHERE2.mapper Java应该编写List<Custom Bean>pageFind如下#################################不确定的返回字段类型[即,当表中的属性是动态的,并且没有对应的实体时]##########x###################.mapper这应该以xml格式编写[在下面的示例中:因为我不确定返回的字段,所以我使用HashMap直接接收查询结果,然后自己处理结果集]SELECTbase.*,t、 idsliveTable_ id,t。row_ idslaveTable_ rowId,t。col_ nameslaveTable_ colName,t。valslaveTable_valFROMbaseLEFTJOIN工作表_data_table_datatONbase.id=t。row_ id WHERE˂!

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查询】

【mysql】 mybatis实现 主从表 left join 1:n 一对多 分页查询 主表从表都有查询条件 【mybatis】count 统计+JSON查询第1张【mysql】 mybatis实现 主从表 left join 1:n 一对多 分页查询 主表从表都有查询条件 【mybatis】count 统计+JSON查询第2张
 <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>
View Code

2.Mapper.java 

List<Map<String,String>> pageFind(WorksheetDataSaveBean queryBean);

Long count(WorksheetDataSaveBean queryBean);

3.入参数据结构

【mysql】 mybatis实现 主从表 left join 1:n 一对多 分页查询 主表从表都有查询条件 【mybatis】count 统计+JSON查询第1张【mysql】 mybatis实现 主从表 left join 1:n 一对多 分页查询 主表从表都有查询条件 【mybatis】count 统计+JSON查询第4张
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;
View Code
【mysql】 mybatis实现 主从表 left join 1:n 一对多 分页查询 主表从表都有查询条件 【mybatis】count 统计+JSON查询第1张【mysql】 mybatis实现 主从表 left join 1:n 一对多 分页查询 主表从表都有查询条件 【mybatis】count 统计+JSON查询第6张
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;
    }



}
View Code

4.controller

【mysql】 mybatis实现 主从表 left join 1:n 一对多 分页查询 主表从表都有查询条件 【mybatis】count 统计+JSON查询第1张【mysql】 mybatis实现 主从表 left join 1:n 一对多 分页查询 主表从表都有查询条件 【mybatis】count 统计+JSON查询第8张
@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;
    }
View Code

检查表是否存在的sql

【mysql】 mybatis实现 主从表 left join 1:n 一对多 分页查询 主表从表都有查询条件 【mybatis】count 统计+JSON查询第1张【mysql】 mybatis实现 主从表 left join 1:n 一对多 分页查询 主表从表都有查询条件 【mybatis】count 统计+JSON查询第10张
<select id="checkTableExist" resultType="java.lang.String" parameterType="java.lang.String">
        SELECT
            table_name
        FROM
            information_schema.TABLES
        WHERE
            table_name = #{tableName};
    </select>
View Code

列名检查 以及 区分主表和子表的查询条件[因为主表是正常数据,子表是JSON数据,查询方式不同,因此需要区分处理]

【mysql】 mybatis实现 主从表 left join 1:n 一对多 分页查询 主表从表都有查询条件 【mybatis】count 统计+JSON查询第1张【mysql】 mybatis实现 主从表 left join 1:n 一对多 分页查询 主表从表都有查询条件 【mybatis】count 统计+JSON查询第12张
/**
     * 列名合法性检查
     * [并处理 列名 加上``符号]
     *
     * =======处理列名注意=======
     * 只有主表单字段 需要处理列名
     * 子表单查询字段 列名无需处理【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);
        }

    }
View Code

组装数据集的工具类

【mysql】 mybatis实现 主从表 left join 1:n 一对多 分页查询 主表从表都有查询条件 【mybatis】count 统计+JSON查询第1张【mysql】 mybatis实现 主从表 left join 1:n 一对多 分页查询 主表从表都有查询条件 【mybatis】count 统计+JSON查询第14张
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);
        }
    }


}
View Code

最后conut ,拿到total,一起返回结果即可

【mysql】 mybatis实现 主从表 left join 1:n 一对多 分页查询 主表从表都有查询条件 【mybatis】count 统计+JSON查询第15张

【mysql】 mybatis实现 主从表 left join 1:n 一对多 分页查询 主表从表都有查询条件 【mybatis】count 统计+JSON查询第16张

 返回结果集

【mysql】 mybatis实现 主从表 left join 1:n 一对多 分页查询 主表从表都有查询条件 【mybatis】count 统计+JSON查询第17张

免责声明:文章转载自《【mysql】 mybatis实现 主从表 left join 1:n 一对多 分页查询 主表从表都有查询条件 【mybatis】count 统计+JSON查询》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇运放的压摆率与GBWAndroid学习笔记进阶21之设置壁纸下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

oracle 的用户管理 sqlplus的常用命令

创建用户:create user 用户名 identified by 密码; SQL> create user scw identified by 123; 用户已创建。 SQL> 在oracle中创建用户只能由管理员或者具有管理员的权限的用户创建 修改密码: 1.修改自己的密码: SQL> passw; 更改 SCW 的口令 旧口令...

C#如何获取其他程序ListView控件中的内容

源码下载:http://download.csdn.net/detail/php_fly/4923388 需求:获取其他程序中的ListView控件的文本内容 原理:进程之间是相互隔离的,数据是不能共享的(有些特例)    LVM_GETTITEMTEXT:将一个数据缓冲区提供给listview32控件,你不能把你的进程的数据缓冲提供给另外的程序,所以要用...

c#定时器Timer

C# Timer用法有哪些呢?我们在使用C# Timer时都会有自己的一些总结,那么这里向你介绍3种方法,希望对你了解和学习C# Timer使用的方法有所帮助。 关于C# Timer类 在C#里关于定时器类就有3个 C# Timer使用的方法1.定义在System.Windows.Forms里 C# Timer使用的方法2.定义在System.Thread...

Java中使用Shardingsphere-JDBC进行分库分表的使用方法(精简)

1.pom.xml中添加依赖 <dependency> <groupId>org.apache.shardingsphere</groupId> <artifactId>sharding-jdbc-spring-boot-starter</artifactId> <vers...

linux 操作 mysql 指定端口登录 以及启动 停止

linux 操作 mysql 指定端口登录 mysql -uroot -p -h10.154.0.43 -P3341 1、查看mysql版本方法一:status;方法二:select version(); 2、Mysql启动、停止、重启常用命令a、启动方式1、使用 service 启动:[root@localhost /]# service mysqld...

Spring 远程调用工具类RestTemplateUtils

Spring 远程调用Rest服务工具类,包含Get、Post、Put、Delete四种调用方式。 依赖jar <dependency> <groupId>org.springframework</groupId> <artifactId>s...