结合网上的教程研究后,我知道了这两个包,分别是生成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。