springboot+mybatisplus进行查询以逗号隔开的字符串字段

当我们在平时中需要通过以逗号隔开的,查询其中含有的数据时,我们会需要用到一个mysql函数,FIND_IN_SET是MySQL中的一个函数,它返回一个字符串在由逗号分隔的字符串列表中的位置。这个函数通常用于在SQL查询中处理以逗号分隔的列表。

 当我们需要查询的时候,就需要下面这样的sql才能进行多个以逗号隔开的查询条件进行拼接,但是呢,在mybatis-puls中怎么写这样的sql呢。

SELECT DISTINCT c.id,c.semesterid,c.professionid,c.classid,c.teacherid,c.courseid,c.classroomid,c.`week`,c.weekbyday,c.section,c.studentnumber,c.`status`,c.remark FROM c_coursearrange c JOIN sys_user_role sur ON c.teacherid = sur.user_id JOIN sys_role r ON sur.role_id = r.id  AND FIND_IN_SET('1', week) > 0 AND FIND_IN_SET('2', week) > 0 AND FIND_IN_SET('1', section) > 0 AND FIND_IN_SET('2', section) > 0 AND FIND_IN_SET('1', weekbyday) > 0 AND FIND_IN_SET('4', weekbyday) > 0

Controller层接口是这么写的,控制层是通过QueryWrapper<CCoursearrange> queryWrapper = new QueryWrapper<>();
方法进行查询的,queryWrapper.last(build)表示在sql最后面添加where条件的sql。
@GetMapping(value = "/list")	
public Result<IPage<CCoursearrange>> queryPageList(CCoursearrange cCoursearrange,
								   @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
								   @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
								   HttpServletRequest req) {
        QueryWrapper<CCoursearrange> queryWrapper = new QueryWrapper<>();
        Page<CCoursearrange> page = new Page<CCoursearrange>(pageNo, pageSize);
		// 判断传过来的查询参数是否为null,为null则不进行此操作,反之进行
        String build = CCoursearrangeController.buildSqlConditions(cCoursearrange);
        //在sql最后面添加sql		
        queryWrapper.last(build);
        IPage<CCoursearrange> pageList = cCoursearrangeService.findTeacherByCoursearrangePage(page, queryWrapper);
        return Result.OK(pageList);
    }




//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!写了方法在下面


	 /**
	  * 判断传过来的查询参数是否为null,为null则不进行此操作,反之进行
	  * @param cCoursearrange
	  * @return
	  */
	 public static String buildSqlConditions(CCoursearrange cCoursearrange) {
		 // 判断是否为null,为null则不进行此操作,反之进行
		 String[] weeksToCheck = null;
		 if (cCoursearrange.getWeek() != null) {
			 weeksToCheck = cCoursearrange.getWeek().split(",");
		 }

		 String[] sectionsToCheck = null;
		 if (cCoursearrange.getSection() != null) {
			 sectionsToCheck = cCoursearrange.getSection().split(",");
		 }

		 String[] weekByDaysToCheck = null;
		 if (cCoursearrange.getWeekbyday() != null) {
			 weekByDaysToCheck = cCoursearrange.getWeekbyday().split(",");
		 }
		 // 构建 FIND_IN_SET 的sql条件,判断是否有查询值,有则添加后面的sql
		 String findInSetConditions = CustomQueryUtils.buildFindInSetConditions(weeksToCheck, sectionsToCheck, weekByDaysToCheck);
		 return findInSetConditions;

	 }

mapper层,mybatisplus是在最后面添加${ew.customSqlSegment}进行条件查询,这样就不需要通过xml进行if判断了。

// 教师所教课程排班
    @Select("SELECT DISTINCT c.id,c.semesterid,c.professionid,c.classid,c.teacherid,c.courseid,c.classroomid,c.`week`,c.weekbyday,c.section,c.studentnumber,c.`status`,c.remark FROM c_coursearrange c JOIN sys_user_role sur ON c.teacherid = sur.user_id JOIN sys_role r ON sur.role_id = r.id ${ew.customSqlSegment} ")
    IPage<CCoursearrange> findTeacherByCoursearrangePage(Page<CCoursearrange> page, @Param("ew") Wrapper<CCoursearrange> queryWrapper);

service层

    @Override
    public IPage<CCoursearrange> findTeacherByCoursearrangePage(Page<CCoursearrange> page, QueryWrapper<CCoursearrange> queryWrapper) {
        return baseMapper.findTeacherByCoursearrangePage(page,queryWrapper);
    }

写了一个util方法。这里面的三个if我并没有进行调优,就是写死了。你们可以根据需要多少查询条件进行编辑几个if判断。

