Spring中JdbcTemplate各个方法的使用介绍(持续更新中....)

目录

execute 系列

1.execute(final String sql)

 2.execute(StatementCallback action)

 3.execute(ConnectionCallback action)

4.execute(String sql, PreparedStatementCallback action)

5. execute(String callString, CallableStatementCallback action)

 6.execute(PreparedStatementCreator psc, PreparedStatementCallback action)

7.execute(CallableStatementCreator csc, CallableStatementCallback action)

query 系列

1.query(String sql, ResultSetExtractor rse)

2.query(String sql, RowCallbackHandler rch)

3.query(String sql, RowMapper rowMapper)

4.query(PreparedStatementCreator psc, @Nullable final PreparedStatementSetter pss, final ResultSetExtractor rse)

5.query(PreparedStatementCreator psc, ResultSetExtractor rse)

6.query(String sql, @Nullable PreparedStatementSetter pss, ResultSetExtractor rse)

7.query(String sql, Object[] args, int[] argTypes, ResultSetExtractor rse)

8.query(String sql, @Nullable Object[] args, ResultSetExtractor rse)

9.query(String sql, ResultSetExtractor rse, @Nullable Object... args)

10.query(PreparedStatementCreator psc, RowCallbackHandler rch) 

11.query(String sql, @Nullable PreparedStatementSetter pss, RowCallbackHandler rch)

12.query(String sql, Object[] args, int[] argTypes, RowCallbackHandler rch)

13.query(String sql, Object[] args, RowCallbackHandler rch)

14.query(String sql, RowCallbackHandler rch, @Nullable Object... args)

15.query(PreparedStatementCreator psc, RowMapper rowMapper)

16.query(String sql, @Nullable PreparedStatementSetter pss, RowMapper rowMapper)

 17.query(String sql, Object[] args, int[] argTypes, RowMapper rowMapper)

18.query(String sql, @Nullable Object[] args, RowMapper rowMapper)

19.query(String sql, RowMapper rowMapper, @Nullable Object... args)

 

queryForList 系列

1.queryForList(String sql, Class elementType)

2.queryForList(String sql)

3.queryForList(String sql, Object[] args, int[] argTypes, Class elementType)

4.queryForList(String sql, Object[] args, Class elementType)

5.queryForList(String sql, Class elementType, @Nullable Object... args)

6.queryForList(String sql, Object[] args, int[] argTypes)

7.queryForList(String sql, @Nullable Object... args)

queryForObject 系列

1.queryForObject(String sql, RowMapper rowMapper)

2.queryForObject(String sql, Class requiredType)

3.queryForObject(String sql, Object[] args, int[] argTypes, RowMapper rowMapper)

4.queryForObject(String sql, @Nullable Object[] args, RowMapper rowMapper)

5.queryForObject(String sql, RowMapper rowMapper, @Nullable Object... args)

6.queryForObject(String sql, Object[] args, int[] argTypes, Class requiredType)

7.queryForObject(String sql, Object[] args, Class requiredType)

8.queryForObject(String sql, Class requiredType, @Nullable Object... args)

update 系列

1.update(final String sql)

2.update(PreparedStatementCreator psc)

3.update(final PreparedStatementCreator psc, final KeyHolder generatedKeyHolder)

4.update(String sql, @Nullable PreparedStatementSetter pss)

5.update(String sql, Object[] args, int[] argTypes)

6.update(String sql, @Nullable Object... args)

batchUpdate 系列

1.batchUpdate(final String... sql)

2.batchUpdate(String sql, final BatchPreparedStatementSetter pss)

3.batchUpdate(String sql, List batchArgs)[]>

4.batchUpdate(String sql, List batchArgs, final int[] argTypes)[]>

5.batchUpdate(String sql, final Collection batchArgs, final int batchSize, final ParameterizedPreparedStatementSetter pss)

call 系列

call(CallableStatementCreator csc, List declaredParameters)

其它方法


 

JdbcTemplate是Spring框架对JDBC封装的一个模板。简化了对sql的操作,不用关心链接的创建和关闭。

 JdbcTemplate主要提供以下五类方法:

  • execute方法:可以用于执行任何SQL语句,一般用于执行DDL语句;
  • update方法及batchUpdate方法:update方法用于执行新增、修改、删除等语句;batchUpdate方法用于执行批处理相关语句;
  • query方法及queryForXXX方法:用于执行查询相关语句;
  • call方法:用于执行存储过程、函数相关语句。

注意:所有执行查询的语句,都要注意查询结果为空的情况,有些方法对于空的查询结果会报异常。

其中主要三类操作:

execute:可以执行所有SQL语句,一般用于执行DDL语句。
update:用于执行INSERT、UPDATE、DELETE等DML语句。
queryXxx:用于DQL数据查询语句。

 

execute 系列

1.execute(final String sql)

public void execute(final String sql) throws DataAccessException

可以执行所有的sql,参数是一个sql,没有返回值。

比如:

    @Autowired
    private JdbcTemplate jdbcTemplate;
    
    @Override
    public Object execute() {
        jdbcTemplate.execute("select * from T_HAO_COALA_ACCOUNT"); // 查询数据
        jdbcTemplate.execute("insert into T_HAO_COALA_ACCOUNT (id,customer_name,sex,principal,bill_date) values (sys_guid(),'测试','1',222,15)"); // 新增数据
        jdbcTemplate.execute("update T_HAO_COALA_ACCOUNT set birthday=to_date('2000-10-07','yyyy-mm-dd') where id='834747A641D24410BF602FE448C61801'"); // 修改数据
        jdbcTemplate.execute("delete T_HAO_COALA_ACCOUNT where id = '1' "); // 删除
        jdbcTemplate.execute("COMMENT ON COLUMN T_HAO_COALA_ACCOUNT.BIRTHDAY IS '客户出生日期'"); // 给字段添加备注
        jdbcTemplate.execute("truncate table T_HAO_COALA_ACCOUNT"); // 清空表数据
        jdbcTemplate.execute("delete table T_HAO_COALA_ACCOUNT"); // 删除表
        jdbcTemplate.execute("drop table T_HAO_COALA_ACCOUNT"); // 删除表
        jdbcTemplate.execute("alter table T_HAO_COALA_ACCOUNT add test_column varchar2(200)"); // 修改表结构 添加字段
        jdbcTemplate.execute("alter table t_hao_coala_account drop column test_column"); // 修改表结构 删除字段
        jdbcTemplate.execute("begin add_data_to_account; end;"); // 执行存储过程
        jdbcTemplate.execute("create table test_execute_new_table(id  VARCHAR2(50),name varchar2(100) )tablespace TEST_DATA"); // 新建表
        
        return null;
    }

 2.execute(StatementCallback<T> action)

public <T> T execute(StatementCallback<T> action) throws DataAccessException

此方法是传入一个StatementCallback对象。StatementCallback接口只有一个方法。

@FunctionalInterface
public interface StatementCallback<T> {

	@Nullable
	T doInStatement(Statement stmt) throws SQLException, DataAccessException;

}

通过回调获取JdbcTemplate提供的Statement,用户可以在该Statement进行sql操作。

其实execute(final String sql)该方法就是调用execute(StatementCallback<T> action)这个方法实现的。所有的sql都能执行,例如:

@Autowired
private JdbcTemplate jdbcTemplate;

@Override
public Object execute() {
    
    // 新增数据
    jdbcTemplate.execute(new StatementCallback() {
        @Override
        public Object doInStatement(Statement stmt) throws SQLException, DataAccessException {
            stmt.execute("insert into T_HAO_COALA_ACCOUNT (id,customer_name,sex,principal,bill_date) values (sys_guid(),'测试22','1',222,15)");
            return null;
        }
    });

    // 查询一条数据 采用lambda表达式
    CoalaAccount execute = jdbcTemplate.execute((StatementCallback<CoalaAccount>) stmt -> {
        ResultSet rs = stmt.executeQuery("select id,customer_name,sex,bill_date from T_HAO_COALA_ACCOUNT where id='2'");
        CoalaAccount account = new CoalaAccount();
        while (rs.next()) {
            account.setId(rs.getString(1));
            account.setCustomerName(rs.getString(2));
            account.setSex(rs.getString(3).charAt(0));
            account.setBillDate(rs.getInt(4));
        }
        return account;
    });
    return null;
}
 

其实像很多query()、update()、batchUpdate()内部都是调用这个方法。

 3.execute(ConnectionCallback<T> action)

public <T> T execute(ConnectionCallback<T> action) throws DataAccessException

通过回调获取JdbcTemplate提供的Connection,用户可在该Connection执行一些操作。例如:

@Autowired
private JdbcTemplate jdbcTemplate;

@Override
public Object execute() {

	String sql = "select id,customer_name,sex,bill_date from T_HAO_COALA_ACCOUNT where sex='1' ";
	List<CoalaAccount> list = new ArrayList<>();
	
	List<CoalaAccount> execute = jdbcTemplate.execute(new ConnectionCallback<List<CoalaAccount>>() {
		@Override
		public List<CoalaAccount> doInConnection(Connection con) throws SQLException, DataAccessException {
			try {
				con.setAutoCommit(false); // 设置为手工提交事务,默认是自动提交
				PreparedStatement ps = con.prepareStatement(sql);
				ps.execute(); // 执行sql
				ResultSet rs = ps.getResultSet();
				while (rs.next()) {
					CoalaAccount account = new CoalaAccount();
					account.setId(rs.getString(1));
					account.setCustomerName(rs.getString(2));
					account.setSex(rs.getString(3).charAt(0));
					account.setBillDate(rs.getInt(4));
					list.add(account);
				}
				con.commit(); // 提交事务,查询时不需要提交
			} catch (Exception e) {
				logger.error("sql处理异常:", e);
				con.rollback(); // 事务回滚
			}
			return list;
		}
	});
}

