看起来您引用的链接是针对非常旧版本的MyBatis。在该页面上,它列出了以下内容:
版本:1.3.3-SNAPSHOT
最新版本是:
mybatis-3.3.0-SNAPSHOT
Grepping 3.x 代码setDistinct
不会返回任何内容:
https ://github.com/mybatis/mybatis-3/search?q=setDistinct
我很惊讶您没有收到有关未找到该方法的编译时错误。您使用的是1.3.3(或 1.x)版本吗?
我建议DISTINCT
在查询中做正确的事。由于MyBatis通常是一种接近 SQL 金属类型的映射框架,我认为最好将其添加到映射器文件的查询本身中。加上这样,你可以具体选择什么DISTINCT
。该setDistinct
方法似乎没有提供任何指定目标的方法。
对于MyBatis 3,我认为类似的查询风格是这样的:
http://mybatis.github.io/mybatis-3/statement-builders.html
这似乎类似于jOOQ风格的DSL。它有一个SELECT_DISTINCT
方法。我个人发现在映射器文件中使用一些XML 标记来编写/读取纯 SQL更容易,因为这是在映射器文件中动态 SQL 的需要,但这在MyBatis 3中肯定是一个可行的选项。
编辑:
所以,我做了一些更多的挖掘,我在MyBatis3 git repo 中找不到代码的原因是因为setDistinct
在mybatis-generator代码库中。
我认为这里的部分问题可能源于Mybatis-Generator在GitHub 上的描述:
MBG 试图对大部分简单 CRUD(创建、检索、更新、删除)的数据库操作产生重大影响。
因此,它提供了一种简单DISTINCT
的方法,但控制有限。
代码驻留在类的addClassElements
方法中ProviderSelectByExampleWithoutBLOBsMethodGenerator
。搜索setDistinct
不会出现在 Github 搜索中,因为它是自动生成的setter。
这是相关的代码片段:
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操作的自我描述背道而驰。