一文MyBatis-Plus快速入門

一、依賴及配置

使用下面的SQL創建數據庫與添加數據

DROP TABLE IF EXISTS user;

CREATE TABLE user
(
    id BIGINT(20) NOT NULL COMMENT '主鍵ID',
    name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
    age INT(11) NULL DEFAULT NULL COMMENT '年齡',
    email VARCHAR(50) NULL DEFAULT NULL COMMENT '郵箱',
    PRIMARY KEY (id)
);

DELETE FROM user;

INSERT INTO user (id, name, age, email) VALUES
(1, 'Jone', 18, '[email protected]'),
(2, 'Jack', 20, '[email protected]'),
(3, 'Tom', 28, '[email protected]'),
(4, 'Sandy', 21, '[email protected]'),
(5, 'Billie', 24, '[email protected]');

1、在idea中創建一個SpringBoot項目,在pom.xml中添需要的依賴

添加MyBatis-Plus、mysql連接驅動、lombok的依賴

<dependency>
    <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.0.5</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
</dependencies>

2、配置數據庫連接

application.yml

spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mp
    username: root
    password: 1234

3、在啓動類中添加註解 ==@MapperScan== 掃描Mapper接口包

@SpringBootApplication
@MapperScan("com.jikedaquan.study.mp.mapper")
public class MpApplication {

    public static void main(String[] args) {
        SpringApplication.run(MpApplication.class, args);
    }

}

4、編寫實體類,使用lombok

@Data
public class User {
    private Long id;
    private String name;
    private Integer age;
    private String email;
}

5、編寫UserMapper接口

UserMapper接口繼承MyBatis-Plus提供的BaseMapper接口即可擁有CRUD的方法,泛型中填寫操作的實體類,這裏爲User

public interface UserMapper extends BaseMapper<User> {
}

6、測試查詢數據

@RunWith(SpringRunner.class)
@SpringBootTest
public class MpApplicationTests {
    @Autowired
    private UserMapper userMapper;
    @Test
    public void contextLoads() {
        List<User> userList = userMapper.selectList(null);//條件爲null時查詢所有數據
        userList.forEach(System.out::println);
    }
}

二、日誌配置

配置日誌到控制檯輸出

mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

三、主鍵生成策略

MyBatis-Plus提供了多種主鍵生成策略以應對不同的場景

策略 說明
AUTO 數據庫ID自增
NONE 該類型爲未設置主鍵類型
INPUT 用戶輸入ID,該類型可以通過自己註冊自動填充插件進行填充
ID_WORKER 全局唯一ID (idWorker)
UUID 全局唯一ID (UUID)
ID_WORKER_STR 字符串全局唯一ID (idWorker 的字符串表示)

1、註解控制主鍵生成策略

在實體類的主鍵字段上添加註解(自增時注意配合數據庫設置)

@Data
public class User {
    @TableId(type = IdType.AUTO)
    private Long id;
    private String name;
    private Integer age;
    private String email;
}

2、全局配置控制主鍵生成策略

application.yml

mybatis-plus:
  global-config:
    db-config:
      id-type: id_worker

四、自動填充

在常用業務中有些屬性需要配置一些默認值,MyBatis-Plus提供了實現此功能的插件。在這裏修改user表添加 create_time 字段和 update_time 字段,在User類中添加對應屬性。

1、爲需要自動填充的屬性添加註解 ==@TableField==

提供了4種自動填充策略:DEFAULT,默認不處理。INSERT,插入填充字段。UPDATE,更新填充字段。INSERT_UPDATE,插入和更新填充字段。

@Data
public class User {
    private Long id;
    private String name;
    private Integer age;
    private String email;

    @TableField(fill = FieldFill.INSERT)
    private Date createTime;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;
}

2、實現字段填充控制器,編寫自定義填充規則

實現 MetaObjectHandler 接口,實現 insertFill 和 updateFill 方法,此處的 create_timeupdate_time字段需要插入時填充值, 只有 update_time 字段在修改時需要填充,所以策略如下。

//需要將自定義填充控制器註冊爲組件
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    private static final Logger LOGGER= LoggerFactory.getLogger(MyMetaObjectHandler.class);

    //insert操作時要填充的字段
    @Override
    public void insertFill(MetaObject metaObject) {
        LOGGER.info("start insert fill ...");
        //根據屬性名字設置要填充的值
        this.setFieldValByName("createTime",new Date(),metaObject);
        this.setFieldValByName("updateTime",new Date(),metaObject);
    }

    //update操作時要填充的字段
    @Override
    public void updateFill(MetaObject metaObject) {
        LOGGER.info("start insert fill ...");
        this.setFieldValByName("updateTime",new Date(),metaObject);
    }
}

3、插入數據測試

@RunWith(SpringRunner.class)
@SpringBootTest
public class CRUDTest {
    @Autowired
    private UserMapper userMapper;

