動手寫個java快速開發(fā)框架-(2)集成mybatis plus

對于一個快速開發(fā)框架來說,離不開一個很重要的功能模塊那就是數(shù)據(jù)庫訪問椿猎,目前在日常開發(fā)中用的最多的當(dāng)然就是mybatis了,但是mybatis同樣也會給我們帶來很多重復(fù)的開發(fā)工作寿弱,例如一般的CRUD犯眠,也有很多開源框架在mybatis的基礎(chǔ)上又封裝了基礎(chǔ)CRUD的基礎(chǔ)類,但是這樣的壞處也顯而易見症革,和mybatis耦合很強筐咧,這里在我們的框架中,我們直接集成國內(nèi)比較好的mybatis組件-mybatis plus噪矛,這個組件在github上的人氣也很高量蕊,因為其底層原理很簡單,所以大家也可以借助于該組件做一些深度二開艇挨,并且與mybatis沒有強耦合残炮,是兩個獨立的jar包。mybatis plus基于mybatis定義了很多Base范性基類缩滨,開發(fā)者只要將自己的Mapper和service繼承自這些范性基類就可以直接繼承基礎(chǔ)的CRUD的方法势就,可以大幅減少代碼量。

下面我們就拿上一篇提到的系統(tǒng)日志記錄數(shù)據(jù)庫的功能來舉例子脉漏,讓大家體驗下在自己的框架中集成mybatis plus苞冯。

POM增加依賴

在之前框架的POM中新增以下依賴,因為我們框架是基于springboot開發(fā)所以這里我們直接使用mybatis plus為springboot開發(fā)的組件‘mybatis-plus-boot-starter’鸠删,可以更加方便和springboot集成抱完,當(dāng)然你也可以依賴mybatis plus基礎(chǔ)庫,但是要做些配置,具體可以參考官網(wǎng)文檔汗唱,所以這里偷懶直接用了boot組件亿虽。

除了依賴mybatis plus的庫谍夭,當(dāng)然訪問數(shù)據(jù)庫還要依賴相關(guān)數(shù)據(jù)庫的connector阅羹,只要是mybatis支持的數(shù)據(jù)庫熟丸,當(dāng)然plus也都可以支持是钥,例子中我們用了大家日常用的最多的mysql讥巡,使用其他數(shù)據(jù)庫的需要替換掉依賴的數(shù)據(jù)庫connector老翘,yml或property里的配置也需要進行調(diào)整芹啥。

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>${mybatis-plus-boot-starter.version}</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>${mysql.version}</version>
</dependency>

mybatis plus相關(guān)資料可以查看github,里面的文檔還是比較完善的:https://github.com/baomidou/mybatis-plus

配置

因為mybatis plus功能太完善铺峭,框架中不需要做任何二開墓怀,直接使用,我們直接拿上一篇提到的日志模塊來舉例卫键,上一篇是寫到文件中傀履,這里我們將同樣的數(shù)據(jù)寫到數(shù)據(jù)庫中。

首先我們在數(shù)據(jù)庫中建立一張名叫sys_log的表莉炉,具體的建表sql可以參看sql目錄下的建表語句钓账,里面的字段和上一篇定義的SysLog實體類的字段一樣,具體參看源碼絮宁。

接下來在application-xxx.yml中配置datasource:

spring:
  datasource:
    url: jdbc:mysql://123.206.118.12:3306/mkframework?useUnicode=true&characterEncoding=utf-8
    username: root
    password: Dnn198411!
    driverClassName: com.mysql.jdbc.Driver

在application.yml中配置mybatis-plus相關(guān)信息,plus中有很多配置參數(shù)梆暮,這里只是配置了日常會用到的一些參數(shù)配置,還有其他的配置大家可以參考plus的github官方文檔資料绍昂。

