当前位置: 首页 > 知识库问答 >
问题:

MyBatis,选择Provider和SQLBuilder

司空锋
2023-03-14

这不仅仅是一个简单的问题,我的英语没有我想要的那么好...我会尽力的。

@SelectProvider(type = PreIngestManager.class, method = "selectPreIngestsSQLBuilder")
@Results({ @Result(property = "id", column = "id"), @Result(property = "inputPath", column = "input_path"),
        @Result(property = "idCategoriaDocumentale", column = "id_categoria_documentale"), @Result(property = "idCliente", column = "id_cliente"),
        @Result(property = "outputSipPath", column = "output_sip_path"), @Result(property = "esito", column = "esito"),
        @Result(property = "stato", column = "stato"), @Result(property = "pathRdp", column = "path_rdp"),
        @Result(property = "dataInizio", column = "data_inizio"), @Result(property = "dataFine", column = "data_fine") })
List<PreIngest> selectPreIngestsByFilters(@Param("idCatDoc") Long idCatDoc, @Param("nomePacchetto") String nomePacchetto,
        @Param("dataInizioInferiore") Date dataInizioInferiore, @Param("dataInizioSuperiore") Date dataInizioSuperiore,
        @Param("statiPreIngest") String statiPreIngest);
public String selectPreIngestsSQLBuilder(Map<String, Object> params) {
    return new SQL() {
        {
            SELECT("*");
            FROM("pre_ingest");
            WHERE("id_categoria_documentale = #{idCatDoc}");
            if (params.get("nomePacchetto") != null)
                WHERE("input_path like '%' || #{nomePacchetto}");
            if (params.get("dataInizioInferiore") != null) {
                if (params.get("dataInizioSuperiore") != null) {
                    WHERE("data_inizio between #{dataInizioInferiore} and #{dataInizioSuperiore}");
                } else {
                    WHERE("data_inizio >= #{dataInizioInferiore}");
                }
            } else {
                if (params.get("dataInizioSuperiore") != null) {
                    WHERE("data_inizio <= #{dataInizioSuperiore}");
                }
            }
            if (params.get("statiPreIngest") != null)
                WHERE("stato in (#{statiPreIngest})");
            ORDER_BY("id ASC");
        }
    }.toString();
}

我必须指定@results注释和每个@result,还是可以使用java模型类?我尝试了@resultmap(value={“mycompany.model.preingest”}),但它不起作用。

最重要的是,如文档中所述,使用SQL builder可以访问方法参数,并将它们作为最终对象

// With conditionals (note the final parameters, required for the anonymous inner class to access them)
public String selectPersonLike(final String id, final String firstName, 
final String lastName) {
return new SQL() {{
   SELECT("P.ID, P.USERNAME, P.PASSWORD, P.FIRST_NAME, P.LAST_NAME");
    FROM("PERSON P");
    if (id != null) {
      WHERE("P.ID like #{id}");
    }
    if (firstName != null) {
      WHERE("P.FIRST_NAME like #{firstName}");
    }
    if (lastName != null) {
      WHERE("P.LAST_NAME like #{lastName}");
    }
    ORDER_BY("P.LAST_NAME");
    }}.toString();
}

但是如果我把这些final放在我的方法中,我就不能访问它们。我需要从方法声明中删除@param吗?是否需要在没有@SelectProvider的情况下调用SQLBuilder?我是在混合溶液吗?

就我所研究的而言,目前我看到了3种方法来执行动态查询,或者自定义where条件。

  1. 使用MyBatisGenerator库并将where条件作为搜索条件与SelectByExample方法一起使用。(我在查询简单时使用此选项)
  2. 直接编写SQL查询,使用if、choose、语句和此处描述的其他语句修改XML映射器文件
  3. 使用带有@SelectProvider注释的SQL生成器类。

你知道什么时候更喜欢2°的方法而不是3°的方法吗?为什么在3°方法文档中我找不到如何使用它?这里写了如何创建自定义查询,但没有写如何启动它们。

非常感谢您的时间和建议。

共有1个答案

归泽宇
2023-03-14

我不知道你是否已经找到了答案,我只是想分享我的经验。顺便说一句,如果我的英语不好,请原谅。

注意:我使用MyBatis 3.4.6和Spring框架。