4.execute(String sql, PreparedStatementCallback<T> action)

    @Override
	@Nullable
	public <T> T execute(String sql, PreparedStatementCallback<T> action) throws DataAccessException {
		return execute(new SimplePreparedStatementCreator(sql), action);
	}

 由传入的sql生成一个预编译语句,由JdbcTemplate通过PreparedStatementCallback回调传回,由用户决定如何执行该PreparedStatement。

例如:

String sql = "select id,customer_name,sex,bill_date from T_HAO_COALA_ACCOUNT where sex='1' ";
// 查询一条记录(实际上是能查询出多条数据,我这里只取一条)
CoalaAccount execute = jdbcTemplate.execute(sql, (PreparedStatementCallback<CoalaAccount>) ps -> {
    ps.execute();
    ResultSet rs = ps.getResultSet();
    CoalaAccount account = new CoalaAccount();
    while (rs.next()) {
        account.setId(rs.getString(1));
        account.setCustomerName(rs.getString(2));
        account.setSex(rs.getString(3).charAt(0));
        account.setBillDate(rs.getInt(4));
    }
    return account;
});
// 执行批量更新操作,执行两次,第一次更新三条数据,第二次更新一条数据
sql = "update T_HAO_COALA_ACCOUNT set bill_date = 1 where arrearage = ? ";
int[] result = jdbcTemplate.execute(sql, (PreparedStatementCallback<int[]>) ps -> {
    ps.setBigDecimal(1, new BigDecimal("2000")); // 传参
    ps.addBatch();
    ps.setBigDecimal(1, new BigDecimal("28500.00")); // 传参
    ps.addBatch();
    int[] ints = ps.executeBatch();
    return ints;
});
logger.info("执行结果:[{}]条数据", Arrays.toString(result));
// 输出结果:执行结果:[[3, 1]]条数据

5. execute(String callString, CallableStatementCallback<T> action)

    @Override
	@Nullable
	public <T> T execute(String callString, CallableStatementCallback<T> action) throws DataAccessException {
		return execute(new SimpleCallableStatementCreator(callString), action);
	}

此方法主要是处理存储过程和函数使用。

// 测试执行添加数据的存储过程
jdbcTemplate.execute("{call add_data_to_account}", new CallableStatementCallback() {
    @Override
    public Object doInCallableStatement(CallableStatement cs) throws SQLException, DataAccessException {
        cs.execute();
        return null;
    }
});
// 测试执行添加数据的存储过程 注意sql语句的传参格式,建议使用{}形式
jdbcTemplate.execute("begin add_data_to_account;end;", (CallableStatementCallback) cs -> {
    cs.execute();
    return null;
});
// 测试执行添加数据的存储过程,此存储过程带有两个输入参数
jdbcTemplate.execute("{call insert_data_to_user(?,?)}", (CallableStatementCallback) cs -> {
    cs.setString(1,"姓名:测试");
    cs.setString(2,"地点:北京");
    cs.execute();
    return null;
});
// 执行取数据的存储过程,存储过程第一个是输入参数,第二个和第三个是输出参数
String execute = jdbcTemplate.execute("{call get_data_from_product(?,?,?)}", (CallableStatementCallback<String>) cs -> {
    cs.setInt(1, 2);
    cs.registerOutParameter(2, Types.VARCHAR); // 注册OUT参数
    cs.registerOutParameter(3, Types.INTEGER); // 注册OUT参数
    cs.executeUpdate();
    String name = cs.getNString(2);
    int count = cs.getInt(3);
    return "货物名称:" + name + "   数量:" + count;
});

 6.execute(PreparedStatementCreator psc, PreparedStatementCallback<T> action)

    @Override
	@Nullable
	public <T> T execute(PreparedStatementCreator psc, PreparedStatementCallback<T> action) throws DataAccessException {}

第一个参数是创建一个预编译语句,第二个是预编译的回调函数。

例如:

// 查询数据
jdbcTemplate.execute(con -> con.prepareStatement("select id,customer_name,sex,bill_date from T_HAO_COALA_ACCOUNT where id = '2' "), (PreparedStatementCallback<CoalaAccount>) ps -> {
    ps.execute();
    ResultSet resultSet = ps.getResultSet();
    CoalaAccount account = new CoalaAccount();
    while (resultSet.next()) {
        account.setId(resultSet.getString(1));
        account.setCustomerName(resultSet.getString(2));
        account.setSex(resultSet.getString(3).charAt(0));
        account.setBillDate(resultSet.getInt(4));
    }
    return account;
});

// 新增数据
String sql = "insert into T_HAO_COALA_ACCOUNT (id,customer_name,sex,principal,bill_date) values (sys_guid(),?,?,?,?)";
jdbcTemplate.execute(new PreparedStatementCreator() {
    @Override
    public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
        PreparedStatement preparedStatement = con.prepareStatement(sql);
        preparedStatement.setString(1, "测试姓名:哈哈哈");
        preparedStatement.setString(2, "1");
        preparedStatement.setBigDecimal(3, new BigDecimal("5000.00"));
        preparedStatement.setInt(4, 3);
        return preparedStatement;
    }
}, new PreparedStatementCallback<Integer>() {
    @Override
    public Integer doInPreparedStatement(PreparedStatement ps) throws SQLException, DataAccessException {
        ps.executeUpdate();
        int updateCount = ps.getUpdateCount();
        logger.info("是否新增成功:{}", updateCount == 1);
        return updateCount;
    }
});

7.execute(CallableStatementCreator csc, CallableStatementCallback<T> action)

@Override
	@Nullable
	public <T> T execute(CallableStatementCreator csc, CallableStatementCallback<T> action)
			throws DataAccessException {
    // ....
}

通过CallableStatementCreator 创建存储过程或者函数的预编译语句,然后由CallableStatementCallback回调函数执行,获取结果,例如:

// 方式一
Object execute = jdbcTemplate.execute(new CallableStatementCreator() {
    @Override
    public CallableStatement createCallableStatement(Connection con) throws SQLException {
        CallableStatement callableStatement = con.prepareCall("{call get_data_from_product(?,?,?)}");
        callableStatement.setInt(1, 3); // 输入参数 主键ID的值
        callableStatement.registerOutParameter(2, Types.VARCHAR); // 注册OUT参数
        callableStatement.registerOutParameter(3, Types.INTEGER); // 注册OUT参数
        return callableStatement;
    }
}, new CallableStatementCallback<Object>() {
    @Override
    public Object doInCallableStatement(CallableStatement cs) throws SQLException, DataAccessException {
        cs.execute();
        ResultSet resultSet = cs.getResultSet();
        String name = cs.getNString(2);
        int count = cs.getInt(3);
        return "货物名称:" + name + "   数量:" + count;
    }
});

// 方式二
// 通过CallableStatementCreatorFactory工厂创建CallableStatementCreator对象
CallableStatementCreatorFactory factory = new CallableStatementCreatorFactory("{call get_data_from_product(?,?,?)}");
factory.addParameter(new SqlParameter("id", Types.INTEGER)); // 设置存储过程的输入参数
factory.addParameter(new SqlOutParameter("name", Types.VARCHAR)); // 设置存储过程的输出参数
factory.addParameter(new SqlOutParameter("count", Types.INTEGER)); // 设置存储过程的输出参数
HashMap<String, Object> param = new HashMap<>();
param.put("id", 3);
jdbcTemplate.execute(factory.newCallableStatementCreator(param), (CallableStatementCallback<Object>) cs -> {
    cs.execute();
    String name = cs.getString(2);
    int count = cs.getInt(3);
    return "货物名称:" + name + "   数量:" + count;
});

 

query 系列

1.query(String sql, ResultSetExtractor<T> rse)

@Override
@Nullable
public <T> T query(final String sql, final ResultSetExtractor<T> rse) throws DataAccessException { }

该方法返回一个泛型对象。sql为查询的sql语句,ResultSetExtractor是结果集数据提取用的,通过extractData(ResultSet rs)处理整个结果集。不支持传入参数。可以根据自己想要的类型返回结果,需要手工处理结果集。

// 查询单个结果对象,ID=2的数据
String sql = "select id,customer_name,sex,bill_date from T_HAO_COALA_ACCOUNT where id='2'";
CoalaAccount account = jdbcTemplate.query(sql, new ResultSetExtractor<CoalaAccount>() {
    @Override
    public CoalaAccount extractData(ResultSet rs) throws SQLException, DataAccessException {
        CoalaAccount account = new CoalaAccount();
        while (rs.next()) {
            account.setId(rs.getString(1));
            account.setCustomerName(rs.getString(2));
            account.setSex(rs.getString(3).charAt(0));
            account.setBillDate(rs.getInt(4));
        }
        return account;
    }
});

// 查询多个对象,返回该对象List。性别是1的所有数据
sql = "select id,customer_name,sex,bill_date from T_HAO_COALA_ACCOUNT where sex='1'";
List<CoalaAccount> list = jdbcTemplate.query(sql, (ResultSetExtractor<List<CoalaAccount>>) rs -> {
    List<CoalaAccount> list1 = new ArrayList<>();
    while (rs.next()) {
        CoalaAccount obj = new CoalaAccount();
        obj.setId(rs.getString(1));
        obj.setCustomerName(rs.getString(2));
        obj.setSex(rs.getString(3).charAt(0));
        obj.setBillDate(rs.getInt(4));
        list1.add(obj);
    }
    return list1;
});

