9. MyBatisPlus实现复杂查询

MyBatisPlus实现复杂查询

在这里插入图片描述

1. wapper介绍

  • Wrapper : 条件构造抽象类,最顶端父类。
    • AbstractWrapper : 用于查询条件封装,生成 sql 的 where 条件。
      • QueryWrapperEntity 对象封装操作类,不是用lambda语法
      • UpdateWrapper : Update 条件封装,用于Entity对象更新操作。
      • AbstractLambdaWrapper : Lambda 语法使用 Wrapper统一处理解析 lambda 获取 column。
      • LambdaQueryWrapper :看名称也能明白就是用于Lambda语法使用的查询Wrapper
      • LambdaUpdateWrapper : Lambda 更新封装Wrapper

在这里插入图片描述

    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class QueryWrapperTests {

        @Autowired
        private UserMapper userMapper;
    }

2. AbstractWrapper

  1. 注意:以下条件构造器的方法入参中的 column均表示数据库字段
  2. 以下查询条件都是在AbstractWrapper中定义的。
2.1 ge、gt、le、lt、isNull、isNotNull
    /**
     * ge 大于等于
     * gt 大于
     * le 小于等于
     * lt 小于
     * isNull 是null
     * isNotNull 不是nul
     * 执行的也是逻辑删除
     */
    @Test
    public void testDelete() {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.isNull("create_time").ge("age", 21).isNotNull("email");
        
        int result = userMapper.delete(queryWrapper);
        System.out.println("result = " + result);
    }
2.2 eq、ne

**注意:**seletOne返回的是一条实体记录,当出现多条时会报错

    /**
     * selectOne返回的是一条实体记录,当出现多条时会报错
     * eq 等于
     * ne 不等于
     */
    @Test
    public void testSelectOne(){
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name","Sandy");
        
        User user = userMapper.selectOne(queryWrapper);
        System.out.println("user = " + user);
    }
2.3 between、notBetween
   /**
     * between 包含大小边界
     */
    @Test
    public void testSelectCount(){
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        
        queryWrapper.between("age",22,30);
        
        Integer count = userMapper.selectCount(queryWrapper);
        System.out.println("count = " + count);
    }
2.4 allEq
    /**
     * allEq等于所有
     * select id,name,age,email,create_time,update_time,version,deleted from user where deleted=0 and name= 'HeMiao'and age = 28
     */
    @Test
    public void testSelctList(){

        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        Map<String,Object> map = new HashMap<>();
        map.put("name","HeMiao");
        map.put("age",28);
        
        queryWrapper.allEq(map);
        List<User> users = userMapper.selectList(queryWrapper);
        users.forEach(System.out::println);
    }
2.5 like、notLike、likeLeft、likeRight

selectMaps返回Map集合列表

    /**
     * like
     * notLike
     * likeLeft
     * likeRight
     */
    @Test
    public void testSelectMaps(){
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.like("name","2");
        
        List<Map<String, Object>> maps = userMapper.selectMaps(queryWrapper);
        maps.forEach(System.out::println);
    }
2.6 in、notIn、inSql、notinSql、exists、notExists

in、notIn:

inSql、notinSql:可以实现子查询

  • 例: inSql("age", "1,2,3,4,5,6")—>age in (1,2,3,4,5,6)
  • 例: inSql("id", "select id from table where id < 3")—>id in (select id from table where id < 3)
2.7 or、and
  1. **注意:**这里使用的是 UpdateWrapper
  2. 不调用or则默认为使用 and
@Test
public void testUpdate1() {

    //修改值
    User user = new User();
    user.setAge(99);
    user.setName("Andy");

    //修改条件
    UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>();
    userUpdateWrapper
        .like("name", "h")
        .or()
        .between("age", 20, 30);

    int result = userMapper.update(user, userUpdateWrapper);

    System.out.println(result);
}
2.8 嵌套or、嵌套and

这里使用了lambda表达式,or中的表达式最后翻译成sql时会被加上圆括号

@Test
public void testUpdate2() {


    //修改值
    User user = new User();
    user.setAge(99);
    user.setName("Andy");

    //修改条件
    UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>();
    userUpdateWrapper
        .like("name", "h")
        .or(i -> i.eq("name", "李白").ne("age", 20));

    int result = userMapper.update(user, userUpdateWrapper);

    System.out.println(result);
}
2.9 orderBy、orderByDesc、orderByAsc
   /**
     * orderBy
     * orderByDesc 降序
     * orderBYAsc  升序
     */
    @Test
    public void testSelectListOrderBy(){
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("id");
        
        List<User> users = userMapper.selectList(queryWrapper);
        users.forEach(System.out::println);
    }