    @Test
    public void testInsert(){
        User user = new User();
        user.setName("jack11");
        user.setAge(20);
        user.setEmail("[email protected]");

        int result= userMapper.insert(user);
        System.out.println(result);
        System.out.println(user);
    } 
}

4、修改數據測試

@Test
public void testUpdate(){
    User user = new User();
    user.setId(2L);
    user.setName("Jackie");
    int result = userMapper.updateById(user);
    System.out.println(result);
}

一次插入數據後,create_timeupdate_time都被填充了設置的時間,做update操作後只有update_time的進行了填充修改。

五、樂觀鎖插件

樂觀鎖的核心原理就是提交版本必須等於記錄當前版本才能執行更新

意圖:

  • 當要更新一條記錄的時候,希望這條記錄沒有被別人更新

樂觀鎖實現方式:

  • 取出記錄時,獲取當前version
  • 更新時,帶上這個version
  • 執行更新時, set version = newVersion where version = oldVersion
  • 如果version不對,就更新失敗

1、添加version到表和類中,爲屬性添加 ==@Version== 註解

@Version
private Integer version;

2、配置插件

@Configuration
public class MyBatisPlusConfig {

    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor(){
        return new OptimisticLockerInterceptor();
    }
}

3、測試修改的兩種情況

@Test
public void testOptimisticLocker1() {
    User user = userMapper.selectById(1128212430124097543L);
    user.setName("修改後");
    int result = userMapper.updateById(user);
    if (result == 1) {
        System.out.println("修改成功");
    } else {
        System.out.println("修改失敗");
    }
}

@Test
public void testOptimisticLocker2() {
    User user = userMapper.selectById(1128212430124097543L);
    user.setName("修改後");
    user.setVersion(user.getVersion()-1);//測試舊版本
    int result = userMapper.updateById(user);
    if (result == 1) {
        System.out.println("修改成功");
    } else {
        System.out.println("修改失敗");
    }
}

六、分頁插件

啓用分頁插件和啓用樂觀鎖插件都是通過註冊一個Bean完成

1、啓用分頁插件

@Bean
public PaginationInterceptor paginationInterceptor(){
    return new PaginationInterceptor();
}

2、測試分頁查詢

@Test
public void testSelectPage(){
    //構建分頁條件第二頁每頁顯示3條
    Page<User> page=new Page<>(2,3);
    //使用分頁條件查詢,不使用其他條件
    userMapper.selectPage(page, null);
    //獲取分頁後查詢出的記錄
    List<User> records = page.getRecords();
    records.forEach(System.out::println);
    System.out.println("是否有下一頁:"+page.hasNext());
    System.out.println("是否有上一頁:"+page.hasPrevious());
    System.out.println("總記錄數:"+page.getTotal());
}

七、邏輯刪除插件

有些數據希望不再展示,但在物理上仍然存在,這時可以使用邏輯刪除。邏輯刪除就是在表中添加一個邏輯字段(在上面基礎上添加字段 deleted),刪除的實質操作就是操作這個邏輯值,在查詢、修改時根據此邏輯值進行近一步操作。

1、啓用邏輯刪除插件

@Bean
public LogicSqlInjector logicSqlInjector(){
    return new LogicSqlInjector();
}

2、添加邏輯映射配置

mybatis-plus:
  global-config:
    db-config:
      logic-delete-value: 1 # 邏輯已刪除值(默認爲 1)
      logic-not-delete-value: 0 # 邏輯未刪除值(默認爲 0)

3、邏輯字段添加註解 ==@TableLogic==

@TableLogic
private Integer deleted;

4、測試邏輯刪除

@Test
public void testLogicDelete(){
    int result=userMapper.deleteById(1L);
    System.out.println(result);
}

觀察日誌可以看到生成的sql是update語句

八、性能分析插件

在開發和測試時觀察sql執行耗時

1、配置SpringBoot爲開發環境

spring:
  profiles:
    active: dev

2、啓用插件

@Bean
@Profile({"dev","test"}) //設置 dev test 環境開啓
public PerformanceInterceptor performanceInterceptor(){
    return new PerformanceInterceptor();
}

九、CRUD其他操作

@Test
public void testSelectById() {
    User user = userMapper.selectById(1L);
    System.out.println(user);
}

@Test
public void testSelectBatchIds() {
    List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));
    users.forEach(System.out::println);
}

@Test
public void testSelectByMap() {
    Map<String, Object> param = new HashMap<>();
    param.put("name", "jack");
    param.put("age", 18);
    List<User> users = userMapper.selectByMap(param);
    users.forEach(System.out::println);
}

@Test
public void testSelectMap(){
    Page<User> page = new Page<>(2, 3);
    IPage<Map<String, Object>> mapIPage = userMapper.selectMapsPage(page, null);
}

@Test
public void testDeleteById(){
    int result = userMapper.deleteById(1L);
    System.out.println(result);
}

@Test
public void testDeleteBatchIds(){
    int result = userMapper.deleteBatchIds(Arrays.asList(2L,3L,4L));
    System.out.println(result);
}

歡迎熱愛技術的小夥伴和我交流

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章