// 查询多个对象,返回Map形式的List。性别是1的所有数据
List<Map<String, Object>> list = jdbcTemplate.query(sql, new ResultSetExtractor<List<Map<String, Object>>>() {
    @Override
    public List<Map<String, Object>> extractData(ResultSet rs) throws SQLException, DataAccessException {
        List<Map<String, Object>> list2 = new ArrayList<>();
        Map<String, Object> map;
        while (rs.next()) {
            map = new HashMap<>();
            map.put("id", rs.getString(1));
            map.put("customerName", rs.getString(2));
            map.put("sex", rs.getString(3));
            map.put("billDate", rs.getString(4));
            list2.add(map);
        }
        return list2;
    }
});

// 查询总数
sql = "select count(*) from T_HAO_COALA_ACCOUNT";
Integer count = jdbcTemplate.query(sql, rs -> {
    rs.next();
    int anInt = rs.getInt(1);
    return anInt;
});

 

2.query(String sql, RowCallbackHandler rch)

    @Override
	public void query(String sql, RowCallbackHandler rch) throws DataAccessException {
		query(sql, new RowCallbackHandlerResultSetExtractor(rch));
	}

其实这个方式就是调用上面那个query()方法,需要用户自己取处理结果集,不过不需要判断ResultSet.next(),交由ResultSetExtractor的实现类的extractData(ResultSet rs)完成。用户只需要处理ResultSet的每一行数据。也不支持sql动态传入参数。

如果查询结果不存在,则会返回null。

 查询单条数据:

HashMap<String, Object> map = new HashMap<>();
jdbcTemplate.query(sql, new RowCallbackHandler() {
    @Override
    public void processRow(ResultSet rs) throws SQLException {
        map.put("id", rs.getString("id"));
        map.put("customerName", rs.getString("customer_name"));
        map.put("sex", rs.getString("sex"));
        map.put("billDate", rs.getString("bill_date"));
    }
});

查询多条数据:

ArrayList<CoalaAccount> list = new ArrayList<>();
sql = "select id,customer_name,sex,bill_date from T_HAO_COALA_ACCOUNT where sex='2'";
jdbcTemplate.query(sql, rs -> {
    CoalaAccount account = new CoalaAccount();
    account.setId(rs.getString(1));
    account.setCustomerName(rs.getString(2));
    account.setSex(rs.getString(3).charAt(0));
    account.setBillDate(rs.getInt(4));
    list.add(account);
});

 

3.query(String sql, RowMapper<T> rowMapper)

    @Override
	public <T> List<T> query(String sql, RowMapper<T> rowMapper) throws DataAccessException {
		return result(query(sql, new RowMapperResultSetExtractor<>(rowMapper)));
	}

该方法返回一个RowMapper指定泛型对象的List集合,用户需要通过mapRow(ResultSet rs, int rowNum)实现方法手动将每一行转换为需要的类型,可以是map也可以是自定义的对象。不支持动态传入参数。

例如:

// 查一条数据
String sql = "select id,customer_name,sex,bill_date from T_HAO_COALA_ACCOUNT where id='2'";
List<CoalaAccount> account = jdbcTemplate.query(sql, new RowMapper<CoalaAccount>() {
    @Override
    public CoalaAccount mapRow(ResultSet rs, int rowNum) throws SQLException {
        CoalaAccount account = new CoalaAccount();
        account.setId(rs.getString(1));
        account.setCustomerName(rs.getString(2));
        account.setSex(rs.getString(3).charAt(0));
        account.setBillDate(rs.getInt(4));
        return account;
    }
});

// 查多条数据
sql = "select id,customer_name,sex,bill_date from T_HAO_COALA_ACCOUNT where sex='2'";
List<CoalaAccount>  list = jdbcTemplate.query(sql, new RowMapper<CoalaAccount>() {
    @Override
    public CoalaAccount mapRow(ResultSet rs, int rowNum) throws SQLException {
        CoalaAccount obj = new CoalaAccount();
        obj.setId(rs.getString("id"));
        obj.setCustomerName(rs.getString("customer_name"));
        obj.setSex(rs.getString("sex").charAt(0));
        obj.setBillDate(rs.getInt("bill_date"));
        return obj;
    }
});

// 查询总数
sql = "select count(*) from T_HAO_COALA_ACCOUNT";
List<Integer> count = jdbcTemplate.query(sql, new RowMapper<Integer>() {
    @Override
    public Integer mapRow(ResultSet rs, int rowNum) throws SQLException {
        int anInt = rs.getInt(1);
        return anInt;
    }
});

 

4.query(PreparedStatementCreator psc, @Nullable final PreparedStatementSetter pss, final ResultSetExtractor<T> rse)

@Nullable
public <T> T query(
	PreparedStatementCreator psc, @Nullable final PreparedStatementSetter pss, final ResultSetExtractor<T> rse)
			throws DataAccessException {  }

这是个很重要的方法,其它很多query()方法底层都是调用这个方法实现的。该方法有三个参数,

PreparedStatementCreator:创建一个预编译的sql语句。

PreparedStatementSetter:如果sql中有动态的参数占位符,则给占位符赋值参数值。

ResultSetExtractor:处理sql执行的结果,将结果集中每一行转换为需要对象,需要先调用ResultSet.next()。

例如:

// 查询一条记录,sql中无动态参数
String sql = "select id,customer_name,sex,bill_date from T_HAO_COALA_ACCOUNT where id='2'";
CoalaAccount account = jdbcTemplate.query(new PreparedStatementCreator() {
    @Override
    public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
        return con.prepareStatement(sql);
    }
}, new PreparedStatementSetter() {
    @Override
    public void setValues(PreparedStatement ps) throws SQLException {
        // nothing to do ....
    }
}, new ResultSetExtractor<CoalaAccount>() {
    @Override
    public CoalaAccount extractData(ResultSet rs) throws SQLException, DataAccessException {
        CoalaAccount account = new CoalaAccount();
        while (rs.next()) {
            account.setId(rs.getString(1));
            account.setCustomerName(rs.getString(2));
            account.setSex(rs.getString(3).charAt(0));
            account.setBillDate(rs.getInt(4));
        }
        return account;
    }
});

// 查询多条记录,sql中有动态参数,使用的是lambda表达式
String sql2 = "select id,customer_name,sex,bill_date from T_HAO_COALA_ACCOUNT where sex = ? and bill_date > ?";
List<CoalaAccount> list = jdbcTemplate.query(
        con -> con.prepareStatement(sql2),
        ps -> {
            // 给sql中的占位符设置参数值
            ps.setString(1, "1");
            ps.setInt(2, 10);
        },
        (ResultSetExtractor<List<CoalaAccount>>) rs -> {
            ArrayList<CoalaAccount> list1 = new ArrayList<>();
            while (rs.next()) {
                CoalaAccount account1 = new CoalaAccount();
                account1.setId(rs.getString(1));
                account1.setCustomerName(rs.getString(2));
                account1.setSex(rs.getString(3).charAt(0));
                account1.setBillDate(rs.getInt(4));
                list1.add(account1);
            }
            return list1;
        });

5.query(PreparedStatementCreator psc, ResultSetExtractor<T> rse)

    @Override
	@Nullable
	public <T> T query(PreparedStatementCreator psc, ResultSetExtractor<T> rse) throws DataAccessException {
		return query(psc, null, rse);
	}

该方法其实和上面的一样,从其方法内部的实现可以看出就是调用上面的方法(4.query(PreparedStatementCreator psc, @Nullable final PreparedStatementSetter pss, final ResultSetExtractor<T> rse))。只是不支持传入动态的参数了,使用方式和上面类似:

        String sql = "select id,customer_name,sex,bill_date from T_HAO_COALA_ACCOUNT where id='2'";
        CoalaAccount account = jdbcTemplate.query(new PreparedStatementCreator() {
            @Override
            public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
                return con.prepareStatement(sql);
            }
        }, new ResultSetExtractor<CoalaAccount>() {
            @Override
            public CoalaAccount extractData(ResultSet rs) throws SQLException, DataAccessException {
                CoalaAccount account = new CoalaAccount();
                while (rs.next()) {
                    account.setId(rs.getString(1));
                    account.setCustomerName(rs.getString(2));
                    account.setSex(rs.getString(3).charAt(0));
                    account.setBillDate(rs.getInt(4));
                }
                return account;
            }
        });

6.query(String sql, @Nullable PreparedStatementSetter pss, ResultSetExtractor<T> rse)

	@Override
	@Nullable
	public <T> T query(String sql, @Nullable PreparedStatementSetter pss, ResultSetExtractor<T> rse) throws DataAccessException {
		return query(new SimplePreparedStatementCreator(sql), pss, rse);
	}

和上面的方法一样,也是调用的4.query(PreparedStatementCreator psc, @Nullable final PreparedStatementSetter pss, final ResultSetExtractor<T> rse),具体的处理方式都一样,支持动态的参数,需要处理sql中的占位符。

        String sql = "select id,customer_name,sex,bill_date from T_HAO_COALA_ACCOUNT where id='2'";
        jdbcTemplate.query(sql, new PreparedStatementSetter() {
            @Override
            public void setValues(PreparedStatement ps) throws SQLException {
            // 如果sql中有占位符,则处理占位符的参数值,没有不做任何处理。
            }
        }, new ResultSetExtractor<CoalaAccount>() {
            @Override
            public CoalaAccount extractData(ResultSet rs) throws SQLException, DataAccessException {
                // 处理结果集,
                return null;
            }
        });

 

