1. 以@SelectProvider为例
@SelectProvider
是 MyBatis 提供的一个注解,用于动态生成 SQL 查询语句。它允许开发者在运行时根据复杂的业务逻辑动态构建 SQL。
2. 作用
- 动态 SQL: 根据传入的参数动态地构建 SQL 语句,而不是在 XML 或注解中硬编码。
- 代码重用: 将 SQL 语句的构建逻辑放在单独的类中,可以重用这些逻辑。
- 复杂查询: 适用于那些难以用静态 SQL 或 MyBatis 的 XML 动态标签表达的复杂查询。
3. 使用场景
- 多条件查询: 当查询条件非常多且变化多端时。
- 分页查询: 需要根据不同的页码和页面大小动态构建 SQL 的 LIMIT 子句。
- 报表统计: 需要根据用户输入的多个参数动态生成统计查询。
- 复杂的联表查询: 需要根据不同的业务逻辑动态选择联表的字段和表。
代码示例
1 定义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);
}
2 动态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);
}
}