一、引言
在平时的开发中,我们可能会遇到需要通过遍历一个id集合,然后通过id查询出这些商品,通常,我们可能会一下子就想到直接使用for循环遍历id集合,然后再通过id查询商品,那么如果这样子做,就会在for循环中多次访问数据库,造成程序性能和资源的损耗,当你的id集合大时,需要访问的次数就要很多,然而我们使用foreach循环就可以很好的避免这种情况。
二、应用场景
此处举例通过商品id集合查询商品,可以有两种方法
第一种:使用for循环,遍历id集合,在集合中查询数据库。
@Resource
private ProductMapper productMapper;
List<Integer> idList=new ArrayList<>();//模拟一个商品id集合,供查询用
@Test
public void testFor(){//使用for循环的方式
idList.add(26);
idList.add(27);
idList.add(28);
idList.add(29);//添加商品id
long startTime = System.currentTimeMillis();
for (Integer productId : idList) {//遍历出id,再用id查询数据库,并计算时间
productMapper.selectByPrimaryKey(productId);
}
long endTime=System.currentTimeMillis();
System.out.println(endTime-startTime);//结果为937秒,共查到四条数据,执行了四次sql语句。
}这样子的方式,如果数据很多,那么就得很多次访问数据库,效率十分低下,接下来介绍更好的方式。
第二种:使用foreach+IN的方式,在sql中遍历id,一次性查询
@Test
public void testForeachIn(){//使用Foreach+IN的方式
idList.add(26);
idList.add(27);
idList.add(28);
idList.add(29);//添加商品id
long startTime = System.currentTimeMillis();
productMapper.selectByPrimaryKeyList(idList);//这里使用for+IN查询数据库,只查询一次就能将所有数据拿出来。
long endTime=System.currentTimeMillis();
System.out.println(endTime-startTime);//结果为547
}对比之下,比for循环多次查询数据库快了很多,当数据更多时,好处就体现出来了。查看第二个测试的sql语句可以发现秘密所在:如图

一次性在sql中,将四个id传入,一次性查询出来了,这就是比for循环内一次次访问数据库快的原因。具体的实现如下:
①先在mapper接口中定义一个抽象方法。
/**
* 使用Foreach-In代替for循环查询,提高性能,减少访问数据库次数
* @param idList
* @return
*/
List<Product> selectByPrimaryKeyList(@Param("idList") List<Integer> idList);其中@Param("idList")是必要的加的,这里定义注解的值,在sql中要循环这个名字的collection,所以要写好,尽量跟集合参数的名字保持一致。接下来,就是在Mapper.xml中编写对应的sql语句
②编写sql(由mybatis-generator生成)语句
<select id="selectByPrimaryKeyList" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from mall_product
<where>
<if test="idList.size()>0">
id in
<foreach collection="idList" item="id" index="index" open="(" close=")" separator=",">
#{id}
</foreach>
</if>
</where>
</select>其中,当idList.size()>0时,就执行where条件,当遍历idList集合,item代表集合内元素,collection为@Param注解的value,格式要为#{},这样子就可以实现一次查询多条数据,并封装到集合中,List集合和Set集合根据具体需求选择。
以上就是两种方式的对比以及Foreach+IN的使用方式。