mybatis、mybatis-plus 中使用 @selectProvider,@InsertProvider, @UpdateProvider,@DeleteProvider动态生成sql

1. 以@SelectProvider为例

@SelectProvider 是 MyBatis 提供的一个注解,用于动态生成 SQL 查询语句。它允许开发者在运行时根据复杂的业务逻辑动态构建 SQL。

2. 作用

  • 动态 SQL: 根据传入的参数动态地构建 SQL 语句,而不是在 XML 或注解中硬编码。
  • 代码重用: 将 SQL 语句的构建逻辑放在单独的类中,可以重用这些逻辑。
  • 复杂查询: 适用于那些难以用静态 SQL 或 MyBatis 的 XML 动态标签表达的复杂查询。

3. 使用场景

  • 多条件查询: 当查询条件非常多且变化多端时。
  • 分页查询: 需要根据不同的页码和页面大小动态构建 SQL 的 LIMIT 子句。
  • 报表统计: 需要根据用户输入的多个参数动态生成统计查询。
  • 复杂的联表查询: 需要根据不同的业务逻辑动态选择联表的字段和表。


代码示例

定义mapper文件,springboot中添加 @MapperScan扫描别忘了

package cn.baidu.sharding_jdbc_test.shujuku;

import cn.baidu.sharding_jdbc_test.pojo.TbHotel;
import cn.baidu.sharding_jdbc_test.shujuku_sql.JiudianSqlProvider;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.SelectProvider;

import java.util.List;
import java.util.Map;

@Mapper
public interface JiudianMapper {

    @SelectProvider(type = JiudianSqlProvider.class, method = "search_1_sql")
    List<Map<String, Object>> search_1();


    @SelectProvider(type = JiudianSqlProvider.class, method = "search_2_sql")
    List<Map<String, Object>> search_2(@Param("id") Integer id);


    @SelectProvider(type = JiudianSqlProvider.class, method = "search_3_sql")
    List<Map<String, Object>> search_3(@Param("ids") List<Integer> ids, @Param("name") String name);


    @SelectProvider(type = JiudianSqlProvider.class, method = "search_4_sql")
    List<Map<String, Object>> search_4(TbHotel tbHotel);


    @SelectProvider(type = JiudianSqlProvider.class, method = "search_5_sql")
    List<Map<String, Object>> search_5(Map<String, Object> paramMap);

}

动态sql生成逻辑类

package cn.baidu.sharding_jdbc_test.shujuku_sql;

import cn.baidu.sharding_jdbc_test.pojo.TbHotel;
import org.apache.ibatis.jdbc.SQL;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class JiudianSqlProvider {

    public String search_1_sql() {

        return "select * from tb_hotel";
    }

    public String search_2_sql(Integer id) {
        SQL sql = new SQL();
        sql.SELECT("*").FROM("tb_hotel").WHERE("id = #{id}");
        return sql.toString();
    }

    public String search_3_sql(List<Integer> ids, String name) {
        SQL sql = new SQL();
        sql.SELECT("*")
                .FROM("tb_hotel");
        if (ids != null && !ids.isEmpty()) {
            String collect = ids.stream().map(String::valueOf).collect(Collectors.joining(","));
            sql.WHERE("id in (" + collect + ")");
        }

        if (name != null && !name.isEmpty()) {
            sql.WHERE("name like concat('%',#{name},'%')");
        }

        return sql.toString();
    }


    public String search_4_sql(TbHotel tbHotel) {
        System.out.println("tbHotel = " + tbHotel);

        SQL sql = new SQL();

        sql.SELECT("*")
                .FROM("tb_hotel");

        if (tbHotel.getId() != null) {
            sql.WHERE("id < #{id}");
        }

        if (tbHotel.getName() != null && !tbHotel.getName().isEmpty()) {
            sql.WHERE("name like concat('%',#{name},'%')");
        }
        return sql.toString();
    }


    public String search_5_sql(Map<String, Object> map) {
        System.out.println("map = " + map);

        SQL sql = new SQL();

        sql.SELECT("*")
                .FROM("tb_hotel");

        if (map.get("id") != null) {
            sql.WHERE("id < #{id}");
        }

        if (map.get("name") != null && !map.get("name").toString().isEmpty()) {
            sql.WHERE("name like concat('%',#{name},'%')");
        }
        return sql.toString();
    }

}

3 测试

package cn.baidu.sharding_jdbc_test.aaaa.serviceimpl;

