热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

mybatis实现主从表leftjoin1:n一对多分页查询主表从表都有查询条件count需求:1.主从表数据是1:m2.主从表各自都有查询条件3.最后

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

需求:

========================================

1.主从表数据 是 1:m

2.主从表各自都有查询条件

3.最后查询结果 需要分页,并统计总数

注意:

=======================================

1.查询的分页,必须在数据库做,否则分页没有意义

解决方法:

注意 下面的入参中 [第一页的10条]

pageNum=0PageSize=10

实际入参应该是处理过的

pageNum = pageNum*10pageSize= 10

##############################有对应实体接收查询结果的情况下################################

1.mapper.xml应该这么写

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

2.mapper.java应该这么写

List pageFind(WorksheetDataSaveBean queryBean);

############################### 不确定返回字段类型[即表中属性是动态的,没有对应实体的情况下]###################################

1.mapper.xml中应该这么写

[下面的示例中:因为我不确定返回的字段,所以用HashMap直接接收查询结果后 自己处理的结果集]

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

2.mapper.java应该这么写

List> pageFind(WorksheetDataSaveBean queryBean);

===================================count=============================================

count 是什么?count就是页面的 总共total条数

1.mapper.xml应该这么写

SELECT

count( DISTINCT base.id ) count

FROM

worksheet_data_${dataId} base

LEFT JOIN

worksheet_data_table_data c

ON

c.row_id = base.id

-- 拼接条件的地方

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结果集 size=主size*子size 【因此,结果集需要将子表数据封装进主表数据集 java处理】

6.上述结果集条数不能作为分页查询的count统计,返回总页码【因此需要额外count()查询,以返回正确的total】

代码参考:

1.Mapper.xml【一个page查询   一个count查询】

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

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

