Java 控制datanucleus创建查询的方式

Java 控制datanucleus创建查询的方式,java,mysql,jdo,datanucleus,Java,Mysql,Jdo,Datanucleus,目前,我正在一个项目中使用datanucleus 4.0.2。 在一些表中,我有多达一百万行,这通常不是db处理的问题 但是,当datanucleus获取所有依赖元素时,它将生成一个如下所示的查询: SELECT 'my.com.CHILD_TABLE' AS NUCLEUS_TYPE, `CHILD_TABLE`.`ID` # And alot of more fields FROM `CHILD_TABLE` WHERE EXISTS( SELECT DI

目前,我正在一个项目中使用datanucleus 4.0.2。 在一些表中,我有多达一百万行,这通常不是db处理的问题

但是,当datanucleus获取所有依赖元素时,它将生成一个如下所示的查询:

SELECT 
    'my.com.CHILD_TABLE' AS NUCLEUS_TYPE,
    `CHILD_TABLE`.`ID` # And alot of more fields
FROM
    `CHILD_TABLE` 
WHERE
    EXISTS( SELECT DISTINCT
            'my.com.MIDDLE_TABLE' AS NUCLEUS_TYPE,
                `MIDDLE_TABLE`.`ID`
        FROM
            `MIDDLE_TABLE` 
               INNER JOIN
            `FIRST_TABLE` ON `MIDDLE_TABLE`.`MIDDLE_PARENT_ID_OID` = `FIRST_TABLE`.`ID`
        WHERE
            `FIRST_TABLE`.`TABLE_OWNER_ID_OID` = 5057520
                AND `CHILD_TABLE`.`PARENT_ID_OID` = `MIDDLE_TABLE`.`ID`)
出于某种原因,mysql需要为此扫描子表中的所有100万行。(这可能是查询执行计划程序的错误)

将其转换为此表单

SELECT 
    'my.com.CHILD_TABLE' AS NUCLEUS_TYPE,
    `CHILD_TABLE`.`ID`
FROM
    `CHILD_TABLE` 
INNER JOIN `MIDDLE_TABLE` 
    ON `CHILD_TABLE`.`PARENT_ID_OID` = `MIDDLE_TABLE`.`ID`
               INNER JOIN
            `FIRST_TABLE` ON `MIDDLE_TABLE`.`MIDDLE_PARENT_ID_OID` = `FIRST_TABLE`.`ID`
        WHERE
            `FIRST_TABLE`.`TABLE_OWNER_ID_OID` = 5057520
只需扫描9行或类似行即可获得神奇效果

是否可以控制datanucleus如何生成这些查询

另外,我发现了一篇相关的帖子,解释了mysql存在的问题

用一些代码更新了问题 以下是实体关系的设置方式:

@PersistenceCapable(detachable = "true", identityType = IdentityType.APPLICATION)
class ChildTable {
    @PrimaryKey
    private Long id;
    MiddleTable middleTable;
    // More fields
}

@PersistenceCapable(detachable = "true", identityType = IdentityType.APPLICATION)
class MiddleTable {
    @PrimaryKey
    private Long id;
    ParentTable parentTable;
    @Persistent(mappedBy="middleTable", defaultFetchGroup="true")
    private Set<ChildTable> children;

}
@PersistenceCapable(detachable = "true", identityType = IdentityType.APPLICATION)
class ParentTable {
    @PrimaryKey
    private Long id;

    MasterTable masterTable;
    @Persistent(mappedBy="parentTable")
    private Set<MiddleTable> children;
 }

// Master table code is left out for brewety, same set up

Query query = pm.newQuery(MiddleTable.class);
Collection<MiddleTable> entitySet;

try {
    query.setFilter("parentTable.masterTable == :masterTable");
    entitySet = (Collection<MiddleTable>) query.execute(masterTable);

}
finally {
    query.closeAll();
}
@PersistenceCapable(detachatable=“true”,identityType=identityType.APPLICATION)
类子表{
@主键
私人长id;
中间桌;
//更多领域
}
@PersistenceCapable(detaccable=“true”,identityType=identityType.APPLICATION)
阶级中间桌{
@主键
私人长id;
ParentTable ParentTable;
@持久(mappedBy=“middleTable”,defaultFetchGroup=“true”)
私人儿童;
}
@PersistenceCapable(detaccable=“true”,identityType=identityType.APPLICATION)
类父表{
@主键
私人长id;
主台主台;
@持久性(mappedBy=“parentTable”)
私人儿童;
}
//brewety保留了主表代码,设置相同
Query=pm.newQuery(MiddleTable.class);
集合实体集;
试一试{
query.setFilter(“parentTable.masterTable==:masterTable”);
entitySet=(集合)query.execute(主表);
}
最后{
query.closeAll();
}
基本上,这里发生的是在执行查询时,datanucleus还将执行两个本机查询。 第一个很好用。它看起来像是我发布的第一个原始查询,除了存在的东西


启动第二个,因为子项位于默认的获取组中。这就是我想要减少查询数量的原因。稍后将访问所有子项。

这可能吗?但您必须解释类以及您执行的第一个SQL操作place@NeilStockton用实体类更新了问题。你在想什么?日志上写着?关于调用第二个查询的原因?我知道您可以通过查询扩展(在文档中)关闭辅助字段的“批量获取”,但不知道您是否可以请求内部联接。。。假设这是您所指的批量获取查询。最好的方法是以他们的代码为起点。我放弃了这个方法。我认为核心问题在于mysql,对于这些特定的查询,它不应该太慢。我最终使用了自定义结果类和两个独立的jdo查询(一个用于中间类,一个用于子类)。然后我手动设置关系。