【背景】
項目使用了mybatis-generator插件自動生成mysql表對應的xml、mapper和entity。對於一些複雜sql和自定義的sql,我們在xml和mapper進行相應維護。
【問題描述】
在後續的版本迭代中,數據庫表難免會有所調整和擴展。此時如果再用mybatis-generator插件重新自動生成,會把該表原有的mapper文件覆蓋,xml文件追加。
目前的解決方式:
(1) 把mapper和xml中自定義的語句拷貝出來,
(2) 清理原有xml、mapper文件,
(3) 用mybatis-generator插件重新生成,
(4) 把自定義的sql語句拷貝回去。
目前此種方法的缺陷:
(1)需要手動操作,拷來拷去的繁瑣;
(2)手動操作容易誤操作和遺漏;
(3)項目新成員無意識或意識欠缺,改表後重新生成時容易遺忘把手寫部分的sql拷回去,造成線上安全問題;
【分析】
mybatis generator自動生成時可選是“追加”還是“覆蓋”,不論追加還是覆蓋,都不能達到我們想要的同一個文件既能自動修改原來的代碼,又能不變我們手寫追加的代碼。
【解決方案】
把我們手寫的sql放到一個擴展的mapper和xml中,繼承原生的mapper和xml,這樣就可以每次重新生成時就只覆蓋原生的表而不影響到我們自寫的代碼。
【代碼示例】
下面以購物車order_cart表爲例
1.這是mybatis-generator自動生成好的原生的mapper和xml
Mapper的使用:
在方法的調用處,自動注入OrderCartMapper,使用其中的方法即可。
2.購物車表裏,我們需要新增兩個自定義的方法:獲取用戶購物車中所有的店鋪getDistinctShopIdByUserId()、獲取用戶購物車中的商品種類數countByUserId()。
那麼我們再定義一個擴展mapper名爲OrderCartExtendsMapper,繼承原有的OrderCartMapper,定義一個擴展的xml名爲OrderCartExtendsMapper.xml,來實現OrderCartExtendsMapper。然後把我們自定義的這兩個方法寫在這兩個擴展文件。
這樣一來,當購物車表有字段調整或擴展時,我們再用mybatis-generator自動生成,也只是變更的原有的OrderCartMapper和OrderCartMapper.xml,而不會影響到我們手動添加的部分。
Mapper的使用:
在方法的調用處,自動注入OrderCartExtendsMapper,使用其中的方法即可。
【擴展】
Mybatis generator自動生成代碼時,需要insert方法返回主鍵值,怎麼做?
方法一:在generator配置中添加
<!-- tableName:用於自動生成代碼的數據庫表;domainObjectName:對應於數據庫表的javaBean類名;不需要生成Example類 -->
<table schema="" tableName="ACT_SecurityBlockLog" domainObjectName="BlockLog"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false">
<property name="useActualColumnNames" value="true"/>
<generatedKey column="id" sqlStatement="MySql" identity="true"/>
</table>
方法二:生成好的xml文件中添加
<insert id="insert" parameterType="Activity" keyProperty="id" useGeneratedKeys="true">
主鍵值 由 對象.getId()取出,insert方法只返回成功的行數。