mybatisPlus使用步骤详解

1.导包:

复制代码
        <!--mybatis-plus jar文件-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.1</version>
        </dependency>

yml和之前的相比多了一个-plus

复制代码
mybatis-plus:
  type-aliases-package: com.hz.mybatisPlusTest01.pojo
  mapper-locations: classpath:/mapper/*.xml

  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    map-underscore-to-camel-case: false #驼峰映射关闭

测试类:

复制代码
@SpringBootTest
@MapperScan("com.hz.mapper")
class MybatisPlusTest01ApplicationTests {
    @Resource
    private ProviderService providerService;
    @Test
    public void findById() {
        providerService.findById(1);
    }
}

2.两种使用mybatis-plus的方式:

这两种方式的方法不太一样

select find

insert save

del remove

1.普通的在service层中调用

就是通过Mapper继承BaseMapper<T>

复制代码
public interface ProviderMapper extends BaseMapper<Provider> {

    @Resource
    private ProviderMapper providerMapper;
然后在测试类中
    @Resource
    private ProviderService providerService;

就是这个需要在service层中调用,省了mapper层的方法

2.跳过service层,直接在controller中调用

service直接继承 ServiceImpl<BaseMapper<Provider>,Provider>

此时就不需要ProviderMapper extends BaseMapper<Provider>,但是ProviderMapper还是要有的

复制代码
public class ProviderServiceImpl extends ServiceImpl<BaseMapper<Provider>,Provider> 
                                                             implements ProviderService {

service的接口继承 IService<Provider>

复制代码
public interface ProviderService extends IService<Provider>

就算这样还是需要mapper层继承不继承应该都行

复制代码
public interface ProviderMapper extends BaseMapper<Provider> 

UpdateWrapper和QueryWrapper的区别:

创建方式

复制代码
UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
QueryWrapper<User> queryWrapper = new QueryWrapper<>();

例子:

LambdaQueryWrapper 构造器:

这个使用lamda表达式::就是.的意思

.select()里面装的字段

.eq( , )让左边的变量等于右边的

.like( , , )左边boolean条件,可以判断是否为null,中间是变量,右边是模糊查询的条件

因为Lambda表达式是通过实体类的,所以起的别名也能够正常使用 ,这里是Provider::getPname实体类会自动转换成proName

复制代码
   lambdaQueryWrapper.select(Provider::getId,Provider::getPname);
labmda的写法:

创建LambdaQueryWrapper的方式也不一样,把值放入的方式也不同

复制代码
 LambdaQueryWrapper<Provider> queryWrapper = new LambdaQueryWrapper<>();

    @Test
    public  void find(){
        LambdaQueryWrapper<Provider> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.select(Provider::getId,Provider::getProCode,Provider::getPname);
        lambdaQueryWrapper.like(Provider::getPname,"大");
        lambdaQueryWrapper.eq(Provider::getProCode,"BJ_GYS003");
        lambdaQueryWrapper.orderByAsc(Provider::getId);
        providerService.list(lambdaQueryWrapper);

    }
QueryWrapper的写法:

这是一种线性的写法

复制代码
    public void find(){
        //条件构造器   select from xx where xxx  like '%xx%' and
       providerService.list(new QueryWrapper<Provider>()
               .select("id","proCode","proDesc","proName")
               .like(true,"proDesc","深圳")
               .eq(true,"proCode","GZ_GYS002")
               .orderByDesc("creationDate"));
    }

.gt用来添加大于的条件

复制代码
    @Test
    public void lambda(){
        LambdaQueryWrapper<Provider> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.like(Provider::getPname,"北")
                .and(wrapper -> wrapper.gt(Provider::getId, 10)); // 添加 id 大于 50 的条件

        providerService.list(lambdaQueryWrapper);

    }

如果索引被撑大了:

在这里填上在此基础上要继续递增的数字,表中的id没有比这个数字再大的

还需要在实体类中加上@TableId(value = "id",type= IdType.AUTO),让id自动递增的

复制代码
	@TableId(value = "id",type= IdType.AUTO)
	private Integer id; //id

解释一下各种方法:

1.removeById(Serializable id):

Serializable id 表示一个通用的参数类型,用于作为主键的标识符(ID)。Serializable 用于确保该方法可以接受不同类型的 ID 参数。Serializable 是 Java 中的一个标记接口,意味着该类型的对象可以被序列化。

3.条件构造器:

测试类:

复制代码
import static org.junit.jupiter.api.Assertions.*;

@SpringBootTest
 public  class ProviderServiceTest {

    @Autowired
    private ProviderService providerService;

    @Test
    public void findlist(){
//        查询所有
        providerService.list();

    }
    /**
     * 模糊查询
     */
    @Test
    public void selectLike(){
        QueryWrapper<Provider> queryWrapper = new QueryWrapper<>();
        queryWrapper.like(true, "proDesc", "大豆油");
        queryWrapper.eq(true,"proCode","BJ_GYS003");
        queryWrapper.or().eq(true,"proCode","BJ_GYS003");
        queryWrapper.orderByAsc("id");
        providerService.list(queryWrapper);
//        查询所有
//        providerService.update(Provider,queryWrapper);

    }


}

