Spring Boot整合MyBatis-Plus(萌新入門-自用總結-核心功能-熱門插件)

MyBatis-Plus之快速啓動

MyBatis-Pluis官網
在 Spring Boot 啓動類中添加 @MapperScan 註解,掃描 Mapper 文件夾:圖中blog具體看項目

@MapperScan("com.example.blog.mapper")

在這裏插入圖片描述

1.核心功能——代碼生成器

1.1添加依賴

配置自動生成時的錯誤:mybatis-plus自動生成的時候報錯 java.lang.NoClassDefFoundError
參考 https://blog.csdn.net/wangjinb/article/details/106488308

MyBatis-Plus 從 3.0.3 之後移除了代碼生成器與模板引擎的默認依賴,需要手動添加相關依賴:

添加 代碼生成器 依賴

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>3.3.2</version>
</dependency>

添加 模板引擎 依賴,MyBatis-Plus 支持 Velocity(默認)、Freemarker、Beetl,用戶可以選擇自己熟悉的模板引擎,如果都不滿足您的要求,可以採用自定義模板引擎。

Velocity(***默認就是說該依賴必須添加,否則會報錯 ***):

<dependency>
    <groupId>org.apache.velocity</groupId>
    <artifactId>velocity-engine-core</artifactId>
    <version>2.2</version>
</dependency>

Freemarker:

<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.30</version>
</dependency>

Beetl:

<dependency>
    <groupId>com.ibeetl</groupId>
    <artifactId>beetl</artifactId>
    <version>3.1.8.RELEASE</version>
</dependency>

注意!如果您選擇了非默認引擎,需要在 AutoGenerator 中 設置模板引擎。

AutoGenerator generator = new AutoGenerator();

// set freemarker engine
generator.setTemplateEngine(new FreemarkerTemplateEngine());

// set beetl engine
generator.setTemplateEngine(new BeetlTemplateEngine());

// set custom engine (reference class is your custom engine class)
generator.setTemplateEngine(new CustomTemplateEngine());

// other config
...

1.2編寫生成文件:

我的生成文件 CodeCreate.java

package com.example.CodeGenerator;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.mysql.cj.xdevapi.Table;

