最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MyBatis-Plus增刪改查的通用化封裝過程

 更新時間:2026年05月31日 10:12:54   作者:工頁光軍  
這段文章詳細介紹了MyBatis-Plus的通用化封裝方案,通過泛型和繼承實現(xiàn)了Mapper、Service、Controller層的通用接口;業(yè)務(wù)模塊僅需繼承這些通用類即可實現(xiàn)增刪改查功能;此方案極大提升了代碼復(fù)用性和擴展性;適用于企業(yè)級開發(fā)實踐

要實現(xiàn) MyBatis-Plus 增刪改查的通用化封裝,核心思路是利用泛型 + 繼承封裝通用的 Mapper、Service、Controller 層,讓業(yè)務(wù)模塊直接繼承這些通用類,無需重復(fù)編寫增刪改查代碼。

以下是完整的實現(xiàn)方案(Spring Boot 環(huán)境):

一、基礎(chǔ)準(zhǔn)備:統(tǒng)一響應(yīng)結(jié)果

先封裝通用響應(yīng)類,保證接口返回格式統(tǒng)一,減少重復(fù)編碼:

package com.example.mpdemo.common;

import lombok.Data;

/**
 * 通用響應(yīng)結(jié)果類
 * @param <T> 響應(yīng)數(shù)據(jù)類型
 */
@Data
public class Result<T> {
    // 響應(yīng)碼(200成功,500失?。?
    private Integer code;
    // 響應(yīng)消息
    private String msg;
    // 響應(yīng)數(shù)據(jù)
    private T data;

    // 成功響應(yīng)(無數(shù)據(jù))
    public static <T> Result<T> success() {
        return new Result<>(200, "操作成功", null);
    }

    // 成功響應(yīng)(有數(shù)據(jù))
    public static <T> Result<T> success(T data) {
        return new Result<>(200, "操作成功", data);
    }

    // 失敗響應(yīng)
    public static <T> Result<T> fail(String msg) {
        return new Result<>(500, msg, null);
    }
}

二、通用層封裝

1. 通用 Mapper 層(BaseMapper 增強)

MyBatis-Plus 的 BaseMapper 已封裝基礎(chǔ) CRUD,我們只需定義通用接口讓業(yè)務(wù) Mapper 繼承:

package com.example.mpdemo.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;

/**
 * 通用 Mapper 接口
 * @param <T> 實體類類型
 */
@Mapper
public interface BaseGenericMapper<T> extends BaseMapper<T> {
    // 無需額外方法,繼承 BaseMapper 的 17 個基礎(chǔ) CRUD 方法即可
}

2. 通用 Service 層

封裝通用 Service 接口和實現(xiàn)類,復(fù)用 IService 的高級 CRUD 能力:

(1)通用 Service 接口

package com.example.mpdemo.service;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;

import java.io.Serializable;
import java.util.List;

/**
 * 通用 Service 接口
 * @param <T> 實體類類型
 */
public interface BaseGenericService<T> extends IService<T> {
    // 可擴展通用方法,比如自定義分頁、批量操作等
    List<T> list(Wrapper<T> queryWrapper);  // 條件查詢列表
    IPage<T> page(IPage<T> page, Wrapper<T> queryWrapper);  // 條件分頁查詢
    T getById(Serializable id);  // 根據(jù) ID 查詢
    boolean saveEntity(T entity);  // 新增
    boolean updateEntity(T entity);  // 修改
    boolean removeById(Serializable id);  // 根據(jù) ID 刪除
}

(2)通用 Service 實現(xiàn)類

package com.example.mpdemo.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.mpdemo.mapper.BaseGenericMapper;
import com.example.mpdemo.service.BaseGenericService;

import java.io.Serializable;
import java.util.List;

/**
 * 通用 Service 實現(xiàn)類
 * @param <M> Mapper 類型
 * @param <T> 實體類類型
 */