7.query(String sql, Object[] args, int[] argTypes, ResultSetExtractor<T> rse)

    @Override
	@Nullable
	public <T> T query(String sql, Object[] args, int[] argTypes, ResultSetExtractor<T> rse) throws DataAccessException {
		return query(sql, newArgTypePreparedStatementSetter(args, argTypes), rse);
	}

 这个方式和上面的几个没有什么差别,看一下方法内部的调用就知道了,也是调用的4.query(PreparedStatementCreator psc, @Nullable final PreparedStatementSetter pss, final ResultSetExtractor<T> rse),只不过把Object[] args, int[] argTypes这两个参数分开了。主要是针对有可变参数的sql。这两个参数的意思是:

Object[] args:占位符对应的参数值。

int[] argTypes:占位符参数值的类型。

比如:

  // 根据泛型定义,可以查询多条也可以查询一条数据,如果sql有占位符则第二个和第三个参数不能是null,元素也必须要有值,且两个数组的长度要一样。
  String sql2 = "select id,customer_name,sex,bill_date from T_HAO_COALA_ACCOUNT where sex = ? and bill_date > ?";
  Object[] param = {"1", 10}; // 占位符对应的参数值
  int[] index = {Types.CHAR, Types.NUMERIC}; // 参数值类型
  List<CoalaAccount> list = jdbcTemplate.query(sql2, param, index, new ResultSetExtractor<List<CoalaAccount>>() {
      @Override
      public List<CoalaAccount> extractData(ResultSet rs) throws SQLException, DataAccessException {
          List<CoalaAccount> list = new ArrayList<>();
          while (rs.next()) {
              CoalaAccount account = new CoalaAccount();
              account.setId(rs.getString(1));
              account.setCustomerName(rs.getString(2));
              account.setSex(rs.getString(3).charAt(0));
              account.setBillDate(rs.getInt(4));
              list.add(account);
          }
          return list;
      }
  });
  
  // 也可以参数值为空,即没有任何占位符
  String sql = "select id,customer_name,sex,bill_date from T_HAO_COALA_ACCOUNT where id='2'";
  List<CoalaAccount> list2 = jdbcTemplate.query(sql, null, null, new ResultSetExtractor<List<CoalaAccount>>() {
      @Override
      public List<CoalaAccount> extractData(ResultSet rs) throws SQLException, DataAccessException {
          List<CoalaAccount> list = new ArrayList<>();
          while (rs.next()) {
              CoalaAccount account = new CoalaAccount();
              account.setId(rs.getString(1));
              account.setCustomerName(rs.getString(2));
              account.setSex(rs.getString(3).charAt(0));
              account.setBillDate(rs.getInt(4));
              list.add(account);
          }
          return list;
      }
  });

 

8.query(String sql, @Nullable Object[] args, ResultSetExtractor<T> rse)

	@Override
	@Nullable
	public <T> T query(String sql, @Nullable Object[] args, ResultSetExtractor<T> rse) throws DataAccessException {
		return query(sql, newArgPreparedStatementSetter(args), rse);
	}

 和上面方法类似,只是缺少int[] argTypes参数,方法内部会根据占位符的顺序传参。主要是针对有可变参数的sql。

  // 没有占位符
  String sql = "select id,customer_name,sex,bill_date from T_HAO_COALA_ACCOUNT where id='2'";
  CoalaAccount account = jdbcTemplate.query(sql, (Object[]) null, new ResultSetExtractor<CoalaAccount>() {
      @Override
      public CoalaAccount extractData(ResultSet rs) throws SQLException, DataAccessException {
          CoalaAccount account = new CoalaAccount();
          while (rs.next()) {
              account.setId(rs.getString(1));
              account.setCustomerName(rs.getString(2));
              account.setSex(rs.getString(3).charAt(0));
              account.setBillDate(rs.getInt(4));
          }
          return account;
      }
  });
  // 有占位符
  String sql2 = "select id,customer_name,sex,bill_date from T_HAO_COALA_ACCOUNT where sex = ? and bill_date > ?";
  Object[] param = {"1", 10};
  List<CoalaAccount> list = jdbcTemplate.query(sql2, param, new ResultSetExtractor<List<CoalaAccount>>() {
      @Override
      public List<CoalaAccount> extractData(ResultSet rs) throws SQLException, DataAccessException {
          List<CoalaAccount> list = new ArrayList<>();
          while (rs.next()) {
              CoalaAccount account = new CoalaAccount();
              account.setId(rs.getString(1));
              account.setCustomerName(rs.getString(2));
              account.setSex(rs.getString(3).charAt(0));
              account.setBillDate(rs.getInt(4));
              list.add(account);
          }
          return list;
      }
  });

9.query(String sql, ResultSetExtractor<T> rse, @Nullable Object... args)

	@Override
	@Nullable
	public <T> T query(String sql, ResultSetExtractor<T> rse, @Nullable Object... args) throws DataAccessException {
		return query(sql, newArgPreparedStatementSetter(args), rse);
	}

和上面的方法类似,只不过把数组参数改为多个可传参数的形式。如果没有参数就传个空的数组。主要是针对有可变参数的sql。

        String sql2 = "select id,customer_name,sex,bill_date from T_HAO_COALA_ACCOUNT where sex = ? and bill_date > ?";
        List<CoalaAccount> list = jdbcTemplate.query(sql2, rs -> {
            List<CoalaAccount> list1 = new ArrayList<>();
            while (rs.next()) {
                CoalaAccount account = new CoalaAccount();
                account.setId(rs.getString(1));
                account.setCustomerName(rs.getString(2));
                account.setSex(rs.getString(3).charAt(0));
                account.setBillDate(rs.getInt(4));
                list1.add(account);
            }
            return list1;
        }, "1", 10); // 传参的位置

 

10.query(PreparedStatementCreator psc, RowCallbackHandler rch) 

	@Override
	public void query(PreparedStatementCreator psc, RowCallbackHandler rch) throws DataAccessException {
		query(psc, new RowCallbackHandlerResultSetExtractor(rch));
	}

 参数一:构建一个预编译的sql语句,如果有可变参数,给其赋值。

参数二:用户处理每一行的结果集,不需要判断ResultSet.next()。

如下:注意,这是个没有返回值的方法。

        ArrayList<CoalaAccount> list = new ArrayList<>();
        String sql2 = "select id,customer_name,sex,bill_date from T_HAO_COALA_ACCOUNT where sex = ? and bill_date > ?";
        jdbcTemplate.query(new PreparedStatementCreator() {
            @Override
            public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
                PreparedStatement ps = con.prepareStatement(sql2);
                ps.setString(1, "1");
                ps.setInt(2, 15);
                ps.executeQuery();
                return ps;
            }
        }, new RowCallbackHandler() {
            @Override
            public void processRow(ResultSet rs) throws SQLException {
                CoalaAccount account = new CoalaAccount();
                account.setId(rs.getString(1));
                account.setCustomerName(rs.getString(2));
                account.setSex(rs.getString(3).charAt(0));
                account.setBillDate(rs.getInt(4));
                list.add(account);
            }
        });

11.query(String sql, @Nullable PreparedStatementSetter pss, RowCallbackHandler rch)

	@Override
	public void query(String sql, @Nullable PreparedStatementSetter pss, RowCallbackHandler rch) throws DataAccessException {
		query(sql, pss, new RowCallbackHandlerResultSetExtractor(rch));
	}

第一个参数:需要查询的sql。

第二个参数:对sql中的参数处理,如果没有则不处理。

第三个参数:对结果集的每一行进行处理,转换成想要的对象。不需要做ResultSet.next()判断。

String sql = "select id,customer_name,sex,bill_date from T_HAO_COALA_ACCOUNT where sex = ? and bill_date > ?";
// 查询多条数据
ArrayList<CoalaAccount> list = new ArrayList<>();
jdbcTemplate.query(sql, new PreparedStatementSetter() {
    @Override
    public void setValues(PreparedStatement ps) throws SQLException {
        ps.setString(1, "1");
        ps.setInt(2, 10);
    }
}, new RowCallbackHandler() {
    @Override
    public void processRow(ResultSet rs) throws SQLException {
        CoalaAccount account = new CoalaAccount();
        account.setId(rs.getString(1));
        account.setCustomerName(rs.getString(2));
        account.setSex(rs.getString(3).charAt(0));
        account.setBillDate(rs.getInt(4));
        list.add(account);
    }
});
// 查询单条数据
CoalaAccount account = new CoalaAccount();
sql = "select id,customer_name,sex,bill_date from T_HAO_COALA_ACCOUNT where id='2'";
jdbcTemplate.query(sql, new PreparedStatementSetter() {
    @Override
    public void setValues(PreparedStatement ps) throws SQLException {
        // sql中没有参数需要处理,故不作任何处理
    }
}, new RowCallbackHandler() {
    @Override
    public void processRow(ResultSet rs) throws SQLException {
        account.setId(rs.getString(1));
        account.setCustomerName(rs.getString(2));
        account.setSex(rs.getString(3).charAt(0));
        account.setBillDate(rs.getInt(4));
    }
});

12.query(String sql, Object[] args, int[] argTypes, RowCallbackHandler rch)

	@Override
	public void query(String sql, Object[] args, int[] argTypes, RowCallbackHandler rch) throws DataAccessException {
		query(sql, newArgTypePreparedStatementSetter(args, argTypes), rch);
	}

第一个参数:要查询的sql。

第二个参数:如果sql中有动态参数,则此为sql中占位符参数的数组,注意顺序保持一致。如果没有则为null。

第三个参数:如果sql有占位符需要处理参数,则此为参数的数据类型,如果sql中没有参数,则为null。

第四个参数:对结果集的每一行进行处理,转换成想要的对象。不需要做ResultSet.next()判断。