//代碼生成器
public class CodeCreate {
    public static  void main(String[] args){
        //DataSourceConfig 數據源配置,通過該配置,指定需要生成代碼的具體數據庫
        //StrategyConfig 數據庫表配置,通過該配置,可指定需要生成哪些表或者排除哪些表
        //PackageConfig 包名配置,通過該配置,指定生成代碼的包路徑
        //TemplateConfig 模板配置,可自定義代碼生成的模板,實現個性化操作
        //GlobalConfig 全局策略配置,具體請查看
        //InjectionConfig 注入配置,通過該配置,可注入自定義參數等操作以實現個性化操作
        AutoGenerator mpg = new AutoGenerator();//構建一個代碼自動生成器對象
        String projectPath = System.getProperty("user.dir");
        //1.全局配置 -> GlobalConfig
        GlobalConfig gc = new GlobalConfig();
        gc.setAuthor("lzy");  //開發人員,默認null
        gc.setActiveRecord(false);//開啓 ActiveRecord 模式
        gc.setBaseResultMap(false);//開啓 BaseResultMap
        gc.setBaseColumnList(false);//開啓 baseColumnList
        gc.setDateType(DateType.ONLY_DATE); //時間類型對應策略,默認值:TIME_PACK
        gc.setIdType(IdType.ID_WORKER);//指定生成的主鍵的ID類型
        gc.setEnableCache(false);//是否在xml中添加二級緩存配置
        gc.setFileOverride(true);//是否覆蓋已有文件,默認false
        gc.setKotlin(false);//開啓 Kotlin 模式
        gc.setOpen(false); //是否打開輸出目錄
        gc.setSwagger2(true);//開啓 swagger2 模式
        gc.setOutputDir(projectPath+"/src/main/java");//生成文件的輸出目錄
        gc.setControllerName("%sController");//controller 命名方式
        gc.setEntityName("%sEntity");//實體命名方式
        gc.setMapperName("%sMapper");//mapper 命名方式
        gc.setServiceName("%sService");//service 命名方式,%s填充實體屬性,%s爲佔位符
        gc.setServiceImplName("%sServiceImpl");//service impl 命名方式
        gc.setXmlName("%sXml");//Mapper xml 命名方式
        mpg.setGlobalConfig(gc);
        //2.配置數據源 -> dataSourceConfig
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://localhost:3306/mybatis?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");  //驅動名稱
        dsc.setUsername("root");                        //數據庫連接用戶名
        dsc.setPassword("123456");                      //數據庫連接密碼
        dsc.setDbType(DbType.MYSQL);                   //數據庫類型,該類內置了常用的數據庫類型
        //dsc.setDbQuery()數據庫信息查詢類,默認由 dbType 類型決定選擇對應數據庫內置實現,實現 IDbQuery 接口自定義數據庫查詢 SQL 語句 定製化返回自己需要的內容
        //dsc.setKeyWordsHandler();
        //dsc.setSchemaName(); 數據庫 schema name
        //dsc.setTypeConvert();類型轉換,默認由 dbType 類型決定選擇對應數據庫內置實現
        mpg.setDataSource(dsc);
        //4.PackageConfig -> 包的相關配置
        PackageConfig pc = new PackageConfig();
        pc.setParent("com.example");   //父包名。如果爲空,將下面子包名必須寫全部, 否則就只需寫子包名
        pc.setModuleName("blog");   //父包模塊名
        pc.setEntity("entity");  //Entity目錄名
        pc.setMapper("mapper"); //Mapper目錄名
        pc.setController("controller"); //Controller目錄名
        pc.setService("service"); //Service目錄名
        pc.setServiceImpl("serviceImpl");//Service Impl包名
        pc.setXml("xml"); //  Mapper XML包名
        //pc.setPathInfo()  路徑配置信息
        mpg.setPackageInfo(pc);
        //3.數據庫表配置 -> StrategyConfig
        StrategyConfig strategy = new StrategyConfig();
        strategy.setInclude("User");  //設置映射表名
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        //strategy.setSuperEntityClass("你自己的父類實體,沒有就不用設置!");
        strategy.setEntityLombokModel(true); //自動lombok
        strategy.setRestControllerStyle(true);//生成 @RestController 控制器
        strategy.setLogicDeleteFieldName("deleted");//邏輯刪除名字
        //isCapitalMode是否大寫命名,skipView是否跳過視圖,

        mpg.setStrategy(strategy);
        //5.模板配置 -> TemplateConfig
//        TemplateConfig tc = new TemplateConfig();
//        tc.setEntity();
//        tc.setEntityKt();
//        tc.setService();
//        tc.setServiceImpl();
//        tc.setMapper();
//        tc.setXml();
//        tc.setController();
//        mpg.setPackageInfo(tc);
        //6.注入配置 -> injectionConfig
      mpg.execute(); //執行
    }
}

1.3我的目錄結構:

以one爲例運行CodeCreate可以生成如下圖的目錄結構
在這裏插入圖片描述
在實際編寫中service層和impl、xml層並未實際用處可以刪除,編寫一下controller層即可返回數據。

package com.example.blog.controller;


import com.example.blog.entity.UserEntity;

import com.example.blog.mapper.UserMapper;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author lzy
 * @since 2020-07-01
 */
@RestController
public class UserController {
    @Autowired

    UserMapper userMapper;

    @RequestMapping(value = "/qurry")
    public UserEntity qurryOne(){

        return userMapper.selectById(4L);
    }

    @RequestMapping(value = "/list")
    public List<UserEntity> queryAllUser(){
        List<UserEntity> users = userMapper.selectList(null);
        return users;
    }

    @RequestMapping(value = "/insert/{name}/{age}/{email}")
    public String insertUser(@PathVariable("name")String name,@PathVariable("age")Integer age,@PathVariable("email")String email){
        UserEntity user = new UserEntity();
        user.setName(name);
        user.setAge(age);
        user.setEmail(email);
        userMapper.insert(user);
        return "insert is running";
    }