DATE_FORMAT(${item.cname} , ${item.dateFormat} ) BETWEEN DATE_FORMAT( #{item.value}, ${item.dateFormat} ) AND DATE_FORMAT( #{item.endValue}, ${item.dateFormat} )

DATE_FORMAT( ${item.cname}, ${item.dateFormat} ) = DATE_FORMAT( #{item.value}, ${item.dateFormat} )

CAST(${item.cname} AS DECIMAL) BETWEEN #{item.value} AND #{item.endValue}

CAST(${item.cname} AS DECIMAL) = #{item.value}

FIND_IN_SET( #{v},${item.cname} )

FIND_IN_SET( #{v},${item.cname} )

${item.cname} -> '$[*].name' like '%${v}%'

JSON_CONTAINS( ${item.cname} ->'$[*].name' , '"${v}"', '$')

${item.cname} -> '$[*].name' like '%${v}%'

JSON_CONTAINS( ${item.cname} ->'$[*].name' , '"${v}"', '$')

${item.cname} like '%${item.value}%'

${item.cname} = #{item.value}

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

t.col_name = #{item.tableName}

AND

STR_TO_DATE(val -> '$.${item.cname}','"%Y-%m-%d %H:%i:%s"') between #{item.value} AND date_add(#{item.endValue}, interval 1 day)

STR_TO_DATE(val -> '$.${item.cname}','"%Y-%m-%d %H:%i:%s"') between #{item.value} AND date_add(#{item.value}, interval 1 day)

CAST(val -> '$."${item.cname}"' AS DECIMAL) BETWEEN #{item.value} AND #{item.endValue}

CAST(val -> '$."${item.cname}"' AS DECIMAL) = #{item.value}

val -> '$.${item.cname}' like '%,${v},%'

val -> '$.${item.cname}' like '%,${v},%'

val -> '$."${item.cname}"' like '%${v}%'

val -> '$."${item.cname}"' like '%${v}%'

val -> '$.${item.cname}' like '%${item.value}%'

JSON_CONTAINS( val ->'$.${item.cname}' , '"${item.value}"', '$')

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

DATE_FORMAT(${item.cname} , ${item.dateFormat} ) BETWEEN DATE_FORMAT( #{item.value}, ${item.dateFormat} ) AND DATE_FORMAT( #{item.endValue}, ${item.dateFormat} )

DATE_FORMAT( ${item.cname}, ${item.dateFormat} ) = DATE_FORMAT( #{item.value}, ${item.dateFormat} )

CAST(${item.cname} AS DECIMAL) BETWEEN #{item.value} AND #{item.endValue}

CAST(${item.cname} AS DECIMAL) = #{item.value}

FIND_IN_SET( #{v},${item.cname} )

FIND_IN_SET( #{v},${item.cname} )

${item.cname} -> '$[*].name' like '%${v}%'

JSON_CONTAINS( ${item.cname} ->'$[*].name' , '"${v}"', '$')

${item.cname} -> '$[*].name' like '%${v}%'

JSON_CONTAINS( ${item.cname} ->'$[*].name' , '"${v}"', '$')

${item.cname} like '%${item.value}%'

${item.cname} = #{item.value}

ANDc.col_name = #{item.tableName}

AND

STR_TO_DATE(val -> '$.${item.cname}','"%Y-%m-%d %H:%i:%s"') between #{item.value} AND date_add(#{item.endValue}, interval 1 day)

STR_TO_DATE(val -> '$.${item.cname}','"%Y-%m-%d %H:%i:%s"') between #{item.value} AND date_add(#{item.value}, interval 1 day)

CAST(val -> '$."${item.cname}"' AS DECIMAL) BETWEEN #{item.value} AND #{item.endValue}

CAST(val -> '$."${item.cname}"' AS DECIMAL) = #{item.value}

val -> '$.${item.cname}' like '%,${v},%'

val -> '$.${item.cname}' like '%,${v},%'

val -> '$."${item.cname}"' like '%${v}%'

val -> '$."${item.cname}"' like '%${v}%'

val -> '$.${item.cname}' like '%${item.value}%'

JSON_CONTAINS( val ->'$.${item.cname}' , '"${item.value}"', '$')

View Code

2.Mapper.java

List>pageFind(WorksheetDataSaveBean queryBean);

Long count(WorksheetDataSaveBean queryBean);

3.入参数据结构

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

public classWorksheetDataSaveBean {privateLong dataId;privateLong rowId;private List list; //入参集合

private List resultList;//结果列集合 要返回哪些列信息

private List slaveList;//子表单查询条件

private Integer pageNum = 0;private Integer pageSize = 10;

View Code

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

public classWorksheetData {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";privateLong id;privateString cname;privateString 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字段查询使用

privateString dateFormat;private List valueList;//对checkbox、select 提供多值查询功能

publicLong getId() {returnid;

}public voidsetId(Long id) {this.id =id;

}publicString getCname() {returncname;

}public voidsetCname(String cname) {this.cname =cname;

}publicString getValue() {returnvalue;

}public voidsetValue(String value) {this.value =value;

initValueList();

}publicString getOperator() {returnoperator;

}public voidsetOperator(String operator) {this.operator =operator;

}publicString getEndValue() {returnendValue;

}public voidsetEndValue(String endValue) {this.endValue =endValue;

}publicString getTableName() {returntableName;

}public voidsetTableName(String tableName) {this.tableName =tableName;

}publicString getReOperator() {returnreOperator;

}public voidsetReOperator(String reOperator) {this.reOperator =reOperator;

}publicInteger getDateUnit() {returndateUnit;

}public voidsetDateUnit(Integer dateUnit) {this.dateUnit =dateUnit;

initDateFormat();

}publicString getDateFormat() {returndateFormat;

}public voidsetDateFormat(String dateFormat) {this.dateFormat =dateFormat;

}public ListgetValueList() {returnvalueList;

}public void setValueList(ListvalueList) {this.valueList =valueList;

}privateString 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'";

}returndateFormat;

}private voidinitValueList(){

List 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

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

@RequestMapping(value = "/pageFindTableData",method = RequestMethod.POST,name="表单数据分页全字段查询")public PageResultBean>pageFindTableData(@RequestBody WorksheetDataSaveBean bean){

PageResultBean> res &#61; new PageResultBean<>();

Long dataId&#61;bean.getDataId();int pageNum &#61;bean.getPageNum();int pageSize &#61;bean.getPageSize();

pageNum&#61; pageNum *pageSize;

bean.setPageNum(pageNum);/*** 1.表名验证 &#43; 列名验证*/

if (dataId !&#61; null){

String tableName&#61; DDLCreater.TABLE_NAME&#43;dataId;//表名验证

String exist &#61;mapper.checkTableExist(tableName);if(StringUtils.isNotBlank(exist)){//列名验证

boolean flag &#61; true;

List paramList &#61;bean.getList();if (paramList !&#61; null && paramList.size() > 0){

flag&#61; checkColName(dataId,paramList,true);

}/*** 2.区分主表子表查询条件 &#43; DB查询 &#43; 组装结果集*/

if(flag){//主子拆分

diffSlaveList(bean);//DB查询

List> maps &#61;tableDataMapper.pageFind(bean);//组装结果

WorksheetPageFindMap map &#61; newWorksheetPageFindMap();

List> result &#61;map.dealMap(maps);//返回

res.initTrue(result,tableDataMapper.count(bean));

}else{

res.initFalse("列名不合法");

}

}else{

res.initFalse("数据表不存在");

}

}else{

res.initFalse("必填参数缺失");

}returnres;

}

View Code

检查表是否存在的sql

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

SELECT

table_name

FROM

information_schema.TABLES

WHERE

table_name &#61; #{tableName};

View Code

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

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

/*** 列名合法性检查

* [并处理 列名 加上&#96;&#96;符号]

*

* &#61;&#61;&#61;&#61;&#61;&#61;&#61;处理列名注意&#61;&#61;&#61;&#61;&#61;&#61;&#61;

* 只有主表单字段 需要处理列名

* 子表单查询字段 列名无需处理【json中查询 字段不能带 &#96;&#96;查询】

*

*

*&#64;paramdataId dataId

*&#64;paramparamList 入参列名集合

*&#64;paramincludeSlaveTable 是否包含子表单列

*&#64;return列名是否合法*/

private boolean checkColName(Long dataId,List paramList,booleanincludeSlaveTable){int size &#61;paramList.size();

WorksheetColBase check&#61; newWorksheetColBase();

check.setDataid(dataId);

check.setState(includeSlaveTable? null: 0);

List byDataIdCheckList &#61;mapper.findByDataId(check);for(WorksheetData data : paramList) {

String colName&#61;data.getCname();

String tableName&#61;data.getTableName();for(WorksheetColBase worksheetColBase : byDataIdCheckList) {if(colName.equals(worksheetColBase.getColName())){

String tableColName&#61;worksheetColBase.getTableColName();if (tableName &#61;&#61; null){if (tableName &#61;&#61;tableColName){//处理列名

data.setCname("&#96;"&#43;colName&#43;"&#96;");

size--;

}

}else{if(tableName.equals(tableColName)){

size--;

}

}

}

}

}return size &#61;&#61; 0 ? true : false;

}/*** 区分 子表单 查询条件 和 主表查询条件

*&#64;parambean*/

private voiddiffSlaveList(WorksheetDataSaveBean bean){

List list &#61; bean.getList(); //入参查询集合

if (list !&#61; null){

List slaveList &#61; new ArrayList<>(); //子表单查询集合

for (int i &#61; 0; i

WorksheetData data&#61;list.get(i);

String tableName&#61;data.getTableName();if (tableName !&#61; null){

slaveList.add(data);

list.remove(data);

i--;

}

}

bean.setSlaveList(slaveList);

}

}

View Code

组装数据集的工具类

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

public classWorksheetPageFindMap {private Map> resultMap &#61; new HashMap<>();private Long rowId;//行ID

private Map rowMap;//行Map

private List> slaveList;//子表单List

private Map slaveMap;//子表单Map

public List> dealMap(List>list){for (MapoldMap : list) {

rowMap&#61; new HashMap<>();

slaveMap&#61; new HashMap<>();

Set keySet &#61;oldMap.keySet();for(String key : keySet) {

String value&#61;String.valueOf(oldMap.get(key));if (key.equals("id")){

rowId&#61;Long.valueOf(value);

init();

append(key,rowId);

}else{if (key.contains("slaveTable_")){

dealSlaveMap(key.split("slaveTable_")[1],value);

}else{if (key.contains("date")){

value&#61; value.split("\\.")[0];

}

append(key,value);

}

}

}

dealSlaveList();

}

List> resultList &#61; new ArrayList<>();for (MapstringObjectMap : resultMap.values()) {

resultList.add(stringObjectMap);

}returnresultList;

}//初始化行方法

