MyBatis-Plus 學(xué)習(xí)筆記

MyBatis-Plus官網(wǎng)地址:https://mp.baomidou.com/

一、mybatis-plus簡(jiǎn)介:

Mybatis-Plus(簡(jiǎn)稱MP)是一個(gè) Mybatis 的增強(qiáng)工具,在 Mybatis 的基礎(chǔ)上只做增強(qiáng)不做改變,為簡(jiǎn)化開發(fā)、提高效率而生。這是官方給的定義,關(guān)于mybatis-plus的更多介紹及特性,可以參考mybatis-plus官網(wǎng)。那么它是怎么增強(qiáng)的呢?其實(shí)就是它已經(jīng)封裝好了一些crud方法,我們不需要再寫xml了,直接調(diào)用這些方法就行,就類似于JPA。

二、mybatis-plus特性:

  • 無(wú)侵入:只做增強(qiáng)不做改變,引入它不會(huì)對(duì)現(xiàn)有工程產(chǎn)生影響,如絲般順滑
  • 損耗小:?jiǎn)?dòng)即會(huì)自動(dòng)注入基本 CURD,性能基本無(wú)損耗,直接面向?qū)ο蟛僮?/li>
  • 強(qiáng)大的 CRUD 操作:內(nèi)置通用 Mapper、通用 Service,僅僅通過(guò)少量配置即可實(shí)現(xiàn)單表大部分 CRUD 操作,更有強(qiáng)大的條件構(gòu)造器,滿足各類使用需求
  • 支持 Lambda 形式調(diào)用:通過(guò) Lambda 表達(dá)式,方便的編寫各類查詢條件,無(wú)需再擔(dān)心字段寫錯(cuò)
  • 支持主鍵自動(dòng)生成:支持多達(dá) 4 種主鍵策略(內(nèi)含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解決主鍵問(wèn)題
  • 支持 ActiveRecord 模式:支持 ActiveRecord 形式調(diào)用,實(shí)體類只需繼承 Model 類即可進(jìn)行強(qiáng)大的 CRUD 操作
  • 支持自定義全局通用操作:支持全局通用方法注入( Write once, use anywhere )
  • 內(nèi)置代碼生成器:采用代碼或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 層代碼,支持模板引擎,更有超多自定義配置等您來(lái)使用
  • 內(nèi)置分頁(yè)插件:基于 MyBatis 物理分頁(yè),開發(fā)者無(wú)需關(guān)心具體操作,配置好插件之后,寫分頁(yè)等同于普通 List 查詢
  • 分頁(yè)插件支持多種數(shù)據(jù)庫(kù):支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多種數(shù)據(jù)庫(kù)
  • 內(nèi)置性能分析插件:可輸出 Sql 語(yǔ)句以及其執(zhí)行時(shí)間,建議開發(fā)測(cè)試時(shí)啟用該功能,能快速揪出慢查詢
  • 內(nèi)置全局?jǐn)r截插件:提供全表 delete 、 update 操作智能分析阻斷,也可自定義攔截規(guī)則,預(yù)防誤操作

三、MyBatis-Plus VS JPA

MyBatis-Plus優(yōu)勢(shì):

  • SQL語(yǔ)句可以自由控制,更靈活,性能較高
  • SQL于代碼分離,易于閱讀和維護(hù)
  • 提供XML標(biāo)簽,支持編寫動(dòng)態(tài)SQL語(yǔ)句

JPA優(yōu)勢(shì):

  • JPA移植性比較好
  • 提供了很多 CRUD方法、開發(fā)效率高
  • 對(duì)象化程度更高

MyBatis-Plus劣勢(shì):

  • 簡(jiǎn)單的CURD都要寫SQL
  • XML中有大量的SQL要維護(hù)
  • MyBatis自身功能很有限,但支持PLlugin