    @RequestMapping(value = "/update/{id}/{name}/{age}/{email}")
    public String update(@PathVariable("id")Long id,@PathVariable("name")String name,@PathVariable("age")Integer age,@PathVariable("email")String email){
        UserEntity user = new UserEntity();
        user.setId(id);
        user.setName(name);
        user.setAge(age);
        user.setEmail(email);
        userMapper.updateById(user);
        return "update is running";
    }
    @RequestMapping(value = "/delete/{id}") //刪除
    public String DeleteUserById(@PathVariable("id")Long id){
        int r =  userMapper.deleteById(id);
        return "Delete is running";
    }
}

如下圖是訪問/hello2得到 list裏面的數據。
在這裏插入圖片描述

2 插件擴展——邏輯刪除

2.1配置文件

application.properties文件配置如下:

#配置邏輯刪除
mybatis-plus.global-config.db-config.logic-delete-field= flag  #全局邏輯刪除字段值 3.3.0開始支持,詳情看下面。
mybatis-plus.global-config.db-config.logic-delete-value=1
mybatis-plus.global-config.db-config.logic-not-delete-value=0

application.yml文件配置如下:(如果你的默認值和mp默認的一樣,該配置可無)

  global-config:
    db-config:
      logic-delete-field: flag  #全局邏輯刪除字段值 3.3.0開始支持,詳情看下面。
      logic-delete-value: 1 # 邏輯已刪除值(默認爲 1)
      logic-not-delete-value: 0 # 邏輯未刪除值(默認爲 0)

2.2數據庫表中添加字段deleted

在數據庫中書寫deleted字段,默認爲0
在這裏插入圖片描述

2.3 Entity層User/UserEntity文件下添加字段(@TableLogic)

在這裏插入圖片描述

字段支持所有數據類型(推薦使用 Integer,Boolean,LocalDateTime)
如果使用LocalDateTime,建議邏輯未刪除值設置爲字符串null,邏輯刪除值只支持數據庫函數例如now() 效果:
使用mp自帶方法刪除和查找都會附帶邏輯刪除功能 (自己寫的xml不會)
設置邏輯刪除後,執行刪除操作實際上是更新操作,更新deleted爲1,從而數據庫可見,用戶不可見
說明:

example
刪除 update user set deleted=1 where id =1 and deleted=0
查找 select * from user where deleted=0

全局邏輯刪除: begin 3.3.0

如果公司代碼比較規範,比如統一了全局都是flag爲邏輯刪除字段。

使用此配置則不需要在實體類上添加 @TableLogic。

但如果實體類上有 @TableLogic 則以實體上的爲準,忽略全局。 即先查找註解再查找全局,都沒有則此表沒有邏輯刪除。

mybatis-plus:
  global-config:
    db-config:
      logic-delete-field: flag  #全局邏輯刪除字段值

附件說明

邏輯刪除是爲了方便數據恢復和保護數據本身價值等等的一種方案,但實際就是刪除。 如果你需要再查出來就不應使用邏輯刪除,而是以一個狀態去表示。
如: 員工離職,賬號被鎖定等都應該是一個狀態字段,此種場景不應使用邏輯刪除。

若確需查找刪除數據,如老闆需要查看歷史所有數據的統計彙總信息,請單獨手寫sql。

3.條件構造器——查詢

3.1編寫測試類 WrapperTest

package com.example;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.blog.mapper.UserMapper;
import com.example.blog.entity.UserEntity;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;
import java.util.Map;

@SpringBootTest
public class WrapperTest {

    @Autowired
    private UserMapper userMapper;

    @Test
    void test1(){
        //查詢name不爲空的用戶,並且郵箱不爲空的用戶,年齡大於等於12
        QueryWrapper<UserEntity> wrapper = new QueryWrapper<>();
        wrapper
                .isNotNull("name")
                .isNotNull("email")
                .ge("age",12);
        userMapper.selectList(wrapper).forEach(System.out::println);
    }

