溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

mybatis-plus的使用方法

發(fā)布時(shí)間:2021-06-30 15:25:18 來源:億速云 閱讀:174 作者:chen 欄目:大數(shù)據(jù)

這篇文章主要介紹“mybatis-plus的使用方法”,在日常操作中,相信很多人在mybatis-plus的使用方法問題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”mybatis-plus的使用方法”的疑惑有所幫助!接下來,請(qǐng)跟著小編一起來學(xué)習(xí)吧!

前言:

關(guān)于mybatis-plus的簡(jiǎn)介以及基本使用,我在《mybatis-plus的使用 ------ 入門》一文中已做介紹,此處不再贅述。本文主要對(duì)mybatis-plus的AR模式、插件、逆向工程、自定義全局操作、公共字段自動(dòng)填充等知識(shí)點(diǎn)進(jìn)行講解。

一、ActiveRecord:

Active Record(活動(dòng)記錄),是一種領(lǐng)域模型模式,特點(diǎn)是一個(gè)模型類對(duì)應(yīng)關(guān)系型數(shù)據(jù)庫中的一個(gè)表,而模型類的一個(gè)實(shí)例對(duì)應(yīng)表中的一行記錄。ActiveRecord 一直廣受動(dòng)態(tài)語言( PHP 、 Ruby 等)的喜愛,而 Java 作為準(zhǔn)靜態(tài)語言,對(duì)于 ActiveRecord 往往只能感嘆其優(yōu)雅,所以 MP 也在 AR 道路上進(jìn)行了一定的探索,僅僅需要讓實(shí)體類繼承 Model 類且實(shí)現(xiàn)主鍵指定方法,即可開啟 AR 之旅。接下來看具體代碼:

1、entity:

@Data
public class User extends Model<User> {
    private Integer id;
    private String name;
    private Integer age;
    private Integer gender;
    //重寫這個(gè)方法,return當(dāng)前類的主鍵
    @Override
    protected Serializable pkVal() {
        return id;
    }
}

注:實(shí)體類繼承Model類,重寫pkVal方法。

2、mapper:

public interface UserDao extends BaseMapper<User> {
}

注:雖然AR模式用不到該接口,但是一定要定義,否則使用AR時(shí)會(huì)報(bào)空指針異常。

3、使用AR:

(1)、AR插入操作:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:spring/spring-dao.xml"})
public class TestAR {
    @Test
    public void testArInsert(){
        User user = new User();
        user.setName("林青霞");
        user.setAge(22);
        user.setGender(1);
        boolean result = user.insert();
        System.out.println(result);
    }
}

mybatis-plus的使用方法

image.png

注:可以看到我們并不需要注入mapper接口,不過正如剛才所說,不使用但還是要定義,否則會(huì)報(bào)錯(cuò)。AR操作是通過對(duì)象本身調(diào)用相關(guān)方法,比如要insert一個(gè)user,那就用這個(gè)user調(diào)用insert方法即可。返回值為布爾類型,由上圖可看到返回了true,是操作成功的。

(2)、AR更新操作:

    @Test
    public void testArUpdate(){
        User user = new User();
        user.setId(1);
        user.setName("劉亦菲");
        boolean result = user.updateById();
        System.out.println(result);
    }

注:user調(diào)用updateById方法,將id為1的用戶進(jìn)行更新。

(3)、AR查詢操作:

    @Test
    public void testArSelect(){
        User user = new User();
        //1、根據(jù)id查詢
        //user = user.selectById(1);
        //或者這樣用
        //user.setId(1);
        //user = user.selectById();

        //2、查詢所有
        //List<User> users = user.selectAll();

        //3、根據(jù)條件查詢
        //List<User> users = user.selectList(new EntityWrapper<User>().like("name","劉"));

        //4、查詢符合條件的總數(shù)
        int result = user.selectCount(new EntityWrapper<User>().eq("gender",1));
        System.out.println(result);
    }

注:上面的代碼涉及到了四個(gè)不同的查詢操作,其實(shí)用法與MP的BaseMapper提供的方法的用法差不多,只不過這里是實(shí)體對(duì)象調(diào)用。

(4)、AR刪除操作:

@Test
    public void testArDelete(){
        User user = new User();
        //刪除數(shù)據(jù)庫中不存在的數(shù)據(jù)也是返回true
        //1、根據(jù)id刪除數(shù)據(jù)
        //boolean result = user.deleteById(1);
        //或者這樣寫
        //user.setId(1);
        //boolean result = user.deleteById();

        //2、根據(jù)條件刪除
        boolean result = user.delete(new EntityWrapper<User>().like("name","玲"));
        System.out.println(result);
    }