四、常用注解

  • @TableName:對(duì)數(shù)據(jù)表名注解
  • @TableId:表主鍵標(biāo)識(shí)
  • @TableId(value = “id”, type = IdType.AUTO):自增
  • @TableId(value = “id”, type = IdType.ID_WORKER_STR):分布式全局唯一ID字符串類型
  • @TableId(value = “id”, type = IdType.INPUT):自行輸入
  • @TableId(value = “id”, type = IdType.ID_WORKER):分布式全局唯一ID 長(zhǎng)整型類型
  • @TableId(value = “id”, type = IdType.UUID):32位UUID字符串
  • @TableId(value = “id”, type = IdType.NONE):無(wú)狀態(tài)
  • @TableField:表字段標(biāo)識(shí)
  • @TableField(exist = false):表示該屬性不為數(shù)據(jù)庫(kù)表字段,但又是必須使用的。
  • @TableField(exist = true):表示該屬性為數(shù)據(jù)庫(kù)表字段。
  • @TableField(condition = SqlCondition.LIKE):表示該屬性可以模糊搜索。
  • @TableField(fill = FieldFill.INSERT):注解填充字段 ,生成器策略部分也可以配置!
  • @Version:樂(lè)觀鎖注解、標(biāo)記
  • @EnumValue:通枚舉類注解
  • @TableLogic:表字段邏輯處理注解(邏輯刪除)
  • @SqlParser:租戶注解
  • @KeySequence:序列主鍵策略

五、普通查詢

增:

    @Autowired
    private RentDetailMapper rentDetailMapper;

    @Override
    public void insert(String userId, String dealerId, String strategyId) {
        RentDetail rentDetail=new RentDetail();
        //插入
        rentDetail.setUserId(userId);
        rentDetail.setDealerId(dealerId);
        rentDetail.setStrategyId(strategyId);
        rentDetailMapper.insert(rentDetail);
    }

刪:

    @Autowired
    private RentDetailMapper rentDetailMapper;

    @Override
    public void delete(String Id) {
        //刪除
        rentDetailMapper.deleteById(Id);
    }

改:

    @Autowired
    private RentDetailMapper rentDetailMapper;

    @Override
    public void update(String userId, String dealerId, String strategyId) {
        RentDetail rentDetail=new RentDetail();
        //更新
        rentDetail.setUserId(userId);
        rentDetail.setDealerId(dealerId);
        rentDetail.setStrategyId(strategyId);
        rentDetailMapper.updateById(rentDetail);
    }

查:

    @Autowired
    private RentDetailMapper rentDetailMapper;

    @Override
    public void select(String Id) {
        //查找
        rentDetailMapper.selectById(Id);
    }

六、自定義SQL查詢

接口示例:

@Mapper
@Repository
public interface IUserDao extends BaseMapper<User> {

    /**
     * 根據(jù)電話查找id、昵稱
     * @param mobile
     * @param sourceId
     * @return
     */
    List<UserMobileVO> findId(@Param("mobile")String mobile,@Param("sourceId")String sourceId);
}

xml示例:
ps:MyBatisPlus是有駝峰命名的,不需要一個(gè)一個(gè)字段進(jìn)行映射

<?xml version="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.netx.web.dao.IUserDao">

    <select id="findId" resultType="com.netx.web.vo.UserMobileVO" >
   SELECT
    id,
    mobile,
    real_name
    FROM
        `user`
    WHERE
        mobile like '%${mobile}%'and
        deleted = 0
        and register_source=#{sourceId}
    </select>
</mapper>

動(dòng)態(tài)SQL示例:
PS:若是排序的動(dòng)態(tài)查詢需要注意不用#{字段名}而是用${字段名}

<select id="pageStrategy" resultType="com.app.entity.Strategy">
        select * from strategy
        <where>
             <!--若傳入的參數(shù)為空,則不做對(duì)應(yīng)的篩選-->
            <if test="search.house != null and search.house != ''">
                house = #{search.house}
            </if>
            <if test="search.currncy != null and search.currncy != ''">
                and currncy = #{search.currncy}
            </if>
            and deleted = 0 order by
        <choose>
             <!--若某一參數(shù)不為空,則做對(duì)應(yīng)的排序(這里要前端傳desc或asc來(lái)做降升序控制)-->
            <when test="search.yiedlRate != null and search.yiedlRate != ''">
                yiedl_rate ${search.yiedlRate}
            </when>
            <when test="search.winRate != null and search.winRate != ''">
                win_rate ${search.winRate}
            </when>
            <when test="search.totalRentedCount != null and search.totalRentedCount != ''">
                total_rented_count ${search.totalRentedCount}
            </when>
            <otherwise>
                create_time desc
            </otherwise>
        </choose>
        </where>
    </select>

七、條件構(gòu)造器

更多詳細(xì)用法盡在官方文檔:https://mp.baomidou.com/guide/wrapper.html#select

