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

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

一、mybatis-plus簡介:

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

二蜕窿、mybatis-plus特性:

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

三、MyBatis-Plus VS JPA

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

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

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

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

MyBatis-Plus劣勢(shì):

  • 簡單的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 長整型類型
  • @TableId(value = “id”, type = IdType.UUID):32位UUID字符串
  • @TableId(value = “id”, type = IdType.NONE):無狀態(tài)
  • @TableField:表字段標(biāo)識(shí)
  • @TableField(exist = false):表示該屬性不為數(shù)據(jù)庫表字段塞蹭,但又是必須使用的。
  • @TableField(exist = true):表示該屬性為數(shù)據(jù)庫表字段讶坯。
  • @TableField(condition = SqlCondition.LIKE):表示該屬性可以模糊搜索番电。
  • @TableField(fill = FieldFill.INSERT):注解填充字段 ,生成器策略部分也可以配置!
  • @Version:樂觀鎖注解漱办、標(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來做降升序控制)-->
            <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);
    }

八扬霜、分頁查詢

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

XML 自定義分頁

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

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

  • Active Record(活動(dòng)記錄)材原,簡稱AR躯泰,是一種領(lǐng)域模型模式,特點(diǎn)就是一個(gè)模型類對(duì)應(yīng)關(guān)系型數(shù)據(jù)庫中的一個(gè)表华糖,而模型類的一個(gè)實(shí)例對(duì)應(yīng)表中的一條記錄麦向;
    參考文章:https://blog.csdn.net/xiaofeivip_top/article/details/94871238
    開啟AR模式的方法很簡單,就是讓我們的實(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;

   /**
    * 通過exit設(shè)置當(dāng)前字段不存在數(shù)據(jù)庫里面
    */
   @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);

        // 分頁
        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ù)庫列名 A_COLUMN(下劃線命名) 到經(jīng)典 Java 屬性名 aColumn(駝峰命名) 的類似映射裳朋。

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

#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)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市绑莺,隨后出現(xiàn)的幾起案子暖眼,更是在濱河造成了極大的恐慌,老刑警劉巖纺裁,帶你破解...
    沈念sama閱讀 210,978評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件诫肠,死亡現(xiàn)場(chǎng)離奇詭異司澎,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)栋豫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門挤安,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人丧鸯,你說我怎么就攤上這事蛤铜。” “怎么了骡送?”我有些...
    開封第一講書人閱讀 156,623評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長絮记。 經(jīng)常有香客問我摔踱,道長,這世上最難降的妖魔是什么怨愤? 我笑而不...
    開封第一講書人閱讀 56,324評(píng)論 1 282
  • 正文 為了忘掉前任派敷,我火速辦了婚禮,結(jié)果婚禮上撰洗,老公的妹妹穿的比我還像新娘篮愉。我一直安慰自己,他們只是感情好差导,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評(píng)論 5 384
  • 文/花漫 我一把揭開白布试躏。 她就那樣靜靜地躺著,像睡著了一般设褐。 火紅的嫁衣襯著肌膚如雪颠蕴。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,741評(píng)論 1 289
  • 那天助析,我揣著相機(jī)與錄音犀被,去河邊找鬼。 笑死外冀,一個(gè)胖子當(dāng)著我的面吹牛寡键,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播雪隧,決...
    沈念sama閱讀 38,892評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼西轩,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了脑沿?” 一聲冷哼從身側(cè)響起遭商,我...
    開封第一講書人閱讀 37,655評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎捅伤,沒想到半個(gè)月后劫流,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,104評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年祠汇,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了仍秤。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,569評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡可很,死狀恐怖诗力,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情我抠,我是刑警寧澤苇本,帶...
    沈念sama閱讀 34,254評(píng)論 4 328
  • 正文 年R本政府宣布,位于F島的核電站菜拓,受9級(jí)特大地震影響瓣窄,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜纳鼎,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評(píng)論 3 312
  • 文/蒙蒙 一俺夕、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧贱鄙,春花似錦劝贸、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至瞎颗,卻和暖如春氯迂,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背言缤。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評(píng)論 1 264
  • 我被黑心中介騙來泰國打工嚼蚀, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人管挟。 一個(gè)月前我還...
    沈念sama閱讀 46,260評(píng)論 2 360
  • 正文 我出身青樓轿曙,卻偏偏與公主長得像,于是被迫代替她去往敵國和親僻孝。 傳聞我的和親對(duì)象是個(gè)殘疾皇子导帝,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容