springboot2.x 集成 Mybatis plus(多數(shù)據(jù)源)榔昔,提升20%的開發(fā)效率

前言

很多人在做ORM框架選型的時(shí)候,都在猶豫:Mybatis定硝、Mybatis plus皿桑、Spring data JPA 如何選?尤其是Mybatis系列和Spring data JPA如何選蔬啡。經(jīng)過筆者在實(shí)際項(xiàng)目中使用诲侮,極力推薦Mybatis plus。理由如下:

  • Spring data JPA 提供標(biāo)準(zhǔn)化API箱蟆,如MySQL沟绪、Oracle、Elasticsearch都支持空猜。一些簡(jiǎn)單的CURD擼起代碼來(lái)還是很爽绽慈。但復(fù)雜的查詢恨旱,比起Mybatis Plus、Nutz等ORM框架坝疼,復(fù)雜很多搜贤,沒那么容易上手。另外裙士,自定義SQL方面,復(fù)雜一點(diǎn)的SQL管毙,在注解里面來(lái)表達(dá)腿椎,很不美觀,也不易于維護(hù)夭咬。
  • Spring data JPA 底層是使用 Hibernate 的 JPA 技術(shù)實(shí)現(xiàn)啃炸,服務(wù)啟動(dòng)真的是巨慢無(wú)比,尤其是在表很多的時(shí)候卓舵。但應(yīng)該有解決辦法南用,當(dāng)時(shí)沒有時(shí)間研究。
  • 如果選擇了Mybatis掏湾、那何必不選擇Mybatis plus呢裹虫?Mybatis plus只做增強(qiáng)不做改變,真的是潤(rùn)物細(xì)如聲融击。很多簡(jiǎn)單的CURD直接條件構(gòu)造器完成筑公,省去了很多xml代碼。如果又想寫復(fù)雜的SQL秀一秀尊浪,可以去xml定義SQL匣屡,就跟Mybatis一樣!

如何集成

Step1: 引入相關(guān)jar依賴

<!-- Spring Boot Mybatis plus 依賴 -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.2.0</version>
</dependency>

<!-- Spring Boot Dynamic Datasource 依賴 -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
    <version>2.5.6</version>
</dependency>

<!-- MySQL 連接驅(qū)動(dòng)依賴 -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.48</version>
</dependency>

<!-- Druid 連接池管理依賴 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.1.18</version>
</dependency>

Step2:數(shù)據(jù)源配置拇涤。我這里舉例:db1-master捣作、db1-slave、db2-slave這種在實(shí)際項(xiàng)目中遇到的場(chǎng)景:寫主庫(kù)鹅士、讀從庫(kù)券躁,甚至還依賴別的庫(kù)。

spring:
  application:
    name: spring-demo
  # DB 配置
  datasource:
    dynamic:
      primary: db1-master
      p6spy: true
      druid:
        initial-size: 5
        min-idle: 5
        max-active: 20
        validation-query: SELECT 1 FROM DUAL
        test-while-idle: true
        validation-query-timeout: 2
        filters: stat,wall,slf4j
      datasource:
        # db1-主庫(kù)數(shù)據(jù)源
        db1-master:
          url: jdbc:mysql://localhost:3306/user?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&rewriteBatchedStatements=true
          username: root
          password: 123456
        # db1-從數(shù)據(jù)源
        db1-slave:
          url: jdbc:mysql://localhost:3306/user2?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&rewriteBatchedStatements=true
          username: root
          password: 123456
        # db2-從數(shù)據(jù)源
        db2-slave:
          url: jdbc:mysql://localhost:3006/user3?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull
          username: root
          password: 123456

Step3:@MapperScan 聲明掉盅。我這里放到了 MybatisPlusConfig 類里嘱朽,如果你高興,@MapperScan 也可以定義到啟動(dòng)的Main方法類里怔接。

package com.yb.demo.config.db;

import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author daoshenzzg@163.com
 * @date 2019-09-05 09:41
 */
@Configuration
@MapperScan({"com.yb.demo.dao.mapper"})
public class MybatisPlusConfig {
    /**
     * 分頁(yè)插件
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        paginationInterceptor.setLimit(100);
        return paginationInterceptor;
    }
}

Step4:定義Model實(shí)體搪泳。@TableName 對(duì)應(yīng)的就是表名,字段對(duì)應(yīng)表的字段扼脐,表字段是下劃線隔開岸军,實(shí)體類直接是駝峰了奋刽,具體見配置文件:capital-mode: true。

package com.yb.demo.pojo.model.db1;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

/**
 * @author daoshenzzg@163.com
 * @date 2019-08-05 17:58
 */
@Data
@TableName("student")
public class Student1DO {
    private Long id;
    private String studName;
    private Integer studAge;
    private String studSex;
    @TableField(fill = FieldFill.INSERT)
    private Integer createTime;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Integer updateTime;
}

Step5:自動(dòng)填充艰赞。上面的 @TableField(fill = FieldFill.INSERT)佣谐、@TableField(fill = FieldFill.INSERT_UPDATE) 估計(jì)有同學(xué)就在好奇,這是干什么用的方妖。這其實(shí)是Mybatis plus的自動(dòng)填充注解標(biāo)記狭魂。配置 MetaObjectHandler 使用,可以做到自動(dòng)填充字段的效果党觅。

package com.yb.demo.config.db;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

/**
 * @author daoshenzzg@163.com
 * @date 2019-09-04 17:08
 */
@Component
public class DefaultMetaObjectHandler implements MetaObjectHandler {

