MybatisPlus学习

mybatis-plus官网

简介 | MyBatis-Plus (baomidou.com)

一  快速入门

1  创建项目

导入mysql驱动,这里先不做web

2  导入依赖

我这里用的是springboot 3.3.0版本

注意: SpringBoot 3.0 需要 mybatis-spring 3.0.X 版本,否则会报如下错误:
nvalid value type for attribute 'factoryBeanObjectType'‘': java.lang.String

这里有一个小坑

<dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.5</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>3.0.3</version>
        </dependency>

 3  引入例子

package com.demo.learnmybatisplus.Pojo;


import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.stereotype.Component;

@Data
@Component
@AllArgsConstructor
@NoArgsConstructor
public class Users {

    public int id;
    private String username;
    private String password;

}

数据库的相应信息

4  编辑持久层

package com.demo.learnmybatisplus.Mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.demo.learnmybatisplus.Pojo.Users;
import org.apache.ibatis.annotations.Mapper;


@Mapper
public interface UserMapper extends BaseMapper<Users> {

}

5  启动!!! 添加测试

package com.demo.learnmybatisplus;
import com.demo.learnmybatisplus.Mapper.UserMapper;
import com.demo.learnmybatisplus.Pojo.Users;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

@SpringBootTest
class LearnMybatisPLusApplicationTests {

    @Autowired
    private UserMapper userMapper;

    @Test
    public void selectAll(){
        List<Users> users = userMapper.selectList(null);
        System.out.println(users);
    }

}

结果显示

6  坑!!!

SpringBoot 3.0 需要 mybatis-spring 3.0.X 版本,如果没导入,就会报错。当时我找了好久,哪里没加注解呢?!想不到是版本问题

二   方便快捷的CRUD功能

全部的条件构造器可以看这里

条件构造器 | MyBatis-Plus (baomidou.com)

1  简单介绍有哪些

2  前五个操作,增删改查以及查全部

package com.demo.learnmybatisplus;
import com.demo.learnmybatisplus.Mapper.UserMapper;
import com.demo.learnmybatisplus.Pojo.Users;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

@SpringBootTest
@Slf4j
class LearnMybatisPLusApplicationTests {

    @Autowired
    private UserMapper userMapper;

    @Test
    public void selectAll(){
        List<Users> users = userMapper.selectList(null);
        System.out.println(users);
    }

    @Test
    public void TextInsert(){
        Users users = new Users(2, "123456", "789789");
        log.info("新增用户:{}", users);
        //传入的是实体类books
        userMapper.insert(users);
    }

    @Test
    public void TextDelete(){
        int id = 6;
        userMapper.deleteById(id);
    }

    @Test
    public void TextUpdate(){
        Users users = new Users();
        users.setId(4);
        users.setPassword("12356789");
        //根据id锁定修改对象,其他值为修改值
        userMapper.updateById(users);
    }

    @Test
    public void TextSelectAll(){
        List<Users> usersList = userMapper.selectList(null);
    }

}

3  分页查询操作

分页查询需要一个专门的拦截器,来拦截sql语句,实现limit的添加

package com.demo.learnmybatisplus.Config;

import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MpConfiguation {
    @Bean
    public MybatisPlusInterceptor pageInterceptor() {
        //1 创建一个拦截器对象
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        //2 在拦截器内部加入小的分页的拦截器
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        return interceptor;
    }
}

配置好拦截器之后,在测试类测试分页查询的代码

@Test
    public void TextPageSelect() {
        //第一个参数代表查询第几页, 第二个代表每页多少个参数
        IPage page = new Page(2, 3);
        
        userMapper.selectPage(page, null);
        System.out.println("当前页码:" + page.getCurrent());
        System.out.println("每页数据总量:" + page.getSize());
        System.out.println("总页数:" + page.getPages());
        System.out.println("数据总量:" + page.getTotal());
        System.out.println("当前页数据:" + page.getRecords());
    }

开启sql详细日志的输出,来看看limit是怎么被加上去的。平时可以注释掉,避免控制台太多东西,在出错时可以打开此配置来找错

#mybatis日志的输出
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

4  DQL条件查询

