歡迎光臨
每天分享高質量文章

SpringBoot | 第九章:Mybatis-plus 的集成和使用

(點擊上方公眾號,可快速關註)


來源:oKong ,

blog.lqdev.cn/2018/07/21/springboot/chapter-nine/

前言

本章節開始介紹資料訪問方面的相關知識點。對於後端開發者而言,和資料庫打交道是每天都在進行的,所以一個好用的ORM框架是很有必要的。目前,絕大部分公司都選擇MyBatis框架作為底層資料庫持久化框架。

多說幾句

看著現在Mybatis框架的大行其道,讓我不禁想起,大學時期,當時還是hibernate的時代,現在基本已經忘記了。而當時,Mybatis的前身iBatis還在書中的某個章節出現過。當時大學老師的意思是:目前國內基本沒有使用iBatis的公司,所以這一章節略過,略,過。。。現在對這個還記憶猶新,看著現在Mybatis大行其道,不禁令人唏噓呀。

Mybatis-Plus

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

官方網站:http://mp.baomidou.com

簡單來說,Mybatis-Plus是Mybatis的增強工具包,其簡化了CRUD操作,提供了代碼生成器,強大的條件建構式(這是我最喜歡的一個),同時內置了多個實用插件:標配的分頁插件、性能分析插件、全域性攔截插件等。使得開發過程中,基本的範式代碼都一句話解決了,省去了很多重覆的操作(程式猿存在的意義呢,說好的讓我們搬磚呢!)。

SpringBoot集成

這裡選用的mybatis-plus版本為:2.1.9,

mybatisplus-spring-boot-starter版本為:1.0.5。

對應Mybatis版本為:3.4.5

0. 這裡以user表為例子,資料庫為mysql

DROP TABLE IF EXISTS `user`;

