在现代 Java 开发中,我们常常需要处理各种通用的功能和需求,诸如枚举的处理、JSON 数据处理,以及分页查询等。这些功能虽然看似简单,但在实际开发中往往涉及到许多细节和优化。为了提高开发效率、减少重复代码的编写,我们通常会通过封装和抽象这些功能,形成易于复用和维护的工具类或组件。
目录
前言
在现代 Java 开发中,我们常常需要处理各种通用的功能和需求,诸如枚举的处理、JSON 数据处理,以及分页查询等。这些功能虽然看似简单,但在实际开发中往往涉及到许多细节和优化。为了提高开发效率、减少重复代码的编写,我们通常会通过封装和抽象这些功能,形成易于复用和维护的工具类或组件。
枚举处理器
User类中有一个用户状态字段:
            
            
              java
              
              
            
          
              /**
     * 详细信息
     */
    private String info;
    /**
     * 使用状态(1正常 2冻结)
     */
    private Integer status;
        
第一种方式可读性太差,需自己知道哪一个数字对应的是什么状态,既然有对应的枚举类UserStatus,直接使用UserStatus类来代替Integer即可。

此时,数据库中的status还是int整型。此时,就存在一个java中的枚举类型和数据库中的整型的转换问题。

Mybatis的底层帮我们解决这个问题。

在application.yml中配置全局枚举处理器:
            
            
              java
              
              
            
          
          mybatis-plus:
 configuration:
   default-enum-type-handler:   com,baomidou,mybatisplus.core.handlers.MybatisEnumTypeHandler
        详情也可点击该链接(https://baomidou.com/guides/auto-convert-enum/)
UserStatus枚举类
            
            
              java
              
              
            
          
          package com.itheima.mp.enums;
import com.baomidou.mybatisplus.annotation.EnumValue;
import lombok.Getter;
@Getter
public enum UserStatus {
    NORMAL(1,"正常"),
    FROZEN(2,"冻结"),
    ;
    @EnumValue
    private final int value;
    private final String desc;
    UserStatus(int value, String desc) {
        this.value = value;
        this.desc = desc;
    }
}
        
当我们测试时,返回的status是NORMAL。
如果我们想指定返回的数据,那么就需要使用到@JsonValue注解


JSON处理器
数据库中user表中有一个json类型的字段:


Java中一般通过String字符串进行接收

如果想要信息中的一个信息比如年龄,我们可以通过一个类,将各种信息封装到里面。

但是我们的mybatis没有能力自己进行将json类型和对象做转换,此时我们就可以用自定义的类型处理器,Mybatis-Plus提供了这样的自定义类型处理器。

@TableField(typeHandler = JacksonTypeHandler.class)只是让自定义适配器生效;同时@TableName(value = "user",autoResultMap = true)开启自动结果集映射。
        UserInfo类
            
            
              java
              
              
            
          
          package com.itheima.mp.domain.po;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
//静态方法
@AllArgsConstructor(staticName = "of")
public class UserInfo {
    private Integer age;
    private String intro;
    private String gender;
}
        User类
            
            
              java
              
              
            
          
          @TableName(value = "user",autoResultMap = true)
public class User  {
    /**
     * 详细信息
     */
    @TableField(typeHandler = JacksonTypeHandler.class)
    private UserInfo info;
}
        
插件功能
MybatisPlus提供的内置拦截器有下面这些:

分页插件
首先,要在配置类中注册MyBatisPlus的核心插件,同时添加分页插件:
            
            
              java
              
              
            
          
          package com.itheima.mp.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 MybatisConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        //1.创建分页插件
        PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
        //设置最大查询记录
        paginationInnerInterceptor.setMaxLimit(1000L);
        //2.添加分页插件
        interceptor.addInnerInterceptor(paginationInnerInterceptor);
        return interceptor;
    }
}
        接着,就可以使用分页的API:

 测试
            
            
              java
              
              
            
          
              @Test
    void testPageQuery(){
        int pageNo = 1;
        int pageSize = 2;
        //准备分页条件
        Page<User> page = Page.of(pageNo, pageSize);
        //排序条件
        page.addOrder(new OrderItem("balance",true));
        page.addOrder(new OrderItem("id",true));
        //分页查询
        Page<User> p = userService.page(page);
        //总条数
        long total = p.getTotal();
        System.out.println("total = "+total);
        //总页数
        long pages = p.getPages();
        System.out.println("pages = "+pages);
        //分页的总数居
        List<User> users = p.getRecords();
        users.forEach(System.out::println);
    }
        
通用分页实体
需求:实现User的分页查询


PageQuery类
            
            
              java
              
              
            
          
          package com.itheima.mp.query;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel(description = "分页查询实体")
public class PageQuery {
    @ApiModelProperty("页码")
    private Integer pageNo;
    @ApiModelProperty("页大小")
    private Integer pageSize;
    @ApiModelProperty("排序字段")
    private String sortBy;
    @ApiModelProperty("是否升序")
    private boolean isAsc;
}
        UserQuery类
            
            
              java
              
              
            
          
          package com.itheima.mp.query;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel(description = "用户查询条件实体")
