Springboot实战贴近业务查询表单功能,UNION特例说明

业务场景:存在一个编码归属表A:【产品,项目,父编码...】,保存的是业务的产品信息,一个产品有多个项目,多个父编码。另外还有一个子编码归属表B:【父编码,子编码】,表示一个父编码的下层还有多个子编码

一般多数的查询中,都需要用到业务制定的这张编码表,通过编码进行搜索

 ex:业务有一个质量问题单表,字段包括了:单号、发生时间、问题描述、编码、原因分析、发生工序......现在需要查询产品A对应的编码都发生了哪些问题,进行查询过滤,产品A对应有多个编码,如上介绍的业务逻辑,并且还需要把子编码也加上过滤。那下面我们简要看看如何设计这个查询接口。

首先我们定义这个表对应的一个VO实体类,属性一一对应表字段,另外这里补充一点,为了方便接口传参,有时也会在实体类中定义不存在的表字段作为传参时使用的属性,比如:我们查询问题单发生时间在22年1月至6月时,一般都是传递{"startDate":"2022-01","endDate":"2022-06"}这种形式,而我们属性中就可用定义这两个属性 private String startDate;private String endDate


DB编码表如下:

PARENT_B编码归属表
产品项目父编码
itgetdata123
SUB_B子编码表
父编码子编码
123456

 XML映射文件如下:

说明:因为方法是分页查询,传参设计的时候定为两个(ProblemListVO,PageVo),所以判断时需要用_parameter.get(0)来取实体VO的属性,_parameter.get(1)来取分页的页号,页容量

这里where条件是实际业务常用的几种:

1.date_format(CREATE_TIME,"%Y-%m-%d") <![CDATA[ >= ]]> #{0.startDate}

通过传递时间参数,进行过滤时间大于等于指定的日期。

2.ITEM_CODE IN(..UNION..)

因为业务传参的是产品属性,product,一个产品对应多个编码,所以为了考虑用户便捷高效,给用户传递产品,后台转换对应的多个编码,编码需要包含父编码与子编码,为了效率问题,我们用UNION来拼接对应产品的父编码与子编码。

3.PROBLEM_DESC like concat('%',#{0.problemDesc},'%')

模糊匹配,存在一种情况,业务想查该问题单的问题描述字段中,存在指定的文字如:严重/停线等,则可以使用like,进行匹配。 

4.foreach collection='_parameter.get("0").process'

list集合参数,一般是像前端有个下拉框选择固定的内容,比如问题单中的工序,会有:测试工序/加工工序,采用foreach 接收参数,同样可以用like 模糊匹配数据,或者完全匹配,视业务需求 

<?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.app.it.dao.IProblemListDao">
<sql id ="problem_select">
    select 
    NO                no,
    PROBLEM_DESC      problemDesc,
    ITEM_CODE         itemCode,
    CREATE_TIME       createTime, 
    PROCESS           process,
    ......
    from schema.A 
    <where>
        <if test='_parameter.get("0").startDate !=null and _parameter.get("0").startDate!=""'>
            date_format(CREATE_TIME,"%Y-%m-%d") <![CDATA[ >= ]]> #{0.startDate}
        </if>
        <if test='_parameter.get("0").endDate !=null and _parameter.get("0").endDate !=""'>
           and  date_format(CREATE_TIME,"%Y-%m-%d") <![CDATA[ <= ]]> #{0.endDate}
        </if>
         <if test='_parameter.get("0").product !=null and _parameter.get("0").product !=""'>
           and  ITEM_CODE in ( 
                	select SUB_CODE  from schema.SUB_B
                        where PARENT_CODE  in 
					(
					select PARENT_CODE from PARENT_B 
					    where PRODUCT = #{0.product}
					)
					union 
					(
					select PARENT_CODE from PARENT_B
				        where PRODUCT = #{0.product}
					)
            )
        </if>
        <if test='_parameter.get("0").problemDesc !=null and _parameter.get("0").problemDesc !=""'>
            and PROBLEM_DESC like concat('%',#{0.problemDesc},'%')
        </if>
        <if test='_parameter.get("0").process!=null and _parameter.get("0").process.size()>0'>
            and 
            <foreach collection='_parameter.get("0").process' item='item' open='(' separator='or' close=')'>
                PROCESS like concat('%',#{item},'%')
            </foreach>
        </if>
    </where>
    order by CREATE_TIME desc      
</sql>
<select id = "getProblemList" resultType="com.app.it.vo.ProblemListVO">
   select * from (
    <include refid='problem_select'/> ) t limit #{1.pageIndex},#{1.pageSize}
</select>
</mapper>

Dao层接口

@Repository
public interface IProblemDao{
    public List<ProblemListVO> getProblemList(ProblemParamVO param,PageVO page);
}

VO实体类

//问题单表VO
@Data
public class ProblemListVO implements Serializable {
    private static final long serialVersionUID = 1L;
    private String no; // 单号
    private String createTime; // 发生时间
    private String problemDesc; // 问题描述
    private String itemCode; // 编码
    private List<String >process; // 工序
}
//问题单传参参数VO
@Data
public class ProblemParamVO implements Serializable {
    private static final long serialVersionUID = 1L;
    private String startDate; // 开始时间
    private String endDate; // 结束时间
    private String problemDesc; // 问题描述
    private String product; // 产品
    private List<String> process; // 工序
}

Service层

public interface IProblemListService {
    public List<ProblemListVO> getProblemList(
            ProblemParamVO param, PageVO pageVO)
}
@Service
public class ProblemListService implements IProblemListService {
    @Autowired
    private IProblemListDao iProblemListDao;

    @Override
    public  List<ProblemListVO> getProblemList( ProblemParamVO param, PageVO pageVO){
         return iProblemListDao. getProblemList( param,pageVO);
    }
}



Controller层

@RestController
@RequestMapping("/app")
public class ProblemListController  {
    @Autowired
    private IProblemListService iProblemListService;
    //分页传参,通过用PathParam注解传递分页VO,路径能解析到对应的两个分页属性
    @RequestMapping("/problem/page/{pageSize}/{curPage}")
    public  List<ProblemListVO> getProblemList(@RequestBody ProblemParamVO param,@PathParam("") PageVO pageVO){
         return iProblemListService. getProblemList( param,pageVO);
    }
}

前端请求:

URL:域名/app/problem/page/100/1

Body:{

        "startDate":"2022-01-01",

        "endDate":"2022-06-30",

        "product":"it",

        "problemDesc" :"严重",
        "process": ["测试","加工"]

}

 总结:unionhttps://so.csdn.net/so/search?q=union&spm=1001.2101.3001.70201.UNION对两个结果集进行并集操作, 不包括重复行,相当于distinct, 同时进行默认规则的排序,在无需去重的前提下,使用union all的执行效率要比union高

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值