查:

    /**
     * 條件構(gòu)造器 查詢操作
     * 年齡在 18~50 之間性別為男且姓名為 xx 的所有用戶
     *SELECT id AS id,last_name AS lastName,email,gender,age FROM tbl_employee WHERE (age BETWEEN ? AND ? AND gender = ? AND last_name = ?)
     */

    @Test
    public void testSelectPage(){
        Page<Employee> page=new Page<>(0,2);
        EntityWrapper<Employee> entityWrapper=new EntityWrapper<>();
        entityWrapper.between("age",18,50).eq("gender",1).eq("last_name","Tom");
        List<Employee> list = employeeMapper.selectPage(page, entityWrapper);
        System.out.println(list);
    }

刪:

     /**
     * 條件構(gòu)造器 刪除操作
     *刪除名字為Tom并且性別為女年齡為45
     *DELETE FROM tbl_employee WHERE (last_name = ? AND gender = ? AND age = ?)
     */
    @Test
    public void testDelete(){
        EntityWrapper<Employee> entityWrapper=new EntityWrapper<>();
        entityWrapper.eq("last_name","Tom").eq("gender",0).eq("age",45);
        Integer row = employeeMapper.delete(entityWrapper);
        System.out.println(row);
    }

改:

      /**
     * 條件構(gòu)造器 修改操作
     *名字為xiaohong并且性別為女年齡為10的人名字改為honghonglaoshi,郵箱改為120@qq.com
     * UPDATE tbl_employee SET last_name=?, email=? WHERE (last_name = ? AND gender = ? AND age = ?)
     */
    @Test
    public void testUpdate(){
        Employee employee=new Employee();
        employee.setLastName("honghonglaoshi");
        employee.setEmail("120@qq.com");
        EntityWrapper<Employee> entityWrapper=new EntityWrapper<>();
        entityWrapper.eq("last_name","xiaohong").eq("gender",0).eq("age",10);
        Integer row = employeeMapper.update(employee, entityWrapper);
        System.out.println(row);
    }

八、分頁(yè)查詢

官方文檔:https://mybatis.plus/guide/page.html

XML 自定義分頁(yè)

public interface UserMapper {//可以繼承或者不繼承BaseMapper
    /**
     * <p>
     * 查詢 : 根據(jù)state狀態(tài)查詢用戶列表,分頁(yè)顯示
     * </p>
     *
     * @param page 分頁(yè)對(duì)象,xml中可以從里面進(jìn)行取值,傳遞參數(shù) Page 即自動(dòng)分頁(yè),必須放在第一位(你可以繼承Page實(shí)現(xiàn)自己的分頁(yè)對(duì)象)
     * @param state 狀態(tài)
     * @return 分頁(yè)對(duì)象
     */
    IPage<User> selectPageVo(Page<?> page, Integer state);
}
  • UserMapper.xml 等同于編寫一個(gè)普通 list 查詢,mybatis-plus 自動(dòng)替你分頁(yè)
<select id="selectPageVo" resultType="com.baomidou.cloud.entity.UserVo">
    SELECT id,name FROM user WHERE state=#{state}
</select>
  • UserServiceImpl.java 調(diào)用分頁(yè)方法
public IPage<User> selectUserPage(Page<User> page, Integer state) {
    // 不進(jìn)行 count sql 優(yōu)化,解決 MP 無(wú)法自動(dòng)優(yōu)化 SQL 問(wèn)題,這時(shí)候你需要自己查詢 count 部分
    // page.setOptimizeCountSql(false);
    // 當(dāng) total 為小于 0 或者設(shè)置 setSearchCount(false) 分頁(yè)插件不會(huì)進(jìn)行 count 查詢
    // 要點(diǎn)!! 分頁(yè)返回的對(duì)象與傳入的對(duì)象是同一個(gè)
    return userMapper.selectPageVo(page, state);
}

九、AR策略 (Active Record活動(dòng)記錄)

  • Active Record(活動(dòng)記錄),簡(jiǎn)稱AR,是一種領(lǐng)域模型模式,特點(diǎn)就是一個(gè)模型類對(duì)應(yīng)關(guān)系型數(shù)據(jù)庫(kù)中的一個(gè)表,而模型類的一個(gè)實(shí)例對(duì)應(yīng)表中的一條記錄;
    參考文章:https://blog.csdn.net/xiaofeivip_top/article/details/94871238
    開啟AR模式的方法很簡(jiǎn)單,就是讓我們的實(shí)體類繼承Model類,并實(shí)現(xiàn)其抽象方法,指定主鍵即可,如下:
@Data
public class Employee extends Model<Employee> {

