这不仅仅是一个简单的问题,我的英语没有我想要的那么好.我尽力而为。
我使用java 8,在Postgres 9.6上使用Mybati3.4.6,我需要做一个定制的动态查询。
在我的mapper.java类中,我创建了一个用于myBatis类的方法
@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);我已经指定了要指向的@SelectProvider注释、类和方法,在示例中是PreIngestManager.class和selectPreIngestsSQLBuilder方法。
这就是方法
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();
}以下是我的问题:
我是否需要指定@结果注释和每个@结果,或者我是否可以使用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();
}但如果我用我的方法做最后的决定,我就无法访问它们。是否需要从方法声明中删除@Param?是否需要不使用@SelectProvider来调用SQLBuilder?我在混合溶液吗?
据我所研究,目前我看到了3种方法来执行动态查询或自定义where条件。
你知道什么时候比3°方法更喜欢2°法吗?为什么在3°方法文档中我找不到如何使用它?编写了如何创建自定义查询,而不是如何启动它们。
非常感谢您的时间和建议。
发布于 2018-12-12 12:43:09
我不知道你是否已经找到了答案,我只想分享我的经验。顺便说一句,如果我的英语不好,请原谅。
注意:我使用MyBatis 3.4.6和。
我是否需要指定@结果注释和每个@结果,或者我是否可以使用java模型类?
实际上你可以做任何一件。
如果要使用@Results和@ResultMap,只需在一个mapper文件中指定一次@结果注释即可。诀窍是您需要为其他函数中使用的结果指定id。
使用类的截断版本,例如:
@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和前面提到的引用id的值。
@ResultMap("myResult")
List<PreIngest> selectPreIngestsBySomethingElse(....);.或者我可以使用java模型类?
您可以使用java模型类作为结果,而无需使用@Results和@ResultMap,但您必须确保java模型类具有与查询结果相同的属性/字段。数据库表通常有带有snake_case的字段。由于java使用的是camelCase,所以必须将设置添加到mybati-config.xml文件中。
这就是我通常添加到mybati-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>重要的是mapUnderscoreToCamelCase,将其设置为true,这样您就可以使用java模型类,而无需使用@Results和@ResultMap的麻烦。您可以在MyBatis 3配置中找到对设置的所有解释。
这是使用类的示例,
全班:
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。
但如果我用我的方法做最后的决定,我就无法访问它们。是否需要从方法声明中删除@Param?是否需要不使用@SelectProvider来调用SQLBuilder?
在您的方法中,我无法回答关于这些最终结果的问题,因为我从未使用最终参数创建过SqlBuilder类。
对于SqlBuilder,您必须使用@SelectProvider、@InsertProvider、@UpdateProvider或@DeleteProvider,这取决于您使用的查询。
在我使用SQLBuilder的经验中,如果需要多个参数并使用Map从SqlBuilder类访问它,@Param是必要的。如果不希望在mapper文件中使用@Param,则需要确保上述mapper函数中只有一个参数。如果只指定一个参数,则可以使用java模型类作为参数。
例如,如果使用类,则可以有一个类。
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();
}
}就这样。希望我的经验能有所帮助。
发布于 2018-01-19 14:33:17
我不知道如何使用sql构建器来完成这个任务,但是我确实知道如何使用xml映射文件来完成这个任务:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="path.to.class.PreIngestMapper">
<resultMap id="preIngestManager" type="path.to.class.PreIngestManager">
<id property="id" column="id" />
<result property="id" column="id" />
<result property="inputPath" column="input_path" />
<result property="idCategoriaDocumentale" column="id_categoria_documentale" />
...
</resultMap>
<select id="selectPreIngests" parameterType="Map" resultMap="preIngestManager">
SELECT *
FROM pre_ingest
WHERE id_categoria_documentale = #{idCatDoc}
<if test = "nomePacchetto != null">
and input_path like '%' || #{nomePacchetto}
</if>
...
;
</select>
</mapper>https://stackoverflow.com/questions/48343147
复制相似问题