注:這里介紹了兩個(gè)刪除方法,代碼中已有注釋說明。需要注意的是,刪除數(shù)據(jù)庫中不存在的數(shù)據(jù),結(jié)果也是true。

(5)、AR分頁操作:

@Test
    public void testArPage(){
       User user = new User();
       Page<User> page =
               user.selectPage(new Page<>(1,4),
               new EntityWrapper<User>().like("name","劉"));
       List<User> users = page.getRecords();
       System.out.println(users);
    }

注:這個(gè)分頁方法和BaseMapper提供的分頁一樣都是內(nèi)存分頁,并非物理分頁,因?yàn)閟ql語句中沒用limit,和BaseMapper的selectPage方法一樣,配置了分頁插件后就可以實(shí)現(xiàn)真正的物理分頁。AR的分頁方法與BaseMapper提供的分頁方法不同的是,BaseMapper的selectPage方法返回值是查詢到的記錄的list集合,而AR的selectPage方法返回的是page對(duì)象,該page對(duì)象封裝了查詢到的信息,可以通過getRecords方法獲取信息。

二、插件的配置:

MP提供了很多好用的插件,而且配置簡(jiǎn)單,使用方便。接下來一起看看MP的插件如何使用。

1、分頁插件:
之前就有說到,BaseMapper的selectPage方法和AR提供的selectPage方法都不是物理分頁,需要配置分頁插件后才是物理分頁,那么現(xiàn)在就來看看如何配置這個(gè)插件。

<!-- 3、配置mybatisplus的sqlSessionFactory -->
    <bean id="sqlSessionFactory">

注:在sqlSessionFactory這個(gè)bean中,通過<property name="plugins">配置插件,接下來的所有插件都配置在這個(gè)list中。

@Test
    public void testPage() {
        //配置了分頁插件后,還是和以前一樣的使用selectpage方法,
        //但是現(xiàn)在就是真正的物理分頁了,sql語句中有l(wèi)imit了
        Page<Employee> page = new Page<>(1, 2);
        List<Employee> employeeList =
                emplopyeeDao.selectPage(page, null);
        System.out.println(employeeList);
        System.out.println("================= 相關(guān)的分頁信息 ==================");
        System.out.println("總條數(shù):" + page.getTotal());
        System.out.println("當(dāng)前頁碼:" + page.getCurrent());
        System.out.println("總頁數(shù):" + page.getPages());
        System.out.println("每頁顯示條數(shù):" + page.getSize());
        System.out.println("是否有上一頁:" + page.hasPrevious());
        System.out.println("是否有下一頁:" + page.hasNext());
        //還可以將查詢到的結(jié)果set進(jìn)page對(duì)象中
        page.setRecords(employeeList);
    }

mybatis-plus的使用方法

image.png

由圖可知,sql語句中已經(jīng)有了limit,是物理分頁了。

mybatis-plus的使用方法

image.png

也可以通過page調(diào)用相關(guān)方法獲取到相關(guān)的分頁信息,而且還可以把查詢到的結(jié)果set回page對(duì)象中,方便前端使用。

2、性能分析插件:
在plugin的list中添加如下bean即可開啟性能分析插件:

 <!-- 輸出每條SQL語句及其執(zhí)行時(shí)間,生產(chǎn)環(huán)境不建議使用該插件 -->
 <bean class="com.baomidou.mybatisplus.plugins.PerformanceInterceptor">
        <property name="format">

注:這個(gè)性能分析插件配置了兩個(gè)屬性,第一個(gè)是格式化sql語句,設(shè)置為true后,sql語句格式就像上面的截圖中的一樣;第二個(gè)屬性是sql語句執(zhí)行的最大時(shí)間,超過value值就會(huì)報(bào)錯(cuò),這里表示超過1000毫秒就會(huì)停止執(zhí)行sql語句。

3、執(zhí)行分析插件:

<!-- 如果是對(duì)全表的刪除或更新操作,就會(huì)終止該操作 -->
<bean class="com.baomidou.mybatisplus.plugins.SqlExplainInterceptor">
       <property name="stopProceed" value="true"/>
</bean>

注:這個(gè)插件配置了一個(gè)屬性,stopProceed設(shè)置為true后,如果執(zhí)行的是刪除表中全部?jī)?nèi)容,那就會(huì)拋出異常,終止該操作。該插件主要是防止手抖誤刪數(shù)據(jù)。

@Test
public void testSqlExplain(){
        //條件為null,就是刪除全表,執(zhí)行分析插件會(huì)終止該操作
    emplopyeeDao.delete(null);
}

