上一篇我们讲了如何获取Mybatis-generator的源代码和创建工程,以及通过main方法来生成XML、实体类、mapper文件,这一篇我们来讲通过修改代码来为mapper添加一个方法
2、组合源代码中的示例,实现Dao(Mapper)层添加一个方法
结合网上的教程研究后,我知道了这两个包,分别是生成dao(mapper)文件和XML文件的JAVA类,那么我们先研究javamapper这个包
这个包里的 JavaMapperGenerator.java,有一个方法 getCompilationUnits,它是控制生成的dao文件具体有哪些方法的,代码就是
但是并不是所有的方法都生成,具体逻辑我还没有去研究过
然后我查看这个包下面的叫做 elements包,它里头有很多的类,其实就是截图中addXXX方法需要调用到的类,这些方法会实例化elements包下的类,并使用它组合出方法。
打开SelectByPrimaryKeyMethodGenerator 这个类,这就是根据ID查询数据的方法,
主要介绍这个类里的addInterfaceElements方法,它将我们写方法时候的作用范围,返回类型,方法名,参数,以及import,都专门设计了对象,下面我将注释写出来
我们跟踪红色箭头的方法,发现它返回了一个枚举列表中的某个值,这个枚举在org.mybatis.generator.api.IntrospectedTable类里头,而且枚举里的值,正好于elements包下面的java文件对应,还发现了这些数据是用在了这个类的get和set方法里,跟踪set方法,发现它被本类的calculateXmlAttributes方法调用,并在里头设置了我们所看到的方法名:
到这里,我们就可以想到,添加一个方法,首先要创建在elements包里头创建一个类,然后在这个枚举里头添加数据,实现get和set方法,然后在JavaMapperGenerator类中去add,那么现在我们就可以尝试着建立一个方法了。
第一步.先在elements拷贝一个类,模板就用SelectByPrimaryKeyMethodGenerator ,类名改为SelectByObjectMethodGenerator。
第二步.在org.mybatis.generator.apiIntrospectedTable类的InternalAttribute枚举中添加一条数据
ATTR_SELECT_BY_ObJECT//自定义方法
写上它的get和set方法
public String getSelectByObject() {
return internalAttributes
.get(InternalAttribute.ATTR_SELECT_BY_ObJECT);
}
public void setSelectByObject(String s) {
internalAttributes.put(
InternalAttribute.ATTR_SELECT_BY_ObJECT, s);
}
并在calculateXmlAttributes方法里调用set方法,传入我们想要的方法名
第三步. 在JavaMapperGenerator类中添加一个方法
//自定义方法
protected void addSelectByObjectMethod(Interface interfaze) {
if (introspectedTable.getRules().generateSelectByPrimaryKey()) {
AbstractJavaMapperMethodGenerator methodGenerator = new SelectByObjectMethodGenerator(false);
initializeAndExecuteGenerator(methodGenerator, interfaze);
}
}
注意这里的 if 条件判断,理论上我不应该使用 introspectedTable.getRules().generateSelectByPrimaryKey() 这个判断的,但是如果要去Rule接口新建一个方法的话,它的实现类也很多,修改起来就很麻烦,那么我们这里暂时不改,但是能用,有兴趣的同学,可以自己去深入研究一下,欢迎在博客下面留言,我们一起探讨。
然后在这个类的getCompilationUnits 方法中调用这个方法
完成这三步,就可以在dao层新建一个方法了,但是我们实际引用的模板依然是SelectByPrimaryKeyMethodGenerator 类,所以我们需要修改我们新建的SelectByObjectMethodGenerator类中的 addInterfaceElements 方法
首先我想到的是,SelectByPrimaryKey返回的是一个数据库示例对象,但是我的需求里是要返回一个List,自己不会写这样的返回类型,怎么办,看看有没有写好的例子,正好在SelectAllMethodGenerator类里头,它所生产的方法,正好是List类型的,抄抄抄
@Override
public void addInterfaceElements(Interface interfaze) {
//先创建import对象
Set<FullyQualifiedJavaType> importedTypes = new TreeSet<FullyQualifiedJavaType>();
//添加Lsit的包
importedTypes.add(FullyQualifiedJavaType.getNewListInstance());
//创建方法对象
Method method = new Method();
//设置该方法为public
method.setVisibility(JavaVisibility.PUBLIC);
//设置返回类型是List
FullyQualifiedJavaType returnType = FullyQualifiedJavaType
.getNewListInstance();
FullyQualifiedJavaType listType;
//设置List的类型是实体类的对象
listType = new FullyQualifiedJavaType(
introspectedTable.getBaseRecordType());
importedTypes.add(listType);
//返回类型对象设置为List
returnType.addTypeArgument(listType);
//方法对象设置返回类型对象
method.setReturnType(returnType);
//设置方法名称为我们在IntrospectedTable类中初始化的 “selectByObject”
method.setName(introspectedTable.getSelectByObject());
//设置参数类型是对象
FullyQualifiedJavaType parameterType;
if (isSimple) {
parameterType = new FullyQualifiedJavaType(
introspectedTable.getBaseRecordType());
} else {
parameterType = introspectedTable.getRules()
.calculateAllFieldsClass();
}
//import参数类型对象
importedTypes.add(parameterType);
//为方法添加参数,变量名称record
method.addParameter(new Parameter(parameterType, "record")); //$NON-NLS-1$
//
addMapperAnnotations(interfaze, method);
context.getCommentGenerator().addGeneralMethodComment(method,
introspectedTable);
if (context.getPlugins().clientSelectByPrimaryKeyMethodGenerated(
method, interfaze, introspectedTable)) {
interfaze.addImportedTypes(importedTypes);
interfaze.addMethod(method);
}
}
这是修改完后的代码,注释仅仅写了一部分,也挺拗口的,朋友们可以删了按照自己的,其他的你们可以自己深入研究
第四步. 执行MyTestRun的main方法,就可以看到在dao层的方法中加了一个方法(最好把原来的dao层的java文件删掉,因为我不确定是否覆盖)
理论上就可以看到下图中的新增方法了
下一篇我们会介绍,如何在xml文件中,添加这个方法的sql。