mybatis-plus 的一種很彆扭的用法

熟悉 mybatis-plus 的人都知道,mybatis-plus 提供兩種包含預約義增刪改查操做的接口:java

  • com.baomidou.mybatisplus.core.mapper.BaseMapper
  • com.baomidou.mybatisplus.extension.service.IService

對比這兩個接口,操做都差很少,名字有一點點改變,好比 BaseMapper 裏面叫 insert() 的方法,在 IService 裏面叫 save()。數據庫

其實我也不是很清楚爲何要單獨設計 IService 接口,可是二者確實有區別,就是 IService 提供批處理操做,BaseMapper 沒有。mybatis

另外,IService 的默認實現 com.baomidou.mybatisplus.extension.service.impl.ServiceImpl 就是調用 BaseMapper 來操做數據庫,因此我猜 IService 是 Java 8 以前對 BaseMapper 所作的擴展,而 Java 8 以後,由於有了 default 方法,ServiceImpl 裏面的東西其實均可以移到 BaseMapper 裏面了。app

除此以外還有就是 IService 依賴於 Spring 容器,而 BaseMapper 不依賴;BaseMapper 能夠繼承並添加新的數據庫操做,IService 要擴展的話仍是得調用 Mapper,顯得有些畫蛇添足。this

因此,若是你既要使用批處理操做,又要添加本身的數據庫操做,那就必須兩個接口一塊兒用。設計

好比在下面一個示例項目中,就同時存在二者:code

// StudentService.java
@Service
public class StudentService extends ServiceImpl<StudentMapper, Student> {
}

// StudentMapper.java
@Component
public interface StudentMapper extends BaseMapper<Student> {

    @Select("select * from STUDENT where FIRST_NAME=#{firstName}")
    List<Student> selectByFirstName(@Param("firstName") String firstName);
}

這樣每一個實體都要建立兩個文件,很麻煩。可不能夠簡化呢?能夠,就像下面這樣:對象

// StudentService.java
@Service
public class StudentService extends ServiceImpl<StudentMapper, Student> {

    public interface StudentMapper extends BaseMapper<Student> {

        @Select("select * from STUDENT where FIRST_NAME=#{firstName}")
        List<Student> selectByFirstName(@Param("firstName") String firstName);
    }
}

對,你沒看錯,就把 Mapper 直接寫在 Service 裏面就好。有人就會問了,這個 Mapper 能用嗎?告訴你,能:繼承

@Autowired
StudentService.StudentMapper studentMapper;

像上面這樣引用過來,照常使用便可。接口

另外還有一種方式就是經過 Service 把 Mapper 暴露出來:

public class StudentService extends ServiceImpl<StudentMapper, Student> {
    
    public StudentMapper getMapper() {
        return this.baseMapper;
    }
    
    ...

這個 baseMapper 也是 StudentMapper 的實例。這樣的話,使用的時候就只須要引用 StudentService 一個對象了:

List list = studentService.getMapper().selectByFirstName("First");
相關文章
相關標籤/搜索