運(yùn)行該junit測(cè)試,可以看到報(bào)如下錯(cuò)誤,說明該插件生效了。

mybatis-plus的使用方法

image.png

三、MP的逆向工程:

MyBatis 的代碼生成器基于xml文件進(jìn)行生成,可生成: 實(shí)體類、Mapper 接口、Mapper 映射文件。
MP 的代碼生成器基于Java代碼進(jìn)行生成,可生成: 實(shí)體類(可以選擇是否支持 AR)、Mapper 接口、Mapper 映射文件、 Service 層、Controller 層。
1、添加依賴:

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.37</version>
        </dependency>
        <!-- mp 依賴 -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus</artifactId>
            <version>2.3</version>
        </dependency>
        <!-- mybatisplus逆向工程需要模板引擎,用freemaker也行 -->
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>2.0</version>
        </dependency>

注:上面是必須的三個(gè)依賴,為了可以在控制臺(tái)直觀的看到生成情況,可以添加日志包(slf4j-api和slf4j-log4j2),為了讓生成的代碼不會(huì)報(bào)錯(cuò),還可以根據(jù)情況添加spring相關(guān)的依賴、lombok依賴等。

2、生成器示例代碼:

/**
 * @author: zhu
 * @date: 2018/8/20 11:17
 * mybatis-plus逆向工程示例代碼
 */
public class test {
    @Test
    public void testGenerator(){
        //1、全局配置
        GlobalConfig config = new GlobalConfig();
        config.setActiveRecord(true)//開啟AR模式
              .setAuthor("zhu")//設(shè)置作者
              //生成路徑(一般都是生成在此項(xiàng)目的src/main/java下面)
              .setOutputDir("E:\\develop\\Java\\workspace\\ideaworkspace\\mpg\\src\\main\\java")
              .setFileOverride(true)//第二次生成會(huì)把第一次生成的覆蓋掉
              .setIdType(IdType.AUTO)//主鍵策略
              .setServiceName("%sService")//生成的service接口名字首字母是否為I,這樣設(shè)置就沒有I
              .setBaseResultMap(true)//生成resultMap
              .setBaseColumnList(true);//在xml中生成基礎(chǔ)列
        //2、數(shù)據(jù)源配置
        DataSourceConfig dataSourceConfig = new DataSourceConfig();
        dataSourceConfig.setDbType(DbType.MYSQL)//數(shù)據(jù)庫類型
                        .setDriverName("com.mysql.jdbc.Driver")
                        .setUrl("jdbc:mysql:///數(shù)據(jù)庫名")
                        .setUsername("數(shù)據(jù)庫用戶名")
                        .setPassword("數(shù)據(jù)庫密碼");
        //3、策略配置
        StrategyConfig strategyConfig = new StrategyConfig();
        strategyConfig.setCapitalMode(true)//開啟全局大寫命名
                      .setDbColumnUnderline(true)//表名字段名使用下劃線
                      .setNaming(NamingStrategy.underline_to_camel)//下劃線到駝峰的命名方式
                      .setTablePrefix("tb_")//表名前綴
                      .setEntityLombokModel(true)//使用lombok
                      .setInclude("表1","表2");//逆向工程使用的表
        //4、包名策略配置
        PackageConfig packageConfig = new PackageConfig();
        packageConfig.setParent("com.zhu.mpg")//設(shè)置包名的parent
                     .setMapper("mapper")
                     .setService("service")
                     .setController("controller")
                     .setEntity("entity")
                     .setXml("mapper");//設(shè)置xml文件的目錄
        //5、整合配置
        AutoGenerator autoGenerator = new AutoGenerator();
        autoGenerator.setGlobalConfig(config)
                     .setDataSource(dataSourceConfig)
                     .setStrategy(strategyConfig)
                     .setPackageInfo(packageConfig);
        //6、執(zhí)行
        autoGenerator.execute();
    }
}

注:以上便是示例代碼,只要運(yùn)行該junit測(cè)試,就會(huì)生成entity、mapper接口、mapper的xml文件、service、serviceImpl、controller代碼。每一個(gè)設(shè)置代碼中均有詳細(xì)注釋,此處不再贅述。

四、自定義全局操作:

(一)、AutoSqlInjector :

