实现思路
- 分层封装:按 Entity、Mapper、Service、Controller 四层分别封装通用基类
- 泛型约束:全程使用泛型 T 约束实体类型,保证类型安全
- 通用能力:封装增删改查、分页、条件查询等核心操作,业务层只需继承即可使用
- 标准化接口:提供 RESTful 风格的通用接口,业务 Controller 直接继承即可对外暴露接口
完整代码实现
必要依赖(Maven):
<!-- MyBatis-Plus --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3.1</version></dependency><!-- Lombok(简化实体类编写) --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!-- Web依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>配置 MyBatis-Plus 分页插件(同前文)。
1. 通用实体基类(BaseEntity)
importcom.baomidou.mybatisplus.annotation.IdType;importcom.baomidou.mybatisplus.annotation.TableId;importcom.baomidou.mybatisplus.annotation.TableLogic;importlombok.Data;importjava.io.Serializable;importjava.time.LocalDateTime;/** * 所有实体类的基类,封装通用字段 * @param <ID> 主键类型 */@DatapublicclassBaseEntity<IDextendsSerializable>implementsSerializable{privatestaticfinallongserialVersionUID=1L;/** * 主键ID */@TableId(type=IdType.AUTO)privateIDid;/** * 创建时间 */privateLocalDateTimecreateTime;/** * 更新时间 */privateLocalDateTimeupdateTime;/** * 逻辑删除标识(0-未删除,1-已删除) */@TableLogicprivateIntegerisDeleted;}2. 通用 Mapper 基类(BaseMapper)
importcom.baomidou.mybatisplus.core.mapper.BaseMapper;importorg.apache.ibatis.annotations.Param;importjava.io.Serializable;importjava.util.List;/** * 通用Mapper基类,继承MyBatis-Plus的BaseMapper并扩展通用方法 * @param <T> 实体类型 */publicinterfaceBaseMapper<TextendsBaseEntity<?>>extendscom.baomidou.mybatisplus.core.mapper.BaseMapper<T>{/** * 批量插入(自定义,可选) */intinsertBatch(@Param("list")List<T>list);}3. 通用 Service 接口(IBaseService)
importcom.baomidou.mybatisplus.core.conditions.Wrapper;importcom.baomidou.mybatisplus.core.metadata.IPage;importcom.baomidou.mybatisplus.extension.service.IService;importjava.io.Serializable;importjava.util.List;/** * 通用Service接口 * @param <T> 实体类型 */publicinterfaceIBaseService<TextendsBaseEntity<?>>extendsIService<T>{// 新增booleanadd(Tentity);booleanaddBatch(List<T>entityList);// 删除booleandeleteById(Serializableid);booleandeleteBatchByIds(List<?extendsSerializable>ids);booleandelete(Wrapper<T>queryWrapper);// 更新booleanupdate(Tentity);booleanupdate(Tentity,Wrapper<T>updateWrapper);// 查询TgetById(Serializableid);List<T>listAll();List<T>list(Wrapper<T>queryWrapper);IPage<T>pageList(IntegerpageNum,IntegerpageSize);IPage<T>pageList(IntegerpageNum,IntegerpageSize,Wrapper<T>queryWrapper);TgetOne(Wrapper<T>queryWrapper);longcount(Wrapper<T>queryWrapper);}4. 通用 Service 实现类(BaseServiceImpl)
importcom.baomidou.mybatisplus.core.conditions.Wrapper;importcom.baomidou.mybatisplus.core.metadata.IPage;importcom.baomidou.mybatisplus.core.toolkit.Wrappers;importcom.baomidou.mybatisplus.extension.plugins.pagination.Page;importcom.baomidou.mybatisplus.extension.service.impl.ServiceImpl;importorg.springframework.stereotype.Service;importjava.io.Serializable;importjava.util.List;/** * 通用Service实现类 * @param <M> Mapper类型 * @param <T> 实体类型 */@ServicepublicclassBaseServiceImpl<MextendsBaseMapper<T>,TextendsBaseEntity<?>>extendsServiceImpl<M,T>implementsIBaseService<T>{@Overridepublicbooleanadd(Tentity){returnsave(entity);}@OverridepublicbooleanaddBatch(List<T>entityList){returnsaveBatch(entityList);}@OverridepublicbooleandeleteById(Serializableid){returnremoveById(id);}@OverridepublicbooleandeleteBatchByIds(List<?extendsSerializable>ids){returnremoveByIds(ids);}@Overridepublicbooleandelete(Wrapper<T>queryWrapper){returnremove(queryWrapper);}@Overridepublicbooleanupdate(Tentity){returnupdateById(entity);}@Overridepublicbooleanupdate(Tentity,Wrapper<T>updateWrapper){returnupdate(entity,updateWrapper);}@OverridepublicTgetById(Serializableid){returngetBaseMapper().selectById(id);}@OverridepublicList<T>listAll(){returnlist(Wrappers.emptyWrapper());}@OverridepublicList<T>list(Wrapper<T>queryWrapper){returnsuper.list(queryWrapper);}@OverridepublicIPage<T>pageList(IntegerpageNum,IntegerpageSize){Page<T>page=newPage<>(pageNum,pageSize);returnpage(page,Wrappers.emptyWrapper());}@OverridepublicIPage<T>pageList(IntegerpageNum,IntegerpageSize,Wrapper<T>queryWrapper){Page<T>page=newPage<>(pageNum,pageSize);returnpage(page,queryWrapper);}@OverridepublicTgetOne(Wrapper<T>queryWrapper){returngetOne(queryWrapper,false);}@Overridepubliclongcount(Wrapper<T>queryWrapper){returnsuper.count(queryWrapper);}}5. 通用 Controller 基类(BaseController)
importcom.baomidou.mybatisplus.core.conditions.Wrapper;importcom.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;importcom.baomidou.mybatisplus.core.metadata.IPage;importcom.baomidou.mybatisplus.core.toolkit.Wrappers;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.web.bind.annotation.*;importjava.io.Serializable;importjava.util.List;/** * 通用Controller基类,提供RESTful风格的通用接口 * @param <T> 实体类型 * @param <S> Service类型 */publicabstractclassBaseController<TextendsBaseEntity<?>,SextendsIBaseService<T>>{@AutowiredprotectedSservice;/** * 新增 */@PostMapping("/add")publicbooleanadd(@RequestBodyTentity){returnservice.add(entity);}/** * 批量新增 */@PostMapping("/add/batch")publicbooleanaddBatch(@RequestBodyList<T>entityList){returnservice.addBatch(entityList);}/** * 根据ID删除 */@DeleteMapping("/{id}")publicbooleandeleteById(@PathVariableSerializableid){returnservice.deleteById(id);}/** * 批量删除 */@DeleteMapping("/batch")publicbooleandeleteBatchByIds(@RequestParamList<?extendsSerializable>ids){returnservice.deleteBatchByIds(ids);}/** * 更新 */@PutMapping("/update")publicbooleanupdate(@RequestBodyTentity){returnservice.update(entity);}/** * 根据ID查询 */@GetMapping("/{id}")publicTgetById(@PathVariableSerializableid){returnservice.getById(id);}/** * 查询所有 */@GetMapping("/list")publicList<T>listAll(){returnservice.listAll();}/** * 分页查询 */@GetMapping("/page")publicIPage<T>pageList(@RequestParamIntegerpageNum,@RequestParamIntegerpageSize){returnservice.pageList(pageNum,pageSize);}/** * 条件查询(示例:根据字段名和值查询) */@GetMapping("/list/condition")publicList<T>listByCondition(@RequestParamStringfieldName,@RequestParamStringvalue){LambdaQueryWrapper<T>wrapper=Wrappers.lambdaQuery();// 通用条件查询示例,实际可根据业务扩展wrapper.eq(true,fieldName,value);returnservice.list(wrapper);}/** * 条件分页查询 */@GetMapping("/page/condition")publicIPage<T>pageListByCondition(@RequestParamIntegerpageNum,@RequestParamIntegerpageSize,@RequestParamStringfieldName,@RequestParamStringvalue){LambdaQueryWrapper<T>wrapper=Wrappers.lambdaQuery();wrapper.eq(true,fieldName,value);returnservice.pageList(pageNum,pageSize,wrapper);}}业务层使用示例
1. 业务实体类(User)
importlombok.Data;importlombok.EqualsAndHashCode;/** * 用户实体类 */@Data@EqualsAndHashCode(callSuper=true)publicclassUserextendsBaseEntity<Long>{/** * 用户名 */privateStringuserName;/** * 密码 */privateStringpassword;/** * 手机号 */privateStringphone;/** * 邮箱 */privateStringemail;}2. 业务 Mapper(UserMapper)
/** * 用户Mapper */publicinterfaceUserMapperextendsBaseMapper<User>{// 无需编写基础CRUD方法,直接继承即可}3. 业务 Service 接口(IUserService)
/** * 用户Service接口 */publicinterfaceIUserServiceextendsIBaseService<User>{// 可扩展自定义业务方法UsergetUserByUserName(StringuserName);}4. 业务 Service 实现类(UserServiceImpl)
importorg.springframework.stereotype.Service;/** * 用户Service实现类 */@ServicepublicclassUserServiceImplextendsBaseServiceImpl<UserMapper,User>implementsIUserService{@OverridepublicUsergetUserByUserName(StringuserName){returngetOne(Wrappers.<User>lambdaQuery().eq(User::getUserName,userName));}}5. 业务 Controller(UserController)
importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.bind.annotation.RestController;/** * 用户Controller */@RestController@RequestMapping("/user")publicclassUserControllerextendsBaseController<User,IUserService>{// 无需编写基础接口,直接继承即可// 可扩展自定义接口@GetMapping("/name/{userName}")publicUsergetUserByUserName(@PathVariableStringuserName){returnservice.getUserByUserName(userName);}}总结
- 整套封装基于泛型 T 实现了从 Entity 到 Controller 的全层通用化,所有业务模块只需继承对应基类即可拥有完整的基础 CRUD 能力。
- BaseEntity 封装了通用字段(ID、创建时间、更新时间、逻辑删除),避免各实体重复定义;BaseController 提供了标准化的 RESTful 接口,无需重复编写。
- 保留了扩展能力,业务层可在继承基类的基础上,灵活扩展自定义的业务方法和接口。