public class BaseGenericServiceImpl<M extends BaseGenericMapper<T>, T> 
        extends ServiceImpl<M, T> implements BaseGenericService<T> {

    @Override
    public List<T> list(Wrapper<T> queryWrapper) {
        return baseMapper.selectList(queryWrapper);
    }

    @Override
    public IPage<T> page(IPage<T> page, Wrapper<T> queryWrapper) {
        return baseMapper.selectPage(page, queryWrapper);
    }

    @Override
    public T getById(Serializable id) {
        return baseMapper.selectById(id);
    }

    @Override
    public boolean saveEntity(T entity) {
        return save(entity);  // 復(fù)用 IService 的 save 方法
    }

    @Override
    public boolean updateEntity(T entity) {
        return updateById(entity);  // 復(fù)用 IService 的 updateById 方法
    }

    @Override
    public boolean removeById(Serializable id) {
        return baseMapper.deleteById(id);
    }
}

3. 通用 Controller 層(核心)

封裝通用的增刪改查接口,業(yè)務(wù) Controller 只需繼承此類并指定實體和主鍵類型,無需重復(fù)編寫接口:

package com.example.mpdemo.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.mpdemo.common.Result;
import com.example.mpdemo.service.BaseGenericService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.Serializable;
import java.util.List;

/**
 * 通用 CRUD Controller
 * @param <T> 實體類類型
 * @param <K> 主鍵類型(如 Long、String)
 */
public class BaseGenericController<T, K extends Serializable> {

    // 注入通用 Service(由子類指定具體實現(xiàn))
    @Autowired
    protected BaseGenericService<T> baseService;

    /**
     * 1. 新增
     */
    @PostMapping
    public Result<T> add(@RequestBody T entity) {
        boolean success = baseService.saveEntity(entity);
        return success ? Result.success(entity) : Result.fail("新增失敗");
    }

    /**
     * 2. 根據(jù) ID 刪除
     */
    @DeleteMapping("/{id}")
    public Result<Void> delete(@PathVariable K id) {
        boolean success = baseService.removeById(id);
        return success ? Result.success() : Result.fail("刪除失敗");
    }

    /**
     * 3. 修改
     */
    @PutMapping
    public Result<T> update(@RequestBody T entity) {
        boolean success = baseService.updateEntity(entity);
        return success ? Result.success(entity) : Result.fail("修改失敗");
    }

    /**
     * 4. 根據(jù) ID 查詢
     */
    @GetMapping("/{id}")
    public Result<T> getById(@PathVariable K id) {
        T entity = baseService.getById(id);
        return entity != null ? Result.success(entity) : Result.fail("數(shù)據(jù)不存在");
    }

    /**
     * 5. 查詢所有(無條件)
     */
    @GetMapping("/list")
    public Result<List<T>> list() {
        List<T> list = baseService.list(Wrappers.emptyWrapper());
        return Result.success(list);
    }

    /**
     * 6. 分頁查詢(默認第1頁,每頁10條,可傳參數(shù)自定義)
     */
    @GetMapping("/page")
    public Result<IPage<T>> page(
            @RequestParam(defaultValue = "1") Long current,
            @RequestParam(defaultValue = "10") Long size) {
        IPage<T> page = baseService.page(new Page<>(current, size), Wrappers.emptyWrapper());
        return Result.success(page);
    }
}

三、業(yè)務(wù)模塊使用示例(以 User 為例)

只需編寫少量代碼,繼承通用類即可擁有完整的增刪改查接口:

1. 實體類(User)

沿用之前的 User 實體(無需修改):

package com.example.mpdemo.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

import java.time.LocalDateTime;

@Data
@TableName("user")
public class User {
    @TableId(type = IdType.ASSIGN_ID)
    private Long id;
    private String username;
    private Integer age;
    private String email;
    private LocalDateTime createTime;
}

2. 業(yè)務(wù) Mapper(UserMapper)

繼承通用 Mapper:

package com.example.mpdemo.mapper;

import com.example.mpdemo.entity.User;
import org.springframework.stereotype.Repository;

@Repository
public interface UserMapper extends BaseGenericMapper<User> {
    // 無需編寫任何代碼,自動擁有所有基礎(chǔ) CRUD 能力
}

3. 業(yè)務(wù) Service

(1)Service 接口

package com.example.mpdemo.service;

import com.example.mpdemo.entity.User;