BaseMapper提供了17個(gè)常用方法,但是有些需求這些方法還是不能很好的實(shí)現(xiàn),那么怎么辦呢?大家肯定會(huì)想到是在xml文件中寫sql語句解決。這樣確實(shí)可以,因?yàn)镸P是只做增強(qiáng)不做改變,我們完全可以按照mybatis的原來的方式來解決。不過MP也提供了另一種解決辦法,那就是自定義全局操作。所謂自定義全局操作,也就是我們可以在mapper中自定義一些方法,然后通過某些操作,讓自定義的這個(gè)方法也能像BaseMapper的內(nèi)置方法,供全局調(diào)用。接下來就看看如何實(shí)現(xiàn)(以deleteAll方法為例)。
1、在mapper接口中定義方法:

public interface EmplopyeeDao extends BaseMapper<Employee> {
    int deleteAll();
}
public interface UserDao extends BaseMapper<User> {
    int deleteAll();
}

在這兩個(gè)mapper接口中都定義了deleteAll方法。

2、編寫自定義注入類:

public class MySqlInjector extends AutoSqlInjector {
    @Override
    public void inject(Configuration configuration, MapperBuilderAssistant builderAssistant, 
                              Class<?> mapperClass, Class<?> modelClass, TableInfo table) {
        /* 添加一個(gè)自定義方法 */
        deleteAllUser(mapperClass, modelClass, table);
        System.out.println(table.getTableName());
    }

