天天看點

【MyBatis-Plus】MyBatis-Plus基本操作快速入門

1.MyBatis Plus概述

  • 将​

    ​Mybatis + 通用Mapper + PageHelper​

    ​​更新成 ​

    ​MyBatis Plus​

1.1 簡介

官網:​​MyBatis-Plus​​

參考教程:​​簡介 | MyBatis-Plus​​

​​MyBatis-Plus​​​(簡稱 MP)是一個 ​​MyBatis​​ 的增強工具,在 MyBatis 的基礎上隻做增強不做改變,為簡化開發、提高效率而生。

1.2 特點

  • 無侵入:隻做增強不做改變,引入它不會對現有工程産生影響,如絲般順滑
  • 損耗小:啟動即會自動注入基本 CURD,性能基本無損耗,直接面向對象操作
  • 強大的 CRUD 操作:内置通用 Mapper、通用 Service,僅僅通過少量配置即可實作單表大部分 CRUD 操作,更有強大的條件構造器,滿足各類使用需求
  • 支援 Lambda 形式調用:通過 Lambda 表達式,友善的編寫各類查詢條件,無需再擔心字段寫錯
  • 支援多種資料庫:支援 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer2005、SQLServer 等多種資料庫
  • 支援主鍵自動生成:支援多達 4 種主鍵政策(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解決主鍵問題
  • 支援 XML 熱加載:Mapper 對應的 XML 支援熱加載,對于簡單的 CRUD 操作,甚至可以無 XML 啟動
  • 支援 ActiveRecord 模式:支援 ActiveRecord 形式調用,實體類隻需繼承 Model 類即可進行強大的 CRUD 操作
  • 支援自定義全局通用操作:支援全局通用方法注入( Write once, use anywhere )
  • 支援關鍵詞自動轉義:支援資料庫關鍵詞(order、key......)自動轉義,還可自定義關鍵詞
  • 内置代碼生成器:采用代碼或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 層代碼,支援模闆引擎,更有超多自定義配置等您來使用
  • 内置分頁插件:基于 MyBatis 實體分頁,開發者無需關心具體操作,配置好插件之後,寫分頁等同于普通 List 查詢
  • 内置性能分析插件:可輸出 Sql 語句以及其執行時間,建議開發測試時啟用該功能,能快速揪出慢查詢
  • 内置全局攔截插件:提供全表 delete 、 update 操作智能分析阻斷,也可自定義攔截規則,預防誤操作
  • 内置 Sql 注入剝離器:支援 Sql 注入剝離,有效預防 Sql 注入攻擊

2.入門案例

2.1 搭建環境

  • 步驟
  • 步驟一:建立項目:test-mybatis-plus
  • 步驟二:修改pom.xml,添加依賴
<dependencies>
        <!-- web 開發 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--MySQL資料庫驅動-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!--支援lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <!--測試-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.0</version>
        </dependency>
    </dependencies>      
  • 步驟一:建立項目:test-mybatis-plus
  • 步驟二:修改pom.xml,添加依賴
<!--确定spring boot的版本-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.5.RELEASE</version>
    </parent>      
  • 步驟三:建立yml檔案,配置資料庫相關
【MyBatis-Plus】MyBatis-Plus基本操作快速入門
spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/cloud_db1?useUnicode=true&characterEncoding=UTF-8&serverTimeznotallow=UTC
    username: root
    password: 1234
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl  #輸出日志      

2.2 資料庫和表

CREATE DATABASE cloud_db1;
USE cloud_db1;
CREATE TABLE `tmp_customer` (
  `cid` INT(11) NOT NULL AUTO_INCREMENT,
  `cname` VARCHAR(50) DEFAULT NULL,
  `password` VARCHAR(32) DEFAULT NULL,
  `telephone` VARCHAR(11) DEFAULT NULL,
  `money` DOUBLE DEFAULT NULL,
  `version` INT(11) DEFAULT NULL,
  `create_time` DATE DEFAULT NULL,
  `update_time` DATE DEFAULT NULL,
  PRIMARY KEY (`cid`)
);

INSERT  INTO `tmp_customer`(`cid`,`cname`,`password`,`telephone`,`money`,`version`,`create_time`,`update_time`) 
VALUES (1,'jack','1234','110',1000,NULL,NULL,NULL),(2,'rose','1234','112',1000,NULL,NULL,NULL),(3,'tom','1234','119',1000,NULL,NULL,NULL);      

2.3 入門:查詢所有

  • 步驟
  • 步驟1:配置JavaBean,添加MyBatisPlus對應的注解(表、主鍵、字段等)
  • 步驟2:編寫dao接口,并繼承BaseMapper接口
  • 步驟3:編寫啟動類
  • 步驟4:編寫測試類
  • 步驟1:配置JavaBean
  • ​@TableName​

    ​ 表名注解,value屬性設定表名
package com.czxy.domain;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

import java.util.List;


@Data
@TableName("tmp_customer")
public class Customer {
    @TableId(type = IdType.AUTO)
    private Integer cid;
    private String cname;
    private String password;
    private String telephone;
    private String money;

    private Integer version;

    @TableField(exist = false)
    private List<Integer> ids;
}      
  • 步驟2:編寫dao
package com.czxy.mp.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.czxy.mp.domain.Customer;
import org.apache.ibatis.annotations.Mapper;

/**
 * Created by liangtong.
 */
@Mapper
public interface CustomerMapper extends BaseMapper<Customer> {
}      
  • 步驟3:編寫啟動類
package com.czxy.mp;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * Created by liangtong.
 */
@SpringBootApplication
public class MybatisPlusApplication {
    public static void main(String[] args) {
        SpringApplication.run(MybatisPlusApplication.class, args);
    }
}      
  • 步驟4:編寫測試類
package com.czxy;

import com.czxy.mp.MybatisPlusApplication;
import com.czxy.mp.domain.Customer;
import com.czxy.mp.mapper.CustomerMapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;
import java.util.List;

/**
 * Created by liangtong.
 */
@RunWith(SpringRunner.class)
@SpringBootTest(classes = MybatisPlusApplication.class)
public class TestDemo01 {
    @Resource
    private CustomerMapper customerMapper;

    @Test
    public void testFindAll() {
        List<Customer> list = customerMapper.selectList(null);
        list.forEach(System.out::println);
    }
}      

3.基本操作

3.1 常見API

BaseMapper 封裝CRUD操作,泛型 ​

​T​

​ 為任意實體對象

  • 增删改
方法名 描述
int insert(T entity) 插入一條記錄,entity 為 實體對象
int delete(Wrapper<T> wrapper) 根據 entity 條件,删除記錄,wrapper 可以為 null
int deleteBatchIds(Collection idList) 根據ID 批量删除
int deleteById(Serializable id) 根據 ID 删除
int deleteByMap(Map<String, Object> map) 根據 columnMap 條件,删除記錄
int update(T entity, Wrapper<T> updateWrapper) 根據 whereEntity 條件,更新記錄
int updateById(T entity); 根據 ID 修改
  • 查詢
方法名 描述
T selectById(Serializable id) 根據 ID 查詢
T selectOne(Wrapper<T> queryWrapper) 根據 entity 條件,查詢一條記錄
List<T> selectBatchIds(Collection idList) 根據ID 批量查詢
List<T> selectList(Wrapper<T> queryWrapper) 根據 entity 條件,查詢全部記錄
List<T> selectByMap(Map<String, Object> columnMap) 根據 columnMap 條件
List<Map<String, Object>> selectMaps(Wrapper<T> queryWrapper) 根據 Wrapper 條件,查詢全部記錄
List<Object> selectObjs( Wrapper<T> queryWrapper) 根據 Wrapper 條件,查詢全部記錄。注意: 隻傳回第一個字段的值
IPage<T> selectPage(IPage<T> page, Wrapper<T> queryWrapper) 根據 entity 條件,查詢全部記錄(并翻頁)
IPage<Map<String, Object>> selectMapsPage(IPage<T> page, Wrapper<T> queryWrapper) 根據 Wrapper 條件,查詢全部記錄(并翻頁)
Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper) 根據 Wrapper 條件,查詢總記錄數

