jdbcTemplate.queryForObject方法入参不支持以Map的形式传递参数,需要按照sql语句中参数的顺序组织入参的List。jdbcTemplate.queryForObject方法直接不支持的in查询。只支持Integer.class String.class 这种单数据类型的入参。
例如:
而
NamedParameterJdbcTemplate时,其本来就支持in查询和Map类型的入参。
Spring对数据库的操作在jdbc上面做了深层次的封装,提供了一个 Jdbc Template 类,我们可以直接使用。只需要把DataSource注册到JdbcTemplate之中,其全限定命名为
org.springframework.jdbc.core.JdbcTemplate。要使用JdbcTemlate一般还需要事务和异常的控制。
execute方法:可以用于执行任何SQL语句,一般用于执行DDL语句;update方法及batchUpdate方法:update方法用于执行新增、修改、删除等语句;batchUpdate方法用于执行批处理相关语句;query方法及queryForXXX方法:用于执行查询相关语句;call方法:用于执行存储过程、函数相关语句。
Spring JdbcTemplate是通过实现
org.springframework.jdbc.core.RowMapper这个接口来完成对entity对象映射。
Spring JDBC中目前有两个主要的RowMapper实现,使用它们应该能解决大部分的场景了:SingleColumnRowMapper和BeanPropertyRowMapper。
SingleColumnRowMapper:返回单列数据
BeanPropertyRowMapper:当查询数据库返回的是多列数据,且需要将这些多列数据映射到某个具体的实体类上。
定义自己的RowMapper
如果你SQL查询出来的数据列名就是和实体类的属性名不一样,或者想按照自己的规则来装配实体类,那么就可以定义并使用自己的Row Mapper。
PreparedStatementCreator:通过回调获取JdbcTemplate提供的Connection,由用户使用该Conncetion创建相关的PreparedStatement;
CallableStatementCreator:通过回调获取JdbcTemplate提供的Connection,由用户使用该Conncetion创建相关的CallableStatement;
首先使用PreparedStatementCreator创建一个预编译语句,其次由JdbcTemplate通过PreparedStatementCallback回调传回,由用户决定如何执行该PreparedStatement。此处我们使用的是execute方法。
PreparedStatementSetter:通过回调获取JdbcTemplate提供的PreparedStatement,由用户来对相应的预编译语句相应参数设值;
BatchPreparedStatementSetter:;类似于PreparedStatementSetter,但用于批处理,需要指定批处理大小;
通过JdbcTemplate的int update(String sql, PreparedStatementSetter pss)执行预编译sql,其中sql参数为“insert into user(user_name) values (?) ”,该sql有一个占位符需要在执行前设值,PreparedStatementSetter实现就是为了设值,使用setValues(PreparedStatement pstmt)回调方法设值相应的占位符位置的值。JdbcTemplate也提供一种更简单的方式“update(String sql, Object… args)”来实现设值,所以只要当使用该种方式不满足需求时才应使用PreparedStatementSetter。
ConnectionCallback:通过回调获取JdbcTemplate提供的Connection,用户可在该Connection执行任何数量的操作;
StatementCallback:通过回调获取JdbcTemplate提供的Statement,用户可以在该Statement执行任何数量的操作;
PreparedStatementCallback:通过回调获取JdbcTemplate提供的PreparedStatement,用户可以在该PreparedStatement执行任何数量的操作;
CallableStatementCallback:通过回调获取JdbcTemplate提供的CallableStatement,用户可以在该CallableStatement执行任何数量的操作;
RowMapper:用于将结果集每行数据转换为需要的类型,用户需实现方法mapRow(ResultSet rs, int rowNum)来完成将每行数据转换为相应的类型。
RowCallbackHandler:用于处理ResultSet的每一行结果,用户需实现方法processRow(ResultSet rs)来完成处理,在该回调方法中无需执行rs.next(),该操作由JdbcTemplate来执行,用户只需按行获取数据然后处理即可。
ResultSetExtractor:用于结果集数据提取,用户需实现方法extractData(ResultSet rs)来处理结果集,用户必须处理整个结果集;
RowMapper接口提供mapRow(ResultSet rs, int rowNum)方法将结果集的每一行转换为一个Map,当然可以转换为其他类。
RowCallbackHandler接口也提供方法processRow(ResultSet rs),能将结果集的行转换为需要的形式。
ResultSetExtractor使用回调方法extractData(ResultSet rs)提供给用户整个结果集,让用户决定如何处理该结果集。
当然JdbcTemplate提供更简单的queryForXXX方法,来简化开发:
在经典的 JDBC 用法中, SQL 参数是用占位符 ? 表示,并且受到位置的限制。定位参数的问题在于, 一旦参数的顺序发生变化, 就必须改变参数绑定。
在 Spring JDBC 框架中, 绑定 SQL 参数的另一种选择是使用具名参数(named parameter)。
具名参数:SQL 按名称(以冒号开头)而不是按位置进行指定,具名参数更易于维护,,也提升了可读性。具名参数由框架类在运行时用占位符取代,
具名参数只在
NamedParameterJdbcTemplate 中得到支持。
NamedParameterJdbcTemplate类拓展了JdbcTemplate类,可以使用全部jdbcTemplate方法。
NamedParameterJdbcTemplate主要提供以下三类方法:execute方法、query及queryForXXX方法、update及batchUpdate方法。
NamedParameterJdbcTemplate可以使用DataSource或JdbcTemplate 对象作为构造器参数初始化。
NamedParameterJdbcTemplate类为命名参数设值有两种方式:java.util.Map 、RowMapper 和 SqlParameterSource。
就是一个hash表,好处是可以根据参数名传参,paramMap.put(“sqlparamName”,value)。
这个接口为了实现sql查询结果和对象间的转换,可以自己实现,也可以使用系统实现,主要实现类有:
SingleColumnRowMapper ,sql结果为一个单列的数据,如List
其作用和Map一样,就是为sql中的条件参数赋值,默认实现有 :
MapSqlParameterSource实现非常简单,只是封装了java.util.Map。BeanPropertySqlParameterSource封装了一个JavaBean对象,通过JavaBean对象属性来决定命名参数的值。EmptySqlParameterSource 一个空的SqlParameterSource ,常用来占位使用。
返回单行单列数据
public < T > T queryForObject(String sql, Map
public < T > T queryForObject(String sql, SqlParameterSource paramSource, Class
返回 (多行)单列 数据
public < T> List< T> queryForList(String sql, Map
public < T> List< T> queryForList(String sql, SqlParameterSource paramSource, Class< T> elementType)
返回单行数据
public < T> T queryForObject(String sql, Map< String, ?> paramMap, RowMapper< T>rowMapper)
public < T> T queryForObject(String sql, SqlParameterSource paramSource, RowMapper< T> rowMapper)
注意:这两个API也可以使用SingleColumnRowMapper返回单行单列数据
返回Map形式的单行数据
public Map< String, Object> queryForMap(String sql, Map< String, ?> paramMap)
public Map< String, Object> queryForMap(String sql, SqlParameterSource paramSource)
注意:queryForMap这个方法要求结果必须是有数据的,否则会报错。
返回多行数据
public < T> List< T> query(String sql, Map< String, ?> paramMap, RowMapper< T> rowMapper)
public < T> List< T> query(String sql, SqlParameterSource paramSource, RowMapper< T> rowMapper)
public < T> List< T> query(String sql, RowMapper< T> rowMapper)
同理,也可以使用SingleColumnRowMapper返回单行列表List< String>,List< Integer>等。
返回多行数据(Map)
public List< Map< String, Object>> queryForList(String sql, Map< String, ?> paramMap)
public List< Map< String, Object>> queryForList(String sql, SqlParameterSource paramSource)
使用Map作为参数
int update(String sql, Map
使用SqlParameterSource作为参数
int update(String sql, SqlParameterSource paramSource)