2.10 last
  1. 直接拼接到 sql 的最后
  2. 注意:只能调用一次,多次调用以最后一次为准 有sql注入的风险,请谨慎使用。
@Test
public void testSelectListLast() {

    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
    queryWrapper.last("limit 1");

    List<User> users = userMapper.selectList(queryWrapper);
    users.forEach(System.out::println);
}
2.11 指定要查询的列
  • queryWrapper.select("id","name","age");
   @Test
    public void testSelectListColumn(){
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        
        queryWrapper.select("id","name","age");
        
        List<User> users = userMapper.selectList(queryWrapper);
        users.forEach(System.out::println);
    }
2.12 set、setSql

最终的sql会合并 user.setAge(),以及 userUpdateWrapper.set() 和 setSql() 中 的字段

@Test
public void testUpdateSet() {

    //修改值
    User user = new User();
    user.setAge(99);

    //修改条件
    UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>();
    userUpdateWrapper
        .like("name", "h")
        .set("name", "老李头")//除了可以查询还可以使用set设置修改的字段
        .setSql(" email = '123@qq.com'");//可以有子查询

    int result = userMapper.update(user, userUpdateWrapper);
}

### MyBatis-Plus 外联查询使用教程 MyBatis-Plus 是一款增强型的 MyBatis 框架,简化了开发流程并提供了丰富的功能支持。在外联查询方面,可以通过多种方式实现复杂的数据关联操作。 #### 1. 配置基础环境 为了能够顺利执行外联查询,需先完成 MyBatis-Plus 的基本配置工作。这包括引入依赖、定义实体类以及设置 Mapper 接口等[^4]。 ```xml <!-- Maven 依赖 --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>最新版本号</version> </dependency> ``` #### 2. 定义实体类 假设存在两个表 `user` 和 `role`,分别表示用户和角色的关系。通过创建对应的 Java 实体类来映射数据库中的结构。 ```java // User.java @Data public class User { private Long id; private String name; // 关联字段 private List<Role> roles; } // Role.java @Data public class Role { private Long id; private String roleName; } ``` #### 3. 编写 SQL 查询语句 可以采用 XML 文件或者注解的方式编写自定义 SQL 来处理复杂的外联查询需求。以下是基于注解的一个例子: ```java @Mapper public interface UserMapper extends BaseMapper<User> { @Select("SELECT u.*, r.role_name FROM user u LEFT JOIN role r ON u.id = r.user_id WHERE u.name LIKE CONCAT(&#39;%&#39;, #{name}, &#39;%&#39;)") List<Map<String, Object>> getUserWithRoles(@Param("name") String name); } ``` 此段代码实现了根据用户名模糊查找对应用户的全部信息及其所拥有的角色列表的功能[^5]。 #### 4. 结果集转换 由于上述返回的是 Map 类型的结果集合,在实际应用中可能更倾向于获取对象形式的数据。因此需要进一步加工数据以便于前端展示或其他业务逻辑调用。 ```java @Service public class UserServiceImpl implements IService<User> { @Autowired private UserMapper userMapper; public List<User> getUsersAndTheirRoles(String userName){ List<Map<String,Object>> maps=userMapper.getUserWithRoles(userName); HashMap<Long,List<String>> tempMap=new HashMap<>(); for (Map map : maps) { long userId=(long)map.get("id"); String roleName=String.valueOf(map.get("role_name")); if(tempMap.containsKey(userId)){ ((List<String>)tempMap.get(userId)).add(roleName); }else{ ArrayList<String> list=new ArrayList<>(); list.add(roleName); tempMap.put(userId,list); } } Set set=tempMap.entrySet(); Iterator iterator=set.iterator(); List<User> users=new ArrayList<>(); while(iterator.hasNext()){ Map.Entry entry=(Map.Entry)iterator.next(); User user=new User(); user.setId((Long)(entry.getKey())); user.setRoles(((List<String>)entry.getValue()).stream().map(item->new Role(null,item)).collect(Collectors.toList())); users.add(user); } return users; } } ``` 以上服务层方法完成了从原始结果到目标模型之间的转化过程[^6]。 ### 注意事项 - 确保数据库连接池参数合理配置以应对高并发场景下的性能挑战。 - 对敏感信息做脱敏处理防止泄露隐私数据。 - 测试阶段充分验证各种边界条件确保程序健壮性。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值