spring学习笔记(八)

前言

       今天整理下Spring JDBC,相信很多的Java开发人员都有过使用JDBC API的经历,可是每一次的操做都须要获取连接,建立Statement,异常处理,最后释放资源,这样的工做乏味而枯燥的,好在Spring JDBC为咱们提供了对JDBC API的轻量封装,这样咱们就能够轻松的使用JDBC了.java

JdbcTemplate

        Spring JDBC提供了JdbcTmplate用于完成JDBC操做,JdbcTmplate对JDBC API进行了封装,获取连接,建立Statement,异常处理,最后释放资源这些工做都交给了他帮咱们处理,咱们只须要编写SQL,而后执行SQL获取结果便可,同时JdbcTmplate中还提供了几个用于设置底层JDBC API的属性以下:spring

  • queryTimeout:用于设置JdbcTemplate所建立的Statement的最大查询超时时间,默认为0,即表示使用底层JDBC API的默认设置sql

  • fetchSize:设置底层的ResultSet每次冲数据库放回的行数,默认为0,即便用底层jdbc默认配置,这个属性和影响性能,设置过大,将大量在用内存,设置太小,从数据库读取次数将增长都很影响性能数据库

  • ignoreWarnings:是否忽略SQL警告,默认true,当为false时,出现警告JdbcTmplate将抛出异常数组

JdbcTmplate的配置相对简单,只须要在Spring配置中向JdbcTmplate注入DataSource既能够获取JdbcTmplate进行操做,因此这里就再也不介绍配置直接开始使用。性能

JdbcTemplate增删改操做

        增删改操做均可以使用JdbcTemplate的 int update(String sql, Object[] params)执行,由于增删改操做都返回影响的行数,此方法还有不少的重载方法:fetch

  • int update(String sql):为不带占位符的SQL语句提供方便spa

  • int update(String sql, Object[] params, int[] argTypes):除了占位符的入参数组外,后面的数组用于指定前面入参的类型,值为java.sql.Types类中的常量属性值code

  • int update(String sql, PreparedStatementSetter pss):PreparedStatementSetter 是一个回调接口,当你但愿能够本身为PreparedStatement设置时可使用,例:对象

  • jdbcTemplate.update(sql, new PreparedStatementSetter() {
        public void setValues(PreparedStatement ps) throws SQLException {
            ps.setString(1, "test1");
            ps.setString(2, "test2");
            ps.setString(3, "test3");
        }
    });
  • int update(PreparedStatementCreator psc):PreparedStatementCreator 也是一个回调接口,当你但愿本身建立PreparedStatement时可使用,例:

  • jdbcTemplate.update(new PreparedStatementCreator() {
        public PreparedStatement createPreparedStatement(Connection conn) throws SQLException {
            PreparedStatement ps = conn.preparedStatement(sql);//字符串sql必须是final的才能在内部类中使用 
            ps.setString(1, "test1");
            ps.setString(2, "test2");
            ps.setString(3, "test3");
            return ps;
        }
    });
  • int update(PreparedStatementCreator psc,PreparedStatementSetter pss):双回调用法是上面两种的结合

返回数据库的表自增值

        咱们常常会将表的主键设置成自增的,不少时候都会遇到插入一条数据后须要获得新插入数据的主键值得状况,一般咱们会先执行insert语句后再去select出这个值,JDBC3.0中当新增记录时,容许将数据库自动产生的主键值绑定到Statement或者PrepareStatement中:

  • Statement可使用int executeUpdate(String sql, int autoGeneratedKeys)

  • PrepareStatement能够在建立时设置使用Connection的PrepareStatement prepareStatement(String sql,  int autoGeneratedKeys)方法

autoGeneratedKeys的值都应该设置为Statement.RETURN_GENERATED_KEYS,再执行SQL获取到ResultSet对象后,调用ResultSet对象的getInt()方法既能够得到自增主键值。

        Spring利用这一技术,提供了一个能够返回新增记录对应主键值的方法:

            int update(PreparedStatementCreator psc, KeyHolder generatedKeyHolder)

        org.springframework.jdbc.support.KeyHolder是一个回调接口,Spring使用他保存返回的主键,该接口有以下方法:

  • Number getKey() throws InvalidDataAccessApiUsageException:当一次仅插入一条且主键为数字类型时使用此方法返回主键

  • Map<String, Object> getKeys() throws InvalidDataAccessApiUsageException:一次仅插入一条且是复合主键用这个方法key为列名,value为值

  • List<Map<String, Object>getKeyList():当新增多条记录是用这个方法返回

上述方法使用实例:

......
KeyHolder keyHolder = new GeneratedKeyHolder();
jdbcTemplate.update(new PrepareStatementCreator() {
    public PreparedStatement createPreparedStatement(Connection conn) throws SQLException {
        PreparedStatement ps = conn.preparedStatement(sql);//字符串sql必须是final的才能在内部类中使用 
        ps.setString(1, "test1");
        ps.setString(2, "test2");
        ps.setString(3, "test3");
        return ps;
}, keyHolder);
//以后使用keyHolder对象就能够得到自增的主键值了
int id = keyHolder.getKey().intValue();

批量更改数据

        通常状况下可使用for循环执行SQL语句实现批量更改,可是这样作是效率低下的,由于底层代码没更改一次都须要获取链接建立Statement,执行SQL再释放资源,而Spring提供的int[] batchUpdate(String[] sql)方法只会链接一次而后将SQL批量的交个数据库,这样会效率更高,这个方法也有一个重载方法:

        int[] batchUpdate(String sql, BatchPreparedStatementSetter pss)

例:

......
jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
    public int getBatchSize() {
        //viewSpaces是PrepareStatement的传入参数List
        return viewSpaces.size();
    }
    
    public void setValue(PreparedStatement ps, int index)
                throws SQLException {
        ViewSpace viewSpace = viewSpaces.get(index);
        ps.setString(1, viewSpace.getSapceName());
        ......
    }
});
相关文章
相关标签/搜索