fanstatic

< 2025年2月 >
26 27 28 29 30 31 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 1
2 3 4 5 6 7 8

统计

使用PreparedStatement为有in的sql语句动态赋值

这个方法意思是动态加载?,再给?动态赋值.这个方法意思是动态加载?,再给?动态赋值.可能有好多青年在刚刚学习java 的 PreparedStatement类的时候有过这样一个疑问,如果我想根据多个ID来查找数据的时候怎么写呢?用SELECT my_column FROM my_table where search_column IN (?)

那么?要赋什么样的值呢?setInt(),还是setString(); 

preparedStatement.setString( 1, "'A', 'B', 'C'" ),这样做很明显是不正确的。

 

 

 

网上有很多解决方法,这里我汇集了一下,把一些好的给摘要了下来,
方法一:先写一个方法如下
public static String preparePlaceHolders(int length) {

    StringBuilder builder = new StringBuilder();

    for (int i = 0; i < length;) {

        builder.append("?");

        if (++i < length) {

            builder.append(",");

        }

    }

    return builder.toString();

}



public static void setValues(PreparedStatement preparedStatement, Object... values) throws SQLException {

    for (int i = 0; i < values.length; i++) {

        preparedStatement.setObject(i + 1, values[i]);

    }

}
方法使用如下
这个方法意思是动态加载?,再给?动态赋值.
private static final String SQL_FIND = "SELECT id, name, value FROM data WHERE id IN (%s)";



public List<Data> find(Set<Long> ids) throws SQLException {

    Connection connection = null;

    PreparedStatement statement = null;

    ResultSet resultSet = null;

    List<Data> list = new ArrayList<Data>();

    String sql = String.format(SQL_FIND, preparePlaceHolders(ids.size()));



    try{

        connection = database.getConnection();

        statement = connection.prepareStatement(sql);

        setValues(statement, ids.toArray());

        resultSet = statement.executeQuery();

        while (resultSet.next()) {

            Data data = new Data();

            data.setId(resultSet.getLong("id"));

            data.setName(resultSet.getString("name"));

            data.setValue(resultSet.getInt("value"));

            list.add(data);

        }

    } finally {

        close(connection, statement, resultSet);

    }



    return list;

}
这个方法意思是动态加载?,再给?动态赋值.

方法二:创建一个sql函数


create or replace type split_tbl as table of varchar(32767);

/



create or replace function split

(

  p_list varchar2,

  p_del varchar2 := ','

) return split_tbl pipelined

is

  l_idx    pls_integer;

  l_list    varchar2(32767) := p_list;

  l_value    varchar2(32767);

begin

  loop

    l_idx := instr(l_list,p_del);

    if l_idx > 0 then

      pipe row(substr(l_list,1,l_idx-1));

      l_list := substr(l_list,l_idx+length(p_del));

    else

      pipe row(l_list);

      exit;

    end if;

  end loop;

  return;

end split;

/

 

使用好下
select * from table(split('one,two,three'))
  one
  two
  three

select * from TABLE1 where COL1 in (select * from table(split('value1,value2')))
  value1 AAA
  value2 BBB
PreparedStatement可以使用好下
 "select * from TABLE where COL in (select * from table(split(?)))"

此方法的意思是创建一个split的sql函数把以“1,2,3”形式的字符串劈开返回
  1
  2
  3
形式的表这样就可以用子查询了。
引用:http://stackoverflow.com/questions/178479/preparedstatement-in-clause-alternatives
不知道为什么jdk不为PreparedStatement类提供一个setList()方法。这样就避免了不少面向结构化的开发。

 

posted on   fanstatic  阅读(4621)  评论(3编辑  收藏  举报

点击右上角即可分享
微信分享提示