private voidinit(){

Map oldRowMap &#61;resultMap.get(rowId);if (oldRowMap !&#61; null){

List> oldSlaveList &#61; (List) oldRowMap.get("table");if (oldSlaveList !&#61; null){if (rowMap.get("table") &#61;&#61; null){

slaveList&#61; new ArrayList<>();

}

slaveList.addAll(oldSlaveList);

append("table",slaveList);

}

}

resultMap.put(rowId,rowMap);

}//行数据追加方法

private voidappend(String key,Object value){

rowMap.put(key,value);

}//子表单集合 初始化

private voiddealSlaveMap(String key,String value){

slaveMap.put(key,value);

}//子表单List 处理

private voiddealSlaveList(){//说明有子表单数据

if (slaveMap.size() > 0){

slaveList&#61; (List) rowMap.get("table");if (slaveList &#61;&#61; null){

slaveList&#61; new ArrayList<>();

append("table",slaveList);

}

slaveList.add(slaveMap);

}

}

}

View Code

最后conut &#xff0c;拿到total&#xff0c;一起返回结果即可

f9b24b5eb6b6510e1251d624221bac01.png

cff9c794d2f5c3309343603207823b62.png

返回结果集

e0907324be82a29415393d0e65583a68.png



推荐阅读
author-avatar
是不是有谁代替我陪在你身旁
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有