How to do in-query in jDBI?

后端 未结 4 605
轮回少年
轮回少年 2020-12-05 17:11

How can I execute somethings like this in jDBI ?

@SqlQuery(\"select id from foo where name in \")
List getIds(@Bind(         


        
相关标签:
4条回答
  • 2020-12-05 17:53

    This should work:

    @SqlQuery("select id from foo where name in (<nameList>)")
    List<Integer> getIds(@BindIn("nameList") List<String> nameList);
    

    Don't forget to annotate class containing this method with:

    @UseStringTemplate3StatementLocator
    

    annotation (beacuse under the hood JDBI uses Apache StringTemplate to do such substitutions). Also note that with this annotation, you cannot use '<' character in your SQL queries without escaping (beacause it is a special symbol used by StringTemplate).

    0 讨论(0)
  • 2020-12-05 18:05

    With PostgreSQL, I was able to use the ANY comparison and bind the collection to an array to achieve this.

    public interface Foo {
        @SqlQuery("SELECT id FROM foo WHERE name = ANY (:nameList)")
        List<Integer> getIds(@BindStringList("nameList") List<String> nameList);
    }
    
    @BindingAnnotation(BindStringList.BindFactory.class)
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.PARAMETER})
    public @interface BindStringList {
        String value() default "it";
    
        class BindFactory implements BinderFactory {
            @Override
            public Binder build(Annotation annotation) {
                return new Binder<BindStringList, Collection<String>>() {
                    @Override
                    public void bind(SQLStatement<?> q, BindStringList bind, Collection<String> arg) {
                        try {
                            Array array = q.getContext().getConnection().createArrayOf("varchar", arg.toArray());
                            q.bindBySqlType(bind.value(), array, Types.ARRAY);
                        } catch (SQLException e) {
                            // handle error
                        }
                    }
                };
            }
        }
    }
    

    NB: ANY is not part of the ANSI SQL standard, so this creates a hard dependency on PostgreSQL.

    0 讨论(0)
  • 2020-12-05 18:05

    If you are using the JDBI 3 Fluent API, you can use bindList() with an attribute:

    List<String> keys = new ArrayList<String>()
    keys.add("user_name");
    keys.add("street");
    
    handle.createQuery("SELECT value FROM items WHERE kind in (<listOfKinds>)")
          .bindList("listOfKinds", keys)
          .mapTo(String.class)
          .list();
    
    // Or, using the 'vararg' definition
    handle.createQuery("SELECT value FROM items WHERE kind in (<varargListOfKinds>)")
          .bindList("varargListOfKinds", "user_name", "docs", "street", "library")
          .mapTo(String.class)
          .list();
    

    Note how the query string uses <listOfKinds> instead of the usual :listOfKinds.

    Documentation is here: http://jdbi.org/#_binding_arguments

    0 讨论(0)
  • 2020-12-05 18:11

    Use @Define annotation to build dynamic queries in jDBI. Example:

    @SqlUpdate("insert into <table> (id, name) values (:id, :name)")
    public void insert(@Define("table") String table, @BindBean Something s);
    
    @SqlQuery("select id, name from <table> where id = :id")
    public Something findById(@Define("table") String table, @Bind("id") Long id);
    
    0 讨论(0)
提交回复
热议问题