public class UserQuery extends PageQuery {
    @ApiModelProperty("用户名关键字")
    private String name;
    @ApiModelProperty("用户状态:1-正常,2-冻结")
    private Integer status;
    @ApiModelProperty("余额最小值")
    private Integer minBalance;
    @ApiModelProperty("余额最大值")
    private Integer maxBalance;
}
        PageDTO类
            
            
              java
              
              
            
          
          package com.itheima.mp.domain.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
@Data
@ApiModel(description = "分页结果")
public class PageDTO {
    @ApiModelProperty("总条数")
    private Long total;
    @ApiModelProperty("总条数")
    private Long pages;
    @ApiModelProperty("集合")
    private List<?> list;
}
        IUserService接口
            
            
              java
              
              
            
          
           PageDTO queryUsersPage(UserQuery query);
        UserServiceImpl实现类
            
            
              java
              
              
            
          
              @Override
    public PageDTO queryUsersPage(UserQuery query) {
        String name = query.getName();
        Integer status = query.getStatus();
        //构建查询条件
        Page<User> page = Page.of(query.getPageNo(), query.getPageSize());
        //排序条件
        if(query.getSortBy()!=null){
            page.addOrder(new OrderItem(query.getSortBy(),query.isAsc()));
        }else {
            page.addOrder(new OrderItem("update_time",false));
        }
        //分页查询
        Page<User> p = lambdaQuery()
                .like(name != null, User::getUsername, name)
                .eq(status != null, User::getStatus, status)
                .page(page);
        //封装VO结果
        PageDTO pageDTO = new PageDTO();
        //总条数
        pageDTO.setTotal(p.getTotal());
        //总页数
        pageDTO.setPages(p.getPages());
        //当前页数据
        List<User> records = p.getRecords();
        if(CollUtil.isEmpty(records)){
            pageDTO.setList(Collections.emptyList());
            return pageDTO;
        }
        //拷贝userVO
        List<UserVO> userVOS = BeanUtil.copyToList(records, UserVO.class);
        pageDTO.setList(userVOS);
        //返回
        return pageDTO;
    }
        
需求:
- 在PageQuery中定义方法,将PageQuery对象转为MyBatisPlus中的Page对象
 - 在PageDTO中定义方法,将MyBatisPlus中的Page结果转为PageDTO结果
 
PageQuery类
            
            
              java
              
              
            
          
          package com.itheima.mp.domain.query;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.mp.domain.po.User;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel(description = "分页查询实体")
public class PageQuery {
    @ApiModelProperty("页码")
    private Integer pageNo = 1;
    @ApiModelProperty("页大小")
    private Integer pageSize = 5;
    @ApiModelProperty("排序字段")
    private String sortBy;
    @ApiModelProperty("是否升序")
    private boolean isAsc = true;
    public <T> Page<T> ToMpPage(OrderItem ... ithems) {
        Page<T> page = Page.of(pageNo, pageSize);
        //排序条件
        if(sortBy != null){
            page.addOrder(new OrderItem(sortBy,isAsc));
        }else if(ithems != null){
            //为空,默认排序
            page.addOrder(ithems);
        }
        return page;
    }
    public <T> Page<T> ToMpPageDefaultSortByCreateTime() {
        return ToMpPage(new OrderItem("create_time",false));
    }
    public <T> Page<T> ToMpPageDefaultSortByUpdateTime() {
        return ToMpPage(new OrderItem("update_time",false));
    }
    public <T> Page<T> ToMpPage(String sortBy,boolean defaultAsc) {
        return ToMpPage(new OrderItem(sortBy,defaultAsc));
    }
}
        PageDTO类
            
            
              java
              
              
            
          
          package com.itheima.mp.domain.dto;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.mp.domain.po.User;
import com.itheima.mp.domain.vo.UserVO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Collections;
import java.util.List;
@Data
@ApiModel(description = "分页结果")
public class PageDTO {
    @ApiModelProperty("总条数")
    private Long total;
    @ApiModelProperty("总条数")
    private Long pages;
    @ApiModelProperty("集合")
    private List<?> list;
    public static <PO,VO>  PageDTO of(Page<PO> p,Class<VO> clazz) {
        //封装VO结果
        PageDTO pageDTO = new PageDTO();
        //总条数
        pageDTO.setTotal(p.getTotal());
        //总页数
        pageDTO.setPages(p.getPages());
        //当前页数据
        List<PO> records = p.getRecords();
        if(CollUtil.isEmpty(records)){
            pageDTO.setList(Collections.emptyList());
            return pageDTO;
        }
        //拷贝userVO
        List<VO> userVOS = BeanUtil.copyToList(records,clazz);
        pageDTO.setList(userVOS);
        //返回
        return pageDTO;
    }
}
        总结
这篇博客中,我们详细介绍了如何实现并优化三个常见的功能处理器:枚举处理器、JSON 处理器和分页插件。
这些技术的合理封装和应用,不仅能让我们的代码更加高效、简洁,还能有效地提升系统的可维护性。在实际开发过程中,遇到类似需求时,我们可以借助这些封装好的工具,避免重复劳动,专注于业务逻辑的实现。
希望通过本篇博客,能为你在开发中处理枚举、JSON 和分页等功能提供一些实用的思路与技术方案。如果你有任何问题或建议,欢迎留言讨论,我们一起探索更好的开发方式。