一共四种方法,主要用第三种方法  构建条件查询器

    //条件查询
    @Test
    public void TextSelect(){
        //方式一  常规格式
        QueryWrapper qw = new QueryWrapper();
        qw.lt("id", 6);//id小于于6
        qw.ge("id", 4);//id大于2
        List<Users> usersList = userMapper.selectList(qw);
        System.out.println(usersList);

//        方式二  lambda链式编程
        QueryWrapper<Users> qwU = new QueryWrapper<>();
        qwU.lambda().lt(Users::getId, 6).ge(Users::getId,4);
        List<Users> usersListU = userMapper.selectList(qwU);
        System.out.println(usersListU);

        //方式三  lambda的简化
        LambdaQueryWrapper<Users> lqw = new LambdaQueryWrapper<>();
        lqw.lt(Users::getId, 6).ge(Users::getId,4);
        List<Users> usersListlqu = userMapper.selectList(lqw);
        System.out.println(usersListlqu);

        //组合条件,上面的是and的条件,这个是or的条件
        lqw.lt(Users::getId, 6).or().ge(Users::getId,4);
    }
}

补充,对null的判断

//条件查询,对空的判断
    @Test
    public void TextNull(){
        LambdaQueryWrapper<Users> lqw = new LambdaQueryWrapper<>();
        Users user1 = new Users();
        user1.setId(3);
        //如果不为空,及前面的表达式为true,则条件生效
        lqw.lt(user1 != null, Users::getId, 4);
    }

5  查询投影

他主要有两个功能,一个是查询部分的信息。

另一个是可以使用函数等Users类里面没有的信息。因为之前学到的查询都是封装到了实体类的中,本例是Users,所以他不能显示Users里面mei

//条件查询,查询部分信息,以及使用函数等Users类里面没有的信息
    @Test
    public void TextSelectPath(){
        //查询部分属性
        LambdaQueryWrapper<Users> lqw = new LambdaQueryWrapper<>();
        lqw.select(Users::getId);
        lqw.lt(Users::getId, 6);
        List<Users> users = userMapper.selectList(lqw);
        System.out.println(users);

        //查询函数以及其他User类没有的值
        /*
        注意selectMaps和上面LambdaQueryWrapper查询的selectList是不一样的,
        和之前的也是不一样的
        LambdaQueryWrapper不具有这个方法
        这个方法有局限,并不是所有的函数都支持,
        则需要时我们可以像mybatis一样自己写@Select语句
         */
        QueryWrapper<Users> qw = new QueryWrapper<>();
        qw.select("count(*) as count, id");
        qw.groupBy("id");
        List<Map<String, Object>> list = userMapper.selectMaps(qw);
        System.out.println(list);


        //这就是自己定义的方法
        List<Map<Integer, Object>> listByMe = userMapper.TextCount();
        System.out.println(listByMe);
    }

UserMapper中自己定义的方法,这里有个sql规范,用了聚合函数与非聚合函数就要用分组,只用聚合函数就不用一定要分组

package com.demo.learnmybatisplus.Mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.demo.learnmybatisplus.Pojo.Users;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

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


@Mapper
public interface UserMapper extends BaseMapper<Users> {

    @Select("select count(*), id from users group by id")
    List<Map<Integer, Object>> TextCount();
}

6  映射配置兼容性

问题一  : 实体类里面字段名字与数据库不匹配

问题二 :  编码中实体类添加了数据库没有的字段

问题三 :  查询的权限扩大,有些字段不希望被查询到

问题四:  实体类名字与数据库的表名字不一致

7  逻辑删除

情景:在实际业务中,我们删除数据会对业务造成不可挽回的伤害,所以我们要采取另一种方式来实现删除功能

这里的逻辑:mybatisplus会提供方法,在表格中添加一栏数据来标记此数据是否被删除,从而在其他过程中不在涉及该数据

步骤一 :在数据库添加字段,这里添加了deleted字段

步骤二 : 在实体类添加字段,也是deleted

步骤三: 在yml文件内让spring能识别mybatisplus这个功能:在表格中添加一栏数据来标记此数据是否被删除,若识别为已经删除,则在其他过程中不再涉及该数据

测试一把,看看他是怎么实现的