import cn.baidu.sharding_jdbc_test.ShardingJdbcTestApplication;
import cn.baidu.sharding_jdbc_test.pojo.TbHotel;
import cn.baidu.sharding_jdbc_test.shujuku.JiudianMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@SpringBootTest(classes = {ShardingJdbcTestApplication.class})
public class Test_2 {

    @Autowired
    private JiudianMapper jiudianMapper;

    @Test
    void test_1() {
        List<Map<String, Object>> result = jiudianMapper.search_1();
        System.out.println("result = " + result);
    }

    @Test
    void test_2() {
        List<Map<String, Object>> result = jiudianMapper.search_2(5);
        System.out.println("result = " + result);
    }


    @Test
    void test_3() {
        List<Map<String, Object>> result = jiudianMapper.search_3(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), "北京");
        System.out.println("result = " + result);
    }

    @Test
    void test_4() {
        TbHotel tbHotel = new TbHotel();
        tbHotel.setId(20l);
        tbHotel.setName("北京");
        List<Map<String, Object>> result = jiudianMapper.search_4(tbHotel);
        System.out.println("result = " + result);
    }


    @Test
    void test_5() {

        Map<String, Object> map = new HashMap<>();
        map.put("id", 10l);
        map.put("name", "北京");
        List<Map<String, Object>> result = jiudianMapper.search_5(map);
        System.out.println("result = " + result);
    }

}


 

  • 8
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1、使用 SelectProvider 进行 left join Mybatis Plus 提供了一个 SelectProvider 类,可以动态生成 SQL 语句。在 left join 操作,我们可以使用 SelectProvider 来实现。 例如,我们有两个表,一个是用户表 user,另一个是订单表 order。我们想要查询某个用户的所有订单信息,可以使用 left join 来实现。 首先,我们需要定义一个查询语句的模板,使用 @SelectProvider 注解来指定: ``` @SelectProvider(type = MyProvider.class, method = "selectUserOrders") List<UserOrder> selectUserOrders(@Param("userId") Long userId); ``` 其,MyProvider 是我们定义的一个 SelectProvider 类,selectUserOrders 是其的一个方法,用来生成查询语句。 然后,在 MyProvider ,我们需要实现 selectUserOrders 方法,生成查询语句: ``` public String selectUserOrders(@Param("userId") Long userId) { return new SQL(){{ SELECT("user.*, order.*"); FROM("user"); LEFT_JOIN("order ON user.id = order.user_id"); WHERE("user.id = #{userId}"); }}.toString(); } ``` 在这个方法,我们使用 SQL 类来生成查询语句。首先,使用 SELECT 方法指定要查询的字段,使用 FROM 方法指定主表,使用 LEFT_JOIN 方法来进行左连接操作,使用 WHERE 方法来指定查询条件。 2、使用分页插件进行分页查询 Mybatis Plus 提供了一个分页插件,可以方便地实现分页查询。 首先,我们需要在配置文件开启分页插件: ``` <plugins> <plugin interceptor="com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor"> <property name="dialectType" value="mysql"/> </plugin> </plugins> ``` 然后,在查询方法,我们可以使用 Page 类来进行分页查询: ``` Page<UserOrder> page = new Page<>(1, 10); List<UserOrder> userOrders = userOrderMapper.selectUserOrders(page, userId); ``` 其,Page 的第一个参数是当前页码,第二个参数是每页显示的记录数。userOrderMapper 是我们定义的一个 Mapper 接口,selectUserOrders 是其的一个方法,用来进行查询操作。 在 selectUserOrders 方法,我们需要使用 Mybatis Plus 提供的分页参数注解 @Param 来指定分页参数: ``` List<UserOrder> selectUserOrders(@Param("page") Page<UserOrder> page, @Param("userId") Long userId); ``` 然后,在 SQL 语句,我们可以使用 Mybatis Plus 提供的分页语句来进行分页操作: ``` public String selectUserOrders(@Param("page") Page<UserOrder> page, @Param("userId") Long userId) { return new SQL(){{ SELECT("user.*, order.*"); FROM("user"); LEFT_JOIN("order ON user.id = order.user_id"); WHERE("user.id = #{userId}"); }}.toString() + " LIMIT " + page.getOffset() + ", " + page.getSize(); } ``` 在这个方法,我们需要使用 Page 类提供的 getOffset 和 getSize 方法来获取当前分页的偏移量和每页显示的记录数,然后将它们拼接到 SQL 语句的末尾。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值