CREATE TABLE `user` (

  `id` bigint(20) DEFAULT NULL COMMENT ‘唯一標示’,

  `code` varchar(20) DEFAULT NULL COMMENT ‘編碼’,

  `name` varchar(64) DEFAULT NULL COMMENT ‘名稱’,

  `status` char(1) DEFAULT ‘1’ COMMENT ‘狀態 1啟用 0 停用’,

  `gmt_create` datetime DEFAULT CURRENT_TIMESTAMP COMMENT ‘創建時間’,

  `gmt_modified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT ‘修改時間’

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

1. pom依賴:

    com.baomidou

    mybatisplus-spring-boot-starter

    1.0.5

    com.baomidou

    mybatis-plus

    2.1.9

2. 配置檔案(當然也可以直接使用@Bean的方式進行或者通過application配置檔案進行,詳見官網)

spring-mybatis.xml

 

       xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xmlns:tx=”http://www.springframework.org/schema/tx”

       xsi:schemaLocation=”http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd”>

 

   

   

       

       

       

       

       

       

       

       

       

       

       

       

       

       

 

       

       

       

       

 

       

       

       

       

 

       

       

       

       

       

       

 

       

       

   

 

   

   

          class=”org.springframework.jdbc.datasource.DataSourceTransactionManager”>

       

   

 

   

   

 

   

   

       

       

       

       

       

       

       

       

       

   

   

       

       

   

   

   

       

   

 

3. 編寫啟動類,應用啟動時自動加載配置xml檔案

/**

 *  mybatisPlus 配置類,使其加載配置檔案

 * @author oKong

 *

 */

@Configuration

@ImportResource(locations = {“classpath:/mybatis/spring-mybatis.xml”})

//@MapperScan(“cn.lqdev.learning.springboot.chapter9.biz.dao”)

//@EnableTransactionManagement

public class MybatisPlusConfig {

 

}

至此,mybatis-plus就配置完成了,接下來,利用代碼生成器一次性創建所需的dao、mapper、通用CRUDservice類。

4. 編寫代碼生成器類

由於生成器依賴velocity模版引擎,故需要加入依賴:

    org.apache.velocity

    velocity-engine-core

    2.0

    test

MysqlGenerator,此類較長,相關配置可根據實際情況信息修改替換。

public class MysqlGenerator {

 

    private static final String PACKAGE_NAME = “cn.lqdev.learning.springboot.chapter9”;

    private static final String MODULE_NAME = “biz”;

    private static final String OUT_PATH = “D:\\develop\\code”;

    private static final String AUTHOR = “oKong”;

 

    private static final String DRIVER = “com.mysql.jdbc.Driver”;

    private static final String URL = “jdbc:mysql://127.0.0.1:3306/learning?useUnicode=true&characterEncoding;=UTF-8”;

    private static final String USER_NAME = “root”;

    private static final String PASSWORD = “123456”;

 

    /**

     *

     * MySQL 生成演示

     *

     */

    public static void main(String[] args) {

        // 自定義需要填充的欄位

        List tableFillList = new ArrayList();

 

        // 代碼生成器

        AutoGenerator mpg = new AutoGenerator().setGlobalConfig(

                // 全域性配置

                new GlobalConfig().setOutputDir(OUT_PATH)// 輸出目錄

                        .setFileOverride(true)// 是否改寫檔案

                        .setActiveRecord(true)// 開啟 activeRecord 樣式

                        .setEnableCache(false)// XML 二級快取

                        .setBaseResultMap(false)// XML ResultMap

                        .setBaseColumnList(true)// XML columList

                        .setAuthor(AUTHOR)

                        // 自定義檔案命名,註意 %s 會自動填充表物體屬性!

                        .setXmlName(“%sMapper”).setMapperName(“%sDao”)

        // .setServiceName(“MP%sService”)

        // .setServiceImplName(“%sServiceDiy”)

        // .setControllerName(“%sAction”)

        ).setDataSource(

                // 資料源配置

                new DataSourceConfig().setDbType(DbType.MYSQL)// 資料庫型別

                        .setTypeConvert(new MySqlTypeConvert() {

                            // 自定義資料庫表欄位型別轉換【可選】

                            @Override

                            public DbColumnType processTypeConvert(String fieldType) {

                                System.out.println(“轉換型別:” + fieldType);

                                // if ( fieldType.toLowerCase().contains( “tinyint” ) ) {

                                // return DbColumnType.BOOLEAN;

                                // }

                                return super.processTypeConvert(fieldType);

                            }

                        }).setDriverName(DRIVER).setUsername(USER_NAME).setPassword(PASSWORD).setUrl(URL))

                .setStrategy(

                        // 策略配置

                        new StrategyConfig()

                                // .setCapitalMode(true)// 全域性大寫命名

                                .setDbColumnUnderline(true)// 全域性下劃線命名

                                // .setTablePrefix(new String[]{“unionpay_”})// 此處可以修改為您的表前綴

                                .setNaming(NamingStrategy.underline_to_camel)// 表名生成策略

                                // .setInclude(new String[] {“citycode_org”}) // 需要生成的表

                                // .setExclude(new String[]{“test”}) // 排除生成的表

                                // 自定義物體,公共欄位

                                // .setSuperEntityColumns(new String[]{“test_id”})

                                .setTableFillList(tableFillList)

                                // 自定義物體父類

                                // .setSuperEntityClass(“com.baomidou.demo.common.base.BsBaseEntity”)

                                // // 自定義 mapper 父類

                                // .setSuperMapperClass(“com.baomidou.demo.common.base.BsBaseMapper”)

                                // // 自定義 service 父類

                                // .setSuperServiceClass(“com.baomidou.demo.common.base.BsBaseService”)

                                // // 自定義 service 實現類父類

                                // .setSuperServiceImplClass(“com.baomidou.demo.common.base.BsBaseServiceImpl”)

                                // 自定義 controller 父類

                                // .setSuperControllerClass(“com.baomidou.demo.TestController”)

                                // 【物體】是否生成欄位常量(預設 false)

                                // public static final String ID = “test_id”;

                                .setEntityColumnConstant(true)

                                // 【物體】是否為構建者模型(預設 false)

                                // public User setName(String name) {this.name = name; return this;}

                                .setEntityBuilderModel(true)

                                // 【物體】是否為lombok模型(預設 false)document

                                .setEntityLombokModel(true)

                // Boolean型別欄位是否移除is前綴處理

                // .setEntityBooleanColumnRemoveIsPrefix(true)

                // .setRestControllerStyle(true)

                // .setControllerMappingHyphenStyle(true)

                ).setPackageInfo(

                        // 包配置

                        new PackageConfig().setModuleName(MODULE_NAME).setParent(PACKAGE_NAME)// 自定義包路徑

                                .setController(“controller”)// 這裡是控制器包名,預設 web

                                .setXml(“mapper”).setMapper(“dao”)

 

                ).setCfg(

                        // 註入自定義配置,可以在 VM 中使用 cfg.abc 設置的值

                        new InjectionConfig() {

                            @Override

                            public void initMap() {

                                Map map = new HashMap();

                                map.put(“abc”, this.getConfig().getGlobalConfig().getAuthor() + “-mp”);

                                this.setMap(map);

                            }

                        }.setFileOutConfigList(

                                Collections.singletonList(new FileOutConfig(“/templates/mapper.xml.vm”) {

                                    // 自定義輸出檔案目錄

                                    @Override

                                    public String outputFile(TableInfo tableInfo) {

                                        return OUT_PATH + “/xml/” + tableInfo.getEntityName() + “Mapper.xml”;

                                    }

                                })))

                .setTemplate(

                        // 關閉預設 xml 生成,調整生成 至 根目錄

                        new TemplateConfig().setXml(null)

        // 自定義模板配置,模板可以參考原始碼 /mybatis-plus/src/main/resources/template 使用 copy

        // 至您專案 src/main/resources/template 目錄下,模板名稱也可自定義如下配置:

        // .setController(“…”);

        // .setEntity(“…”);

        // .setMapper(“…”);

        // .setXml(“…”);

        // .setService(“…”);

        // .setServiceImpl(“…”);

        );

 

        // 執行生成

        mpg.execute();

    }

 

}

運行後即可,省了多少事!

簡單實體

簡單演示下增刪改查及分頁的使用。

使用分頁時,mybatis-config.xml需要加入分頁插件:PerformanceInterceptor

 

 

編寫控制層

/**

 * 用戶控制層 簡單演示增刪改查及分頁

 * @author oKong

 *

 */

@RestController

@RequestMapping(“/user”)

public class UserController {

 

    @Autowired

    IUserService userService;

 

    @PostMapping(“add”)

    //正常業務時, 需要在user類裡面進行事務控制,控制層一般不進行業務控制的。

    //@Transactional(rollbackFor = Exception.class)

    public Map addUser(@Valid @RequestBody UserReq userReq){

 

        User user = new User();

        user.setCode(userReq.getCode());

        user.setName(userReq.getName());

        //由於設置了主鍵策略 id可不用賦值 會自動生成

        //user.setId(0L);

        userService.insert(user);

        Map result = new HashMap();

        result.put(“respCode”, “01”);

        result.put(“respMsg”, “新增成功”);

        //事務測試

        //System.out.println(1/0);

        return result;

    }

 

    @PostMapping(“update”)

    public Map updateUser(@Valid @RequestBody UserReq userReq){

 

        if(userReq.getId() == null || “”.equals(userReq.getId())) {

            throw new CommonException(“0000”, “更新時ID不能為空”);

        }

        User user = new User();

        user.setCode(userReq.getCode());

        user.setName(userReq.getName());

        user.setId(Long.parseLong(userReq.getId()));        

        userService.updateById(user);

        Map result = new HashMap();

        result.put(“respCode”, “01”);

        result.put(“respMsg”, “更新成功”);

        return result;

    }

 

    @GetMapping(“/get/{id}”)

    public Map getUser(@PathVariable(“id”) String id){

        //查詢

        User user = userService.selectById(id);

        if(user == null) {

            throw new CommonException(“0001”, “用戶ID:” + id + “,未找到”);

        }

        UserResp resp = UserResp.builder()

                .id(user.getId().toString())

                .code(user.getCode())

                .name(user.getName())

                .status(user.getStatus())

                .build();

        Map result = new HashMap();

        result.put(“respCode”, “01”);

        result.put(“respMsg”, “成功”);

        result.put(“data”, resp);

        return result;

    }

 

    @GetMapping(“/page”)

    public Map pageUser(int current, int size){

        //分頁

        Page page = new Page<>(current, size);

        Map result = new HashMap();

        result.put(“respCode”, “01”);

        result.put(“respMsg”, “成功”);

        result.put(“data”, userService.selectPage(page));

        return result;

    }       

}

啟動應用後,使用postman依次訪問對應的url地址即可。

資料庫:

分頁

由於配置了分析插件,控制台會輸出執行的sql陳述句

其他的就不一一貼圖了。

關於事務

正常情況下,只需要在服務層中加入@Transactional即可,事務相關的此章節不進行闡述,之後有機會會專門拿一個章節來說明下。

示例中為了方便,直接在控制層中加入了@Transactional進行事務測試,正式開發過程中,強烈建議在服務層進行業務控制,控制層一般上是進行邏輯判斷的!

物體物件欄位為列舉類

可能在實際開發中,大家會碰到,為了方便,一些型別、狀態欄位會編寫成列舉型別,比如啟用狀態:DISABLE(“0”),ENABLE(“1”)。此時可通過配置typeHandlers進行自定義型別的處理,這裡簡單以EnumOrdinalTypeHandler(儲存enum類里的序號值)進行示例,當然也可根據需要進行自定義處理器的編寫,比如編寫一個通用的列舉轉換器等,其他相關知識點,大家可自行谷歌。

StatusEnums

public enum StatusEnum {

 

    DISABLE,

    ENABLE;

 

}

將user物件修改成列舉型別

/**

 * 狀態1 啟用 0 停用

 */

private StatusEnum status;

配置檔案mybatis-config.xml加入處理類

   

     javaType=”cn.lqdev.learning.springboot.chapter9.biz.entity.StatusEnum”/>

之後就會自動進行轉換了。大家可下載示例,進行實際操作下。

總結

本章節主要是對Mybatis-plus的集成和簡單使用進行了說明,詳細的用法,可到官網查看,官網有詳細的使用指南,這裡就不班門弄斧了。至此,對於一般的開發需求基本上都可以滿足了。接下來的章節會重點講解其他配套工具的使用,敬請期待!

最後

目前互聯網上很多大佬都有springboot系列教程,如有雷同,請多多包涵了。本文是作者在電腦前一字一句敲的,每一步都是實踐的。若文中有所錯誤之處,還望提出,謝謝。

系列


【關於投稿】


如果大家有原創好文投稿,請直接給公號發送留言。


① 留言格式:
【投稿】+《 文章標題》+ 文章鏈接

② 示例:
【投稿】《不要自稱是程式員,我十多年的 IT 職場總結》:http://blog.jobbole.com/94148/

③ 最後請附上您的個人簡介哈~



看完本文有收穫?請轉發分享給更多人

關註「ImportNew」,提升Java技能

赞(0)

分享創造快樂