// 查询单条数据
String sql = "select id,customer_name,sex,bill_date from T_HAO_COALA_ACCOUNT where id='2'";
CoalaAccount account = new CoalaAccount();
jdbcTemplate.query(sql, null, null, new RowCallbackHandler() {
    @Override
    public void processRow(ResultSet rs) throws SQLException {
        account.setId(rs.getString(1));
        account.setCustomerName(rs.getString(2));
        account.setSex(rs.getString(3).charAt(0));
        account.setBillDate(rs.getInt(4));
    }
});

// 查询多条数据
sql = "select id,customer_name,sex,bill_date from T_HAO_COALA_ACCOUNT where sex = ? and bill_date > ?";
ArrayList<CoalaAccount> list = new ArrayList<>();
Object[] param = {"1", 10};
int[] index = {Types.CHAR, Types.NUMERIC};
jdbcTemplate.query(sql, param, index, new RowCallbackHandler() {
    @Override
    public void processRow(ResultSet rs) throws SQLException {
        CoalaAccount account = new CoalaAccount();
        account.setId(rs.getString(1));
        account.setCustomerName(rs.getString(2));
        account.setSex(rs.getString(3).charAt(0));
        account.setBillDate(rs.getInt(4));
        list.add(account);
    }
});

13.query(String sql, Object[] args, RowCallbackHandler rch)

	@Override
	public void query(String sql, Object[] args, RowCallbackHandler rch) throws DataAccessException {
		query(sql, newArgPreparedStatementSetter(args), rch);
	}

 此方法省略了占位符在sql中参数值的类型数组。所以使用的时候一定要保证sql的参数和占位符的顺序一致。如果查询结果为空则例子中的list结果为空。

String sql = "select id,customer_name,sex,bill_date from T_HAO_COALA_ACCOUNT where sex = ? and bill_date > ?";
ArrayList<CoalaAccount> list = new ArrayList<>();
Object[] param = {"4", 10};
jdbcTemplate.query(sql, param, new RowCallbackHandler() {
    @Override
    public void processRow(ResultSet rs) throws SQLException {
        CoalaAccount account = new CoalaAccount();
        account.setId(rs.getString(1));
        account.setCustomerName(rs.getString(2));
        account.setSex(rs.getString(3).charAt(0));
        account.setBillDate(rs.getInt(4));
        list.add(account);
    }
});

14.query(String sql, RowCallbackHandler rch, @Nullable Object... args)

	@Override
	public void query(String sql, RowCallbackHandler rch, @Nullable Object... args) throws DataAccessException {
		query(sql, newArgPreparedStatementSetter(args), rch);
	}

和上面的方法一样,只不过把参数数组改为多个参数数组的形式。如果没有占位符则不需要最后的参数。

String sql = "select id,customer_name,sex,bill_date from T_HAO_COALA_ACCOUNT where sex = ? and bill_date > ?";
ArrayList<CoalaAccount> list = new ArrayList<>();
jdbcTemplate.query(sql,new RowCallbackHandler() {
    @Override
    public void processRow(ResultSet rs) throws SQLException {
        CoalaAccount account = new CoalaAccount();
        account.setId(rs.getString(1));
        account.setCustomerName(rs.getString(2));
        account.setSex(rs.getString(3).charAt(0));
        account.setBillDate(rs.getInt(4));
        list.add(account);
    }
},"2",10);

 

15.query(PreparedStatementCreator psc, RowMapper<T> rowMapper)

	@Override
	public <T> List<T> query(PreparedStatementCreator psc, RowMapper<T> rowMapper) throws DataAccessException {
		return result(query(psc, new RowMapperResultSetExtractor<>(rowMapper)));
	}

第一个参数:创建一个预编译的sql,如果sql中有占位符,则需要进行处理。

第二个参数:查询的每一行结果集,需要手动进行转换为想要的对象。

 注意:这个方法和后面的几个query()方法返回的是List<T>对象。无论查询时单条记录还是多条记录,返回的都是List。

// 查询多条数据,sql中有占位符
String sql = "select id,customer_name,sex,bill_date from T_HAO_COALA_ACCOUNT where sex = ? and bill_date > ?";
List<List<CoalaAccount>> list = jdbcTemplate.query(new PreparedStatementCreator() {
    @Override
    public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
        PreparedStatement ps = con.prepareStatement(sql);
        ps.setString(1, "1");
        ps.setInt(2, 10);
        return ps;
    }
}, new RowMapper<List<CoalaAccount>>() {
    ArrayList<CoalaAccount> list = new ArrayList<>();

    @Override
    public List<CoalaAccount> mapRow(ResultSet rs, int rowNum) throws SQLException {
        CoalaAccount account = new CoalaAccount();
        account.setId(rs.getString(1));
        account.setCustomerName(rs.getString(2));
        account.setSex(rs.getString(3).charAt(0));
        account.setBillDate(rs.getInt(4));
        list.add(account);
        return list;
    }
});

// 查询单条数据 ,sql中没有占位符
String queryById = "select id,customer_name,sex,bill_date from T_HAO_COALA_ACCOUNT where id='2'";
List<CoalaAccount> accounts = jdbcTemplate.query(new PreparedStatementCreator() {
    @Override
    public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
        return con.prepareStatement(queryById);
    }
}, new RowMapper<CoalaAccount>() {
    @Override
    public CoalaAccount mapRow(ResultSet rs, int rowNum) throws SQLException {
        CoalaAccount account = new CoalaAccount();
        account.setId(rs.getString(1));
        account.setCustomerName(rs.getString(2));
        account.setSex(rs.getString(3).charAt(0));
        account.setBillDate(rs.getInt(4));
        return account;
    }
});

16.query(String sql, @Nullable PreparedStatementSetter pss, RowMapper<T> rowMapper)

	@Override
	public <T> List<T> query(String sql, @Nullable PreparedStatementSetter pss, RowMapper<T> rowMapper) throws DataAccessException {
		return result(query(sql, pss, new RowMapperResultSetExtractor<>(rowMapper)));
	}

直接看例子

String queryById = "select id,customer_name,sex,bill_date from T_HAO_COALA_ACCOUNT where id='2'";
List<CoalaAccount> query = jdbcTemplate.query(queryById, new PreparedStatementSetter() {
    @Override
    public void setValues(PreparedStatement ps) throws SQLException {

    }
}, new RowMapper<CoalaAccount>() {
    @Override
    public CoalaAccount mapRow(ResultSet rs, int rowNum) throws SQLException {
        CoalaAccount account = new CoalaAccount();
        account.setId(rs.getString(1));
        account.setCustomerName(rs.getString(2));
        account.setSex(rs.getString(3).charAt(0));
        account.setBillDate(rs.getInt(4));
        return account;
    }
});

 17.query(String sql, Object[] args, int[] argTypes, RowMapper<T> rowMapper)

	@Override
	public <T> List<T> query(String sql, Object[] args, int[] argTypes, RowMapper<T> rowMapper) throws DataAccessException {
		return result(query(sql, args, argTypes, new RowMapperResultSetExtractor<>(rowMapper)));
	}

 第一个参数:需要执行的查询sql。

第二个参数:有sql中占位符参数构成的数组。如果没有则为传null。注意顺序保持一致。

第三个参数:参数值的数据库类型。如果没有则为传null。

第四个参数:查询结果的每一行结果集。

例如:

String sql = "select id,customer_name,sex,bill_date from T_HAO_COALA_ACCOUNT where sex = ? and bill_date > ?";
Object[] param = { "1", 10};
int[] index = {Types.CHAR, Types.NUMERIC};

List<CoalaAccount> list = jdbcTemplate.query(sql, param, index, new RowMapper<CoalaAccount>() {
    @Override
    public CoalaAccount mapRow(ResultSet rs, int rowNum) throws SQLException {
        CoalaAccount account = new CoalaAccount();
        account.setId(rs.getString(1));
        account.setCustomerName(rs.getString(2));
        account.setSex(rs.getString(3).charAt(0));
        account.setBillDate(rs.getInt(4));
        return account;
    }
});

18.query(String sql, @Nullable Object[] args, RowMapper<T> rowMapper)

	@Override
	public <T> List<T> query(String sql, @Nullable Object[] args, RowMapper<T> rowMapper) throws DataAccessException {
		return result(query(sql, args, new RowMapperResultSetExtractor<>(rowMapper)));
	}

第一个参数:需要执行的查询sql。

第二个参数:有sql中占位符参数构成的数组。如果没有则为传null。注意顺序保持一致。

第三个参数:查询结果的每一行结果集。

例如:

String sql = "select id,customer_name,sex,bill_date from T_HAO_COALA_ACCOUNT where sex = ? and bill_date > ?";
Object[] param = { "1",10};

List<CoalaAccount> list = jdbcTemplate.query(sql, param, new RowMapper<CoalaAccount>() {
    @Override
    public CoalaAccount mapRow(ResultSet rs, int rowNum) throws SQLException {
        CoalaAccount account = new CoalaAccount();
        account.setId(rs.getString(1));
        account.setCustomerName(rs.getString(2));
        account.setSex(rs.getString(3).charAt(0));
        account.setBillDate(rs.getInt(4));
        return account;
    }
});

19.query(String sql, RowMapper<T> rowMapper, @Nullable Object... args)

	@Override
	public <T> List<T> query(String sql, RowMapper<T> rowMapper, @Nullable Object... args) throws DataAccessException {
		return result(query(sql, args, new RowMapperResultSetExtractor<>(rowMapper)));
	}

 第一个参数:需要执行的查询sql。

第二个参数:查询结果的每一行结果集。

第三个参数:采用多参数组的形式,指sql中占位符的参数值,没有则不写。

例如:

String sql = "select id,customer_name,sex,bill_date from T_HAO_COALA_ACCOUNT where sex = ? and bill_date > ?";