3.2 添加

   @Test

   public void testInsert() {

       Customer customer = new Customer();

       customer.setCname("測試");

       customerMapper.insert(customer);

  }

  • 獲得自動增長列資訊
【MyBatis-Plus】MyBatis-Plus基本操作快速入門
@Test
    public void testInsert() {
        Customer customer = new Customer();
        customer.setCname("測試");
        customerMapper.insert(customer);
        System.out.println(customer);
    }      

3.3 更新

  • 通過id更新
@Test
    public void testUpdate() {
        Customer customer = new Customer();
        customer.setCid(15);
        customer.setCname("測試777");
        customer.setPassword("777");

        // 需要給Customer設定@TableId
        customerMapper.updateById(customer);
    }      
  • 更新所有
@Test
    public void testUpdate2() {
        Customer customer = new Customer();
        customer.setCname("測試777");
        customer.setPassword("777");
        // 更新所有
        customerMapper.update(customer,null);
    }      

3.4 删除

  • 根據id進行删除
@Test
    public void testDelete() {
        // 需要給Customer設定@TableId
        int i = customerMapper.deleteById(11);
        System.out.println(i);
    }      
  • 批量删除
@Test
    public void testBatchDelete() {
        // 需要給Customer設定@TableId
        int i = customerMapper.deleteBatchIds(Arrays.asList(9,10));
        System.out.println(i);
    }      

