jdbcTemplate模板的一些方法初学笔记

前言

本篇文章将遇到的一些jdbcTemplate方法,出现问题的地方做记录

正文

jdbcTemplate.queryForObject()

Object queryForObject(String sql, Object[] args, Class requiredType)
这个重载方法,requiredType是一个单列的返回类型,select中只能有一个column
代码分析

public Object queryForObject(String sql, Object args[], Class requiredType)throws DataAccessException {
        return queryForObject(sql, args, getSingleColumnRowMapper(requiredType));
}
//getSingleColumnRowMapper就可以说明问题
public Object mapRow(ResultSet rs, int rowNum)
        throws SQLException
    {
        ResultSetMetaData rsmd;
        Object result;
        rsmd = rs.getMetaData();
        int nrOfColumns = rsmd.getColumnCount();
        if(nrOfColumns != 1)  //不是单列抛出异常
            throw new IncorrectResultSetColumnCountException(1, nrOfColumns);
        result = getColumnValue(rs, 1, requiredType);
        if(result == null || requiredType == null || requiredType.isInstance(result))
            break MISSING_BLOCK_LABEL_136;
        return convertValueToRequiredType(result, requiredType);
        IllegalArgumentException ex;
        ex;
        throw new TypeMismatchDataAccessException((new StringBuilder()).append("Type mismatch affecting row number ").append(rowNum).append(" and column type '").append(rsmd.getColumnTypeName(1)).append("': ").append(ex.getMessage()).toString());
        return result;
    }

如何解决? 可以使用框架提供的BeanPropertyRowMapper,自己会将rs中的column值反射到指定的映射对象User中

public User findUser(RegisterDTO dto) {
        String sql = "select t.id as userid ,t.displayname from user1 t where t.displayname = ? ";
        Object args[] = new Object[]{dto.getDisplayname()};
        return (User) jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper(User.class),args);
    }

或者可以自己使用匿名内部类,新建一个RowMapper,自定义返回

jdbcTemplate.queryForObject() 返回唯一值

queryForObject与queryForMap返回唯一值,且一定要有值,如果没有值的话,抛出异常org.springframework.dao.EmptyResultDataAccessException: Incorrect result size: expected 1, actual 0
代码分析

@Override
    public <T> T queryForObject(String sql, RowMapper<T> rowMapper, Object... args) throws DataAccessException {
        List<T> results = query(sql, args, new RowMapperResultSetExtractor<T>(rowMapper, 1));
        return DataAccessUtils.requiredSingleResult(results);
    }

DataAccessUtils.requiredSingleResult(results)

public static <T> T requiredSingleResult(Collection<T> results) throws IncorrectResultSizeDataAccessException {
        int size = (results != null ? results.size() : 0);
        if (size == 0) { //查询的结果为0,抛异常
            throw new EmptyResultDataAccessException(1);
        }
        if (results.size() > 1) { //结果数量1抛异常
            throw new IncorrectResultSizeDataAccessException(1, size);
        }
        return results.iterator().next();
    }

解决办法,只能在调用queryForObject的时候捕捉这个异常了。
代码如下

@SuppressWarnings({ "unchecked", "rawtypes" })
    @Override
    public User findUser(RegisterDTO dto) {
        String sql = "select t.id as userid ,t.displayname from user1 t where t.displayname = ? ";
        Object args[] = new Object[]{dto.getDisplayname()};
        //return (User) jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper(User.class),args);
        try {
        return (User) jdbcTemplate.queryForObject(sql, new RowMapper(){

            @Override
            public Object mapRow(ResultSet resultset, int i) throws SQLException {
                User user = new User();
                user.setDisplayname(resultset.getString("displayname"));
                return user;
            }


        },args);
        }catch(EmptyResultDataAccessException e) {
            return null;
        }
    }

这代码看起来有点蛋疼,queryForObject用起来也有点蛋疼

jdbcTemplate.queryForList()

 public List queryForList(String sql, Class elementType)
        throws DataAccessException
    {
        return query(sql, getSingleColumnRowMapper(elementType));
    }

像这里,指定了elementType,都是使用SingleColumnRowMapper,返回单列,解决办法,和queryForObject一样

未完待续

你可能感兴趣的:(String)