赞
踩
在演示UpdateWrapper的案例中,我们在代码中编写了更新的SQL语句:
这种写法在某些企业也是不允许的,因为SQL语句最好都维护在持久层,而不是业务层。就当前案例来说,由于条件是in语句,只能将SQL写在Mapper.xml文件,利用foreach来生成动态SQL。 这实在是太麻烦了。假如查询条件更复杂,动态SQL的编写也会更加复杂。
所以,MybatisPlus提供了自定义SQL功能,可以让我们利用Wrapper生成查询条件,再结合Mapper.xml编写SQL
以当前案例来说,我们可以这样写:
- @Test
- void testCustomWrapper() {
- // 1.准备自定义查询条件
- List<Long> ids = List.of(1L, 2L, 4L);
- QueryWrapper<User> wrapper = new QueryWrapper<User>().in("id", ids);
-
- // 2.调用mapper的自定义方法,直接传递Wrapper
- userMapper.deductBalanceByIds(200, wrapper);
- }
然后在UserMapper中自定义SQL:
- package com.itheima.mp.mapper;
-
- import com.baomidou.mybatisplus.core.mapper.BaseMapper;
- import com.itheima.mp.domain.po.User;
- import org.apache.ibatis.annotations.Param;
- import org.apache.ibatis.annotations.Update;
- import org.apache.ibatis.annotations.Param;
-
- public interface UserMapper extends BaseMapper<User> {
- @Select("UPDATE user SET balance = balance - #{money} ${ew.customSqlSegment}")
- void deductBalanceByIds(@Param("money") int money, @Param("ew") QueryWrapper<User> wrapper);
- }
这样就省去了编写复杂查询条件的烦恼了。
视频写法
-
-
- /**
- * 更新
- * CustomSqlUpdate:自定义更新SQL
- */
-
- @Test
- public void testCustomSqlUpdate(){
- //更新条件
- // 1.准备自定义查询条件
- List<Long> ids = List.of(1L, 2L, 4L);
- int amount = 200;
- // 定义条件
- QueryWrapper<User> wrapper = new QueryWrapper<User>().in("id", ids);
- // 调用mapper的自定义方法,直接传递Wrapper
- //3.调用自定义SQL方法
- userMapper.updateBalanceByIds(wrapper,amount);
-
- }

- public interface UserMapper extends BaseMapper<User> {
-
- // void updateBalanceByIds(@Param("ew") QueryWrapper<User> wrapper,@Param("amount") int amount);
-
- /**
- * 更新
- * @param wrapper
- * @param amount
- */
- void updateBalanceByIds(@Param(Constants.WRAPPER) QueryWrapper<User> wrapper,@Param("amount") int amount);
- }
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
- <mapper namespace="com.itheima.mp.mapper.UserMapper">
-
- <update id="updateBalanceByIds">
- update tb_user SET balance = balance - #{amount} ${ew.customSqlSegment}
-
-
-
- </update>
- </mapper>
理论上来讲MyBatisPlus是不支持多表查询的,不过我们可以利用Wrapper中自定义条件结合自定义SQL来实现多表查询的效果。 例如,我们要查询出所有收货地址在北京的并且用户id在1、2、4之中的用户 要是自己基于mybatis实现SQL,大概是这样的:
- <select id="queryUserByIdAndAddr" resultType="com.itheima.mp.domain.po.User">
- SELECT *
- FROM user u
- INNER JOIN address a ON u.id = a.user_id
- WHERE u.id
- <foreach collection="ids" separator="," item="id" open="IN (" close=")">
- #{id}
- </foreach>
- AND a.city = #{city}
- </select>
可以看出其中最复杂的就是WHERE条件的编写,如果业务复杂一些,这里的SQL会更变态。
但是基于自定义SQL结合Wrapper的玩法,我们就可以利用Wrapper来构建查询条件,然后手写SELECT及FROM部分,实现多表查询。
查询条件这样来构建:
- @Test
- void testCustomJoinWrapper() {
- // 1.准备自定义查询条件
- QueryWrapper<User> wrapper = new QueryWrapper<User>()
- .in("u.id", List.of(1L, 2L, 4L))
- .eq("a.city", "北京");
-
- // 2.调用mapper的自定义方法
- List<User> users = userMapper.queryUserByWrapper(wrapper);
-
- users.forEach(System.out::println);
- }
然后在UserMapper中自定义方法:
- @Select("SELECT u.* FROM user u INNER JOIN address a ON u.id = a.user_id ${ew.customSqlSegment}")
- List<User> queryUserByWrapper(@Param("ew")QueryWrapper<User> wrapper);
当然,也可以在UserMapper.xml
中写SQL:
- <select id="queryUserByIdAndAddr" resultType="com.itheima.mp.domain.po.User">
- SELECT * FROM user u INNER JOIN address a ON u.id = a.user_id ${ew.customSqlSegment}
- </select>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。