• 使用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()方法。这样就避免了不少面向结构化的开发。
  • 相关阅读:
    Excel操作 Microsoft.Office.Interop.Excel.dll的使用
    C#通过Microsoft.Office.Interop.Word操作Word
    Swift编码总结2
    Swift编码总结1
    Python第一阶段06
    Python第一阶段05
    Python第一阶段04
    Python第一阶段03
    Python第一阶段02
    Python第一阶段01
  • 原文地址:https://www.cnblogs.com/fanstatic/p/2125003.html
Copyright © 2020-2023  润新知