4.查詢

4.1 Map條件

@Test
    public void testMap(){
        Map map = new HashMap();
        map.put("cname","測試");
        map.put("password","123456");

        List list = customerMapper.selectByMap(map);
        list.forEach(System.out::println);
    }      

4.2 Wrapper條件

4.2.1 wrapper介紹

【MyBatis-Plus】MyBatis-Plus基本操作快速入門
  • Wrapper : 條件構造抽象類,最頂端父類
  • AbstractWrapper : 用于查詢條件封裝,生成 sql 的 where 條件
  • QueryWrapper : Entity 對象封裝操作類,不是用lambda文法
  • UpdateWrapper : Update 條件封裝,用于Entity對象更新操作
  • AbstractLambdaWrapper : Lambda 文法使用 Wrapper統一處了解析 lambda 擷取 column。
  • LambdaQueryWrapper :看名稱也能明白就是用于Lambda文法使用的查詢Wrapper
  • LambdaUpdateWrapper : Lambda 更新封裝Wrapper
  • 如果想進行複雜條件查詢,那麼需要使用條件構造器 Wapper,涉及到如下方法
方法名 描述
selectOne
selectCount
selectList
selectMaps
selectObjs
update
delete
  • 拼湊條件相關關鍵字
查詢方式 說明
setSqlSelect 設定 SELECT 查詢字段
where WHERE 語句,拼接 + WHERE 條件
and AND 語句,拼接 + AND 字段=值
andNew AND 語句,拼接 + AND (字段=值)
or OR 語句,拼接 + OR 字段=值
orNew OR 語句,拼接 + OR (字段=值)
eq 等于=
allEq 基于 map 内容等于=
ne 不等于<>
gt 大于>
ge 大于等于>=
lt 小于<
le 小于等于<=
like 模糊查詢 LIKE
notLike 模糊查詢 NOT LIKE
in IN 查詢
notIn NOT IN 查詢
isNull NULL 值查詢
isNotNull IS NOT NULL
groupBy 分組 GROUP BY
having HAVING 關鍵詞
orderBy 排序 ORDER BY
orderAsc ASC 排序 ORDER BY
orderDesc DESC 排序 ORDER BY
exists EXISTS 條件語句
notExists NOT EXISTS 條件語句
between BETWEEN 條件語句
notBetween NOT BETWEEN 條件語句
addFilter 自由拼接 SQL
last 拼接在最後,例如:last(“LIMIT 1”)

4.2.2 條件查詢

  • 基本多條件查詢
@Test
    public void testWrapper(){
        // 拼湊條件
        QueryWrapper<Customer> queryWrapper = new QueryWrapper();
        // 1)模糊查詢
        queryWrapper.like("cname","測試");
        // 2)等值查詢
        queryWrapper.eq("password","777");
        // 3)批量查詢
        queryWrapper.in("cid",1,2,3,4);
        // 4) 範圍
        queryWrapper.ge("money", 800);
        queryWrapper.le("money" , 1500);

        // 查詢
        List<Customer> list = customerMapper.selectList(queryWrapper);
        list.forEach(System.out::println);
    }      
  • 條件判斷
@Test
    public void findCondition2() {
        Customer customer = new Customer();
        customer.setPassword("777");
        customer.setCname("888");
        customer.setIdList(Arrays.asList(2,3,4));
        customer.setCid(3);
        //條件查詢
        QueryWrapper<Customer> queryWrapper = new QueryWrapper<>();
        // 1) 等值查詢
        queryWrapper.eq( customer.getPassword()!=null ,"password", customer.getPassword());
        // 2) 模糊查詢
        queryWrapper.like(customer.getCname() != null , "cname",customer.getCname());
        // 3) in語句
        queryWrapper.in(customer.getIdList() != null , "cid",customer.getIdList());
        // 4) 大于等于
        queryWrapper.ge(customer.getCid() != null , "cid" , customer.getCid());


        //查詢
        List<Customer> list = customerMapper.selectList(queryWrapper);
        //list.forEach(customer-> System.out.println(customer));
        list.forEach(System.out::println);

    }      

4.3.3 條件更新

  • 基本更新