   @TableId(value = "id",type = IdType.AUTO)
   private Integer id;

   @TableField
   private String lastName;
   private String email;
   private Integer gender;
   private Integer age;

   /**
    * 通過(guò)exit設(shè)置當(dāng)前字段不存在數(shù)據(jù)庫(kù)里面
    */
   @TableField(exist = false)
   private Double salary;

   /**
    * 指定當(dāng)前實(shí)體類的 主鍵屬性
    * @return
    */
   @Override
   protected Serializable pkVal() {
       return id;
   }

}

測(cè)試:

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringBootMybatisplusARTests {

    /**
     * 添加
     */
    @Test
    public void insertAR() {
        Employee employee = new Employee();
        employee.setLastName("AR");
        employee.setEmail("ar@xiaofei.com");
        employee.setGender(1);
        employee.setAge(22);

        boolean insert = employee.insert();
        System.err.println(insert);
        System.err.println(employee.getId());
    }

    /**
     * 修改
     */
    @Test
    public void updateAR() {
        Employee employee = new Employee();
        employee.setId(10);
        employee.setGender(0);
        employee.setAge(0);
        boolean b = employee.updateById();
        System.err.println(b);
    }

    /**
     * 查詢
     */
    @Test
    public void selectAR() {
        // 根據(jù)Id查詢
        Employee employee = new Employee();
        Employee employee1 = employee.selectById(1);
        // System.err.println(employee1);

        // 查詢?nèi)?        List<Employee> employeesAll = employee.selectAll();
        // System.err.println(employeesAll);

        // 查詢名字帶有M的
        List<Employee> employees = employee.selectList(new EntityWrapper().like("last_name", "M"));
        // System.err.println(employees);

        // 查詢總數(shù)量
        int count = employee.selectCount(null);
        // System.err.println(count);

        // 分頁(yè)
        Page<Employee> page = employee.selectPage(
                new Page<Employee>(1, 2), null);
        System.err.println(page);
        /**
         *  Page:{ [Pagination { total=0 ,size=2 ,pages=0 ,current=1 }], records-size:2 }
         */
        List<Employee> emps = page.getRecords();
        System.err.println("數(shù)據(jù):" + emps);
    }

    /**
     * 刪除
     * <p>
     * 注意:刪除不存在的數(shù)據(jù)在邏輯上也是成功的;
     */
    @Test
    public void deleteAR() {
        Employee employee = new Employee();
        boolean b = employee.deleteById(10);
        System.err.println(b);
    }
}

注意點(diǎn):刪除不存在的數(shù)據(jù)在邏輯上也是成功的;

十、基本配置

官方文檔:https://mp.baomidou.com/config/#基本配置
使用方式:
Spring Boot:

mybatis-plus:
  ......
  configuration:
    ......
  global-config:
    ......
    db-config:
      ......  

Configuration

mapUnderscoreToCamelCase

  • 類型:boolean
  • 默認(rèn)值:true

是否開啟自動(dòng)駝峰命名規(guī)則(camel case)映射,即從經(jīng)典數(shù)據(jù)庫(kù)列名 A_COLUMN(下劃線命名) 到經(jīng)典 Java 屬性名 aColumn(駝峰命名) 的類似映射。

?注意
?此屬性在 MyBatis 中原默認(rèn)值為 false,在 MyBatis-Plus 中,此屬性也將用于生成最終的 SQL 的 select body
?如果您的數(shù)據(jù)庫(kù)命名符合規(guī)則無(wú)需使用 @TableField 注解指定數(shù)據(jù)庫(kù)字段名

#defaultEnumTypeHandler

  • 類型:Class<? extends TypeHandler
  • 默認(rèn)值:org.apache.ibatis.type.EnumTypeHandler

默認(rèn)枚舉處理類,如果配置了該屬性,枚舉將統(tǒng)一使用指定處理器進(jìn)行處理

  • org.apache.ibatis.type.EnumTypeHandler : 存儲(chǔ)枚舉的名稱
  • org.apache.ibatis.type.EnumOrdinalTypeHandler : 存儲(chǔ)枚舉的索引
  • com.baomidou.mybatisplus.extension.handlers.MybatisEnumTypeHandler : 枚舉類需要實(shí)現(xiàn)IEnum接口或字段標(biāo)記@EnumValue注解.(3.1.2以下版本為EnumTypeHandler)

其他就不一一列舉,有興趣可以在官方文檔查閱

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容