SpringBoot整合通用mapper实现泛型BaseController增删改方式

 更新时间:2025年11月17日 08:52:46   作者:夕夕夕兮  
本文介绍了如何在SpringBoot项目中整合通用Mapper实现泛型BaseController的增删改功能,通过统一的代码实现减少重复,提高开发效率

SpringBoot整合通用mapper实现泛型BaseController增删改

目前写项目做需求时增删改查一直用得比较频繁,但是在做开发的时候,却并不想一次一次写重复的代码,尝试着整合了一下泛型实现统一增删改。

一、开发环境

       JDK:1.8 
       SpringBoot:2.4.4

二、加入依赖(所用到的是tk.mybatis中的通用mapper)

     <!--swaggerUi-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>
        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>swagger-bootstrap-ui</artifactId>
            <version>1.9.2</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.3</version>
        </dependency>
     <!--简化javabean代码的插件-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.16</version>
        </dependency>
        <!--通用mapper启动器-->
        <dependency>
            <groupId>tk.mybatis</groupId>
            <artifactId>mapper-spring-boot-starter</artifactId>
            <version>2.1.5</version>
        </dependency>

三、代码实现

1. BaseMapper(因为tk.mapper是不能被springboot扫描到的,所以不能放在springboot扫描mapper的包下,不然会报错)

package com.carshow.data.base.mapper;

import tk.mybatis.mapper.common.Mapper;
import tk.mybatis.mapper.common.MySqlMapper;

public abstract interface BaseMapper<T> extends Mapper<T>, MySqlMapper<T> {
}

2. IBaseService

package com.carshow.data.base.service;


import com.carshow.data.common.contant.ResultBody;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

public interface IBaseService<T, ID, EXAMPLE> {

    List<T> selectAll();

    T selectById(String id);

    /**
     * 单个实体对象全量字段保存
     *
     * @param record
     * @return
     */
    int save(T record);

    /**
     * 单个实体对象非空字段保存
     *
     * @param record
     * @return
     */
    int saveSelective(T record);

    /**
     * 多个实体对象保存
     *
     * @param list
     * @return
     */
//    int saveList(java.util.List<? extends T> list);

    /**
     * 单个实体对象删除
     *
     * @param record
     * @return
     */
    int delete(T record);

    /**
     * 单个实体对象条件删除
     *
     * @param record
     * @param example
     * @return
     */
    int deleteByExample(T record, EXAMPLE example);

    /**
     * 单个实体对象主键删除
     *
     * @param key
     * @return
     */
    int deleteByPrimaryKey(ID key);

    /**
     * 单个实体对象条件全量字段更新
     *
     * @param record
     * @param example
     * @return
     */
    int updateByExample(T record, EXAMPLE example);

    /**
     * 单个实体对象条件非空字段更新
     *
     * @param record
     * @param example
     * @return
     */
    int updateByExampleSelective(T record, EXAMPLE example);

    /**
     * 单个实体对象主键全量字段更新
     *
     * @param record
     * @return
     */
    int updateByPrimaryKey(T record);

    /**
     * 单个实体对象主键非空字段更新
     *
     * @param record
     * @return
     */
    int updateByPrimaryKeySelective(T record);

}

3. BaseServiceImpl

package com.carshow.data.base.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.carshow.data.base.mapper.BaseMapper;
import com.carshow.data.base.service.IBaseService;
import com.carshow.data.common.contant.ResultBody;
import com.carshow.data.ftp.FtpUtil;
import org.apache.commons.net.ftp.FTP;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.ParameterizedType;
import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Author xw
 * @Description 公用实现类
 * @Date 2021/1/11  19:13
 */
@Service
@Transactional//开启声明式事务注解,为该类添加事务支持。
public abstract class BaseServiceImpl<T, ID, EXAMPLE> implements IBaseService<T, ID, EXAMPLE> {

    // 定义抽象方法getMyMapper获取当前实体Mapper对象
    protected abstract BaseMapper<T> getBaseMapper();