    @Override
    public void insertFill(MetaObject metaObject) {
        this.setFieldValByName("createTime", (int) System.currentTimeMillis() / 1000, metaObject);
        this.setFieldValByName("updateTime", (int) System.currentTimeMillis() / 1000, metaObject);
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        this.setFieldValByName("updateTime", (int) System.currentTimeMillis() / 1000, metaObject);
    }
}

Step6:定義Mapper雌澄。其中@DS注解可以明確指定使用哪個(gè)數(shù)據(jù)源,用以實(shí)現(xiàn)動(dòng)態(tài)數(shù)據(jù)源配置杯瞻。如果是同一數(shù)據(jù)源镐牺,實(shí)體類都一樣,只是有主從之分魁莉,如何切換呢睬涧?其實(shí)也簡(jiǎn)單:只需要在調(diào)用該mapper的service方法上加上 @DS("db1-master") 或 @DS("db1-slave") 就可以完成主從切換了。

package com.yb.demo.dao.mapper.db1;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yb.demo.pojo.model.db1.Student1DO;
import org.springframework.stereotype.Repository;

/**
 * @author daoshenzzg@163.com
 * @date 2019-08-05 17:56
 */
@DS("db1-master")
@Repository
public interface Student1Mapper extends BaseMapper<Student1DO> {
}

Step7:XML配置旗唁,如果你愿意畦浓,幾乎不需要寫任何xml代碼。

<?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.yb.demo.dao.mapper.db1.Student1Mapper">
</mapper>

Step8:如何做到的呢检疫?Mybatis plus 支持條件構(gòu)造器宅粥。

@Slf4j
@Service
public class StudentService extends ServiceImpl<Student1Mapper, Student1DO> {

    /**
     * 學(xué)生列表
     *
     * @return
     */
    public List<Student1DO> listStudent(String studName) {
        QueryWrapper<Student1DO> queryWrapper = new QueryWrapper<>();
        queryWrapper.like("student_name", studName);
        return super.list(queryWrapper);
    }
}    

Step9:分頁(yè)也不需要寫任何xml代碼!电谣!

@Slf4j
@Service
public class StudentService extends ServiceImpl<Student1Mapper, Student1DO> {

    /**
     * 學(xué)生列表
     *
     * @return
     */
    public IPage<Student1DO> listStudentByPage(String studName, int pageNum, int pageSize) {
        Page<Student1DO> page = new Page<>(pageNum, pageSize);
        QueryWrapper<Student1DO> queryWrapper = new QueryWrapper<>();
        queryWrapper.like("student_name", studName);
        return super.page(page, queryWrapper);
    }
}    

Step10:很關(guān)鍵的一步秽梅。@SpringBootApplication(exclude = DruidDataSourceAutoConfigure.class)

package com.yb.demo;

import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.transaction.annotation.EnableTransactionManagement;

/**
 * @author daoshenzzg@163.com
 * @date 2019-08-05 16:19
 */
@EnableTransactionManagement
@SpringBootApplication(exclude = DruidDataSourceAutoConfigure.class)
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

結(jié)束語(yǔ)

實(shí)際開發(fā)過程中,使用Mybatis plus基礎(chǔ)的CURD方法及條件構(gòu)造器剿牺,可以提升許多開發(fā)效率企垦。

本系列文章

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末剪返,一起剝皮案震驚了整個(gè)濱河市废累,隨后出現(xiàn)的幾起案子认轨,更是在濱河造成了極大的恐慌窟勃,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,183評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件捅僵,死亡現(xiàn)場(chǎng)離奇詭異钱反,居然都是意外死亡掖看,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門面哥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)哎壳,“玉大人,你說我怎么就攤上這事幢竹《停” “怎么了恩静?”我有些...
    開封第一講書人閱讀 168,766評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵焕毫,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我驶乾,道長(zhǎng)邑飒,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,854評(píng)論 1 299
  • 正文 為了忘掉前任级乐,我火速辦了婚禮疙咸,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘风科。我一直安慰自己撒轮,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評(píng)論 6 398
  • 文/花漫 我一把揭開白布贼穆。 她就那樣靜靜地躺著题山,像睡著了一般。 火紅的嫁衣襯著肌膚如雪故痊。 梳的紋絲不亂的頭發(fā)上顶瞳,一...
    開封第一講書人閱讀 52,457評(píng)論 1 311
  • 那天,我揣著相機(jī)與錄音愕秫,去河邊找鬼慨菱。 笑死,一個(gè)胖子當(dāng)著我的面吹牛戴甩,可吹牛的內(nèi)容都是我干的符喝。 我是一名探鬼主播,決...
    沈念sama閱讀 40,999評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼甜孤,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼洲劣!你這毒婦竟也來(lái)了备蚓?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,914評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤囱稽,失蹤者是張志新(化名)和其女友劉穎郊尝,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體战惊,經(jīng)...
    沈念sama閱讀 46,465評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡流昏,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了吞获。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片况凉。...
    茶點(diǎn)故事閱讀 40,675評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖各拷,靈堂內(nèi)的尸體忽然破棺而出刁绒,到底是詐尸還是另有隱情,我是刑警寧澤烤黍,帶...
    沈念sama閱讀 36,354評(píng)論 5 351
  • 正文 年R本政府宣布知市,位于F島的核電站,受9級(jí)特大地震影響速蕊,放射性物質(zhì)發(fā)生泄漏嫂丙。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評(píng)論 3 335
  • 文/蒙蒙 一规哲、第九天 我趴在偏房一處隱蔽的房頂上張望跟啤。 院中可真熱鬧,春花似錦唉锌、人聲如沸隅肥。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)腥放。三九已至,卻和暖如春痘番,著一層夾襖步出監(jiān)牢的瞬間捉片,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工汞舱, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留伍纫,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,091評(píng)論 3 378
  • 正文 我出身青樓昂芜,卻偏偏與公主長(zhǎng)得像莹规,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子泌神,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評(píng)論 2 360