Mybatis在工程中的槽點
工程中的mapper文件往往非常大,動則上千行,最近經常聽見周圍的同學們吐槽難以維護,還不如寫Java代碼。
最近就在思考這樣一個問題,既然mapper文件太那蛋疼,為什么大家還是使用mapper文件呢,為什么不使用mybatis的注解或者使用spring-jdbc提供的JdbcTemplate(有使用JPA的)
結合自己的思考和一些實驗,覺得有以下原因:
- 有些同學被一些視頻洗腦了,認為xml比java代碼更好維護
- Java中寫sql實在不是一個好的sql編寫方式,用java寫出來的sql確實比xml中的sql更難看懂
- 雖然mybatis提供了注解的方式,但是sql還是非常難以編寫
- ResultMap還是得用xml,否則就得重復的寫多次@Results
總結起來其實就一個原因:Java的語法對長一點的字符串太不友好了,很難編寫出可讀性好的SQL,所以大家還是更愿意寫xml來表示sql的對象的映射
不使用xml的方式
如何做到不使用xml呢?其實是有多種選擇的,比如mybatis for scala,但是scala語法不熟悉,學習成本太大,實際上如果Java對string有比較好的支持,那寫sql會容易得多
雖然Java對String的支持不夠友好,但是groovy或者kotlin對string有非常好的支持,可以嘗試用groovy或者kotlin加上mybatis的注解來寫映射接口,比如kotlin:

因為Java是可以和groovy或者kotlin在同一工程中混合使用的,因此使用kotlin或者groovy的方式在Java中是能正常被調用的,有了這種語法糖層面的支持,在代碼中寫SQL變得容易很多
解決重復SQL的問題
使用注解后,如果需要寫多個查詢,查詢字段需要寫多次,例如(本例中省略了ResultMap的使用):

這里的select之后的字段名,在多個不同的查詢之中都是相同的,如何解決這個問題呢?我們可以使用mybatis插件處理,最后的效果如下:

關鍵在于處理這個@Macro注解,
注解定義如下:

插件中需要處理sql,對sql做文本替換,這樣我們就能夠得到通過注解支持的可利用的sql片斷,插件實現(xiàn)如下:

對ResultMap的處理
在前面的例子中,映射接口中省略了@Results,加上@Results后完整的注解使用方式應該如下:

可以看到,需要在每個查詢方法上都加上@Results,如果多個方法上的@Result一模一樣,那么重復的注解會被定義多次。
同樣,我們可以通過實現(xiàn)mybatis插件方式支持默認的ResultMap,最終效果如下:

如果數(shù)據庫中的字段名與Java中的屬性名是標準的下劃線與駝峰格式,比如數(shù)據庫中的create_time對應于java中的createTime,那么可以不寫@DefaultResults的results屬性,例如:

整體代碼簡潔很多,使用多行字符串語法后如下:

未完待續(xù)
今天太晚了,后面再繼續(xù)講述如何簡化動態(tài)sql在mapper接口中的編寫