    public void deleteAllUser(Class<?> mapperClass, Class<?> modelClass, TableInfo table) {
        /* 執(zhí)行 SQL ,動(dòng)態(tài) SQL 參考類 SqlMethod */
        String sql = "delete from ">

注:該類繼承AutoSqlInjector,重寫inject方法。然后編寫sql語句,指定mapper接口中的方法,最后調(diào)用addDeleteMappedStatement方法即可。

3、在spring配置文件中配置:

<!-- 定義自定義注入器 -->
<bean class="com.zhu.mybatisplus.injector.MySqlInjector" id="mySqlInjector"/>
<!-- 5、mybatisplus的全局策略配置 -->
    <bean id="globalConfiguration" class="com.baomidou.mybatisplus.entity.GlobalConfiguration">
        <property name="idType" value="0"/>
        <property name="tablePrefix" value="tb_"/>
        <!-- 注入自定義全局操作 -->
        <property name="sqlInjector" ref="mySqlInjector"/>
    </bean>

注:先把剛才自定義的類注冊(cè)成bean,然后在全局策略配置的bean中引用自定義類的bean即可。

4、測(cè)試:

@Test
public void testMySqlInjector(){
    Integer result = userDao.deleteAll();
    System.out.println(result);
}

@Test
public void testMySqlInjector2(){
    Integer result = emplopyeeDao.deleteAll();
    System.out.println(result);
}

注:經(jīng)測(cè)試,當(dāng)userDao調(diào)用deleteAll方法時(shí),會(huì)刪除tb_user表的所有數(shù)據(jù),employeeDao調(diào)用deleteAll方法時(shí),會(huì)刪除tb_employee表的所有數(shù)據(jù)。說明deleteAll方法是有效的。不過在運(yùn)行這兩個(gè)測(cè)試時(shí),由于是全表刪除操作,所有要先把執(zhí)行分析插件關(guān)了。

(二)、邏輯刪除:

其實(shí)數(shù)據(jù)并不會(huì)輕易的刪除掉,畢竟數(shù)據(jù)收集不易,所以就有了邏輯刪除。邏輯刪除: 并不會(huì)真正的從數(shù)據(jù)庫中將數(shù)據(jù)刪除掉,而是將當(dāng)前被刪除的這條數(shù)據(jù)中的一個(gè)邏輯刪除字段置為刪除狀態(tài),比如該數(shù)據(jù)有一個(gè)字段logic_flag,當(dāng)其值為1表示未刪除,值為-1表示刪除,那么邏輯刪除就是將1變成-1。
1、數(shù)據(jù)表:
在數(shù)據(jù)表中需要添加邏輯刪除字段(logic_flag)。

mybatis-plus的使用方法

image.png

2、實(shí)體類:

@Data
public class User{
    private Integer id;
    private String name;
    private Integer age;
    private Integer gender;
    @TableLogic //標(biāo)記邏輯刪除屬性
    private Integer logicFlag;
}

注:數(shù)據(jù)庫中邏輯刪除字段是logic_flag,所以實(shí)體類中的logicFlag需要用@TableLogic注解標(biāo)記。

3、mapper:

public interface UserDao extends BaseMapper<User> {
}

4、配置邏輯刪除:
需要在spring-dao.xml中做如下配置:
首先定義邏輯刪除的bean:

<!-- 邏輯刪除 -->
<bean class="com.baomidou.mybatisplus.mapper.LogicSqlInjector">

再在全局配置的bean中注入邏輯刪除以及邏輯刪除值:

<!-- 5、mybatisplus的全局策略配置 -->
    <bean id="globalConfiguration" class="com.baomidou.mybatisplus.entity.GlobalConfiguration">
        <!-- 此處省略其他全局配置 -->
        <!-- 注入自定義全局操作,做邏輯刪除時(shí)需要先注釋掉 -->
        <!--<property name="sqlInjector" ref="mySqlInjector"/>-->
        <!-- 注入邏輯刪除,先要把自定義的注釋掉 -->
        <property name="sqlInjector" ref="logicSqlInjector"/>
        <!-- 注入邏輯刪除值 -->
        <property name="logicDeleteValue" value="-1"/><!-- -1是刪除狀態(tài) -->
        <property name="logicNotDeleteValue" value="1"/><!-- 1是未刪除狀態(tài) -->
    </bean>

注:因?yàn)檫壿媱h除實(shí)際上也是一個(gè)sqlInjector,所以先要把剛才做自定義全局操作時(shí)注入的自定義全局操作注釋掉,上面代碼中已有詳細(xì)注釋說明。

6、測(cè)試:

@Test
    public void testLogicDelete(){
        Integer result = userDao.deleteById(1);
        System.out.println(result);
        //User user = userDao.selectById(1);
        //System.out.println(user);
    }

注:運(yùn)行該測(cè)試,執(zhí)行刪除操作的時(shí)候,真正執(zhí)行的sql語句是UPDATE tb_user SET logic_flag=-1 WHERE id=?,就是把邏輯刪除字段的值設(shè)置為-1;當(dāng)邏輯刪除字段的值是-1時(shí)再執(zhí)行查詢操作,sql是SELECT ... FROM tb_user WHERE id=? AND logic_flag=1,所以查詢結(jié)果是null。
 

五、公共字段自動(dòng)填充:

我們知道,當(dāng)我們進(jìn)行插入或者更新操作時(shí),沒有設(shè)置值的屬性,那么在數(shù)據(jù)表中要么是為null,要么是保留原來的值。有的時(shí)候我們我們沒有賦值但是卻不想讓其為空,比如name屬性,我們插入時(shí)會(huì)默認(rèn)賦上“林志玲”,更新時(shí)會(huì)默認(rèn)賦值上“朱茵”,那么就可以用公共字段自動(dòng)填充。
1、使用@TableField注解標(biāo)記填充字段

@TableField(fill = FieldFill.INSERT_UPDATE)//插入和更新時(shí)填充
 private String name;

2、編寫公共字段填充處理器類:

public class MyMetaObjectHandler extends MetaObjectHandler {
    @Override
    public void insertFill(MetaObject metaObject) {
        Object fieldValue = getFieldValByName("name",metaObject); //獲取需要填充的字段
        if(fieldValue == null){   //如果該字段沒有設(shè)置值
            setFieldValByName("name","林志玲",metaObject); //那就將其設(shè)置為"林志玲"
        }
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        Object fieldValue = getFieldValByName("name",metaObject);//獲取需要填充的字段
        if(fieldValue == null){ //如果該字段沒有設(shè)置值
            setFieldValByName("name","朱茵",metaObject);  //那就將其設(shè)置為"朱茵"
        }
    }
}

注:該類繼承了MetaObjectHandler類,重寫了insertFill和updateFill方法,在這兩個(gè)方法獲取需要填充的字段以及默認(rèn)填充的值。

3、在spring-dao.xml中配置:

<!-- 公共字段填充處理器 -->
<bean class="com.zhu.mybatisplus.handler.MyMetaObjectHandler" id="myMetaObjectHandler"/>
<!-- 5、mybatisplus的全局策略配置 -->
    <bean id="globalConfiguration" class="com.baomidou.mybatisplus.entity.GlobalConfiguration">
        <!-- 此處省略其他配置 -->
        <!-- 注入公共字段填充處理器 -->
        <property name="metaObjectHandler" ref="myMetaObjectHandler"/>
    </bean>

注:和配置邏輯刪除一樣,都是先將自定義的類注冊(cè)成bean,再在全局策略配置中引用這個(gè)bean即可。

4、測(cè)試:

@Test
public void testHandlerInsert() {
        User user = new User();
        user.setGender(1);
        user.setAge(22);
        user.setLogicFlag(1);
        userDao.insert(user);
}

mybatis-plus的使用方法

image.png


注:可以看到,雖然我們并沒有給name賦值,但是已經(jīng)自動(dòng)把“林志玲”傳進(jìn)去了。更新時(shí)也一樣有效,此處就不將測(cè)試代碼貼出來了。

到此,關(guān)于“mybatis-plus的使用方法”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI