【背景】
项目使用了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方法只返回成功的行数。