    private Class<T> modelClass;//当前泛型的真实类型Class
    public BaseServiceImpl() {
        ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();
        modelClass = (Class<T>) pt.getActualTypeArguments()[0];
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<T> selectAll() {
        return getBaseMapper().selectAll();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public T selectById(String id) {
        return getBaseMapper().selectByPrimaryKey(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int save(T record) {
        int res = getBaseMapper().insert(record);
        return res;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int saveSelective(T record) {
        int res = getBaseMapper().insertSelective(record);
        return res;
    }

//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    public int saveList(java.util.List<? extends T> list) {
//        int res = getBaseMapper().insertList(list);
//        return res;
//    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int delete(T record) {
        int res = getBaseMapper().delete(record);
        return res;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteByExample(T record, EXAMPLE example) {
        int res = getBaseMapper().deleteByExample(example);
        return res;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteByPrimaryKey(ID key) {
        int res = getBaseMapper().deleteByPrimaryKey(key);
        return res;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateByExample(T record, EXAMPLE example) {
        int res = getBaseMapper().updateByExample(record, example);
        return res;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateByExampleSelective(T record, EXAMPLE example) {
        int res = getBaseMapper().updateByExampleSelective(record, example);
        return res;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateByPrimaryKey(T record) {
        int res = getBaseMapper().updateByPrimaryKey(record);
        return res;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateByPrimaryKeySelective(T record) {
        int res = getBaseMapper().updateByPrimaryKeySelective(record);
        return res;
    }
}

4. 声明泛型基类–AbstractController

package com.carshow.data.base.controller;

/**
 * @Author xw
 * @Description 声明泛型基类
 * @Date 2021/4/13  10:41
 */
public abstract  class AbstractController<T, K> {

    /**
     * 新增
     * @param t
     * @return
     */
    public abstract int addJson(T t);

    /**
     * 修改
     * @param t
     * @return
     */
    public abstract int updateJson(T t);

    /**
     * 单个实体对象主键删除
     * @param
     * @return
     */
    public abstract int delJson(K id);
}

5. 实现泛型父类–BaseController

package com.carshow.data.base.controller;

import com.carshow.data.base.service.IBaseService;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

import javax.annotation.Resource;


/**
 * @Author xw
 * @Description 实现泛型父类
 * @Date 2021/4/13  10:49
 */
public class BaseController<T, K> extends AbstractController<T, K> {

    @Autowired
    private IBaseService<T, K,Object> baseService;

    @PostMapping("/addJson")
    @ApiOperation(value = "新增",notes = "公用方法")
    @Override
    public int addJson(@RequestBody T t) {
        return baseService.save(t);
    }

    @PostMapping("/updateJson")
    @ApiOperation(value = "修改",notes = "公用方法")
    @Override
    public int updateJson(@RequestBody T t) {
        return baseService.updateByPrimaryKeySelective(t);
    }

    @GetMapping("/delJson")
    @ApiOperation(value = "删除",notes = "公用方法")
    @Override
    public int delJson(K id) {
        return baseService.deleteByPrimaryKey(id);
    }
}

截止,我们的方法已经写完,接下来我们只需要去继承Base类,就可以免去我们经常写重复代码的烦恼……

eg:

@RestController
@RequestMapping(Common.PATH_URL+"/user")
//Api注解,描述信息 可通过tag进行分类
@Api(value = "UserController", description = "关于用户管理信息接口")
public class UserController extends BaseController<TUser,String> {
    @Autowired
    private IUserService userService;
  }




public interface IUserService extends IBaseService<TUser,String,Object> {}



**
 * @Author xw
 * @Description 用户实现类
 * @Date 2021/4/9  14:08
 */
@Slf4j
@Service
public class UserServiceImpl  extends BaseServiceImpl<TUser,String,Object> implements IUserService {

    @Resource
    private UserMapper userMapper;
    @Override
    protected BaseMapper<TUser> getBaseMapper() {
        return userMapper;
    }
  }


@Mapper
public interface UserMapper extends BaseMapper<TUser> {}

注意事项:

1.tk.mybatis.mapper.common.Mapper 的导包与org.apache.ibatis.annotations.Mapper导包不要搞混淆

2.tk.mybatis.mapper.common.Mapper不要被启动类@MapperScan(“com.xx.xx.mapper”)扫描到,不然会报错。

3.如果项目中需逻辑进行判断,可直接重写base里面的方法进行需求开发

4.项目针对需求开发,可进行扩展

结果:启动项目后,可直接在user下访问到增删改接口,经测试没问题!

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • SpringBoot thymeleaf的使用方法解析

    SpringBoot thymeleaf的使用方法解析

    这篇文章主要介绍了SpringBoot thymeleaf的使用方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03
  • java ThreadPoolExecutor 并发调用实例详解

    java ThreadPoolExecutor 并发调用实例详解

    这篇文章主要介绍了java ThreadPoolExecutor 并发调用实例详解的相关资料,需要的朋友可以参考下
    2017-05-05
  • Java如何提供给第三方使用接口方法详解

    Java如何提供给第三方使用接口方法详解

    最近在做一个项目,因一些机制问题,需要我用java代码调用第三方接口,下面这篇文章主要给大家介绍了关于Java如何提供给第三方使用接口方法的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-08-08
  • JavaWeb-WebSocket浏览器服务器双向通信方式

    JavaWeb-WebSocket浏览器服务器双向通信方式

    文章介绍了WebSocket协议的工作原理和应用场景,包括与HTTP的对比,接着,详细介绍了如何在Java中使用WebSocket,包括配置类、服务编写和前端页面的实现
    2025-02-02
  • java使用zookeeper实现的分布式锁示例

    java使用zookeeper实现的分布式锁示例

    这篇文章主要介绍了java使用zookeeper实现的分布式锁示例,需要的朋友可以参考下
    2014-05-05
  • 详解非spring框架下使用querydsl的方法

    详解非spring框架下使用querydsl的方法

    Querydsl是一个采用API代替拼凑字符串来构造查询语句,可跟 Hibernate 和 JPA 等框架结合使用。本文介绍的是非spring环境下querydsl JPA整合使用,感兴趣的小伙伴们可以参考一下
    2019-01-01
  • Spring Cloud Config 使用本地配置文件方式

    Spring Cloud Config 使用本地配置文件方式

    这篇文章主要介绍了Spring Cloud Config 使用本地配置文件方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • JAVA IDEA项目打包为jar包的步骤详解

    JAVA IDEA项目打包为jar包的步骤详解

    在Java开发中我们通常会将我们的项目打包成可执行的Jar包,以便于在其他环境中部署和运行,下面这篇文章主要给大家介绍了关于JAVA IDEA项目打包为jar包的相关资料,需要的朋友可以参考下
    2024-08-08
  • Java实现班级管理系统

    Java实现班级管理系统

    这篇文章主要为大家详细介绍了Java实现班级管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • Java实现月饼的制作、下单和售卖功能

    Java实现月饼的制作、下单和售卖功能

    这篇文章主要介绍了Java实现月饼的制作、下单和售卖,借此机会,我们用Lambda实现一遍月饼制作,下单,售卖的开发设计模式,主要有制作月饼的工厂模式,结合实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2022-09-09

最新评论