本文介绍了如何在JDBI中使用IN运算符?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在Dropwizard上使用MYSQL JDBI进行IN查询(我认为不相关).

I'm trying to do a IN query using MYSQL JDBI on Dropwizard (not relevant, I assume).

@SqlQuery("SELECT id FROM table where field in (<list>)")
List<Integer> findSomething(@BindIn("list") List<String> someList);

根据建议此处,我ve也用

@UseStringTemplate3StatementLocator

但是当我启动应用程序时,出现以下错误:

But when I'm starting the application, I get the following error:

Exception in thread "main" java.lang.annotation.AnnotationFormatError: Invalid default: public abstract java.lang.Class org.skife.jdbi.v2.sqlobject.stringtemplate.UseStringTemplate3StatementLocator.errorListener()

有人对如何解决此问题有个好主意吗?

Does anyone have a good idea on how to solve this issue?

推荐答案

有两种方法可以实现它.

There are two ways to achieve it.

1 .使用UseStringTemplate3StatementLocator

此注释期望 Group Files

说我有这个文件PersonExternalizedSqlDAO

Say I have this file PersonExternalizedSqlDAO

// PersonExternalizedSqlDAO.java

package com.daoexp.dao;

@@ExternalizedSqlViaStringTemplate3
@RegisterMapper(PersonMapper.class)
public interface PersonExternalizedSqlDAO {
    @SqlQuery
    List<Person> getPersonByNames(@BindIn("names") List<String> names);
}

由于我们使用的是UseStringTemplate3StatementLocator,因此必须在相同的类路径中创建*.sql.stg文件.例如:(在resources/com/daoexp/dao/PersonExternalizedSqlDAO.sql.stg

Since we are using UseStringTemplate3StatementLocator we have to create *.sql.stg file in same class path.For ex: in resources/com/daoexp/dao/PersonExternalizedSqlDAO.sql.stg

group PersonExternalizedSqlDAO;

getPersonByNames(names) ::= <<
  select * from person where name in (<names>)
>>

现在,您应该可以毫无问题地进行查询了.

Now you should be able to query without any issues.

2 .另一种方法是使用ArgumentFactory处理带有@Bind的JDBI的自定义数据类型(在本例中为List).这是最可取的方法.

2. Another approach is to use ArgumentFactory that handles your custom data type(in this case List) for JDBI with @Bind. This is most preferable approach.

因此创建此列表参数工厂

So create this list argument factory

public class ListArgumentFactory implements ArgumentFactory<List> {
    @Override
    public boolean accepts(Class<?> expectedType, Object value, StatementContext ctx) {
        return value instanceof List;
    }

    @Override
    public Argument build(Class<?> expectedType, final List value, StatementContext ctx) {
        return new Argument() {
            @Override
            public void apply(int position, PreparedStatement statement, StatementContext ctx) throws SQLException {
                String type = null;
                if(value.get(0).getClass() == String.class){
                    type = "varchar";
                } else if(value.get(0).getClass() == Integer.class){
                    // For integer and so on...
                } else {
                    // throw error.. type not handled
                }
                Array array = ctx.getConnection().createArrayOf(type, value.toArray());
                statement.setArray(position, array);
            }
        };
    }
}

该类做什么?

  • 接受List的实例
  • 将整数/字符串列表转换为数组,并与准备好的语句绑定

确保您在DBI实例中注册了该参数工厂.

Make sure you register this argument factory with your DBI instance.

final DBIFactory factory = new DBIFactory();
final DBI jdbi = factory.build(environment, configuration.getDataSourceFactory(), "h2");
jdbi.registerArgumentFactory(new ListArgumentFactory());

现在,您应该能够以更简单的方式使用List进行查询(即,您必须使用@Bind).而已.

Now you should be able to query using List in more simpler way(i.e) you have to use @Bind. Thats it.

@RegisterMapper(PersonMapper.class)
public interface PersonDAO {
    @SqlQuery("select * from person where name = any(:names)")
    List<Person> getPersonByNames(@Bind("names") List<String> names);
}

引用:

其他信息:

// PersonMapper.java
public class PersonMapper implements ResultSetMapper<Person> {

    public Person map(int index, ResultSet r, StatementContext ctx) throws SQLException {
        Person person = new Person();
        person.setId(r.getInt("id"));
        person.setName(r.getString("name"));

        return person;
    }
}

这篇关于如何在JDBI中使用IN运算符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-22 10:12