zoukankan      html  css  js  c++  java
  • Java step by step (4): Hibernate and Bind Variables

    关于在SQL语句中是用Bind Variables的重要性就不用多说了,最近在看代码的时候发现有一条比较耗时的SQL语句居然是在Java代码中动态拼接而成的。这条SQL语句之前也进行过一些简单的重写优化工作,在with语句中特别用到hint 了/*+materialize*/。之前认为这个hint在WITH语句中没有必要使用,Oracle应该会自动创建一个临时表用于with语句结果的存储,结果居然发现加不加这个hint差别还是蛮大的,最后就加上了这个hint. 

    OK,回到正题上来。这个SQL需要接收的参数是一个动态的逗号分隔的字符串,放在in list中用的。很显然,如果用PL/SQL来写这个语句的话,是不能用如下的方式的....



    ---------------------------------------------------------------------------------

    function test(p_list_of_names in varchar2)return ....

    as

      select * 

      from ...

      where name in (p_list_of_names)

      ...

    end;

    --------------------------------------------------------------------------------
     


    一般这种情况下用Pl/SQL方式的话,最简单的就是用动态SQL执行,但是很显然这个就会失去bind variables的优势,会造成SQL Hard Parse次数的增加。为了避免动态SQL, 一般我们会借助nested table来做,但是这样会造成执行计划的不准确。这个可以参见(http://www.cnblogs.com/fangwenyu/archive/2011/04/18/2020191.html).



    不过貌似这个问题在Hibernate中很容易得到解决,SQL语句还是可以写成上面那样,只是在绑定参数的时候,传入一个数组就OK了。如下所示...

    import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;

    public class demo {

    private String sql;

    private NamedParameterJdbcTemplate jdbcTemplate;

    public void setSql(final String sql) {
    this.sql = sql;
    }

    public String getSql() {
    return this.sql;
    }

    public List<XXX> retrieveResult(final String userId) {
    Set
    <String> userIds = combineUserIds(userId);

    Map
    <String, Object> params = new HashMap<String, Object>();
    params.put(
    "userIds", userIds);

    List
    <XXX> result = jdbcTemplate.query(this.getSql(), params,
    new RowMapper<XXX>() {
    public XXX mapRow(ResultSet rs, int line) throws SQLException {

    ....

     

    这里面的SQL语句放在了XML文件中,用Spring IoC自动初始化...

    <bean id="demo"class="demo">

    <property name="sql" value="
    select * from xxx where user_id in (:userIds)"/>
    </bean>

      
     

    在运行的时候,Hibernate会把:userIds替换成一些列的"?" placeholder (根据传进来数组的元素个数),这样也就可以使用绑定变量了。 

  • 相关阅读:
    07noip 统计数字 解题报告
    07noip 矩阵取数游戏 解题报告
    10 noip 乌龟棋 解题报告
    10 noip 引水入城 解题报告
    让我们来看一看C++ 简短自序
    curl post请求封装
    array_merge与数组加
    composer设置autoload自己的代码
    mysql使用笔记
    android入门:zxing学习笔记(六)
  • 原文地址:https://www.cnblogs.com/fangwenyu/p/2128563.html
Copyright © 2011-2022 走看看