    @Test
    void test2(){
        //查詢名字風花雪月
        QueryWrapper<UserEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("name","風花雪月");
        UserEntity user =  userMapper.selectOne(wrapper);
        System.out.println(user);
    }

    @Test
    void test3(){
        //查詢年齡在18-30
        QueryWrapper<UserEntity> wrapper = new QueryWrapper<>();
        wrapper.between("age",18,30);
        Integer count =  userMapper.selectCount(wrapper);
        System.out.println(count);
    }

    @Test
    void test4(){
        //查詢名字沒有e並且右邊以t開頭
        QueryWrapper<UserEntity> wrapper = new QueryWrapper<>();
        wrapper
                .notLike("name","e")
                .likeRight("email","t");

        List<Map<String, Object>> maps =  userMapper.selectMaps(wrapper);
        maps.forEach(System.out::println);
    }

    @Test
    void test5(){
        //id在子查詢中查詢出來
        QueryWrapper<UserEntity> wrapper = new QueryWrapper<>();
        wrapper.inSql("id","select id from user where id>3");

        List<Object> objects =  userMapper.selectObjs(wrapper);
        objects.forEach(System.out::println);
    }

    @Test
    void test6(){
        //通過id排序
        QueryWrapper<UserEntity> wrapper = new QueryWrapper<>();
        wrapper.orderByAsc("id");

        List<UserEntity> users =  userMapper.selectList(wrapper);
        users.forEach(System.out::println);
    }
}

4.核心功能——分頁插件

4.1編寫配置類MyBatisPlusConfig (取自官網拿來即用

package com.example.config;

import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@EnableTransactionManagement
@Configuration
@MapperScan("com.example.blog.mapper")  //掃描文件夾
public class MyBatisPlusConfig {
    //分頁插件
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        // 設置請求的頁面大於最大頁後操作, true調回到首頁,false 繼續請求  默認false
        // paginationInterceptor.setOverflow(false);
        // 設置最大單頁限制數量,默認 500 條,-1 不受限制
        // paginationInterceptor.setLimit(500);
        // 開啓 count 的 join 優化,只針對部分 left join
        paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
        return paginationInterceptor;
    }
}

4.2測試函數以及效果圖

在這裏插入圖片描述

5.插件擴展——自動填充功能

5.1步驟一:數據庫添加字段

在這裏插入圖片描述

5.2步驟二:在UserEntity中添加字段,也可以在自動生成中配置

在這裏插入圖片描述

5.3步驟三:自定義實現類 MyMetaObjectHandler

package com.example.handler;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.util.Date;

@Slf4j
@Component //
public class MyMetaObjectHandler implements MetaObjectHandler {

   //插入時的更新策略
    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("start insert fill...");
        this.setFieldValByName("createTime",new Date(),metaObject);
        this.setFieldValByName("updateTime",new Date(),metaObject);
    }
    //更新時的填充策略
    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("start update fill...");
        this.setFieldValByName("updateTime",new Date(),metaObject);
    }
}

5.4注意事項:

字段必須聲明TableField註解,屬性fill選擇對應策略,該聲明告知Mybatis-Plus需要預留注入SQL字段
填充處理器MyMetaObjectHandler在 Spring Boot 中需要聲明@Component或@Bean注入
要想根據註解FieldFill.xxx和字段名以及字段類型來區分必須使用父類的strictInsertFill或者strictUpdateFill方法
不需要根據任何來區分可以使用父類的fillStrategy方法**

5.5 FieIdFill策略在5.2中的應用

public enum FieldFill {
    /**
     * 默認不處理
     */
    DEFAULT,
    /**
     * 插入填充字段
     */
    INSERT,
    /**
     * 更新填充字段
     */
    UPDATE,
    /**
     * 插入和更新填充字段
     */
    INSERT_UPDATE
}

6:自用小插件——SQL配置日誌輸出

在這裏插入圖片描述

6.1:效果圖展示

在這裏插入圖片描述

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