1. 程式人生 > 實用技巧 >01 新建SpringBoot專案 整合Mybatis Plus(Spring Boot 前後端分離)

01 新建SpringBoot專案 整合Mybatis Plus(Spring Boot 前後端分離)

新建SpringBoot專案

  • create new project

  • 在這裡,URL可以改成阿里雲的URL:https://start.aliyun.com/

  • 或者換一個網路環境(作者在這裡本來是連的校園網,嘗試多次無果,換成移動網,再使用http://start.spring.io/,嘗試成功(但也不是每次都能成功),或者也可以去官網下載好,匯入IDEA)

  • 下載好需要的依賴

    • 點next,設定好路徑,點finish

  • 專案初始化後的目錄結構

整合Mybatis Plus

 <!-- 整合mybatis plus -->
        <!--mp-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.2.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!--mp程式碼生成器-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.2.0</version>
        </dependency>

寫配置資訊

# DataSource Config
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/myvueblog?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=Asia/Shanghai
    username: root
    password: 1996chen
mybatis-plus:
  mapper-locations: classpath*:/mapper/**Mapper.xml
server:
  port: 8081

建立資料庫表

-- myvueblog.sql
SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for m_blog
-- ----------------------------
DROP TABLE IF EXISTS `m_blog`;
CREATE TABLE `m_blog` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `user_id` bigint(20) NOT NULL,
  `title` varchar(255) NOT NULL,
  `description` varchar(255) NOT NULL,
  `content` longtext,
  `created` datetime NOT NULL ON UPDATE CURRENT_TIMESTAMP,
  `status` tinyint(4) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8mb4;

-- ----------------------------
-- Records of m_blog
-- ----------------------------
INSERT INTO `m_blog` VALUES ('1', '1', '生活就像海洋,只有意志堅強的人才能到達彼岸', '這裡是摘要哈哈哈', '內容???', '2020-05-21 22:08:42', '0');
INSERT INTO `m_blog` VALUES ('2', '1', '最值得學習的部落格專案eblog', 'eblog是一個基於Springboot2.1.2開發的部落格學習專案,為了讓專案融合更多的知識點,達到學習目的,編寫了詳細的從0到1開發文件。主要學習包括:自定義Freemarker標籤,使用shiro+redis完成了會話共享,redis的zset結構完成本週熱議排行榜,t-io+websocket完成即時訊息通知和群聊,rabbitmq+elasticsearch完成部落格內容搜尋引擎等。值得學習的地方很多!', '**推薦閱讀:**\r\n\r\n[分享一套SpringBoot開發部落格系統原始碼,以及完整開發文件!速度儲存!](https://mp.weixin.qq.com/s/jz6e977xP-OyaAKNjNca8w)\r\n\r\n[Github上最值得學習的100個Java開源專案,涵蓋各種技術棧!](https://mp.weixin.qq.com/s/N-U0TaEUXnBFfBsmt_OESQ)\r\n\r\n[2020年最新的常問企業面試題大全以及答案](https://mp.weixin.qq.com/s/lR5LC5GnD2Gs59ecV5R0XA)', '2020-05-28 09:36:38', '0');
INSERT INTO `m_blog` VALUES ('3', '1', '公眾號MarkerHub文章索引', '梳理Java知識,解析開源專案! 公眾號【MarkerHub】的文章分類索引,直聯公眾號文章連結!https://github.com/MarkerHub/JavaIndex', '**推薦閱讀:**\r\n\r\n[分享一套SpringBoot開發部落格系統原始碼,以及完整開發文件!速度儲存!](https://mp.weixin.qq.com/s/jz6e977xP-OyaAKNjNca8w)\r\n\r\n[Github上最值得學習的100個Java開源專案,涵蓋各種技術棧!](https://mp.weixin.qq.com/s/N-U0TaEUXnBFfBsmt_OESQ)\r\n\r\n[2020年最新的常問企業面試題大全以及答案](https://mp.weixin.qq.com/s/lR5LC5GnD2Gs59ecV5R0XA)', '2020-05-28 09:36:45', '0');
INSERT INTO `m_blog` VALUES ('7', '1', '你真的會寫單例模式嗎?', '單例模式可能是程式碼最少的模式了,但是少不一定意味著簡單,想要用好、用對單例模式,還真得費一番腦筋。本文對 Java 中常見的單例模式寫法做了一個總結,如有錯漏之處,懇請讀者指正。', '> 作者:吃桔子的攻城獅 來源:http://www.tekbroaden.com/singleton-java.html\n\n\n單例模式可能是程式碼最少的模式了,但是少不一定意味著簡單,想要用好、用對單例模式,還真得費一番腦筋。本文對 Java 中常見的單例模式寫法做了一個總結,如有錯漏之處,懇請讀者指正。\n\n餓漢法\n===\n\n顧名思義,餓漢法就是在第一次引用該類的時候就建立物件例項,而不管實際是否需要建立。程式碼如下:\n\n```\npublic class Singleton {  \n    private static Singleton = new Singleton();\n    private Singleton() {}\n    public static getSignleton(){\n        return singleton;\n    }\n}\n\n```\n\n這樣做的好處是編寫簡單,但是無法做到延遲建立物件。但是我們很多時候都希望物件可以儘可能地延遲載入,從而減小負載,所以就需要下面的懶漢法:\n', '2020-05-22 00:42:44', '0');
INSERT INTO `m_blog` VALUES ('9', '1', '真正理解Mysql的四種隔離級別@', '事務是應用程式中一系列嚴密的操作,所有操作必須成功完成,否則在每個操作中所作的所有更改都會被撤消。也就是事務具有原子性,一個事務中的一系列的操作要麼全部成功,要麼一個都不做。\n\n事務的結束有兩種,當事務中的所以步驟全部成功執行時,事務提交。如果其中一個步驟失敗,將發生回滾操作,撤消撤消之前到事務開始時的所以操作。', '### 什麼是事務  \n\n> 事務是應用程式中一系列嚴密的操作,所有操作必須成功完成,否則在每個操作中所作的所有更改都會被撤消。也就是事務具有原子性,一個事務中的一系列的操作要麼全部成功,要麼一個都不做。\n> \n> 事務的結束有兩種,當事務中的所以步驟全部成功執行時,事務提交。如果其中一個步驟失敗,將發生回滾操作,撤消撤消之前到事務開始時的所以操作。\n\n**事務的 ACID**\n\n事務具有四個特徵:原子性( Atomicity )、一致性( Consistency )、隔離性( Isolation )和持續性( Durability )。這四個特性簡稱為 ACID 特性。\n\n> 1 、原子性。事務是資料庫的邏輯工作單位,事務中包含的各操作要麼都做,要麼都不做\n> \n> 2 、一致性。事 務執行的結果必須是使資料庫從一個一致性狀態變到另一個一致性狀態。因此當資料庫只包含成功事務提交的結果時,就說資料庫處於一致性狀態。如果資料庫系統 執行中發生故障,有些事務尚未完成就被迫中斷,這些未完成事務對資料庫所做的修改有一部分已寫入物理資料庫,這時資料庫就處於一種不正確的狀態,或者說是 不一致的狀態。', '2020-05-22 22:04:46', '0');
INSERT INTO `m_blog` VALUES ('10', '1', '部落格專案eblog講解視訊上線啦,長達17個小時!!', '1. 慕課網免費資源好久都沒更新了,新教程大都付費\n2. B站上的視訊繁多,通過收藏和彈幕數量通常很容易判斷出視訊是否優質\n3. 講真,B站的彈幕文化,讓我覺得,我不是一個在學習,自古人才出評論。哈哈哈\n4. B站視訊通常廣告少,up主的用心錄製,通常只為了你關注他', 'ok,再回到我們的eblog專案,原始碼、文件、視訊我都開源出來了。來些基本操作:github上給個star,B站視訊給個三連支援咧。\n\neblog原始碼:https://github.com/MarkerHub/eblog\n\n點選這裡:[10+篇完整開發文件](https://mp.weixin.qq.com/mp/homepage?__biz=MzIwODkzOTc1MQ==&hid=1&sn=8e512316c3dfe140e636d0c996951166)\n\n![](//image-1300566513.cos.ap-guangzhou.myqcloud.com/upload/images/20200508/c290d945b7d24c79b172759bdb5b94e0.png)\n\n視訊講解:(記得關注我噢!)\n\nhttps://www.bilibili.com/video/BV1ri4y1x71A\n\n![](//image-1300566513.cos.ap-guangzhou.myqcloud.com/upload/images/20200508/983b5abc1c934360a1a1362347a275f7.png)\n\n專案其實還很多bug的,哈哈,我還需要進行二次迭代,到時候再發迭代文件出來。\n\n關注下我的B站,作為一個自媒體的自由職業者,沒有什麼比漲粉更讓我開心的了,嘻嘻。\n\n近期即將推出的視訊教程:\n\n1. 搭建腳手架,前後端分離首秀\n2. Shiro入門到精通教程\n3. SpringBoot2.2.6最新入門教程', '2020-05-22 22:05:49', '0');

-- ----------------------------
-- Table structure for m_user
-- ----------------------------
DROP TABLE IF EXISTS `m_user`;
CREATE TABLE `m_user` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `username` varchar(64) DEFAULT NULL,
  `avatar` varchar(255) DEFAULT NULL,
  `email` varchar(64) DEFAULT NULL,
  `password` varchar(64) DEFAULT NULL,
  `status` int(5) NOT NULL,
  `created` datetime DEFAULT NULL,
  `last_login` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `UK_USERNAME` (`username`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of m_user
-- ----------------------------
INSERT INTO `m_user` VALUES ('1', 'markerhub', 'https://image-1300566513.cos.ap-guangzhou.myqcloud.com/upload/images/5a9f48118166308daba8b6da7e466aab.jpg', null, '96e79218965eb72c92a549dd5a330112', '0', '2020-04-20 10:44:01', null);

開啟mapper介面掃描,新增分頁外掛

  • 新建一個包:通過@mapperScan註解指定要變成實現類的介面所在的包,然後包下面的所有介面在編譯之後都會生成相應的實現類。PaginationInterceptor是一個分頁外掛。
  • com.gychen.config.MybatisPlusConfig
@Configuration
@EnableTransactionManagement
@MapperScan("com.gychen.mapper")
public class MybatisPlusConfig {
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        return paginationInterceptor;
    }
}

程式碼生成

  • 如果你沒再用其他外掛,那麼現在就已經可以使用mybatis plus了,官方給我們提供了一個程式碼生成器,然後我寫上自己的引數之後,就可以直接根據資料庫表資訊生成entity、service、mapper等介面和實現類。
  • com.gychen.CodeGenerator
  • 修改資料庫資訊和包路徑名
package com.gychen;

import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

// 演示例子,執行 main 方法控制檯輸入模組表名回車自動生成對應專案目錄中
public class CodeGenerator {

    /**
     * <p>
     * 讀取控制檯內容
     * </p>
     */
    public static String scanner(String tip) {
        Scanner scanner = new Scanner(System.in);
        StringBuilder help = new StringBuilder();
        help.append("請輸入" + tip + ":");
        System.out.println(help.toString());
        if (scanner.hasNext()) {
            String ipt = scanner.next();
            if (StringUtils.isNotEmpty(ipt)) {
                return ipt;
            }
        }
        throw new MybatisPlusException("請輸入正確的" + tip + "!");
    }

    public static void main(String[] args) {
        // 程式碼生成器
        AutoGenerator mpg = new AutoGenerator();

        // 全域性配置
        GlobalConfig gc = new GlobalConfig();
        String projectPath = System.getProperty("user.dir");
        gc.setOutputDir(projectPath + "/src/main/java");
//        gc.setOutputDir("D:\\test");
        gc.setAuthor("關注wx號:wxcgy666");
        gc.setOpen(false);
        // gc.setSwagger2(true); 實體屬性 Swagger2 註解
        gc.setServiceName("%sService");
        mpg.setGlobalConfig(gc);

        // 資料來源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://localhost:3306/myvueblog?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=UTC");
        // dsc.setSchemaName("public");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("1996chen");
        mpg.setDataSource(dsc);

        // 包配置
        PackageConfig pc = new PackageConfig();
        pc.setModuleName(null);
        pc.setParent("com.gychen");
        mpg.setPackageInfo(pc);

        // 自定義配置
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {
                // to do nothing
            }
        };

        // 如果模板引擎是 freemarker
        String templatePath = "/templates/mapper.xml.ftl";
        // 如果模板引擎是 velocity
        // String templatePath = "/templates/mapper.xml.vm";

        // 自定義輸出配置
        List<FileOutConfig> focList = new ArrayList<>();
        // 自定義配置會被優先輸出
        focList.add(new FileOutConfig(templatePath) {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定義輸出檔名 , 如果你 Entity 設定了前後綴、此處注意 xml 的名稱會跟著發生變化!!
                return projectPath + "/src/main/resources/mapper/"
                        + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
            }
        });

        cfg.setFileOutConfigList(focList);
        mpg.setCfg(cfg);

        // 配置模板
        TemplateConfig templateConfig = new TemplateConfig();

        templateConfig.setXml(null);
        mpg.setTemplate(templateConfig);

        // 策略配置
        StrategyConfig strategy = new StrategyConfig();
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        strategy.setEntityLombokModel(true);
        strategy.setRestControllerStyle(true);
        strategy.setInclude(scanner("表名,多個英文逗號分割").split(","));
        strategy.setControllerMappingHyphenStyle(true);
        strategy.setTablePrefix("m_");
        mpg.setStrategy(strategy);
        mpg.setTemplateEngine(new FreemarkerTemplateEngine());
        mpg.execute();
    }
}
  • 執行CodeGenerator.java
  • 輸入資料庫表(m_user,m_blog)名來自動生成程式碼
  • 然後就出現這些目錄和程式碼

測試程式碼

  • 在UserController裡寫上測試程式碼

  • @RestController
    @RequestMapping("/user")
    public class UserController {
        @Autowired
        UserService userService;
        @GetMapping("/index")
        public Object index(){
            return userService.getById(1L);
        }
    }
    
  • 然後run起來(第一次學SpringBoot,竟然連Tomcat都不需要配置)

    • 在這裡run的時候沒有成功,是因為spring-boot-starter-parent的2.2.6版本太高了,改為2.1.2.RELEASE就run成功了。