MyBatis动态sql详解(foreach语句详解【IN】)
**MyBatis动态sql详解(foreach语句详解)**
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 理论基础: 一、介绍: foreach主要是用于一个循环,大部分用到的是循环的生成sql,下面说一下动态foreach的属性: foreach元素的属性主要有item,index,collection,open,separator,close。 1 、collection表示如何来得到这个集合,如果传入的直接为一个List,那么collection值就为list,如果直接传入的为一个array不可变数组,那么collection值就为array,如果传入的为一个dto,比如dto里面的array变量名为idLists,那么collection的值就为idLists。 2 、item表示集合中每一个元素进行迭代时的别名,比如item为value,那么,每次获取的都使用#{value}即可 3 、index指定一个名字,用于表示在迭代过程中,每次迭代到的位置,一般很少使用这个 4 、open表示该语句以什么开始 5 、separator表示在每次进行迭代之间以什么符号作为分隔符 6 、close表示以什么结束 二、原理: 动态SQL,最后都会根据条件拼成SQL,foreach也不例外,原理为: 首先根据collection来得到集合,然后写入open字符,然后开始遍历: 每次遍历,都会执行里面的条件得到生成的sql,然后加入separator,遍历完成之后,加入close字符。 三、实战: 1.1 、直接传入一个List可变数组: 比如我想找users表中id在一个数组中的,可以这样: ————————————————<br><br> //使用注解开发,注解在接口上实现<br>@Select("select * from tp_admin")<br>List<TpAdmin> gettp_admins();<br><br>//foreach yufachaxun<br>List<TpAdmin> foreachlists(List<Integer> idlist);<br><br><br><!-- foreach fangshi chaxun--><br><select id="foreachlists" resultType="com.example.demo.entity.TpAdmin"><br> select * from tp_admin where id in<br> <foreach collection="list" index="index" item="item" open="(" separator="," close=")"><br> #{item}<br> </foreach><br></select><br><br><br>////foreach yufachaxun<br>@Test<br>void testforeachlist(){<br> List<Integer> idlist = new ArrayList<>();<br> idlist.add(1);<br> idlist.add(2);<br> List<TpAdmin> foreachlists = tpadminmapper.foreachlists(idlist);<br> System.out.println(foreachlists);<br>} |
2.collection属性值的三种情况
如果传入的参数类型为list时: collection的默认属性值为list,同样可以使用@Param注解自定义name;
如果传入的参数类型为array时: collection的默认属性值为array,同样可以使用@Param注解自定义name;
如果传入的参数类型为Map时: collection的属性值可为三种情况:(1.遍历map.keys;2.遍历map.values;3.遍历map.entrySet()),稍后会在代码中示例;
https://blog.csdn.net/qq_44447372/article/details/122589982
2、直接传入一个array不可变数组:
1 2 3 4 5 6 | <select id= "dymamicForeachArrayGetUser" resultType= "com.happyheng.entity.User" > select * from users where id in <foreach collection= "array" index = "index" item = "idArray" open= "(" separator= "," close= ")" > #{idArray} </foreach> </select> |
java代码中的使用:
1 2 3 4 5 6 7 8 9 10 11 | public static void testDynamicForeach() { SqlSession session = MyBatisUtil.getSqlSession( true ); int [] ids = new int []{ 7 , 8 , 10 , 11 }; List<User> users = session.selectList( "dymamicForeachArrayGetUser" , ids); for (User user : users) { System.out.println(user); } session.close(); } |
3、传入一个dto,里面有一个参数为List可变数组
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <select id= "findCommunityInfo" parameterType= "com.happyheng.ParkQuery" resultMap= "resultMap" > SELECT xxx FROM fairyland_account_info account ,fairyland_community_info comm where account.id = comm.fairyland_account_info_id < if test= "userInfoId != null" > AND account.user_info_id = #{userInfoId} </ if > < if test= "userIdList!=null" > AND account.user_info_id IN <foreach collection= "userIdList" item= "userId" open= "(" separator= "," close= ")" > #{userId} </foreach> </ if > </select> |
其中,传入的dto为ParkQuery,里面有一个List 的userIdList参数(注意要有setter和getter) 所以下面的collection为userIdList,其对应的接口为:
public List findCommunityInfo(ParkQuery parkQuery);
4、传入一个dto,里面有一个参数为List可变数组,其中list中每个也是一个dto:
1 2 3 4 5 6 | <update id= "updateStatus" parameterType= "com.happyheng.query.FriendUpdateQuery" > UPDATE friend_introduce_info SET be_used = #{beUsed,jdbcType=TINYINT} WHERE <foreach collection= "listQuery" item= "query" separator= "or" > (user_info_id = #{query.uid} AND introduced_user_info_id =#{query.introduceUid}) </foreach> </update> |
其中item=query即为list中的每个dto即为query,那么 #{query.uid}即为获取dto中的uid。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | /** * 批量插入 * * @param list * @return */ @Insert ( "<script>INSERT INTO logistics_goods " + "(logistics_no,goods_id,goods_amount,order_id,is_rule,order_no,goods_name,goods_weight,should_warehouse,real_warehouse,goods_price,order_create_time,spu_id,goods_label,self_flag,goods_cover_img,receiver_name,receiver_address,receiver_phone,is_alone,goods_max_amount,buyer_id,supplier_id,is_import,deliver_place,is_group)" + "VALUES " + "<foreach collection='list' item='l' index='index' separator=',' >" + "(#{l.logisticsNo},#{l.goodsId},#{l.goodsAmount},#{l.orderId},#{l.isRule},#{l.orderNo},#{l.goodsName},#{l.goodsWeight},#{l.shouldWarehouse},#{l.realWarehouse},#{l.goodsPrice},#{l.orderCreateTime},#{l.spuId},#{l.goodsLabel},#{l.selfFlag},#{l.goodsCoverImg},#{l.receiverName},#{l.receiverAddress},#{l.receiverPhone},#{l.isAlone},#{l.goodsMaxAmount},#{l.buyerId},#{l.supplierId},#{l.isImport},#{l.deliverPlace},#{l.isGroup})" + "</foreach></script>" ) int batchInsertGoods(List<LogisticsGoods> list); /** * 批量更新包裹号 * * @param list * @return */ @Update ( "<script>UPDATE logistics_goods SET" + " logistics_no = CASE id" + "<foreach collection='list' item='l' index='index'>" + " WHEN #{l.id} THEN #{l.logisticsNo}" + "</foreach>" + " END" + " WHERE id IN (" + "<foreach collection='list' item='l' index='index' separator=',' >" + "#{l.id}" + "</foreach>)</script>" ) int batchUpdateLogisticsNo(List<LogisticsGoods> list); /** * 批量更新包裹号 * * @param list * @return */ @Update ( "<script><foreach collection='list' item='item' index='index' open='' close='' separator=';'>" + "UPDATE logistics_goods SET logistics_no = #{item.logisticsNo},goods_amount = #{item.goodsAmount} " + "where id = #{item.id} and del_flag = 0 and logistics_status = 0" + "</foreach></script>" ) int batchUpdateLogisticsNoById(List<LogisticsGoods> list); |
3.代码示例
3.1 collection属性值为List(Array等同):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | @select ( "<script> " + "SELECT * " FROM user_info " + " WHERE " + " <if test=" userName!= null and userName.size() > 0 "> " + " USERNAME IN " + " <foreach collection='userNames' item='value' separator=',' open='(' close=')'>" + " #{value} " + " </foreach>" + " </if>" + "</script>" ) list<userInfo> getUserInfo( @param ( "userNames" ) list<String> userNames) #separator不仅仅使用,使用or或者and,open不仅仅只是使用(而是and ( @select ( "<script> " + "SELECT CONFIGID AS configId count(CONFIGID) as count* " FROM user_info " + " WHERE " + " devGroupId = #{devGroupId}" + " <foreach collection='viewRange' item='item' separator='or' open=' and (' close=')'>" + " ORGNODEPATH like CONCAR('%','<![CDATA[#{item}]]>','%') " + " </foreach>" + "</script>" ) list<Map<String,Long>> queryConfigAndCount( @param ( "devGroupId" ) long devGroupId, @param ( "viewRange" ) set<Long> viewRange) |
3.2 collection属性值类型为Map:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | @select ( "<script> " + "SELECT * " FROM user_info " + " WHERE " + " <if test=" userName!= null and userName.size() > 0 "> " + " (USERNAME,AGE) IN " + " <foreach collection='user.entrySet()' index='key' item='value' separator=',' open='(' close=')'>" + " #{key},#{value} " + " </foreach>" + " </if>" + "</script>" ) List<UserList> getUserInfo( @Param ( "user" ) Map<String,String> user); @select ( "<script> " + "SELECT * " FROM user_info " + " WHERE " + " <if test=" userName!= null and userName.size() > 0 "> " + " USERNAME IN " + " <foreach collection='user.keys' item='key' separator=',' open='(' close=')'>" + " #{key} " + " </foreach>" + " </if>" + "</script>" ) List<UserList> getUserInfo( @Param ( "user" ) Map<String,String> user); @select ( "<script> " + "SELECT * " FROM user_info " + " WHERE " + " <if test=" userName!= null and userName.size() > 0 "> " + " USERNAME IN " + " <foreach collection='user.values' item='value' separator=',' open='(' close=')'>" + " #{value} " + " </foreach>" + " </if>" + "</script>" ) List<UserList> getUserInfo( @Param ( "user" ) Map<String,String> user); |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 字符编码:从基础到乱码解决