List<CoalaAccount> list = jdbcTemplate.query(sql,new RowMapper<CoalaAccount>() {
    @Override
    public CoalaAccount mapRow(ResultSet rs, int rowNum) throws SQLException {
        CoalaAccount account = new CoalaAccount();
        account.setId(rs.getString(1));
        account.setCustomerName(rs.getString(2));
        account.setSex(rs.getString(3).charAt(0));
        account.setBillDate(rs.getInt(4));
        return account;
    }
},"1",10);

 

queryForList 系列

查询多行多列,以List的形式返回结果,如果指定elementType类型,则只能查询单列,否则报错:

org.springframework.jdbc.IncorrectResultSetColumnCountException: Incorrect column count: expected 1, actual 4 

且类型只能时8中基本数据类型,否则报错:

org.springframework.dao.TypeMismatchDataAccessException:

Type mismatch affecting row number 0 and column type 'xxxxxx':

Value [xxxxxx] is of type [java.lang.String] and cannot be converted to required type [xxx.xxx.xxx.xxx]

如果经常查询一些数据,建议使用queryForList()。

需要注意的是:如果查询结果为空则返回空集合,也就是

list.isEmpty() == true

不会报错。

1.queryForList(String sql, Class<T> elementType)

	@Override
	public <T> List<T> queryForList(String sql, Class<T> elementType) throws DataAccessException {
		return query(sql, getSingleColumnRowMapper(elementType));
	}

此方法用于sql中没有动态参数,且查询结果为单列多行,返回一个指定类型的List集合,指定的类型只能是8个基本数据类型。

        String sql = "select customer_name from T_HAO_COALA_ACCOUNT where sex = '3' and bill_date > 10 ";
        List<String> names = jdbcTemplate.queryForList(sql, String.class);

 

2.queryForList(String sql)

	@Override
	public List<Map<String, Object>> queryForList(String sql) throws DataAccessException {
		return query(sql, getColumnMapRowMapper());
	}

可以查询多行多列,返回一个List集合,List元素是Map,也就是查询结果中每一行的数据,只不过以map的形式返回。 

如果sql中没有动态参数,推荐使用。

比如以下查询

        String sql = "select id,customer_name,sex,bill_date from T_HAO_COALA_ACCOUNT where sex = '1' and bill_date > 12 ";
        List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);

查询结果maps为(我这里以JSON形式展示):

[
    {
        "ID": "65536F6490C44D45B149F6C1BB54EE3F",
        "CUSTOMER_NAME": "测试22",
        "SEX": "1",
        "BILL_DATE": 15
    },
    {
        "ID": "DC78F9F3698F4BE1AA4A3DEF39509271",
        "CUSTOMER_NAME": "测试22",
        "SEX": "1",
        "BILL_DATE": 15
    },
    {
        "ID": "8078AF90A83548C28886F218930CB334",
        "CUSTOMER_NAME": "测试22",
        "SEX": "1",
        "BILL_DATE": 15
    },
    {
        "ID": "834747A641D24410BF602FE448C61801",
        "CUSTOMER_NAME": "测试",
        "SEX": "1",
        "BILL_DATE": 15
    }
]

 

3.queryForList(String sql, Object[] args, int[] argTypes, Class<T> elementType)

	@Override
	public <T> List<T> queryForList(String sql, Object[] args, int[] argTypes, Class<T> elementType) throws DataAccessException {
		return query(sql, args, argTypes, getSingleColumnRowMapper(elementType));
	}

查询多行单列,sql中可以有动态参数,。

第二个参数:如果sql中有动态参数,则此为sql中占位符参数的数组,注意顺序保持一致。如果没有则为null。

第三个参数:如果sql有占位符需要处理参数,则此为参数的数据库类型,如果sql中没有参数,则为null。

第三个参数:必须是8个基本数据类型其一。

比如:

        String sql = "select customer_name from T_HAO_COALA_ACCOUNT where sex = ? and bill_date > ? ";
        Object[] param = {"1", 12};
        int[] index = {Types.CHAR, Types.NUMERIC};
        List<String> list = jdbcTemplate.queryForList(sql, param, index, String.class);

结果如下:

[
    "测试22",
    "测试22",
    "测试22",
    "测试"
]

 

4.queryForList(String sql, Object[] args, Class<T> elementType)

	@Override
	public <T> List<T> queryForList(String sql, Object[] args, Class<T> elementType) throws DataAccessException {
		return query(sql, args, getSingleColumnRowMapper(elementType));
	}

同上,只不过少了个 argTypes参数,这个参数其实可有可无,就不举例了。

5.queryForList(String sql, Class<T> elementType, @Nullable Object... args)

	@Override
	public <T> List<T> queryForList(String sql, Class<T> elementType, @Nullable Object... args) throws DataAccessException {
		return query(sql, args, getSingleColumnRowMapper(elementType));
	}

查询多行单列,第二个参数的类型必须是八个基本数据类型之一,动态占位符参数采用多个参数传参的方式。如:

        String sql = "select customer_name from T_HAO_COALA_ACCOUNT where sex = ? and bill_date > ? ";
        List<String> list = jdbcTemplate.queryForList(sql, String.class, "1", 12);

 

6.queryForList(String sql, Object[] args, int[] argTypes)

	@Override
	public List<Map<String, Object>> queryForList(String sql, Object[] args, int[] argTypes) throws DataAccessException {
		return query(sql, args, argTypes, getColumnMapRowMapper());
	}

查询多行多列,sql中可以传多个动态参数 ,如:

        String sql = "select id,customer_name,sex,bill_date from T_HAO_COALA_ACCOUNT where sex = ? and bill_date > ? ";
        Object[] param = {"1", 12};
        int[] index = {Types.CHAR, Types.NUMERIC};
        List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql, param, index);

结果如下:

[
    {
        "ID": "65536F6490C44D45B149F6C1BB54EE3F",
        "CUSTOMER_NAME": "测试22",
        "SEX": "1",
        "BILL_DATE": 15
    },
    {
        "ID": "DC78F9F3698F4BE1AA4A3DEF39509271",
        "CUSTOMER_NAME": "测试22",
        "SEX": "1",
        "BILL_DATE": 15
    },
    {
        "ID": "8078AF90A83548C28886F218930CB334",
        "CUSTOMER_NAME": "测试22",
        "SEX": "1",
        "BILL_DATE": 15
    },
    {
        "ID": "834747A641D24410BF602FE448C61801",
        "CUSTOMER_NAME": "测试",
        "SEX": "1",
        "BILL_DATE": 15
    }
]

 

7.queryForList(String sql, @Nullable Object... args)

	@Override
	public List<Map<String, Object>> queryForList(String sql, @Nullable Object... args) throws DataAccessException {
		return query(sql, args, getColumnMapRowMapper());
	}

如果sql中有动态参数,推荐使用这个,比较方便。如:

        String sql = "select id,customer_name,sex,bill_date from T_HAO_COALA_ACCOUNT where sex = ? and bill_date > ? ";
        List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql, "1", 12);

 如果参数过多的话,可以采用数组的形式,其实都一样的,上面的查询也可以这样:

        String sql = "select id,customer_name,sex,bill_date from T_HAO_COALA_ACCOUNT where sex = ? and bill_date > ? ";

        Object[] param = {"1", 12};
        List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql, param);

 结果都是一样的。

[
    {
        "ID": "65536F6490C44D45B149F6C1BB54EE3F",
        "CUSTOMER_NAME": "测试22",
        "SEX": "1",
        "BILL_DATE": 15
    },
    {
        "ID": "DC78F9F3698F4BE1AA4A3DEF39509271",
        "CUSTOMER_NAME": "测试22",
        "SEX": "1",
        "BILL_DATE": 15
    },
    {
        "ID": "8078AF90A83548C28886F218930CB334",
        "CUSTOMER_NAME": "测试22",
        "SEX": "1",
        "BILL_DATE": 15
    },
    {
        "ID": "834747A641D24410BF602FE448C61801",
        "CUSTOMER_NAME": "测试",
        "SEX": "1",
        "BILL_DATE": 15
    }
]

 

queryForObject 系列

queryForObject()方法只能查询单个列且结果只有一行。否则报错。这一点尤其注意。

如果查询结果为空也会报错:

org.springframework.dao.EmptyResultDataAccessException: Incorrect result size: expected 1, actual 0 。

也就是说查询的结果必须有且只有一行一列的值。

如果查询结果是多行,则报错:

org.springframework.dao.IncorrectResultSizeDataAccessException: Incorrect result size: expected 1, actual 12

1.queryForObject(String sql, RowMapper<T> rowMapper)

	@Override
	@Nullable
	public <T> T queryForObject(String sql, RowMapper<T> rowMapper) throws DataAccessException {
		List<T> results = query(sql, rowMapper);
		return DataAccessUtils.nullableSingleResult(results);
	}

返回一个泛型对象。且查询sql不能动态传参,除非将参数在查询之前动态的拼接好,RowMapper用于处理查询的结果。

下面是几个例子。

// 查询对象中的单个属性
String sql = "select customer_name from T_HAO_COALA_ACCOUNT where id= '2'";
CoalaAccount account = jdbcTemplate.queryForObject(sql, new RowMapper<CoalaAccount>() {
    @Override
    public CoalaAccount mapRow(ResultSet rs, int rowNum) throws SQLException {
        CoalaAccount account = new CoalaAccount();
        account.setCustomerName(rs.getString(1));
        return account;
    }
});