当我执行delete方法时

他的输出

他底层做的是一个更新操作,并不是真正的删除

三  BaseMapper源码

我们的mapper继承了这个,从中我们可以看到这个mybatisplus中到底有什么方法

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.baomidou.mybatisplus.core.mapper;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.exceptions.TooManyResultsException;
import org.apache.ibatis.session.ResultHandler;

public interface BaseMapper<T> extends Mapper<T> {
    int insert(T entity);

    int deleteById(Serializable id);

    int deleteById(T entity);

    default int deleteByMap(Map<String, Object> columnMap) {
        return this.delete((Wrapper)Wrappers.query().allEq(columnMap));
    }

    int delete(@Param("ew") Wrapper<T> queryWrapper);

    int deleteBatchIds(@Param("coll") Collection<?> idList);

    int updateById(@Param("et") T entity);

    int update(@Param("et") T entity, @Param("ew") Wrapper<T> updateWrapper);

    default int update(@Param("ew") Wrapper<T> updateWrapper) {
        return this.update((Object)null, updateWrapper);
    }

    T selectById(Serializable id);

    List<T> selectBatchIds(@Param("coll") Collection<? extends Serializable> idList);

    void selectBatchIds(@Param("coll") Collection<? extends Serializable> idList, ResultHandler<T> resultHandler);

    default List<T> selectByMap(Map<String, Object> columnMap) {
        return this.selectList((Wrapper)Wrappers.query().allEq(columnMap));
    }

    default void selectByMap(Map<String, Object> columnMap, ResultHandler<T> resultHandler) {
        this.selectList((Wrapper)Wrappers.query().allEq(columnMap), resultHandler);
    }

    default T selectOne(@Param("ew") Wrapper<T> queryWrapper) {
        return this.selectOne(queryWrapper, true);
    }

    default T selectOne(@Param("ew") Wrapper<T> queryWrapper, boolean throwEx) {
        List<T> list = this.selectList(queryWrapper);
        int size = list.size();
        if (size == 1) {
            return list.get(0);
        } else if (size > 1) {
            if (throwEx) {
                throw new TooManyResultsException("Expected one result (or null) to be returned by selectOne(), but found: " + size);
            } else {
                return list.get(0);
            }
        } else {
            return null;
        }
    }

    default boolean exists(Wrapper<T> queryWrapper) {
        Long count = this.selectCount(queryWrapper);
        return null != count && count > 0L;
    }

    Long selectCount(@Param("ew") Wrapper<T> queryWrapper);

    List<T> selectList(@Param("ew") Wrapper<T> queryWrapper);

    void selectList(@Param("ew") Wrapper<T> queryWrapper, ResultHandler<T> resultHandler);

    List<T> selectList(IPage<T> page, @Param("ew") Wrapper<T> queryWrapper);

    void selectList(IPage<T> page, @Param("ew") Wrapper<T> queryWrapper, ResultHandler<T> resultHandler);

    List<Map<String, Object>> selectMaps(@Param("ew") Wrapper<T> queryWrapper);

    void selectMaps(@Param("ew") Wrapper<T> queryWrapper, ResultHandler<Map<String, Object>> resultHandler);

    List<Map<String, Object>> selectMaps(IPage<? extends Map<String, Object>> page, @Param("ew") Wrapper<T> queryWrapper);

    void selectMaps(IPage<? extends Map<String, Object>> page, @Param("ew") Wrapper<T> queryWrapper, ResultHandler<Map<String, Object>> resultHandler);

    <E> List<E> selectObjs(@Param("ew") Wrapper<T> queryWrapper);

    <E> void selectObjs(@Param("ew") Wrapper<T> queryWrapper, ResultHandler<E> resultHandler);

    default <P extends IPage<T>> P selectPage(P page, @Param("ew") Wrapper<T> queryWrapper) {
        page.setRecords(this.selectList(page, queryWrapper));
        return page;
    }

    default <P extends IPage<Map<String, Object>>> P selectMapsPage(P page, @Param("ew") Wrapper<T> queryWrapper) {
        page.setRecords(this.selectMaps(page, queryWrapper));
        return page;
    }
}

  • 30
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值