Mysql,FIND_IN_SET() 函数 与 Mybatis框架中 foreach 标签联用,解决批量数据查询问题。

68 篇文章 0 订阅
27 篇文章 0 订阅

    批量数据查询,会遇到“栈溢出”的问题,文章末尾我给出了解决方案。

    在日常工作中,有时数据库表中某个字段以 "英文半角逗号拼接多个值" 存放在这个字段中,我们根据入参查找到对应的数据。在这里,使用 FIND_IN_SET() 函数即可解决问题。可以参考我之前的文章: Mysql中 find_in_set() 函数用法详解        

    如果是多个入参,可以使用 FIND_IN_ SET() 函数与 OR 关键字联用,来解决多个入参批量查询问题。如下面SQL、图一、图二所示。

    本篇文章使用的数据库表、表数据,参见文章最后给出的 user2 表表结构、表数据。

SELECT
	u.*
	
FROM `user2` u
WHERE
	1 = 1
	AND ( 
		FIND_IN_SET('二狗', u.many_name)
		OR FIND_IN_SET('大肚包', u.many_name)
		OR FIND_IN_SET('李四', u.many_name)
	)
;

 图一

 图二

                             

    在Java项目中,我们可以借助 Mybatis框架中的 <foreach> 标签来完成多参数批量查询问题。考虑到性能问题,根据《阿里巴巴Java编程规范》,入参的参数应该 小于等于 1000.

                                     

     在下列XML类型的SQL中,我们主要关注 manyNameList 参数。使用 <foreach> 标签、OR 关键字作为分隔符,与 FIND_IN_SET() 函数联用,以此来实现批量查询。

                                        

<select id="listUser" resultType="com.moon.UserVO">
	SELECT
		u.id,
		u.name,
		u.age,
		u.create_date,
		u.many_name
		
	FROM user2 u
	<where>
		1 = 1
		<if test="paramDTO.id != null">
			AND u.id = #{paramDTO.id, jdbcType=BIGINT}
		</if>
		<if test="paramDTO.userId != null">
			AND u.id = #{paramDTO.userId, jdbcType=BIGINT}
		<if test="paramDTO.name != null and paramDTO.name != ''">
			AND u.name = #{paramDTO.name,jdbcType=VARCHAR}
		</if>
		<if test="paramDTO.nameLike != null and paramDTO.nameLike != ''">
			AND u.name LIKE CONCAT('%', #{paramDTO.nameLike, jdbcType=VARCHAR}, '%')
		</if>
		<if test="paramDTO.nameList != null and paramDTO.nameList.size() != 0">
			AND u.name IN
			<foreach collection="paramDTO.nameList" item="item" separator="," index="index" open="(" close=")">
				#{item}
			</foreach>
		</if>
		<if test="paramDTO.manyNameList != null and paramDTO.manyNameList.size() != 0">
			AND
			<foreach collection="paramDTO.manyNameList" item="item" separator="OR" index="index" open="(" close=")">
				FIND_IN_SET(#{item}, u.many_name)
			</foreach>
		</if>
		ORDER BY u.id DESC
	</where>
</select>


user2表的表结构、表数据

CREATE TABLE user2 (
  id bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID, 主键.',
  name varchar(100) DEFAULT NULL COMMENT '姓名',
  age int(3) DEFAULT NULL COMMENT '年龄',
  create_date datetime DEFAULT NULL COMMENT '创建时间',
  many_name varchar(200) DEFAULT NULL COMMENT '多个姓名',
  PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 COMMENT='用户表2';


INSERT INTO user2(id, name, age, create_date, many_name) VALUES (1, '张三', 20, '2020-04-02 09:54:23', '李桃,二狗,王大锤');
INSERT INTO user2(id, name, age, create_date, many_name) VALUES (2, '张三', 20, '2020-01-05 11:20:00', '张三丰,宋曼玉');
INSERT INTO user2(id, name, age, create_date, many_name) VALUES (4, '李四', 25, '2019-10-22 16:27:03', '李四,袁冲,李雪玲');
INSERT INTO user2(id, name, age, create_date, many_name) VALUES (5, '刘涛', 22, '2020-04-06 08:07:30', '二狗,章子怡');
INSERT INTO user2(id, name, age, create_date, many_name) VALUES (6, '张曼玉', 18, '2020-04-09 17:21:45', '李二狗,王小二,李四');
INSERT INTO user2(id, name, age, create_date, many_name) VALUES (7, '周润发', 30, '2022-06-21 10:25:42', '步惊云,神风腿,排云掌');
INSERT INTO user2(id, name, age, create_date, many_name) VALUES (8, '刘德华', 32, '2022-06-24 10:02:16', '二道杠,夜猫子,撸串');


批量数据查询“栈溢出”的问题解决方案参考下文。

Mybatis批量查询,报错:Handler dispatch failed; nested exception is java.lang.StackOverflowError

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值