// 查询总数
sql = "select count(*) from T_HAO_COALA_ACCOUNT where sex = '1'";
Integer count = jdbcTemplate.queryForObject(sql, new RowMapper<Integer>() {
    @Override
    public Integer mapRow(ResultSet rs, int rowNum) throws SQLException {
        return rs.getInt(1);
    }
});
logger.info("总数量:[{}]", count);

// 查询某一列总和
sql = "select sum(bill_date) from T_HAO_COALA_ACCOUNT where sex = '1'";
Integer sum = jdbcTemplate.queryForObject(sql, new RowMapper<Integer>() {
    @Override
    public Integer mapRow(ResultSet rs, int rowNum) throws SQLException {
        return rs.getInt(1);
    }
});
logger.info("账单日总和:[{}]", sum);

// 查询单列
sql = "select customer_name from T_HAO_COALA_ACCOUNT where id= '2'";
String customerName = jdbcTemplate.queryForObject(sql, new RowMapper<String>() {
    @Override
    public String mapRow(ResultSet rs, int rowNum) throws SQLException {
        return rs.getString(1);
    }
});
logger.info("客户姓名:[{}]", customerName);

 

2.queryForObject(String sql, Class<T> requiredType)

	@Override
	@Nullable
	public <T> T queryForObject(String sql, Class<T> requiredType) throws DataAccessException {
		return queryForObject(sql, getSingleColumnRowMapper(requiredType));
	}

 这个方法就是用上面的那个方法,只不过把第二个参数封装了。requiredType必须是常用的8个基本类型,否则报错。

推荐使用。

String customerName = jdbcTemplate.queryForObject("select customer_name from T_HAO_COALA_ACCOUNT where id= '2'", String.class);

// 下面这个会报错:
// org.springframework.dao.TypeMismatchDataAccessException: Type mismatch affecting row number 0 and column type 'VARCHAR2': 
// Value [李四] is of type [java.lang.String] and cannot be converted to required type [com.jason.test.project.model.CoalaAccount]
// CoalaAccount account = jdbcTemplate.queryForObject("select customer_name from T_HAO_COALA_ACCOUNT where id= '2'", CoalaAccount.class); 

Integer sum = jdbcTemplate.queryForObject("select sum(bill_date) from T_HAO_COALA_ACCOUNT where sex = '1'", Integer.class);
String count = jdbcTemplate.queryForObject("select count(*) from T_HAO_COALA_ACCOUNT where sex = '1'", String.class);

3.queryForObject(String sql, Object[] args, int[] argTypes, RowMapper<T> rowMapper)

	@Override
	@Nullable
	public <T> T queryForObject(String sql, Object[] args, int[] argTypes, RowMapper<T> rowMapper)
			throws DataAccessException {

		List<T> results = query(sql, args, argTypes, new RowMapperResultSetExtractor<>(rowMapper, 1));
		return DataAccessUtils.nullableSingleResult(results);
	}

 查询带有参数的sql。

第一个参数:查询sql。

第二个参数:如果sql中有动态参数,则此为sql中占位符参数的数组,注意顺序保持一致。如果没有则为null。

第三个参数:如果sql有占位符需要处理参数,则此为参数在数据库中的类型,如果sql中没有参数,则为null。

第四个参数:手动处理结果集。

String sql = "select count(*) from T_HAO_COALA_ACCOUNT where sex = ? and bill_date = ? ";
Object[] param = {"1", 15};
int[] index = {Types.CHAR, Types.NUMERIC};
Integer count = jdbcTemplate.queryForObject(sql, param, index, new RowMapper<Integer>() {
    @Override
    public Integer mapRow(ResultSet rs, int rowNum) throws SQLException {
        return rs.getInt(1);
    }
});

sql = "select customer_name from T_HAO_COALA_ACCOUNT where id= '2'";
String customerName = jdbcTemplate.queryForObject(sql, null, null, new RowMapper<String>() {
    @Override
    public String mapRow(ResultSet rs, int rowNum) throws SQLException {
        return rs.getString(1);
    }
});

4.queryForObject(String sql, @Nullable Object[] args, RowMapper<T> rowMapper)

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

和上面方法类似,少了个sql参数类型。如果查询时多列,则只会返回第一列的值。

        String sql = "select count(*) from T_HAO_COALA_ACCOUNT where sex = ? and bill_date = ? ";
        Object[] param = {"1", 15};
        Integer count = jdbcTemplate.queryForObject(sql, param, new RowMapper<Integer>() {
            @Override
            public Integer mapRow(ResultSet rs, int rowNum) throws SQLException {
                return rs.getInt(1);
            }
        });

        // 只会返回ID的值
        sql = "select id,customer_name,sex,bill_date from T_HAO_COALA_ACCOUNT where sex = ? and bill_date > ?";
        jdbcTemplate.queryForObject(sql, param, new RowMapper<String>() {
            @Override
            public String mapRow(ResultSet rs, int rowNum) throws SQLException {
                return rs.getString(1);
            }
        });

 

5.queryForObject(String sql, RowMapper<T> rowMapper, @Nullable Object... args)

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

 和上面的几个方式一样,只不过把参数以数组的形式改成多个参数的形式,就不举例了 。

6.queryForObject(String sql, Object[] args, int[] argTypes, Class<T> requiredType)

	@Override
	@Nullable
	public <T> T queryForObject(String sql, Object[] args, int[] argTypes, Class<T> requiredType)
			throws DataAccessException {

		return queryForObject(sql, args, argTypes, getSingleColumnRowMapper(requiredType));
	}

可以传多个参数,参数以数组的形式传入,查询结果以第四个参数的Class类型返回。不用我们手动去处理结果。

推荐使用。 

        String sql = "select count(*) from T_HAO_COALA_ACCOUNT where sex = ? and bill_date = ? ";
        Object[] param = {"1", 10};
        int[] index = {Types.CHAR, Types.NUMERIC};
        Integer count = jdbcTemplate.queryForObject(sql, param, index, Integer.class);

7.queryForObject(String sql, Object[] args, Class<T> requiredType)

	@Override
	public <T> T queryForObject(String sql, Object[] args, Class<T> requiredType) throws DataAccessException {
		return queryForObject(sql, args, getSingleColumnRowMapper(requiredType));
	}

和上面一样,只不过少了个占位符参数值类型的数组。 推荐使用。 不举例了。

8.queryForObject(String sql, Class<T> requiredType, @Nullable Object... args)

	@Override
	public <T> T queryForObject(String sql, Class<T> requiredType, @Nullable Object... args) throws DataAccessException {
		return queryForObject(sql, args, getSingleColumnRowMapper(requiredType));
	}

和上面一样,将数组参数改为多个参数的传参方式。如果参数不多的话推荐使用这个。 不举例了。 

 

update 系列

update()方法可以执行所有execute()能执行的sql,几乎涵盖了所有常用的sql。

1.update(final String sql)

@Override
	public int update(final String sql) throws DataAccessException {
		Assert.notNull(sql, "SQL must not be null");
		if (logger.isDebugEnabled()) {
			logger.debug("Executing SQL update [" + sql + "]");
		}

		/**
		 * Callback to execute the update statement.
		 */
		class UpdateStatementCallback implements StatementCallback<Integer>, SqlProvider {
			@Override
			public Integer doInStatement(Statement stmt) throws SQLException {
				int rows = stmt.executeUpdate(sql);
				if (logger.isTraceEnabled()) {
					logger.trace("SQL update affected " + rows + " rows");
				}
				return rows;
			}
			@Override
			public String getSql() {
				return sql;
			}
		}

		return updateCount(execute(new UpdateStatementCallback()));
	}

 可以看到这个方法其实就是调用execute(StatementCallback<T> action)他的。故此update()方法也能执行很多操作类的sql,不过sql中不能处理动态参数。如:

        String insertIntoSql = "insert into T_HAO_COALA_ACCOUNT (id,customer_name,sex,birthday,balance,arrearage,bill_date) values ('1','test','2',trunc(sysdate),5500,2000,20) ";
        String deleteSql = "delete T_HAO_COALA_ACCOUNT where id = '11' ";
        String updateSql = "update T_HAO_COALA_ACCOUNT set bill_date = 20 where id = '2'";
        String procedureSql = "{call insert_data_to_user('张三2','北京2')";

        jdbcTemplate.update(insertIntoSql);
        jdbcTemplate.update(deleteSql);
        jdbcTemplate.update(updateSql);
        jdbcTemplate.update(procedureSql);

2.update(PreparedStatementCreator psc)

	@Override
	public int update(PreparedStatementCreator psc) throws DataAccessException {
		return update(psc, (PreparedStatementSetter) null);
	}

此方法执行sql时可以传递动态的参数,使用 PreparedStatement 对象操作参数。

        String insertIntoSql = "insert into T_HAO_COALA_ACCOUNT (id,customer_name,sex,birthday,balance,arrearage,bill_date) values ('1','test','2',trunc(sysdate),5500,2000,20) ";
        String deleteSql = "delete T_HAO_COALA_ACCOUNT where id = ? ";
        jdbcTemplate.update(new PreparedStatementCreator() {
            @Override
            public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
                PreparedStatement ps = con.prepareStatement(insertIntoSql);
                return ps;
            }
        });
        jdbcTemplate.update(new PreparedStatementCreator() {
            @Override
            public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
                PreparedStatement ps = con.prepareStatement(deleteSql);
                ps.setString(1,"ED57637E0B7C446BA37D039E1E40AA97");
                return ps;
            }
        });