我必须指定@results注释和每个@result,还是可以使用java模型类?

    @Results(id="myResult", value= {
        @Result(property = "id", column = "id"), 
        @Result(property = "inputPath", column = "input_path"),
        @Result(property = "idCategoriaDocumentale", ... })
    List<PreIngest> selectPreIngestsByFilters(@Param("idCatDoc") Long idCatDoc, @Param("nomePacchetto") String nomePacchetto, ...);
    @ResultMap("myResult")
    List<PreIngest> selectPreIngestsBySomethingElse(....);

...或者我可以使用java模型类吗?

您可以在不使用@results和@resultMap的情况下将java模型类用作结果,但必须确保java模型类具有与查询结果相同的属性/字段。数据库表通常有带有snake_case的字段。由于java使用的是camelCase,所以必须向mybatis-config.xml文件添加设置。

这是我通常添加到mybatis-config.xml中的内容

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
        <settings>
            <!-- changes from the defaults -->
            <setting name="lazyLoadingEnabled" value="false" />
            <setting name="mapUnderscoreToCamelCase" value="true"/>
            <setting name="jdbcTypeForNull" value="NULL"/>
        </settings>
    </configuration>

班级:

public class PreIngest {
    private Long idCategoriaDocumentale;
    private Long idCliente;
    ........ other fields
    ........ setter, getter, etc
}

映射器文件:

List<PreIngest> selectPreIngestsByFilters(@Param("idCatDoc") Long idCatDoc, @Param("nomePacchetto") String nomePacchetto, ...);

现在转到SQLBuilder。

    public class PersonFilter {
        private Long id;
        private String firstName;
        private String lastName;

        ...... setter, getter, etc
    }
    @SelectProvider(type=PersonSqlBuilder.class, method="selectPersonLike")
    List<Person> selectPersonLike(PersonFilter filter);

SqlBuilder类

    public class PersonSqlBuilder {

        public String selectPersonLike(PersonFilter filter) {
            return new SQL() {{
                SELECT("P.ID, P.USERNAME, P.PASSWORD, P.FIRST_NAME, P.LAST_NAME");
                FROM("PERSON P");
                if (filter.getId() != null) {
                    WHERE("P.ID like #{id}");
                }
                if (filter.getFirstName() != null) {
                    WHERE("P.FIRST_NAME like #{firstName}");
                }
                if (filter.getLastName() != null) {
                    WHERE("P.LAST_NAME like #{lastName}");
                }
                ORDER_BY("P.LAST_NAME");
            }}.toString();
        }
    }

就是这样。希望我的经验能有所帮助。

 类似资料:
  • 我试图将Apache Camel(2.20.0)与mybatis组件一起使用。更具体地说,我必须将一个大集合或记录从数据库导出到文件。我想防止内存问题,所以我想使用consumer.useIterator选项。我的路线是: 谢谢你。

  • 我试图使用MyBatis从包含整数的表中获取单个列。我假设将其提取为一个列表(尽管在这一点上我可能错了!) 这是我的mapper.xml 这是我的映射器界面 我的DAO: 我如何称呼它: MyBatis似乎正在创建我期望的SELECT查询: 当我运行它时,我得到了这个: 我敢肯定我在做一些非常愚蠢的事情!

  • MyBatis代码不加载枚举类型(版本:3.4.4)。 在MySQL数据库中,我有一个带有“cartype”字段的表,它是INT(11)类型。在Java中,我创建了一个用于处理汽车类型的枚举: Car mapper xml如下所示(不包含所有数据): 最后,我的豆子看起来如下: bean也包含getters和setters。 当我尝试在java中获取汽车时,它抛出以下异常:

  • 我在mybatis文档和inet中搜索过。但找不到解决方案。 我的目标是:从myBatis动态SQL选择返回阉羊 不创建pojo作为数据库表的表示。 它应该看起来像: 1) 动态SQL: 2) 我在动态选择中输入的参数: } 3) 返回映射的方法:

  • 最近发现一种基于 Java17、SpringBoot3 和 JOOQ 的现代 Java 技术栈,可以作为 mybatis 和 hibernate 的第三种选择 https://www.mjga.cc https://github.com/ccmjga/mjga-scaffold 一篇关于它的介绍 https://segmentfault.com/a/1190000044572199 这个 JOOQ

  • 我想在react中处理选择的事件,示例如何在普通JS中工作。 因此我为选择创建了react组件: