如何使用Mybatis-Plus

Mybatis-Puls (下文简称MP)

如何在SpringBoot中使用

1、首先,引入相关的依赖

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.1</version>
        </dependency>

2、在application.yml文件配置MP的相关属性

mybatis-plus:
  configuration:
    # 在映射实体或者属性时,将数据库中表名和字段名中的下划线去掉,按照驼峰命名法映射
    # 举两个栗子 表名:address_book -->实体类名: AddressBook	字段名:user_name --> 属性名:userName
    map-underscore-to-camel-case: true
    # 开启控制台SQL日志打印
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  global-config:
    db-config:
    # 指定主键生成策略 assign_id 采用雪花算法
      id-type: assign_id
如何使用MP的CRUD

mapper层

  1. 继承MP提供的 BaseMapper<T> 类,并指定泛型

    @Mapper
    public interface EmployeeMapper extends BaseMapper<Employee> {
    
    }
    

service接口层

  1. 继承MP提供的 IService<T> 接口,并指定泛型

    public interface EmployeeService extends IService<Employee> {
        
    }
    

service实现类层

  1. 继承MP提供的 ServiceImpl<M, T>,指定泛型,实现 service 接口

    @Service
    public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper, Employee> implements EmployeeService {
        
    }
    

    需要指定两个泛型,第一个是Mapper,第二个是实体类

如何使用MP的分页插件
  1. 先搞一个配置类
/**
 * @author JUNHAO
 * 配置Mybatis-Plus分页插件
 */
@Configuration
public class MybatisPlusConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}
MP 公共字段自动填充如何实现

在很多场景下,我们需要对某些字段经常的进行填充,比如,员工信息的更新时间、修改时间,也就是在插入或者更新的时候为指定字段赋予指定的值,使用它的好处就是可以统一对这些字段进行处理,避免了重复代码

实现步骤:

  1. 为需要自动填充的公共字段添加@TableField注解,指定自动填充的策略

        /**
         * 员工创建时间
         */
        @TableField(fill = FieldFill.INSERT) // 插入时填充字段
        private LocalDateTime createTime;
        /**
         * 员工信息更新时间
         */
        @TableField(fill = FieldFill.INSERT_UPDATE) // 插入和更新时填充字段
        private LocalDateTime updateTime;
        /**
         * 创建人
         */
        @TableField(fill = FieldFill.INSERT) //插入时填充字段
        private Long createUser;
        /**
         * 更新人
         */
        @TableField(fill = FieldFill.INSERT_UPDATE) // 插入和更新时填充字段
        private Long updateUser;
    

在这里插入图片描述

  1. 创建一个类,类名叫什么不重要,关键是要实现MetaObjectHandler接口,并实现它的两个方法

    /**
     * @author JUNHAO
     * 自定义元数据对象处理器
     */
    @Component
    @Slf4j
    public class MyMetaObjectHandler implements MetaObjectHandler {
        /**
         * 插入操作自动填充
         * @param metaObject
         */
        @Override
        public void insertFill(MetaObject metaObject) {
            metaObject.setValue("createTime", LocalDateTime.now());
            metaObject.setValue("updateTime", LocalDateTime.now());
            metaObject.setValue("createUser", new Long(1));
            metaObject.setValue("updateUser", new Long(1));
    
        }
    
        /**
         * 更新操作自动填充
         * @param metaObject
         */
        @Override
        public void updateFill(MetaObject metaObject) {
            metaObject.setValue("updateTime", LocalDateTime.now());
            metaObject.setValue("updateUser", new Long(1));
        }
    }
    

    出现了一个问题,我们需要填充更新人的id和创建人的id,但是我们又无法通过request去拿session中的数据,这个时候怎么办呢,且看下文。

    接上文,我们可以借助ThreadLocal来获取当前登陆用户的id

    什么是ThreadLocal

    ThreadLocal并不是一个Thread,而是Thread的局部变量。当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其他线程所对应地副本。

    ThreadLocal为每个线程提供单独一份存储空间,具有线程隔离地效果,只有在线程内才能获取到对应的值,线程外则不能访问。

    ThreadLocal常用方法:

    • public void set(T value) 设置当前线程地线程局部变量的值
    • public T get() 返回当前线程所对应的线程局部变量的值

    1、创建一个类BaseContext

    /**
     * @author JUNHAO
     * 基于ThreadLocal封装工具类,用户保存和获取当前登陆的id
     */
    public class BaseContext {
        private static ThreadLocal<Long> threadLocal = new ThreadLocal<>();
    
        /**
         * 设置值
         * @param id
         */
        public static void setCurrentId(Long id) {
            threadLocal.set(id);
        }
    
        /**
         * 获取值
         * @return
         */
        public static Long getCurrentId() {
            return threadLocal.get();
        }
    }
    

    2、在可以获取到用户id的方法中调用我们封装的工具类将用户id放入ThreadLocal

    // ...
    Long empId = (Long) request.getSession().getAttribute("employee");
    BaseContext.setCurrentId(empId);
    // ...
    

    3、在需要获取用户id的地方调用获取id的方法

    /**
     * @author JUNHAO
     * 自定义元数据对象处理器
     */
    @Component
    @Slf4j
    public class MyMetaObjectHandler implements MetaObjectHandler {
        /**
         * 插入操作自动填充
         * @param metaObject
         */
        @Override
        public void insertFill(MetaObject metaObject) {
            metaObject.setValue("createTime", LocalDateTime.now());
            metaObject.setValue("updateTime", LocalDateTime.now());
            metaObject.setValue("createUser", BaseContext.getCurrentId());
            metaObject.setValue("updateUser", BaseContext.getCurrentId());
    
        }
    
        /**
         * 更新操作自动填充
         * @param metaObject
         */
        @Override
        public void updateFill(MetaObject metaObject) {
            log.info("当前线程id{}", Thread.currentThread().getId());
            metaObject.setValue("updateTime", LocalDateTime.now());
            metaObject.setValue("updateUser", BaseContext.getCurrentId());
        }
    }
    

    问题解决


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

oah1021

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值