关于在项目中遇到代码里面写for循环查询这件事

前言:由于本人最近在项目中看到太多其他人在for里面写查询的案例(看着头痛.....),所以就想着把自己遇到的问题提出来总结一下(以下的案例和代码仅做参考)。希望这篇文章对大家写代码的有所帮助。

1.分页里面的for循环查询

方法一:条件分割

 public List<SysUserVO> selectUserAll(SysUser user) {
        List<SysUserVO> vos = new ArrayList<>();
        //分页查询
        List<SysUser> users = sysUserMapper.selectUserAll(user);
        //将分页数据中需要翻译的值过滤出来
        Set<Integer> classId = users.stream().map(SysUser::getClassId).collect(Collectors.toSet());
        //查询需要翻译的值
        List<SysClassInfo> sysClassInfos = classInfoMapper.selectClassInfoAllById(classId);
        //将需要翻译的值转成Map
        Map<Integer, String> classInfoMap = sysClassInfos.stream().collect(Collectors.toMap(SysClassInfo::getId, SysClassInfo::getName));
        //组装数据
        users.forEach(data -> {
            SysUserVO vo = new SysUserVO();
            BeanUtils.copyProperties(data,vo);
            vo.setClassName(classInfoMap.get(data.getClassId()));
            vos.add(vo);
        });
        return vos;
    }

分析:假设我们分页的数据只有10条,那么也就是我们主表查询出来的数据只有10条数据要进行翻译(页面展示数据),这个时候如果在循环里面写查询一个个的去翻译,那么就会和数据库进行10此交互。那如果数据更大呢?50条?100条?岂不是要查50次?100次?效率可想而知。所以这个时候我们可以通过上面的方法进行优化:

将我们主表中需要翻译的值通过流的方式过滤一下,把它转换成另一个我们需要翻译的从表条件,这个时候我们只需要去从表查询我们需要翻译的那几个值就行了,然后再将它转换成map的形式方便我们取值翻译,最后组装一下就是我们最终需要的分页数据了。

这样做的好处就是:最终我们去数据库交换的次数只有两次。相比之下,我们程序处理的数据肯定是比去数据库一条一条的检索翻译快得多。

那这个时候就有小伙伴问了,那如果我们需要翻译的条件过多的时候,岂不是每次都要进行这样分割的操作,那样的话,代码会不会太臃肿了。问得好!下面我开始介绍第二种写法:

方法二:建视图或自写SQL

自写SQL(以Mybatis为例):

