MyBatis Generator setDistinct(true)

时间:2014-07-04 09:05:18

标签: java spring mybatis mybatis-generator

我正在尝试使用指南中描述的setDistinct(true)http://mybatis.github.io/generator/generatedobjects/exampleClassUsage.html

我用这种方式写的:

testExample ae = new testExample();    
testExample.Criteria criteriatest = ae.createCriteria(); 
ae.setDistinct(true); 
criteriatest.andIDENTLAVEqualTo(Long.parseLong(cert.getCODINDIVID())); 
ae.or(criteriatest); 
List<test> listtest = testMapper.selectByExample(ae);

setDistinct(true)不会影响结果。

我应该在哪里添加setDistinct行?

1 个答案:

答案 0 :(得分:2)

您引用的链接看起来像是一个非常旧版本的 MyBatis 。在该页面上,它列出了以下内容:

  

版本:1.3.3-SNAPSHOT

最新版本是:

  

的MyBatis-3.3.0-SNAPSHOT

setDistinct加密3.x代码不会返回任何内容: https://github.com/mybatis/mybatis-3/search?q=setDistinct

我很惊讶您没有收到有关未找到方法的编译时错误。您使用的是版本1.3.3 (或1.x)吗?

我建议在查询中执行DISTINCT权限。由于 MyBatis 通常是一种接近SQL-metal 类型的映射框架,我认为最好将其添加到映射器中文件的查询本身。加上这种方式,你可以具体选择DISTINCT的内容。 setDistinct方法似乎没有提供任何指定目标的方法。

对于 MyBatis 3 ,我认为类似的查询风格是这样的:

http://mybatis.github.io/mybatis-3/statement-builders.html

这似乎类似于 jOOQ -style DSL 。它有一个SELECT_DISTINCT方法。我个人觉得根据映射文件中的动态SQL需要使用一些 XML标记来编码/读取纯SQL 更容易,但这是当然是 MyBatis 3 中可行的选择。

修改

所以,我做了一些挖掘工作,而我无法在 MyBatis3 git repo中找到代码的原因是因为setDistinct位于 mybatis-生成器代码库。

我认为这里的部分问题可能源于 Mybatis-Generator GitHub 的描述:

  

MBG寻求对大部分数据库产生重大影响   简单CRUD(创建,检索,更新,删除)的操作。

因此,它提供了一种简单DISTINCT的方法,但控制有限。

代码位于addClassElements类的ProviderSelectByExampleWithoutBLOBsMethodGenerator方法中。搜索setDistinct不会显示在Github搜索上,因为它是自动生成的 setter

这是相关的code snippet

boolean distinctCheck = true;
        for (IntrospectedColumn introspectedColumn : getColumns()) {
            if (distinctCheck) {
                method.addBodyLine("if (example != null && example.isDistinct()) {"); //$NON-NLS-1$
                method.addBodyLine(String.format("%sSELECT_DISTINCT(\"%s\");", //$NON-NLS-1$
                 builderPrefix,
                    escapeStringForJava(getSelectListPhrase(introspectedColumn))));
                method.addBodyLine("} else {"); //$NON-NLS-1$
                method.addBodyLine(String.format("%sSELECT(\"%s\");", //$NON-NLS-1$
                 builderPrefix,
                    escapeStringForJava(getSelectListPhrase(introspectedColumn))));
                method.addBodyLine("}"); //$NON-NLS-1$
            } else {
                method.addBodyLine(String.format("%sSELECT(\"%s\");", //$NON-NLS-1$
                 builderPrefix,
                    escapeStringForJava(getSelectListPhrase(introspectedColumn))));
            }

            distinctCheck = false;
        }

所以,从本质上讲,这看起来好像包装了我原先提到的SELECT_DISTINCT方法,它试图反省列并将DISTINCT应用于它返回的所有列。

深入挖掘,它最终会调用此代码来获取列:

/**
* Returns all columns in the table (for use by the select by primary key
* and select by example with BLOBs methods)
*
* @return a List of ColumnDefinition objects for all columns in the table
*/
    public List<IntrospectedColumn> getAllColumns() {
        List<IntrospectedColumn> answer = new ArrayList<IntrospectedColumn>();
        answer.addAll(primaryKeyColumns);
        answer.addAll(baseColumns);
        answer.addAll(blobColumns);

        return answer;
    }

所以,这绝对是一个全有或全无DISTINCT(而 Postgres 本身只允许DISTINCT在某些列上。)

在实际调用setDistinct对象之前,尝试将ae移动到最后一行。也许随后的调用会影响列集(尽管从代码中看,它似乎不应该 - 基本上一旦设置了列,setDistinct应该使用它们。)

另一件有趣的事情是看看它实际生成的SQL是否有setDistinct

检查此链接以获取有关调试/日志记录的更多详细信息:

http://mybatis.github.io/generator/reference/logging.html

我建议尝试使用基于XML的映射器文件定义,这些定义将 SQL XML 标记交错以实现动态性。 IMO,它比上面的代码 Mybatis Generator 代码片段更容易理解。我认为这是使用生成器的主要权衡之一 - 最初更容易创建,但以后更难以阅读/维护。

对于超级动态查询,我可以看到更多优势,但那种情况与简单CRUD 操作的自我描述背道而驰。