#mybatis
mybatis-plus:
  mapper-locations: classpath:/mapper/*Mapper.xml
  #實體掃描啦粹,多個package用逗號或者分號分隔
  typeAliasesPackage: com.monkey01.common.domain
#  typeEnumsPackage: com.baomidou.springboot.entity.enums
  global-config:
    # 數(shù)據(jù)庫相關(guān)配置
    db-config:
      #主鍵類型  AUTO:"數(shù)據(jù)庫ID自增", INPUT:"用戶輸入ID",ID_WORKER:"全局唯一ID (數(shù)字類型唯一ID)", UUID:"全局唯一ID UUID";
      id-type: id_worker
      #字段策略 IGNORED:"忽略判斷",NOT_NULL:"非 NULL 判斷"),NOT_EMPTY:"非空判斷"
      field-strategy: not_empty
      #駝峰下劃線轉(zhuǎn)換
      column-underline: true
      #數(shù)據(jù)庫大寫下劃線轉(zhuǎn)換
      #capital-mode: true
      #邏輯刪除配置
      logic-delete-value: 0
      logic-not-delete-value: 1
      db-type: h2
    #刷新mapper 調(diào)試神器
    refresh: true
  # 原生配置
  configuration:
    map-underscore-to-camel-case: true
    cache-enabled: false

定義DO、Mapper治专、Service類

數(shù)據(jù)庫sys_log我們需要定義一個對應(yīng)的DO和它進行ORM映射卖陵。

@TableName("sys_log")
public class SysLogDO implements Serializable {
    @TableId
    private Long id;
    //用戶名
    private String username;
    //用戶操作
    private String operation;
    //請求方法
    private String method;
    //請求URL
    private String url;
    //請求參數(shù)
    private String params;
    //執(zhí)行時長(毫秒)
    private Long time;
    //IP地址
    private String ip;
    //創(chuàng)建時間
    private Date createDate;
    //...省略setter遭顶、getter
    }

大家一定注意到這里和其他的POJO的區(qū)別张峰,那就是在類名前面和id字段定義前面都有注解,這里簡單解釋下棒旗。和mybatis一樣喘批,我們?nèi)粘⒁粋€DO類和數(shù)據(jù)庫表關(guān)聯(lián)起來有兩種方法,一種是使用傳統(tǒng)的mapper.xml將DO類和數(shù)據(jù)庫表關(guān)聯(lián)起來铣揉,字段名如果不一樣的饶深,也需要進行字段之間的映射關(guān)系定義,還有一定方法是在DO類中定義注解逛拱,來將原先定義在XML中的信息定義到注解里敌厘。當(dāng)然plus會對這種傳統(tǒng)的定義方法進行改良,我們只需要在DO類前面加上@TableName(“XXX”)在注解的value中寫上數(shù)據(jù)庫表名就可以將該DO類與對應(yīng)的數(shù)據(jù)庫表映射起來了朽合。如果表中的字段和我們定義的DO類的字段名稱完全一樣或者數(shù)據(jù)庫表字段只是用下劃線替代了DO類中字段的駝峰結(jié)構(gòu)俱两,那么plus會自動進行映射字段饱狂,如果是將下劃線轉(zhuǎn)為駝峰定義需要在上面的配置中將轉(zhuǎn)換設(shè)置為true,column-underline: true宪彩。

還可以看到我們在id字段定義的前面加上了@TableID休讳,該注解只可以定義在使用int或者Long定義的字段上用于自增id生成,在plus的配置中還可以配置生成id的算法尿孔,這里plus官方推薦的是使用開源sequence項目生成的id俊柔,只需要在yml中plus配置下配置id-type: id_worker就可以了。

定義好了DO后活合,還需要和mybatis一樣雏婶,還需要定義mapper接口,下面我們看下我們要實現(xiàn)SysLog的增刪改查需要怎樣定義一個mapper接口白指。

@Mapper
public interface SysLogMapper extends BaseMapper<SysLogDO> {
}

就是這么簡單尚骄,如果只是基本的增刪改查就是這么簡單,一個方法都不需要定義侵续,只需要讓mapper接口繼承自BaseMapper這個范性基類倔丈,里面的范型定義為需要操作的DO類。我們看下BaseMapper源碼就知道為什么這么簡單就可以實現(xiàn)常用的增刪改查功能了状蜗。

public interface BaseMapper<T> {
    Integer insert(T var1);
    Integer deleteById(Serializable var1);
    Integer deleteByMap(@Param("cm") Map<String, Object> var1);
    Integer delete(@Param("ew") Wrapper<T> var1);
    Integer deleteBatchIds(@Param("coll") Collection<? extends Serializable> var1);
    Integer updateById(@Param("et") T var1);
    Integer update(@Param("et") T var1, @Param("ew") Wrapper<T> var2);
    T selectById(Serializable var1);
    List<T> selectBatchIds(@Param("coll") Collection<? extends Serializable> var1);
    List<T> selectByMap(@Param("cm") Map<String, Object> var1);
    T selectOne(@Param("ew") Wrapper<T> var1);
    Integer selectCount(@Param("ew") Wrapper<T> var1);
    List<T> selectList(@Param("ew") Wrapper<T> var1);
    List<Map<String, Object>> selectMaps(@Param("ew") Wrapper<T> var1);
    List<Object> selectObjs(@Param("ew") Wrapper<T> var1);
    IPage<T> selectPage(IPage<T> var1, @Param("ew") Wrapper<T> var2);
    IPage<Map<String, Object>> selectMapsPage(IPage<T> var1, @Param("ew") Wrapper<T> var2);
}

是不是從這里就能發(fā)現(xiàn)需五,我們常用的一些數(shù)據(jù)庫操作都包涵在里面了,包括分頁也都在里面轧坎,是不是一下子效率提升了很多宏邮。

當(dāng)然dao的mapper類定義好了以后就是定義service層的service類了。

@Service("sysLogService")
public class SysLogServiceImpl extends ServiceImpl<SysLogMapper, SysLogDO> implements SysLogService {
    private Logger logger = LoggerFactory.getLogger(getClass());
    @Override
    public void saveSysLog(SysLogDO sysLogDO) {
        this.saveSysLogFile(sysLogDO);
        this.saveSysLogDB(sysLogDO);
    }
    private void saveSysLogFile(SysLogDO sysLogDO){
        logger.info(sysLogDO.toString());
    }
    private boolean saveSysLogDB(SysLogDO sysLogDO) {
        return this.save(sysLogDO);
    }
}

從這里可以發(fā)現(xiàn)只需要讓service實現(xiàn)類繼承plus的ServiceImpl范型類就可以了缸血,在范型類中需要定義上這個service對應(yīng)的mapper類和實體DO類蜜氨,然后在service實現(xiàn)類中就可以通過this調(diào)用上面我們看到的常用的數(shù)據(jù)庫表操作方法了。

能解決大量重復(fù)代碼的開發(fā)工作的核心就是這個ServiceImpl范型類和上面提到的BaseMapper接口捎泻,這里建議大家都可以看看ServiceImpl的源碼飒炎,這里的設(shè)計方法其實可以用到很多我們常用的代碼中。

自動代碼生成

當(dāng)然大家也會發(fā)現(xiàn)上面寫的DO笆豁、Mapper郎汪、Service類也是一個重復(fù)的過程,我們可以通過plus為我們提供的自動代碼生成方法來自動生成這些DO闯狱、Mapper煞赢、Service代碼,這里我們可以很方便的實現(xiàn)這些重復(fù)的代碼哄孤,具體可以參考test目錄下的GeneratorServiceEntity類照筑,在類里面需要配置數(shù)據(jù)庫的相關(guān)信息,還有需要自動生成的類信息。都配置好厚直接執(zhí)行這個Test方法就可以自動生成這些類了凝危,減少了很多重復(fù)的工作饭弓。

總結(jié)

因為目前的mybatis和mybatis plus在orm這塊已經(jīng)做的非常完善了,真的沒必要再自研一套媒抠,直接拿來用弟断,對于mybatis的源碼建議大家有空也可以讀讀,不難趴生,但是里面涉及到很多好的框架設(shè)計方法阀趴,值得去學(xué)習(xí)。

本篇對應(yīng)的代碼tag是v0.2苍匆,大家以點擊下載https://github.com/feiweiwei/MkFramework4java/releases/tag/v0.2刘急,當(dāng)然也可以通過git clone –b v0.2 https://github.com/feiweiwei/MkFramework4java.git下載。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末浸踩,一起剝皮案震驚了整個濱河市叔汁,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌检碗,老刑警劉巖据块,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異折剃,居然都是意外死亡另假,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進店門怕犁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來边篮,“玉大人,你說我怎么就攤上這事奏甫「杲危” “怎么了?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵阵子,是天一觀的道長思杯。 經(jīng)常有香客問我,道長款筑,這世上最難降的妖魔是什么智蝠? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮奈梳,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘解虱。我一直安慰自己攘须,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布殴泰。 她就那樣靜靜地躺著于宙,像睡著了一般浮驳。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上捞魁,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天至会,我揣著相機與錄音,去河邊找鬼谱俭。 笑死奉件,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的昆著。 我是一名探鬼主播县貌,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼凑懂!你這毒婦竟也來了煤痕?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤接谨,失蹤者是張志新(化名)和其女友劉穎摆碉,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體脓豪,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡兆解,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了跑揉。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片锅睛。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖历谍,靈堂內(nèi)的尸體忽然破棺而出现拒,到底是詐尸還是另有隱情,我是刑警寧澤望侈,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布印蔬,位于F島的核電站,受9級特大地震影響脱衙,放射性物質(zhì)發(fā)生泄漏侥猬。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一捐韩、第九天 我趴在偏房一處隱蔽的房頂上張望退唠。 院中可真熱鬧,春花似錦荤胁、人聲如沸瞧预。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽垢油。三九已至盆驹,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間滩愁,已是汗流浹背躯喇。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留硝枉,地道東北人廉丽。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像檀咙,于是被迫代替她去往敵國和親雅倒。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,619評論 2 354

推薦閱讀更多精彩內(nèi)容