3.update(final PreparedStatementCreator psc, final KeyHolder generatedKeyHolder)

	@Override
	public int update(final PreparedStatementCreator psc, final KeyHolder generatedKeyHolder)
			throws DataAccessException {

		Assert.notNull(generatedKeyHolder, "KeyHolder must not be null");
		logger.debug("Executing SQL update and returning generated keys");

		return updateCount(execute(psc, ps -> {
			int rows = ps.executeUpdate();
			List<Map<String, Object>> generatedKeys = generatedKeyHolder.getKeyList();
			generatedKeys.clear();
			ResultSet keys = ps.getGeneratedKeys();
			if (keys != null) {
				try {
					RowMapperResultSetExtractor<Map<String, Object>> rse =
							new RowMapperResultSetExtractor<>(getColumnMapRowMapper(), 1);
					generatedKeys.addAll(result(rse.extractData(keys)));
				}
				finally {
					JdbcUtils.closeResultSet(keys);
				}
			}
			if (logger.isTraceEnabled()) {
				logger.trace("SQL update affected " + rows + " rows and returned " + generatedKeys.size() + " keys");
			}
			return rows;
		}));
	}

此方法对于执行insert sql语句时,可查询执行的主键id的值。也就是最重要的一点根据KeyHolder获取插入记录的ID。

不过获取主键的时候需要注意数据库类别,oracle和mySql是不一样的。

我这里用的时oracle数据库,版本:Oracle Database 19c Enterprise Edition  19.0.0.0.0

MySql没测试,不过个人认为Mysql支持自增长ID,所以如果操作的是Mysql数据库插入动作,获取Id应该是:

Number key = keyHolder.getKey();
int intValue = key.intValue();

具体怎么获取可以自己测试一下。

String insertIntoSql = "insert into T_HAO_COALA_ACCOUNT (id,customer_name,sex,birthday,balance,arrearage,bill_date) values (sys_guid(),'test','2',trunc(sysdate),5500,2000,20) ";
GeneratedKeyHolder keyHolder = new GeneratedKeyHolder();
        jdbcTemplate.update(new PreparedStatementCreator() {
            @Override
            public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
                return con.prepareStatement(insertIntoSql, new String[]{"id"});
            }
        }, keyHolder);
        Map<String, Object> keys = keyHolder.getKeys();
        String id = (String) keys.get("id");
        logger.info("添加的主键ID:[{}]", id);

 

4.update(String sql, @Nullable PreparedStatementSetter pss)

	@Override
	public int update(String sql, @Nullable PreparedStatementSetter pss) throws DataAccessException {
		return update(new SimplePreparedStatementCreator(sql), pss);
	}

此方法可执行带有动态参数的sql,参数由PreparedStatement对象操作,无需ps.execute();方法,否则sql会被执行两次。如:

        String insertIntoSql = "insert into T_HAO_COALA_ACCOUNT (id,customer_name,sex,birthday,balance,arrearage,bill_date) values (sys_guid(),'testtest','2',trunc(sysdate),5500,2000,20) ";
        String deleteSql = "delete T_HAO_COALA_ACCOUNT where id = ? ";
        jdbcTemplate.update(insertIntoSql, new PreparedStatementSetter() {
            @Override
            public void setValues(PreparedStatement ps) throws SQLException {

            }
        });
        jdbcTemplate.update(deleteSql, new PreparedStatementSetter() {
            @Override
            public void setValues(PreparedStatement ps) throws SQLException {
                ps.setString(1, "09CCE5E3E7D14C118B6B624AD8E7BA24");
            }
        });

5.update(String sql, Object[] args, int[] argTypes)

	@Override
	public int update(String sql, Object[] args, int[] argTypes) throws DataAccessException {
		return update(sql, newArgTypePreparedStatementSetter(args, argTypes));
	}

执行带有动态参数的sql,通过两个数组入参。

对于此方法中:

第一个参数:执行的sql。

第二个参数:sql中参数的值。

第三个数组:动态参数的各个类型。

如:

        String updateSql = "update T_HAO_COALA_ACCOUNT set CUSTOMER_NAME =? where id =? ";
        Object[] param = {"李四2222", "2"};
        int[] index = {Types.VARCHAR, Types.VARCHAR};
        jdbcTemplate.update(updateSql, param, index);

6.update(String sql, @Nullable Object... args)

	@Override
	public int update(String sql, @Nullable Object... args) throws DataAccessException {
		return update(sql, newArgPreparedStatementSetter(args));
	}

推荐使用。

方法比较简单。

其中第二个多参参数形式为sql中动态参数的值数组。

如:

        String updateSql = "update T_HAO_COALA_ACCOUNT set CUSTOMER_NAME =? where id =? ";
        Object[] param = {"李四", "2"};
        jdbcTemplate.update(updateSql, param);

 

batchUpdate 系列

同update()方法一样,batchUpdate()也能处理很多批量操作的sql,比如:insert语句、update语句、delete语句等等。

1.batchUpdate(final String... sql)

源码太长,就不贴了

使用方法如下,对于执行的sql 不能带有动态参数。

        String updateSql = "update T_HAO_COALA_ACCOUNT set BILL_DATE = 26 where id = '2'";
        jdbcTemplate.batchUpdate(updateSql);

2.batchUpdate(String sql, final BatchPreparedStatementSetter pss)

源码太长,不贴了

 动态参数通过BatchPreparedStatementSetter接口的匿名类实现。如:

String updateSql = "update T_HAO_COALA_ACCOUNT set PRINCIPAL =? where id =?";
        List<CoalaAccount> list = new ArrayList<>();
        list.add(new CoalaAccount("2", new BigDecimal(5000)));
        list.add(new CoalaAccount("3", new BigDecimal(6000)));
        list.add(new CoalaAccount("4", new BigDecimal(7000)));
        list.add(new CoalaAccount("5", new BigDecimal(8000)));
        jdbcTemplate.batchUpdate(updateSql, new BatchPreparedStatementSetter() {
            @Override
            public void setValues(PreparedStatement ps, int i) throws SQLException {
                ps.setBigDecimal(1, list.get(i).getPrincipal());
                ps.setString(2, list.get(i).getId());
            }

            @Override
            public int getBatchSize() {
                return list.size();
            }
        });

3.batchUpdate(String sql, List<Object[]> batchArgs)

不贴源码了

对于第二个参数 List<Object[]> batchArgs用于存放sql中的动态参数对应的值,如下:

        Object[] obj1 = new Object[3];
        obj1[0]="batchUpdate_Test_name_1";
        obj1[1]=10;
        obj1[2]="2";

        Object[] obj2 = new Object[3];
        obj2[0]="batchUpdate_Test_name_2";
        obj2[1]=20;
        obj2[2]="3";

        List<Object[]> param = new ArrayList<>();
        param.add(obj1);
        param.add(obj2);
        jdbcTemplate.batchUpdate("update T_HAO_COALA_ACCOUNT set CUSTOMER_NAME = ?,PRINCIPAL = ? where id = ?",param);

4.batchUpdate(String sql, List<Object[]> batchArgs, final int[] argTypes)

不贴源码了。

同上面的方法一样,采用数组泛型的List存放参数值,第三个参数为数据库中对应字段的属性。比如:

        Object[] obj1 = new Object[3];
        obj1[0] = "batchUpdate_Test_name_1_type1";
        obj1[1] = 1001;
        obj1[2] = "65536F6490C44D45B149F6C1BB54EE3F";

        Object[] obj2 = new Object[3];
        obj2[0] = "batchUpdate_Test_name_2_type2";
        obj2[1] = 2002;
        obj2[2] = "DC78F9F3698F4BE1AA4A3DEF39509271";

        List<Object[]> param = new ArrayList<>();
        param.add(obj1);
        param.add(obj2);

        int[] type = new int[3];
        type[0] = Types.CHAR; // 这里使用 Types.CHAR 也行
        type[1] = Types.NUMERIC;
        type[2] = Types.VARCHAR; // 这里使用 Types.VARCHAR 也行
        jdbcTemplate.batchUpdate("update T_HAO_COALA_ACCOUNT set CUSTOMER_NAME = ?,PRINCIPAL = ? where id = ?", param, type);

5.batchUpdate(String sql, final Collection<T> batchArgs, final int batchSize, final ParameterizedPreparedStatementSetter<T> pss)

个人觉得这个批量操作的方法比较好用。

第一个参数:要执行的sql。

第二个参数:sql参数的对象集合。

第三个参数:需要处理数据的数量。

第四个参数:根据第二个参数泛型取对应的值赋值给PreparedStatement对象,用于执行sql。

比如:

        String updateSql = "update T_HAO_COALA_ACCOUNT set PRINCIPAL =? , BIRTHDAY = ? where id =?";
        List<CoalaAccount> list = new ArrayList<>();
        list.add(new CoalaAccount("2", new BigDecimal(5), DateUtils.parseDate("2020-01-01", "yyyy-MM-dd")));
        list.add(new CoalaAccount("3", new BigDecimal(6), DateUtils.parseDate("2020-01-02", "yyyy-MM-dd")));
        list.add(new CoalaAccount("4", new BigDecimal(7), DateUtils.parseDate("2020-01-03", "yyyy-MM-dd")));
        list.add(new CoalaAccount("5", new BigDecimal(8), DateUtils.parseDate("2020-01-04", "yyyy-MM-dd")));
        jdbcTemplate.batchUpdate(updateSql, list, list.size(), new ParameterizedPreparedStatementSetter<CoalaAccount>() {
            @Override
            public void setValues(PreparedStatement ps, CoalaAccount argument) throws SQLException {
                ps.setBigDecimal(1, argument.getPrincipal());
                ps.setDate(2, new Date(argument.getBirthday().getTime())); // 注意Date类型的转换
                ps.setString(3, argument.getId());
            }
        });

 

call 系列

call(CallableStatementCreator csc, List<SqlParameter> declaredParameters)

 

其它方法

 

  • 12
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值