zoukankan      html  css  js  c++  java
  • JdbcTemplate的使用

    NamedParameterJdbcTemplate中包含了一个JdbcTemplateNamedParameterJdbcTemplate中的很多方法实际上还是交由JdbcTemplate去完成。NamedParameterJdbcTemplateJdbcTemplate增加的功能是对输入的条件参数取别名。例如:

    String sql2 = "select id,tname as name,tpwd as password from tadd where tname = :name";将查询参数中数据库的列名tname换成了name

     

    SimpleJdbcTemplate中包含了一个NamedParameterJdbcTemplateSimpleJdbcTemplate中的很多实现是交由了底层的JdbcTemplate去完成。SimpleJdbcTemplate所增强的功能是泛型和可变长度的参数。

    Spring 3.1版本之后,NamedParameterJdbcTemplateJdbcTemplate也支持了泛型,SimpleJdbcTemplate就被标注为了过时。但是在Spring 3.1版本之前,能使用SimpleJdbcTemplate还是要使用SimpleJdbcTemplate

     

    SimpleJdbcTemplate中的主要方法如下:

      mysql> desc tadd; 

      +-------+------------------------+--------+--------+-------------+------------------------------------+

      | Field | Type                                | Null     | Key        | Default        | Extra                            |

      +-------+----------------------+-----------+--------+--------------+-----------------------------------+

      | id     | bigint(255)          | NO          | PRI        |                     | auto_increment                      |

      | tname | varchar(300)                | YES        |               | NULL         |                                   |

      | tpwd  | varchar(300) | YES      |                 | NULL    |              |                                                               |

      +-----------+--------------------+---------+--------+---------------+-----------------------------------+

      mysql> insert into tadd(tname,tpwd) values ('apply','asure');

         

    首先来看只返回一条记录的查询操作,返回多条记录将失败。

        使用queryForObject方法及其重载的方法  

       1. 没有JavaBean时的操作,使用queryForObject(String sql, RowMapper<T> rm, Map<String, ?> args)

    String sql2 = "select id,tname as name,tpwd as password from tadd where tname = :n";
        RowMapper<UserBean> rw = new RowMapper<UserBean>(){
                @Override
                public UserBean mapRow(ResultSet paramResultSet, int paramInt) throws SQLException {
                    UserBean ub = new UserBean();
                    ub.setId(paramResultSet.getObject("id") + "");
                    ub.setName(paramResultSet.getObject("name") + "");
                    ub.setPassword(paramResultSet.getObject("password") + "");
                    return ub;
                }
            };
            Map<String, String> map = new HashMap<String, String>();
            map.put("n", "apply");
            UserBean ub = jdbctemplate.queryForObject(sql2, rw, map);

     查询语句中as后面的名称是别名,会将查询结果中数据库的列名替换为别名。tname = :n条件参数取别名有二个作用,一是可以作用于Map参数,第二个是作用于下面的BeanPropertySqlParameterSource,使用BeanPropertySqlParameterSource时别名要和JavaBean中的名称一致。

      2.也可以使用可变长度的参数,这时条件参数不能取别名,要使用占位符的形式:

    String sql2 = "select id,tname as name,tpwd as password from tadd where tname = ?";
        UserBean ub = jdbctemplate.queryForObject(sql2, rw, "apply");

     

    3.创建一个名为UserBeanJavaBean,属性为idnamepassword,对应属性有getset方法。

    使用方法:T queryForObject(String sql, ParameterizedRowMapper<T> rm, Map<String, ?> args)

    UserBean ub = jdbctemplate.queryForObject(sql2new BeanPropertyRowMapper(UserBean.class),map);

    可以使用可变长度的参数,这时sql中也同样条件参数不能取别名:

    UserBean ub = jdbctemplate.queryForObject(sql2new BeanPropertyRowMapper(UserBean.class),"apply");

    4.还可以将Map参数替换,采用完全的面向对象的方式:

    String sql2 = "select id,tname as name,tpwd as password from tadd where tname = :name";
    
    userb.setName("apply");
    
    UserBean ub = jdbctemplate.queryForObject(sql2, new BeanPropertyRowMapper(UserBean.class),new BeanPropertySqlParameterSource(userb));

      注意:使用BeanPropertySqlParameterSource时别名要和JavaBean中的名称一致,否则会出错,和第一种情况比较。

    5.查询结果又多条时,可以使用queryqueryForList或者queryForMap,只要弄清楚参数中的ParameterizedRowMapperSqlParameterSource即可。 

    查询结果为基本类型或者String型时,可以使用queryForObject, queryForInt等。

    查询的操作使用各种的query重载方法,增加、删除、修改的操作使用各种的update重载方法,使用类似。 

    还有就是批量修改使用batchUpdate的各种重载方法。     

    6. NamedParameterJdbcTemplate中的各方法与SimpleJdbcTemplate类似,可能参数的顺序会不太一样。有下面几个有用的方法:

      用KeyHolder获取新插入数据的主键值,可以是单一主键或者是联合主键。

    String sql3 = "insert into tadd(tname) values (:name)";
    
    UserBean userb = new UserBean();
    
    userb.setName("applyee");
    
    KeyHolder kh = new GeneratedKeyHolder();
    
    jdbctemplate.update(sql3, new BeanPropertySqlParameterSource(userb), kh);
    
    userb.setId(kh.getKey().intValue()+ "");

    7.行映射器ResultSetExtractorRowCallbackHandlerRowMapper

    RowMapper前面已经用到,应用起来也最为简单,只需要处理单行数据即可。

    String sql4 = "select id,tname as name,tpwd as password from tadd where id < :id";
    RowMapper<UserBean> rw = new RowMapper<UserBean>(){
                @Override
                public UserBean mapRow(ResultSet paramResultSet, int paramInt) throws SQLException {
                    UserBean ub = new UserBean();
                    ub.setId(paramResultSet.getObject("id") + "");
                    ub.setName(paramResultSet.getObject("name") + "");
                    ub.setPassword(paramResultSet.getObject("password") + "");
                    return ub;
                }
        };
    UserBean user = new UserBean();
            user.setId("4");        
    List<UserBean> users = jdbctemplate.query(sql4, new BeanPropertySqlParameterSource(user), rw);
            for(UserBean u: users){
                System.out.println(u);
        }

      RowCallbackHandler需要自己处理每行的数据

    final List<UserBean> userList = new ArrayList<UserBean>();
            RowCallbackHandler rch = new RowCallbackHandler(){
                @Override
                public void processRow(ResultSet paramResultSet)
                        throws SQLException {
                    UserBean ub = new UserBean();
                    ub.setId(paramResultSet.getObject("id") + "");
                    ub.setName(paramResultSet.getObject("name") + "");
                    ub.setPassword(paramResultSet.getObject("password") + "");
                    userList.add(ub);
                }
            
            };
            
            UserBean user = new UserBean();
            user.setId("4");        
            jdbctemplate.query(sql4, new BeanPropertySqlParameterSource(user), rch);
            for(UserBean u: userList){
                System.out.println(u);
            }

      ResultSetExtractor也需要自己处理结果集:

    ResultSetExtractor rse = new ResultSetExtractor(){
                public Object extractData(ResultSet rs)
                        throws SQLException, DataAccessException {
                    List<UserBean> userList = new ArrayList<UserBean>();
                    while(rs.next()){
                        UserBean ub = new UserBean();
                        ub.setId(rs.getObject("id") + "");
                        ub.setName(rs.getObject("name") + "");
                        ub.setPassword(rs.getObject("password") + "");
                        userList.add(ub);
                    }    
                    return userList;
                }            
            };
            
            UserBean user = new UserBean();
            user.setId("4");        
            List<UserBean> ul = jdbctemplate.query(sql4, new BeanPropertySqlParameterSource(user), rse);
            for(UserBean u: ul){
                System.out.println(u);
            }

    8.还可以使用回调函数的方式来实现,相当于自己可以使用JDBC重写代码,而不是使用封装好的方法:

    sql语句的回调,使用PreparedStatementCallback返回已经编译好的sql语句再进行处理

    test.execute("update xx set name = 'oo' where id= ?",
        new PreparedStatementCallback(){
         public Object doInPreparedStatement(PreparedStatement ps) throws SQLException, DataAccessException {
          ps.setString(1, "123");//这里的参数对应?
          ps.addBatch();
          ps.setString(1, "456");
          ps.addBatch();
          return ps.executeBatch();
         }
      }); 

    连接的回调execute(ConnectionCallback<T> action)

     

    9. 通过JDBCTemplate操作数据库,链接是不需要手动地关闭的,但是如果从JDBCTemplate中获取了链接则需要手动地去关闭链接。

    例如,jdbcTemplate.getDataSource().getConnection()就需要自己去关闭数据库链接,否则会导致严重的后果。

    DataSourceUtils.releaseConnection(con, getDataSource());

     

  • 相关阅读:
    [SDOI2012]任务安排
    JavaScript数据存储和深浅拷贝实际运用
    在VUE中使用Echarts
    JavaScript的原型链
    关于JavaScript的43道题①
    JS为什么是单线程的?
    HTTP协议②缓存
    HTTP协议①介绍
    树形结构的数据渲染(element-ui&VUE)
    js中定义变量之②var let const的区别
  • 原文地址:https://www.cnblogs.com/lnlvinso/p/4194708.html
Copyright © 2011-2022 走看看