在selectqueryjooq中使用java方法

在selectqueryjooq中使用java方法,java,mysql,jooq,Java,Mysql,Jooq,我有一个mysql查询,其格式如下 dslContext .select( ITEMDATA.ITEMID, ITEMDATA.COST, ITEMNAMES.ITEMNAME ) .from(ITEMDATA) .join(ITEMNAMES) .on(ITEMDA

我有一个mysql查询,其格式如下

        dslContext
            .select(
                ITEMDATA.ITEMID,
                ITEMDATA.COST,
                ITEMNAMES.ITEMNAME
            )
            .from(ITEMDATA)
            .join(ITEMNAMES)
            .on(ITEMDATA.ITEMID=ITEMNAMES.ITEMID)
            .where(conditions);
上面的查询将ITEMDATA与ITEMNAMES表联接,以在结果中选择ITEMNAME。我正在内存中缓存ITEMNAMES表,希望避免与ITEMNAMES表连接。这将加快查询速度并简化查询,因为实际查询要复杂得多

我想使用类似于下面的东西。我想在select params列表中调用itemNamesCache.getItemName,该列表给出ITEMNAME并返回select结果的一部分。getItemName应将响应中返回的ITEMID作为参数,并提供ITEMNAME

    dslContext.
        select(
            ITEMDATA.ITEMID,
            ITEMDATA.COST,
            itemNamesCache.getItemName(valueOfItemId)
        )
        .from(ITEMDATA)
        .where(conditions);

另外:我可以迭代结果并调用itemNamesCache.getItemName。但是如果可能的话,我想在查询中嵌入一些东西,您不能将SQL查询回调回一些Java逻辑,即使您正在使用jOOQ和Java构建SQL查询,这看起来是可行的

但是,您可以通过使用以前构建的缓存修补记录来后处理jOOQ结果:

Java解决方案 如果您使用的数据库真的无法处理这个简单的连接,并且您已经检查了所有适当的索引和约束!然后,您可以尝试以下解决方案:

//假设这种进口: 导入静态org.jooq.impl.DSL.*; 写

映射项名称缓存= dslContext.SelectDifferentitemNames.ITEMID、ITEMNAMES.NAME .FromItemName .fetchMapITEMNAMES.ITEMID、ITEMNAMES.NAME; dslContext 选择 ITEMDATA.ITEMID, ITEMDATA.COST, //在这里创建一个空列 INLINEULL,String.class.asITEMNAMES.NAME .fromITEMDATA .条件 //用缓存的值填充空列 .fetchr->r.value3itemnescache.getr.value1; 基于SQL的解决方案 SQL实现这一点的方法是编写一个

选择 itemdata.itemid, itemdata.cost, 从itemnames.itemid=itemdata.itemid的itemnames中选择itemnames.name 从…起 项目数据 哪里 ... 与约克 //假设这种进口: 导入静态org.jooq.impl.DSL.*; 。。。写:

dslContext 选择 ITEMDATA.ITEMID, ITEMDATA.COST, fieldselectITEMNAMES.NAME .FromItemName .whereITEMDATA.ITEMID.eqITEMNAMES.ITEMID .asITEMNAMES.NAME .fromITEMDATA .条件 取来 理论上,两个查询应该以完全相同的速度运行,因为如果您在ITEMDATA.ITEMID上有外键,它们是等效的


实际上,大多数数据库在连接查询方面可能会有更好的性能,除非它们实现标量子查询缓存,例如Oracle,它可以大大加快第二次查询的速度,具体取决于不同的ITEMID的数量,越小越好。

注:ITEMDATA.ITEMID=ITEMNAMES.ITEMID这实际上不起作用。你可能想使用eq方法当然我可以做一个连接。但是实际的查询要复杂得多,它涉及5个表。第一个原因是简化查询。第二个是查询性能。如果避免联接,性能不会提高吗?5联接不是一个复杂的查询:对于大多数数据库来说,它也不是一个困难的查询。只要尝试一下并测量一下,您就会发现join解决方案可能是最快的。我做了一次join,并测量了直接忽略java层延迟在db服务器上执行查询所花费的时间。如果没有联接,查询需要0.26秒,而使用联接则需要0.58秒。您有所有必需的索引吗?您是否多次运行查询以避免任何测量错误?您是否将该解决方案与我的相关子查询备选方案进行了比较?抱歉,耽搁了。我已经准备好了所有需要的索引,并运行了几次。连接需要更多的时间。子查询所用的时间几乎完全相同,相差0.01秒。