<select id="selectUserAll1" resultMap="SysUserVO">
        SELECT
        a.*,
        b.`name` AS className
        FROM
        ( SELECT * FROM t_user LIMIT #{beginPage},#{endPage} ) AS a
        LEFT JOIN ( SELECT * FROM t_class_info LIMIT #{beginPage},#{endPage} ) AS b ON a.class_id = b.id
        WHERE
        1 =1
        <if test="user.id != null">
            AND a.id = #{user.id}
        </if>
        <if test="user.name != null and user.name != ''">
            AND a.name = #{user.name}
        </if>
        <if test="user.sex != null and user.sex != ''">
            AND a.sex = #{user.sex}
        </if>
        <if test="user.height != null">
            AND a.height = #{user.height}
        </if>
        <if test="user.age != null">
            AND a.age = #{user.age}
        </if>
        <if test="user.number != null and user.number != ''">
            AND a.number = #{user.number}
        </if>
        <if test="user.birthday != null">
            AND a.birthday = #{user.birthday}
        </if>
        <if test="user.classId != null">
            AND a.class_id = #{user.classId}
        </if>
    </select>

 dao层:

List<SysUserVO> selectUserAll1(@Param("user") SysUser user,@Param("beginPage")Integer beginPage,@Param("endPage")Integer endPage);

servie层:

public List<SysUserVO> selectUserAll1(SysUser user) {
        return sysUserMapper.selectUserAll1(user,0,10);
    }

注意:此处我们只是模拟分页的查询条件

分析:这种方式我们可以在service层省去大量的数据处理的操作,但是,弊端也很明显:那就是xml文件不太好维护,如果判断条件没有写好的话,很容易出现问题。而且如果遇到比较复杂的查询,非常考验sql功底。

如果不想在在Mybatis里面写这么复杂的判断条件或者用的是其他的框架(如JPA,Hibernate)。可以考虑在在数据库建视图,原理和自写SQL类似:

代码:

 <select id="selectUserAll2" resultMap="SysUserVO">
        select * from t_class_user_view where 1=1
        <if test="user.id != null">
            AND a.id = #{user.id}
        </if>
        <if test="user.name != null and user.name != ''">
            AND a.name = #{user.name}
        </if>
        <if test="user.sex != null and user.sex != ''">
            AND a.sex = #{user.sex}
        </if>
        <if test="user.height != null">
            AND a.height = #{user.height}
        </if>
        <if test="user.age != null">
            AND a.age = #{user.age}
        </if>
        <if test="user.number != null and user.number != ''">
            AND a.number = #{user.number}
        </if>
        <if test="user.birthday != null">
            AND a.birthday = #{user.birthday}
        </if>
        <if test="user.classId != null">
            AND a.class_id = #{user.classId}
        </if>
    </select>

相信大家肯定这个时候也发现了新的问题,那就是如果用视图的话,在SQL的可塑性就没有那么强了。遇到数据量极大的时候反而没有自写的SQL好用(视图只能在后面带上分页条件)。不过相对的,这种方式对于JPA而言可能是比较好的解决方案。

2.插入时候的for循环

Mybatis插入详见:Mybatis批量插入的几种方式-CSDN博客

JPA和Hibernate的插入(如果觉得复杂,其实也可以使用原始的jdbc写,虽然有点复杂,但是效率还是比较高的):有关Hibernate/JPA的批量插入更新_jpa hibernate批量插入@query-CSDN博客

  • 21
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在 Python ,可以在 for 循环结束后使用 else 语句来执行一些操作。else 语句将在循环正常结束时执行,也就是说,当循环条件为 False 时,else 语句才会执行。 下面是一个示例: ``` for i in range(10): print(i) else: print("循环结束了") ``` 在这个示例循环将从 0 开始遍历到 9,在每次迭代输出 i 的值。当 i 的值达到 9 时,循环条件为 False,else 语句就会执行,输出 "循环结束了"。 注意:如果在循环使用了 break 语句来退出循环,那么 else 语句将不会执行。 希望这能帮到您! ### 回答2: 在Python,我们可以使用for循环的else语句来在循环结束后执行一些操作。此语法的用途是检测循环是否正常完成,如果循环没有被断,则执行else语句块。下面是一个示例代码: ```python numbers = [1, 2, 3, 4, 5] target = 10 total = 0 for num in numbers: total += num if total >= target: break else: print("循环正常完成!") print("最终的总和为:", total) ``` 在这个例子,我们使用for循环来对列表的数字进行累加,直到总和达到或超过目标值。如果循环在达到目标值之前结束,表示循环断,else语句不会被执行。但是如果循环正常完成,则会执行else语句。 在这个示例循环执行到第4次时,累加的总和已经达到目标值10,所以循环被break语句断。因此,else语句块不会被执行。最终,我们会输出循环断时的总和,即最终的总和为6。 需要注意的是,如果在循环使用了return、break或continue语句,都会导致循环断,else语句不会被执行。只有当循环正常结束时,才会执行else语句块代码。 ### 回答3: 在Python,可以使用`else`语句来在`for`循环结束之后执行一些操作。`else`语句会在循环正常结束时被执行,但如果在循环遇到了`break`语句,则`else`语句将不会被执行。 下面是一个使用`else`语句的示例代码: ```python numbers = [1, 2, 3, 4, 5] for number in numbers: if number == 3: print("循环遇到了3,跳出循环") break print(number) else: print("循环结束") print("在循环结束后执行的操作") ``` 上述代码会依次打印出1、2、"循环遇到了3,跳出循环",然后执行`else`语句代码打印出"循环结束"。最后会打印出"在循环结束后执行的操作"。 需要注意的是,如果在`for`循环没有遇到`break`语句,`else`语句会被执行;但如果在循环遇到了`break`语句跳出循环,`else`语句就不会被执行。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值