Larry.Z 解决方案帮助我解决了将自动生成的文件与手动编辑的文件分开的相同问题。我在我的项目中有一个自定义文件夹结构,并调整了 Larry 解决方案以在我的项目中工作,并通过使用 Larry 解决方案调整它来添加这个答案以帮助其他人。
最好的解决方案是在 Mybatis 生成器 ( MBG ) 中添加功能以集成手动修改的 xml 映射器。MBG 必须添加解析功能以将相应的手节点方法添加到客户端映射器界面,但现在此功能不存在,因此我使用并调整了 Larry.Z 解决方案。
在我的项目中,我使用:
<properties>
...
<java.version>1.7</java.version>
<spring.version>3.2.2.RELEASE</spring.version>
<mybatis.version>3.2.2</mybatis.version>
<mybatis-spring.version>1.2.0</mybatis-spring.version>
<mybatis-generator-core.version>1.3.2</mybatis-generator-core.version>
...
</properties>
我的文件夹结构是:
<base>/dao/
: MBG 生成的 dao 类
<base>/dao/extended/
: 扩展生成类 ( <DaoGeneratedName>Extended
)
<base>/sqlmap/
: MBG 生成的客户端接口和对应的 xml 映射器
<base>/sqlmap/extended/
:
hand xml mapper 和hand client Interface
( <InterfaceGenerated>Extended extends InterfaceGenerated {...
)
<base>/sqlmap/generated/
: MBG 生成的映射器命名空间的副本已更改
我已经配置好Mybatis-spring
<bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer"
p:basePackage="<base>.sqlmap"
p:sqlSessionTemplate-ref="sqlSessionTemplate"
p:nameGenerator-ref="myBeanNameGenerator"
/>
仅当您需要像我这样的自定义名称时才实施 myBeanNameGenerator。在此示例中,您可以删除行p:nameGenerator-ref="myBeanNameGenerator"
如果您的所有客户端接口都被扩展,您可以在上面替换
p:basePackage="<base>.sqlmap.extended"
(我的项目配置很大,所以我提取了最重要的一点)
这是我的客户端界面和映射器手动编码的示例:
import <base>.dao.Countries;
import <base>.sqlmap.CountriesMapper;
import org.apache.ibatis.annotations.Param;
public interface CountriesMapperExtended extends CountriesMapper {
/**
*
* @param code
* @return
*/
Countries selectByCountryCode(@Param("code") String code);
}
CountryMapper 在哪里是 MBG 生成的客户端接口
手工编码的相关 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="<base>.sqlmap.extended.CountriesMapperExtended">
<select id="selectByCountryCode" parameterType="java.lang.String" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from countries co
where co.countrycode = #{code,jdbcType=VARCHAR}
</select>
</mapper>
为了完成所有工作,我必须将 MBG 生成的所有接口方法集成到 xml 映射器中,为此,我复制了 MBG 生成的 xml 映射器<base>/sqlmap/generated/
并更改了他的命名空间:
<?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="<base>.sqlmap.extended.CountriesMapperExtended">
... unchanged ...
</mapper>
当数据库更改时会出现问题,我必须使用 MBG 来反映新的数据库结构。
所以我快速创建了一个 bash 脚本来监视<base>/sqlmap/extended/
并检查是否有手动编码的 xml 映射器。如果有手工编码的 xml 映射器,复制相应的 MBG 生成更改他的命名空间。
所有这些代码都不是一个优雅的解决方案,但可以工作。
所以bash脚本会覆盖文件<base>/sqlmap/generated/
,而不是把你的代码放到这个文件夹中。
制作项目的备份副本并修改 bash 脚本,以自定义它并由您负责使用。
#!/bin/bash
CURDIR="$(pwd)"
SCRIPT_DIR=`dirname $0`
usage()
{
cat << EOF
usage: $0 options
This script is usefull to generate xml map to extend mybatis
generator client interfaces. It suppose this structure:
<base>/sqlmap/ : generated xml mapper and interfaces
<base>/sqlmap/extended/ : extended xml mapper and interfaces
<base>/sqlmap/generated/ : copy of generated xml mapper changing
its namespace
If exist a mapper xml in <base>/sqlmap/extend identify by a name
ending in Extended this script generate a copy of original generated
xml map of extended interface changing then namespace to reflect the
extended Interface in <base>/sqlmap/generated.
This script require a list of base path:
$0 path1 path2 ...
Required parameters are marked by an *
OPTIONS:
-h, --help Show this message
EOF
}
declare -a BASES
let INDEX=0
TEMP=`getopt -o "hb:" --long "help,base:" -n "$0" -- "$@"`
eval set -- "$TEMP"
while true ; do
case "$1" in
-h|--help)
usage
exit 1 ;;
--)
shift ;
break ;;
*)
echo "Too mutch parametes!!! abort." ;
exit 1 ;;
esac
done
#process all paths
let INDEX=0
BASE="$1"
while [ "${BASE:0:1}" == "/" ]
do
shift ;
BASES[$INDEX]="$BASE"
let INDEX+=1
BASE="$1"
done
if [ "$INDEX" -le "0" ]
then
echo "--bases options cannot be emplty"
usage
exit 1
fi
for BASE in ${BASES[@]}
do
if [ ! -d "$BASE" ]
then
echo "Error: every base parameter must be a folder!!"
echo "Base=$BASE is not a folder"
usage
exit 1
fi
SQLMAP="$BASE/sqlmap"
if [ ! -d "$SQLMAP" ]
then
echo "Error: every base parameter must have a sqlmap folder!!"
echo "$SQLMAP is not a folder"
usage
exit 1
fi
EXTENDED="$BASE/sqlmap/extended"
if [ ! -d "$EXTENDED" ]
then
echo "Error: every base parameter must have a sqlmap/extended folder!!"
echo "$EXTENDED is not a folder"
usage
exit 1
fi
GENERATED="$BASE/sqlmap/generated"
if [ ! -d "$GENERATED" ]
then
mkdir -p "$GENERATED"
fi
while IFS= read -r -d '' file
do
name="${file##*/}"
#path="${file%/*}"
ext=".${name##*.}"
nameNoSuffix="${name%$ext}"
nameBase="${nameNoSuffix%Extended}"
sed -r 's/<mapper namespace="(.+)\.([^."]+)"\s*>\s*$/<mapper namespace="\1.extended.\2Extended">/' "$SQLMAP/$nameBase.xml" > "$GENERATED/$nameNoSuffix.xml"
done < <(eval "find $EXTENDED/ -type f -name \*Extended\.xml -print0")
done
exit 0
脚本的使用
$ ./post-generator.sh "/home/...<base>"
不要把最后一个/
放在路径上
这个路径是包含sqlmap、sqlmap/extended、sqlmap/generated的文件夹的路径
如果您像我一样拥有多个路径,则可以使用路径列表
为了通过 maven 使用它,我在项目 pom.xml 中使用了这个插件:
<plugin>
<artifactId>exec-maven-plugin</artifactId>
<groupId>org.codehaus.mojo</groupId>
<version>1.2.1</version>
<executions>
<execution>
<id>build client extended xml</id>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>${basedir}/scripts/post-generator.sh</executable>
<workingDirectory>${basedir}/scripts</workingDirectory>
<arguments>
<argument>${basedir}/<basepath1></argument>
<argument>${basedir}/<basepath2></argument>
</arguments>
</configuration>
</plugin>
在项目文件夹中,您可以使用$ mvn exec:exec
或$ mvn mybatis-generator:generate exec:exec
如果您使用 Netbeans,您可以配置项目操作以在mybatis-generator:generate exec:exec
不离开 Netbeans 的情况下运行这些目标。当数据库结构发生变化时,您可以手动启动它。
现在您可以毫无问题地使用扩展映射器,如果数据库结构发生变化,让 MBG 完成他的工作。
在您的 bean 中,您可以注入具有
自动生成的 MBG 方法以及您的手动编码方法的扩展接口:
<bean id="service" class="<base>.services.ServiceImpl" scope="singleton"
...
p:countriesMapper-ref="countriesMapperExtended"
...
p:sqlSessionTemplate-ref="sqlSessionTemplate"
/>
countryMapperExtended bean 由上面的 mapperScanner 生成。