4.Mybatis-Plus-Join:

因为mybatisPlus没有表连接,这个MybatisPlusJoin是用于表连接的,并且它能够轻松实现表的分页(需要工具)

先导包

复制代码
 <dependency>
            <groupId>com.github.yulichang</groupId>
            <artifactId>mybatis-plus-join-boot-starter</artifactId>
            <version>1.5.1</version>
        </dependency>

MPJ分页:

分页插件

复制代码
package com.hz.config;
import com.baomidou.mybatisplus.annotation.DbType;
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 MybatisPlusConfig {
    /**
     * 添加分页插件
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); // 如果配置多个插件, 切记分页最后添加
        // 如果有多数据源可以不配具体类型, 否则都建议配上具体的 DbType
        return interceptor;
    }
}

一种要在service层写方法的分页用 . selectPage ( page , null );

第二种可以直接在controller中写方法的用. page(page,null);

复制代码
    @Test
    public void fenye(){
            Page<Provider> page = new Page<>(1,5);
            providerService.page(page,null);
// 输出page对象分页查询信息
            System.out.println("总条数:" + page.getTotal());
            System.out.println("每页显示条数:" + page.getSize());
            System.out.println("总页数:" + page.getPages());
            System.out.println("当前页:" + page.getCurrent());
            System.out.println("是否有上一页:" + page.hasPrevious());
            System.out.println("是否有下一页:" + page.hasNext());
            System.out.println("查询结果:" + page.getRecords());
    }

5.逻辑删除:

isDelete字段: 0:未删除 1:已删除

配置属性:
复制代码
mybatis-plus:
  global-config:
    db-config:
      logic-delete-field: idDelete # 全局逻辑删除字段名
      logic-delete-value: 1 # 逻辑已删除值
      logic-not-delete-value: 0 # 逻辑未删除值
给字段加上注解:
复制代码
 @TableLogic
    private int idDelete;

也就是这里的删除不是真正的删除,是逻辑删除,也就相当于更新:把isDelete字段更新成1,以后再查询的时候只查isDelete字段等于0的

再次查询的时候会自动拼上idDelete=0

6.多租户:

就是不同用户看到不同的数据,也就是根据创建人来获取数据,2创建人只能获取2的信息

多租户插件:

getTenantId()这个方法就是获取创建人的信息,这里假设

getTenantIdColumn()这个方法就是返回看什么字段决定多租户,返回这个字段createdBy

复制代码
@Component
public class CustomTenantHandler implements TenantLineHandler {


    @Override
    public Expression getTenantId() {
//        假装从redis获取用户id
        int userId=2;

        return new LongValue(userId);
    }

    @Override
    public String getTenantIdColumn() {
        return "createdBy";
    }
    @Override
    public boolean ignoreTable(String tableName) {
        return TenantLineHandler.super.ignoreTable(tableName);
    }
}
在分页上插件上配置多租户:

14-16行就是新增加的三行

复制代码
@Configuration
public class MybatisPlusConfig {
    @Autowired
    private CustomTenantHandler customTenantHandler;
    /**
     * 添加分页插件
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); // 如果配置多个插件, 切记分页最后添加
        // 如果有多数据源可以不配具体类型, 否则都建议配上具体的 DbType
        
        TenantLineInnerInterceptor tenantInterceptor = new TenantLineInnerInterceptor();
        tenantInterceptor.setTenantLineHandler(customTenantHandler);
        interceptor.addInnerInterceptor(tenantInterceptor);
        return interceptor;
    }
}
相关推荐
JohnYan1 分钟前
工作笔记 - ASN.1密钥结构和编码研究
javascript·后端·安全
学习OK呀7 分钟前
日常docker的实操命令场景
后端
掉鱼的猫8 分钟前
qwen3 惊喜发布,用 ollama + solon ai (java) 尝个鲜
java·openai·deepseek
雾原9 分钟前
Nginx高频用途的详细配置和性能调优
后端
类似不类似9 分钟前
快速配置linux远程开发-go语言
开发语言·后端·golang
前端付豪10 分钟前
1、为什么浏览器要有渲染流程? ——带你一口气吃透 Critical Rendering Path
前端·后端·浏览器
前端付豪12 分钟前
3、Node.js异步编程彻底吃透
前端·后端·node.js
老胖闲聊14 分钟前
Flask 请求数据获取方法详解
后端·python·flask
GuGuStudy15 分钟前
这都是什么多线程知识
java
Bob999816 分钟前
Amlogic S905L3系列盒子 ROM DIY相关
java·javascript·数据仓库·vscode·eclipse·tomcat·vim