public interface UserService extends BaseGenericService<User> {
    // 可擴展自定義業(yè)務(wù)方法
}

(2)Service 實現(xiàn)類

package com.example.mpdemo.service.impl;

import com.example.mpdemo.entity.User;
import com.example.mpdemo.mapper.UserMapper;
import com.example.mpdemo.service.UserService;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl extends BaseGenericServiceImpl<UserMapper, User> implements UserService {
    // 無需編寫任何代碼,自動繼承通用 Service 的所有方法
}

4. 業(yè)務(wù) Controller

繼承通用 Controller,指定實體(User)和主鍵類型(Long):

package com.example.mpdemo.controller;

import com.example.mpdemo.entity.User;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 用戶控制器,繼承通用 Controller 后自動擁有所有 CRUD 接口
 */
@RestController
@RequestMapping("/user")
public class UserController extends BaseGenericController<User, Long> {
    // 無需編寫任何接口代碼,自動擁有:
    // POST /user → 新增
    // DELETE /user/{id} → 刪除
    // PUT /user → 修改
    // GET /user/{id} → 根據(jù)ID查詢
    // GET /user/list → 查詢所有
    // GET /user/page → 分頁查詢
}

四、接口測試(Postman/Curl)

接口請求方式說明示例請求參數(shù)
/userPOST新增用戶{"username":"張三","age":20,"email":"zhangsan@example.com","createTime":"2026-03-13 10:00:00"}
/user/1DELETE刪除用戶路徑參數(shù) id=1
/userPUT修改用戶{"id":1,"username":"張三","age":21}
/user/1GET查詢單個用戶路徑參數(shù) id=1
/user/listGET查詢所有用戶無參數(shù)
/user/page?current=1&size=2GET分頁查詢參數(shù) current=1(頁碼)、size=2(每頁條數(shù))

五、擴展說明

  • 自定義條件查詢:若需添加條件查詢,可在通用 Controller 中擴展,或在業(yè)務(wù) Controller 中新增方法:
// UserController 中新增條件查詢接口
@GetMapping("/listByAge")
public Result<List<User>> listByAge(@RequestParam Integer age) {
    LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery(User.class)
            .gt(User::getAge, age);
    List<User> list = baseService.list(wrapper);
    return Result.success(list);
}
  • 異常處理:可添加全局異常處理器(@RestControllerAdvice),統(tǒng)一捕獲增刪改查中的異常(如主鍵不存在、參數(shù)非法等);
  • 權(quán)限控制:若需接口權(quán)限,可在通用 Controller 或業(yè)務(wù) Controller 中添加 @PreAuthorize 等注解;
  • 參數(shù)校驗:可在實體類中添加 @NotNull、@NotBlank 等校驗注解,配合 @Valid 實現(xiàn)參數(shù)校驗。

總結(jié)

  • 核心思路:通過泛型 + 繼承封裝通用的 Mapper、Service、Controller,業(yè)務(wù)模塊只需繼承通用類,無需重復(fù)編寫增刪改查代碼;
  • 復(fù)用性:通用層封裝了 6 個核心 CRUD 接口(新增、刪除、修改、單查、列表、分頁),覆蓋 90% 以上的單表業(yè)務(wù)場景;
  • 擴展性:通用類預(yù)留了擴展接口,業(yè)務(wù)模塊可按需新增自定義方法,不破壞通用邏輯。

這種方式極大減少了重復(fù)編碼,符合“開閉原則”,是企業(yè)開發(fā)中常用的 MyBatis-Plus 最佳實踐。

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論

呼和浩特市| 察雅县| 平南县| 瑞丽市| 嫩江县| 雷波县| 慈溪市| 大邑县| 建宁县| 安阳市| 大宁县| 大埔县| 靖远县| 忻州市| 罗城| 库伦旗| 香格里拉县| 合川市| 三门县| 清水县| 泽库县| 石柱| 甘谷县| 秦皇岛市| 甘南县| 南涧| 永清县| 清水河县| 榆林市| 九寨沟县| 会东县| 共和县| 姚安县| 潜山县| 五家渠市| 元谋县| 虞城县| 鱼台县| 凌云县| 视频| 凌云县|