简单说明一下:

  1. 处理weeks数组
    • 首先检查weeks数组是否非空且长度大于0。
    • 使用Arrays.toString(weeks).equals("[]")来检查数组是否为空数组。
    • 如果weeks数组非空,则不进行weeks的sql添加,然后继续判断下面的数组是否为空,不为空则进行添加FIND_IN_SET进行判断提交的数据中含有的字符。
    • 使用AND来连接多个条件,并添加括号来确保逻辑的正确性。
    • 通过循环遍历weeks数组,并使用FIND_IN_SET函数来为每个元素构建条件。
    • firstCondition变量用于跟踪是否已添加第一个条件,从而避免在第一个条件前添加多余的AND

当您调用buildSqlConditions(cCoursearrange)方法时,它会:

  • 检查cCoursearrange对象的weeksectionweekbyday属性。
  • 如果这些属性不为null,则将它们拆分为数组。
  • 调用buildFindInSetConditions方法为这些数组构建SQL条件。
  • 返回由buildFindInSetConditions生成的SQL条件字符串。
package org.jeecg.modules.classs.util;

import java.util.Arrays;
import java.util.Collection;

public class CustomQueryUtils {

    /**
     * 构建 FIND_IN_SET 条件的 SQL 片段
     *
     * @param weeks      包含周编号的集合
     * @param sections   包含节次编号的集合
     * @param weekByDays 包含星期几编号的集合
     *                   循环集合Collection<String>里面的数据进行动态添加sql
     * @return SQL 片段字符串
     */
    public static String buildFindInSetConditions(String[] weeks, String[] sections, String[] weekByDays) {
        StringBuilder sb = new StringBuilder("");
        if (weeks!=null && weeks.length>0) {
            if (!Arrays.toString(weeks).equals("[]")){
                sb.append(" AND (");
                boolean firstCondition = true; // 用来跟踪是否已添加第一个条件
                if (weeks.length>0){
                    for (String week : weeks) {
                        if (!firstCondition) { // 跳过第一个的 AND (
                            sb.append(" AND ");
                        }
                        sb.append("FIND_IN_SET('").append(week).append("', week) > 0");
                        firstCondition = false; // 标记第一个条件已添加
                    }
                }
                sb.append(")");
            }

        }

        if (sections!=null && sections.length>0) {
            if (!Arrays.toString(sections).equals("[]")){
                sb.append(" AND (");
                boolean firstCondition = true; // 用来跟踪是否已添加第一个条件
                for (String section : sections) {
                    if (!firstCondition) { // 跳过第一个的 AND (
                        sb.append(" AND ");
                    }
                    sb.append("FIND_IN_SET('").append(section).append("', section) > 0");
                    firstCondition = false; // 标记第一个条件已添加
                }
                sb.append(")");
            }
        }

        if (weekByDays!=null && weekByDays.length>0) {
            if (!Arrays.toString(weekByDays).equals("[]")){
                sb.append(" AND (");
                boolean firstCondition = true; // 用来跟踪是否已添加第一个条件
                for (String weekbyday : weekByDays) {
                    if (!firstCondition) { // 跳过第一个的 AND (
                        sb.append(" AND ");
                    }
                    sb.append("FIND_IN_SET('").append(weekbyday).append("', weekbyday) > 0");
                    firstCondition = false; // 标记第一个条件已添加
                }
                sb.append(")");
            }
        }

        return sb.toString();
    }

}

当我们点击查询的时候,就会产生以下的sql:

随后我们的sql在后面添加了我们需要的sql片段,查询到每个字段(以逗号隔开的数据)包含其中的。

SELECT DISTINCT c.id,c.semesterid,c.professionid,c.classid,c.teacherid,c.courseid,c.classroomid,c.`week`,c.weekbyday,c.section,c.studentnumber,c.`status`,c.remark FROM c_coursearrange c JOIN sys_user_role sur ON c.teacherid = sur.user_id JOIN sys_role r ON sur.role_id = r.id   AND (FIND_IN_SET('1', week) > 0 AND FIND_IN_SET('2', week) > 0 AND FIND_IN_SET('3', week) > 0) AND (FIND_IN_SET('1', section) > 0 AND FIND_IN_SET('2', section) > 0 AND FIND_IN_SET('3', section) > 0 AND FIND_IN_SET('4', section) > 0) AND (FIND_IN_SET('1', weekbyday) > 0 AND FIND_IN_SET('2', weekbyday) > 0 AND FIND_IN_SET('3', weekbyday) > 0)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小小Wwww

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值