MyBatis-Plus 通用 Service(IService)详解与实战

3 阅读3分钟

MyBatis-Plus 通用 Service(IService)详解与实战

#mybatis #mybatis-plus #spring boot

MyBatis-Plus 的通用 Service 层(IService)封装了大量 CRUD 操作,极大简化了开发流程。本文将基于User实体类,全面实现 IService 接口的核心方法,并提供完整测试案例。

一、核心组件介绍

  1. IService 接口 MyBatis-Plus 提供的IService接口是 Service 层的核心,定义了 40 + 常用方法,涵盖:

基础 CRUD(新增、删除、修改、查询) 批量操作 条件查询 分页查询 逻辑删除等 2. ServiceImpl 实现类 ServiceImpl<M extends BaseMapper, T>是 IService 的默认实现,需要指定:

泛型 M:对应的 Mapper 接口 泛型 T:实体类 二、环境准备

  1. 依赖引入(pom.xml)

org.springframework.boot

spring-boot-starter

com.baomidou

mybatis-plus-boot-starter

3.5.3.1

mysql

mysql-connector-java

runtime

org.projectlombok

lombok

true

org.springframework.boot

spring-boot-starter-test

test

  1. 核心接口与类定义 (1)UserMapper 接口

package com.qcby.mybatisplus1.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;

import com.qcby.mybatisplus1.domain.User;

public interface UserMapper extends BaseMapper {

}

(2)UserService 接口

package com.qcby.mybatisplus1.service;

import com.baomidou.mybatisplus.extension.service.IService;

import com.qcby.mybatisplus1.domain.User;

public interface UserService extends IService {

}

(3)UserServiceImpl 实现类

package com.qcby.mybatisplus1.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.qcby.mybatisplus1.domain.User;

import com.qcby.mybatisplus1.mapper.UserMapper;

import com.qcby.mybatisplus1.service.UserService;

import org.springframework.stereotype.Service;

@Service

public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

}

三、IService 核心方法实现与测试

  1. 测试类基础配置

package com.qcby.mybatisplus1.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import com.baomidou.mybatisplus.core.metadata.IPage;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import com.qcby.mybatisplus1.domain.User;

import org.junit.jupiter.api.Test;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.boot.test.context.SpringBootTest;

import java.util.*;

import static org.junit.jupiter.api.Assertions.*;

@SpringBootTest

public class UserServiceTest {

@Autowired

private UserService userService;

}

  1. 新增操作 (1)单个新增

@Test

public void testSave() {

User user = new User(null, "张三", 20, "zhangsan@qq.com");

boolean result = userService.save(user);

assertTrue(result);

System.out.println("新增后的ID:" + user.getId()); // 自动生成的ID

}

(2)批量新增

@Test

public void testSaveBatch() {

List userList = new ArrayList<>();

userList.add(new User(null, "李四", 22, "lisi@qq.com"));

userList.add(new User(null, "王五", 25, "wangwu@qq.com"));

boolean result = userService.saveBatch(userList);

assertTrue(result);

userList.forEach(user -> System.out.println("批量新增ID:" + user.getId()));

}

  1. 修改操作 (1)根据 ID 修改

@Test

public void testUpdateById() {

User user = new User(1L, "张三更新", 21, "zhangsan_update@qq.com");

boolean result = userService.updateById(user);

assertTrue(result);

}

(2)条件修改

@Test

public void testUpdate() {

// 将名字为"李四"的年龄改为23

User updateUser = new User();

updateUser.setAge(23);

QueryWrapper queryWrapper = new QueryWrapper<>();

queryWrapper.eq("name", "李四");

boolean result = userService.update(updateUser, queryWrapper);

assertTrue(result);

}

  1. 删除操作 (1)根据 ID 删除

@Test

public void testRemoveById() {

boolean result = userService.removeById(1L);

assertTrue(result);

}

(2)批量删除

@Test

public void testRemoveByIds() {

List ids = Arrays.asList(2L, 3L);

boolean result = userService.removeByIds(ids);

assertTrue(result);

}

(3)条件删除

@Test

public void testRemove() {

QueryWrapper queryWrapper = new QueryWrapper<>();

queryWrapper.eq("age", 25); // 删除年龄为25的用户

boolean result = userService.remove(queryWrapper);

assertTrue(result);

}

  1. 查询操作 (1)根据 ID 查询

@Test

public void testGetById() {

User user = userService.getById(1L);

assertNotNull(user);

System.out.println("查询结果:" + user);

}

(2)批量查询

@Test

public void testListByIds() {

List ids = Arrays.asList(1L, 2L);

List userList = userService.listByIds(ids);

assertFalse(userList.isEmpty());

userList.forEach(System.out::println);

}

(3)条件查询

@Test

public void testList() {

QueryWrapper queryWrapper = new QueryWrapper<>();

queryWrapper.ge("age", 22) // 年龄>=22

.like("email", "qq.com"); // 邮箱包含qq.com

List userList = userService.list(queryWrapper);

userList.forEach(System.out::println);

}

(4)分页查询

@Test

public void testPage() {

Page page = new Page<>(1, 2); // 第1页,每页2条

QueryWrapper queryWrapper = new QueryWrapper<>();

queryWrapper.orderByDesc("age"); // 按年龄倒序

IPage userIPage = userService.page(page, queryWrapper);

System.out.println("总页数:" + userIPage.getPages());

System.out.println("总记录数:" + userIPage.getTotal());

userIPage.getRecords().forEach(System.out::println);

}

  1. 其他常用方法 (1)查询记录总数

@Test

public void testCount() {

QueryWrapper queryWrapper = new QueryWrapper<>();

queryWrapper.gt("age", 20); // 统计年龄>20的用户数

long count = userService.count(queryWrapper);

System.out.println("符合条件的记录数:" + count);

}

(2)判断记录是否存在

@Test

public void testExists() {

QueryWrapper queryWrapper = new QueryWrapper<>();

queryWrapper.eq("name", "张三");

boolean exists = userService.exists(queryWrapper);

System.out.println("是否存在:" + exists);

}

四、分页插件配置(必需) 使用分页功能需要配置分页插件,否则分页不生效:

package com.qcby.mybatisplus1.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 MyBatisPlusConfig {

@Bean

public MybatisPlusInterceptor mybatisPlusInterceptor() {

MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();

// 添加分页插件

interceptor.addInnerInterceptor(new PaginationInnerInterceptor());

return interceptor;

}

}

五、总结 MyBatis-Plus 的 IService 接口为我们提供了丰富的 CRUD 操作方法,主要分为以下几类:

操作类型

核心方法

新增

save()、saveBatch()

修改

updateById()、update()

删除

removeById()、removeByIds()、remove()

查询

getById()、listByIds()、list()、page()

统计

count()、exists()

通过继承 ServiceImpl 实现类,我们无需编写具体实现代码,直接调用这些方法即可完成数据库操作,极大提高了开发效率。

实际开发中,可根据业务需求灵活组合这些方法,复杂查询可通过 QueryWrapper 构建条件。

后续可以结合具体业务场景,进一步扩展 Service 层的功能,比如添加自定义查询方法等。 ———————————————— 版权声明:本文为CSDN博主「开往1982」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:blog.csdn.net/weixin_6326…