@Test
    public void testWrapperUpdate(){
        //1 更新資料
        Customer customer = new Customer();
        customer.setVersion(1);

        //2 更新條件
        UpdateWrapper<Customer> updateWrapper = new UpdateWrapper<>();
        updateWrapper.in("cid", 1,2,3);

        //3 更新
        int update = customerMapper.update(customer, updateWrapper);
        System.out.println(update);
    }      

4.3 分頁

4.3.1 内置插件

  • 主體插件: MybatisPlusInterceptor,該插件内部插件集:
  • 分頁插件: PaginationInnerInterceptor
  • 多租戶插件: TenantLineInnerInterceptor
  • 動态表名插件: DynamicTableNameInnerInterceptor
  • 樂觀鎖插件: OptimisticLockerInnerInterceptor
  • sql性能規範插件: IllegalSQLInnerInterceptor
  • 防止全表更新與删除插件: BlockAttackInnerInterceptor

4.3.2 配置類

【MyBatis-Plus】MyBatis-Plus基本操作快速入門
package com.czxy.mp.config;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.autoconfigure.ConfigurationCustomizer;
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 MybatisPlusConfig {

    /**
     * 配置插件
     * @return
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){

        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        // 分頁插件
        mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));

        return mybatisPlusInterceptor;
    }

    /**
     * 新的分頁插件,一緩和二緩遵循mybatis的規則,需要設定 MybatisConfiguration#useDeprecatedExecutor = false 避免緩存出現問題(該屬性會在舊插件移除後一同移除)
     * @return
     */
    @Bean
    public ConfigurationCustomizer configurationCustomizer() {
        return configuration -> configuration.setUseDeprecatedExecutor(false);
    }
}      

4.3.3 分頁

@Test
    public void testPage(){
        // 分頁資料
        int pageNum = 1;
        int pageSize = 3;
        Page<Customer> page = new Page<>(pageNum , pageSize);
        page.setSearchCount(true);

        // 查詢
        customerMapper.selectPage(page, null);

        // 分頁資料
        System.err.println("目前頁碼:" + page.getCurrent());
        System.err.println("每頁顯示記錄數:" + page.getSize());
        System.err.println("總頁數:" + page.getPages());
        System.err.println("總記錄數:" + page.getTotal());
        System.err.println("是否有下一頁:" + page.hasNext());
        System.err.println("是否有上一頁:" + page.hasPrevious());
        // 分頁資料清單
        page.getRecords().forEach(System.err::println);
    }      

5.常見注解

5.1 表名注解:@TableName

屬性 描述
value 表名
keepGlobalPrefix 是否保持使用全局的 tablePrefix 的值(如果設定了全局 tablePrefix 且自行設定了 value 的值)
【MyBatis-Plus】MyBatis-Plus基本操作快速入門

5.2 主鍵注解:@TableId

屬性 描述
value 主鍵字段名
type 主鍵類型 IdType.ASSIGN_UUID ,配置設定UUID,MyBatisPlus維護String資料 IdType.ASSIGN_ID ,配置設定ID(預設使用雪花算法)MyBatisPlus維護Long資料 IdType.AUTO ,自動增長(資料庫維護)
  • 測試表:User
CREATE TABLE tmp_user(
    uid VARCHAR(100),
    uname VARCHAR(50)
);      
  • JavaBean
package com.czxy.mp.domain;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;


@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    //@TableId(type = IdType.ASSIGN_UUID)       //随機一個字元串
    @TableId(type = IdType.ASSIGN_ID)           //随機一個數字(Long)
    private String uid;
    private String uname;
}      

5.2 字段注解(非主鍵) : @TableField

屬性 描述
value 資料庫字段名
fill 字段自動填充政策 FieldFill.INSERT 插入時填充字段 FieldFill.UPDATE 更新時填充字段 FieldFill.INSERT_UPDATE 插入和更新時填充字段
exist 是否存儲到資料庫(是否是臨時資料)

6.常見配置

mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl  #輸出日志
    map-underscore-to-camel-case: true  #駝峰命名
  global-config:
    db-config:
      id-type: auto  #全局配置,id自動增強
      table-prefix: tmp_ #表名字首
  type-aliases-package: com.czxy.mp.domain #别名包掃描路徑
  mapper-locations: classpath*:/mapper/**/*.xml #映射檔案位置      
  • 整合xml
【MyBatis-Plus】MyBatis-Plus基本操作快速入門
<?xml versinotallow="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.czxy.mp.mapper.CustomerMapper">

    <select id="findAll" resultType="customer">
        select * from tmp_customer
    </select>

</mapper>      
  • CustomerMapper對應的方法
package com.czxy.mp.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.czxy.mp.domain.Customer;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;


@Mapper
public interface CustomerMapper extends BaseMapper<Customer> {

    public List<Customer> findAll();
}