javascript
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框架對(duì)JDBC封裝的一個(gè)模板。簡(jiǎn)化了對(duì)sql的操作,不用關(guān)心鏈接的創(chuàng)建和關(guān)閉。?JdbcTemplate主要提供以下五類(lèi)方法:
- execute方法:可以用于執(zhí)行任何SQL語(yǔ)句,一般用于執(zhí)行DDL語(yǔ)句;
- update方法及batchUpdate方法:update方法用于執(zhí)行新增、修改、刪除等語(yǔ)句;batchUpdate方法用于執(zhí)行批處理相關(guān)語(yǔ)句;
- query方法及queryForXXX方法:用于執(zhí)行查詢相關(guān)語(yǔ)句;
- call方法:用于執(zhí)行存儲(chǔ)過(guò)程、函數(shù)相關(guān)語(yǔ)句。
注意:所有執(zhí)行查詢的語(yǔ)句,都要注意查詢結(jié)果為空的情況,有些方法對(duì)于空的查詢結(jié)果會(huì)報(bào)異常。
其中主要三類(lèi)操作:
execute:可以執(zhí)行所有SQL語(yǔ)句,一般用于執(zhí)行DDL語(yǔ)句。 update:用于執(zhí)行INSERT、UPDATE、DELETE等DML語(yǔ)句。 queryXxx:用于DQL數(shù)據(jù)查詢語(yǔ)句。?
execute 系列
1.execute(final String sql)
public void execute(final String sql) throws DataAccessException可以執(zhí)行所有的sql,參數(shù)是一個(gè)sql,沒(méi)有返回值。
比如:
@Autowiredprivate JdbcTemplate jdbcTemplate;@Overridepublic Object execute() {jdbcTemplate.execute("select * from T_HAO_COALA_ACCOUNT"); // 查詢數(shù)據(jù)jdbcTemplate.execute("insert into T_HAO_COALA_ACCOUNT (id,customer_name,sex,principal,bill_date) values (sys_guid(),'測(cè)試','1',222,15)"); // 新增數(shù)據(jù)jdbcTemplate.execute("update T_HAO_COALA_ACCOUNT set birthday=to_date('2000-10-07','yyyy-mm-dd') where id='834747A641D24410BF602FE448C61801'"); // 修改數(shù)據(jù)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"); // 清空表數(shù)據(jù)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)"); // 修改表結(jié)構(gòu) 添加字段jdbcTemplate.execute("alter table t_hao_coala_account drop column test_column"); // 修改表結(jié)構(gòu) 刪除字段jdbcTemplate.execute("begin add_data_to_account; end;"); // 執(zhí)行存儲(chǔ)過(guò)程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此方法是傳入一個(gè)StatementCallback對(duì)象。StatementCallback接口只有一個(gè)方法。
@FunctionalInterface public interface StatementCallback<T> {@NullableT doInStatement(Statement stmt) throws SQLException, DataAccessException;}通過(guò)回調(diào)獲取JdbcTemplate提供的Statement,用戶可以在該Statement進(jìn)行sql操作。
其實(shí)execute(final String sql)該方法就是調(diào)用execute(StatementCallback<T> action)這個(gè)方法實(shí)現(xiàn)的。所有的sql都能執(zhí)行,例如:
@Autowired private JdbcTemplate jdbcTemplate;@Override public Object execute() {// 新增數(shù)據(jù)jdbcTemplate.execute(new StatementCallback() {@Overridepublic 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(),'測(cè)試22','1',222,15)");return null;}});// 查詢一條數(shù)據(jù) 采用lambda表達(dá)式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; }其實(shí)像很多query()、update()、batchUpdate()內(nèi)部都是調(diào)用這個(gè)方法。
?3.execute(ConnectionCallback<T> action)
public <T> T execute(ConnectionCallback<T> action) throws DataAccessException通過(guò)回調(diào)獲取JdbcTemplate提供的Connection,用戶可在該Connection執(zhí)行一些操作。例如:
@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>>() {@Overridepublic List<CoalaAccount> doInConnection(Connection con) throws SQLException, DataAccessException {try {con.setAutoCommit(false); // 設(shè)置為手工提交事務(wù),默認(rèn)是自動(dòng)提交PreparedStatement ps = con.prepareStatement(sql);ps.execute(); // 執(zhí)行sqlResultSet 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(); // 提交事務(wù),查詢時(shí)不需要提交} catch (Exception e) {logger.error("sql處理異常:", e);con.rollback(); // 事務(wù)回滾}return list;}}); }4.execute(String sql, PreparedStatementCallback<T> action)
@Override@Nullablepublic <T> T execute(String sql, PreparedStatementCallback<T> action) throws DataAccessException {return execute(new SimplePreparedStatementCreator(sql), action);}?由傳入的sql生成一個(gè)預(yù)編譯語(yǔ)句,由JdbcTemplate通過(guò)PreparedStatementCallback回調(diào)傳回,由用戶決定如何執(zhí)行該P(yáng)reparedStatement。
例如:
String sql = "select id,customer_name,sex,bill_date from T_HAO_COALA_ACCOUNT where sex='1' "; // 查詢一條記錄(實(shí)際上是能查詢出多條數(shù)據(jù),我這里只取一條) 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; }); // 執(zhí)行批量更新操作,執(zhí)行兩次,第一次更新三條數(shù)據(jù),第二次更新一條數(shù)據(jù) 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("執(zhí)行結(jié)果:[{}]條數(shù)據(jù)", Arrays.toString(result)); // 輸出結(jié)果:執(zhí)行結(jié)果:[[3, 1]]條數(shù)據(jù)5.?execute(String callString, CallableStatementCallback<T> action)
@Override@Nullablepublic <T> T execute(String callString, CallableStatementCallback<T> action) throws DataAccessException {return execute(new SimpleCallableStatementCreator(callString), action);}此方法主要是處理存儲(chǔ)過(guò)程和函數(shù)使用。
// 測(cè)試執(zhí)行添加數(shù)據(jù)的存儲(chǔ)過(guò)程 jdbcTemplate.execute("{call add_data_to_account}", new CallableStatementCallback() {@Overridepublic Object doInCallableStatement(CallableStatement cs) throws SQLException, DataAccessException {cs.execute();return null;} }); // 測(cè)試執(zhí)行添加數(shù)據(jù)的存儲(chǔ)過(guò)程 注意sql語(yǔ)句的傳參格式,建議使用{}形式 jdbcTemplate.execute("begin add_data_to_account;end;", (CallableStatementCallback) cs -> {cs.execute();return null; }); // 測(cè)試執(zhí)行添加數(shù)據(jù)的存儲(chǔ)過(guò)程,此存儲(chǔ)過(guò)程帶有兩個(gè)輸入?yún)?shù) jdbcTemplate.execute("{call insert_data_to_user(?,?)}", (CallableStatementCallback) cs -> {cs.setString(1,"姓名:測(cè)試");cs.setString(2,"地點(diǎn):北京");cs.execute();return null; }); // 執(zhí)行取數(shù)據(jù)的存儲(chǔ)過(guò)程,存儲(chǔ)過(guò)程第一個(gè)是輸入?yún)?shù),第二個(gè)和第三個(gè)是輸出參數(shù) String execute = jdbcTemplate.execute("{call get_data_from_product(?,?,?)}", (CallableStatementCallback<String>) cs -> {cs.setInt(1, 2);cs.registerOutParameter(2, Types.VARCHAR); // 注冊(cè)O(shè)UT參數(shù)cs.registerOutParameter(3, Types.INTEGER); // 注冊(cè)O(shè)UT參數(shù)cs.executeUpdate();String name = cs.getNString(2);int count = cs.getInt(3);return "貨物名稱(chēng):" + name + " 數(shù)量:" + count; });?6.execute(PreparedStatementCreator psc, PreparedStatementCallback<T> action)
@Override@Nullablepublic <T> T execute(PreparedStatementCreator psc, PreparedStatementCallback<T> action) throws DataAccessException {}第一個(gè)參數(shù)是創(chuàng)建一個(gè)預(yù)編譯語(yǔ)句,第二個(gè)是預(yù)編譯的回調(diào)函數(shù)。
例如:
// 查詢數(shù)據(jù) 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; });// 新增數(shù)據(jù) String sql = "insert into T_HAO_COALA_ACCOUNT (id,customer_name,sex,principal,bill_date) values (sys_guid(),?,?,?,?)"; jdbcTemplate.execute(new PreparedStatementCreator() {@Overridepublic PreparedStatement createPreparedStatement(Connection con) throws SQLException {PreparedStatement preparedStatement = con.prepareStatement(sql);preparedStatement.setString(1, "測(cè)試姓名:哈哈哈");preparedStatement.setString(2, "1");preparedStatement.setBigDecimal(3, new BigDecimal("5000.00"));preparedStatement.setInt(4, 3);return preparedStatement;} }, new PreparedStatementCallback<Integer>() {@Overridepublic 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@Nullablepublic <T> T execute(CallableStatementCreator csc, CallableStatementCallback<T> action)throws DataAccessException {// .... }通過(guò)CallableStatementCreator 創(chuàng)建存儲(chǔ)過(guò)程或者函數(shù)的預(yù)編譯語(yǔ)句,然后由CallableStatementCallback回調(diào)函數(shù)執(zhí)行,獲取結(jié)果,例如:
// 方式一 Object execute = jdbcTemplate.execute(new CallableStatementCreator() {@Overridepublic CallableStatement createCallableStatement(Connection con) throws SQLException {CallableStatement callableStatement = con.prepareCall("{call get_data_from_product(?,?,?)}");callableStatement.setInt(1, 3); // 輸入?yún)?shù) 主鍵ID的值callableStatement.registerOutParameter(2, Types.VARCHAR); // 注冊(cè)O(shè)UT參數(shù)callableStatement.registerOutParameter(3, Types.INTEGER); // 注冊(cè)O(shè)UT參數(shù)return callableStatement;} }, new CallableStatementCallback<Object>() {@Overridepublic Object doInCallableStatement(CallableStatement cs) throws SQLException, DataAccessException {cs.execute();ResultSet resultSet = cs.getResultSet();String name = cs.getNString(2);int count = cs.getInt(3);return "貨物名稱(chēng):" + name + " 數(shù)量:" + count;} });// 方式二 // 通過(guò)CallableStatementCreatorFactory工廠創(chuàng)建CallableStatementCreator對(duì)象 CallableStatementCreatorFactory factory = new CallableStatementCreatorFactory("{call get_data_from_product(?,?,?)}"); factory.addParameter(new SqlParameter("id", Types.INTEGER)); // 設(shè)置存儲(chǔ)過(guò)程的輸入?yún)?shù) factory.addParameter(new SqlOutParameter("name", Types.VARCHAR)); // 設(shè)置存儲(chǔ)過(guò)程的輸出參數(shù) factory.addParameter(new SqlOutParameter("count", Types.INTEGER)); // 設(shè)置存儲(chǔ)過(guò)程的輸出參數(shù) 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 "貨物名稱(chēng):" + name + " 數(shù)量:" + count; });?
query 系列
1.query(String sql, ResultSetExtractor<T> rse)
@Override @Nullable public <T> T query(final String sql, final ResultSetExtractor<T> rse) throws DataAccessException { }該方法返回一個(gè)泛型對(duì)象。sql為查詢的sql語(yǔ)句,ResultSetExtractor是結(jié)果集數(shù)據(jù)提取用的,通過(guò)extractData(ResultSet rs)處理整個(gè)結(jié)果集。不支持傳入?yún)?shù)。可以根據(jù)自己想要的類(lèi)型返回結(jié)果,需要手工處理結(jié)果集。
// 查詢單個(gè)結(jié)果對(duì)象,ID=2的數(shù)據(jù) 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>() {@Overridepublic 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;} });// 查詢多個(gè)對(duì)象,返回該對(duì)象List。性別是1的所有數(shù)據(jù) 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; });// 查詢多個(gè)對(duì)象,返回Map形式的List。性別是1的所有數(shù)據(jù) List<Map<String, Object>> list = jdbcTemplate.query(sql, new ResultSetExtractor<List<Map<String, Object>>>() {@Overridepublic 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;} });// 查詢總數(shù) 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)
@Overridepublic void query(String sql, RowCallbackHandler rch) throws DataAccessException {query(sql, new RowCallbackHandlerResultSetExtractor(rch));}其實(shí)這個(gè)方式就是調(diào)用上面那個(gè)query()方法,需要用戶自己取處理結(jié)果集,不過(guò)不需要判斷ResultSet.next(),交由ResultSetExtractor的實(shí)現(xiàn)類(lèi)的extractData(ResultSet rs)完成。用戶只需要處理ResultSet的每一行數(shù)據(jù)。也不支持sql動(dòng)態(tài)傳入?yún)?shù)。
如果查詢結(jié)果不存在,則會(huì)返回null。
?查詢單條數(shù)據(jù):
HashMap<String, Object> map = new HashMap<>(); jdbcTemplate.query(sql, new RowCallbackHandler() {@Overridepublic 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"));} });查詢多條數(shù)據(jù):
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)
@Overridepublic <T> List<T> query(String sql, RowMapper<T> rowMapper) throws DataAccessException {return result(query(sql, new RowMapperResultSetExtractor<>(rowMapper)));}該方法返回一個(gè)RowMapper指定泛型對(duì)象的List集合,用戶需要通過(guò)mapRow(ResultSet rs, int rowNum)實(shí)現(xiàn)方法手動(dòng)將每一行轉(zhuǎn)換為需要的類(lèi)型,可以是map也可以是自定義的對(duì)象。不支持動(dòng)態(tài)傳入?yún)?shù)。
例如:
// 查一條數(shù)據(jù) 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>() {@Overridepublic 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;} });// 查多條數(shù)據(jù) 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>() {@Overridepublic 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;} });// 查詢總數(shù) sql = "select count(*) from T_HAO_COALA_ACCOUNT"; List<Integer> count = jdbcTemplate.query(sql, new RowMapper<Integer>() {@Overridepublic 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 { }這是個(gè)很重要的方法,其它很多query()方法底層都是調(diào)用這個(gè)方法實(shí)現(xiàn)的。該方法有三個(gè)參數(shù),
PreparedStatementCreator:創(chuàng)建一個(gè)預(yù)編譯的sql語(yǔ)句。
PreparedStatementSetter:如果sql中有動(dòng)態(tài)的參數(shù)占位符,則給占位符賦值參數(shù)值。
ResultSetExtractor:處理sql執(zhí)行的結(jié)果,將結(jié)果集中每一行轉(zhuǎn)換為需要對(duì)象,需要先調(diào)用ResultSet.next()。
例如:
// 查詢一條記錄,sql中無(wú)動(dòng)態(tài)參數(shù) String sql = "select id,customer_name,sex,bill_date from T_HAO_COALA_ACCOUNT where id='2'"; CoalaAccount account = jdbcTemplate.query(new PreparedStatementCreator() {@Overridepublic PreparedStatement createPreparedStatement(Connection con) throws SQLException {return con.prepareStatement(sql);} }, new PreparedStatementSetter() {@Overridepublic void setValues(PreparedStatement ps) throws SQLException {// nothing to do ....} }, new ResultSetExtractor<CoalaAccount>() {@Overridepublic 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中有動(dòng)態(tài)參數(shù),使用的是lambda表達(dá)式 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中的占位符設(shè)置參數(shù)值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@Nullablepublic <T> T query(PreparedStatementCreator psc, ResultSetExtractor<T> rse) throws DataAccessException {return query(psc, null, rse);}該方法其實(shí)和上面的一樣,從其方法內(nèi)部的實(shí)現(xiàn)可以看出就是調(diào)用上面的方法(4.query(PreparedStatementCreator psc, @Nullable final PreparedStatementSetter pss, final ResultSetExtractor<T> rse))。只是不支持傳入動(dòng)態(tài)的參數(shù)了,使用方式和上面類(lèi)似:
String sql = "select id,customer_name,sex,bill_date from T_HAO_COALA_ACCOUNT where id='2'";CoalaAccount account = jdbcTemplate.query(new PreparedStatementCreator() {@Overridepublic PreparedStatement createPreparedStatement(Connection con) throws SQLException {return con.prepareStatement(sql);}}, new ResultSetExtractor<CoalaAccount>() {@Overridepublic 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@Nullablepublic <T> T query(String sql, @Nullable PreparedStatementSetter pss, ResultSetExtractor<T> rse) throws DataAccessException {return query(new SimplePreparedStatementCreator(sql), pss, rse);}和上面的方法一樣,也是調(diào)用的4.query(PreparedStatementCreator psc, @Nullable final PreparedStatementSetter pss, final ResultSetExtractor<T> rse),具體的處理方式都一樣,支持動(dòng)態(tài)的參數(shù),需要處理sql中的占位符。
String sql = "select id,customer_name,sex,bill_date from T_HAO_COALA_ACCOUNT where id='2'";jdbcTemplate.query(sql, new PreparedStatementSetter() {@Overridepublic void setValues(PreparedStatement ps) throws SQLException {// 如果sql中有占位符,則處理占位符的參數(shù)值,沒(méi)有不做任何處理。}}, new ResultSetExtractor<CoalaAccount>() {@Overridepublic CoalaAccount extractData(ResultSet rs) throws SQLException, DataAccessException {// 處理結(jié)果集,return null;}});?
7.query(String sql, Object[] args, int[] argTypes, ResultSetExtractor<T> rse)
@Override@Nullablepublic <T> T query(String sql, Object[] args, int[] argTypes, ResultSetExtractor<T> rse) throws DataAccessException {return query(sql, newArgTypePreparedStatementSetter(args, argTypes), rse);}?這個(gè)方式和上面的幾個(gè)沒(méi)有什么差別,看一下方法內(nèi)部的調(diào)用就知道了,也是調(diào)用的4.query(PreparedStatementCreator psc, @Nullable final PreparedStatementSetter pss, final ResultSetExtractor<T> rse),只不過(guò)把Object[] args, int[] argTypes這兩個(gè)參數(shù)分開(kāi)了。主要是針對(duì)有可變參數(shù)的sql。這兩個(gè)參數(shù)的意思是:
Object[] args:占位符對(duì)應(yīng)的參數(shù)值。
int[] argTypes:占位符參數(shù)值的類(lèi)型。
比如:
// 根據(jù)泛型定義,可以查詢多條也可以查詢一條數(shù)據(jù),如果sql有占位符則第二個(gè)和第三個(gè)參數(shù)不能是null,元素也必須要有值,且兩個(gè)數(shù)組的長(zhǎng)度要一樣。String sql2 = "select id,customer_name,sex,bill_date from T_HAO_COALA_ACCOUNT where sex = ? and bill_date > ?";Object[] param = {"1", 10}; // 占位符對(duì)應(yīng)的參數(shù)值int[] index = {Types.CHAR, Types.NUMERIC}; // 參數(shù)值類(lèi)型List<CoalaAccount> list = jdbcTemplate.query(sql2, param, index, new ResultSetExtractor<List<CoalaAccount>>() {@Overridepublic 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;}});// 也可以參數(shù)值為空,即沒(méi)有任何占位符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>>() {@Overridepublic 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@Nullablepublic <T> T query(String sql, @Nullable Object[] args, ResultSetExtractor<T> rse) throws DataAccessException {return query(sql, newArgPreparedStatementSetter(args), rse);}?和上面方法類(lèi)似,只是缺少int[] argTypes參數(shù),方法內(nèi)部會(huì)根據(jù)占位符的順序傳參。主要是針對(duì)有可變參數(shù)的sql。
// 沒(méi)有占位符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>() {@Overridepublic 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>>() {@Overridepublic 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@Nullablepublic <T> T query(String sql, ResultSetExtractor<T> rse, @Nullable Object... args) throws DataAccessException {return query(sql, newArgPreparedStatementSetter(args), rse);}和上面的方法類(lèi)似,只不過(guò)把數(shù)組參數(shù)改為多個(gè)可傳參數(shù)的形式。如果沒(méi)有參數(shù)就傳個(gè)空的數(shù)組。主要是針對(duì)有可變參數(shù)的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)?
@Overridepublic void query(PreparedStatementCreator psc, RowCallbackHandler rch) throws DataAccessException {query(psc, new RowCallbackHandlerResultSetExtractor(rch));}?參數(shù)一:構(gòu)建一個(gè)預(yù)編譯的sql語(yǔ)句,如果有可變參數(shù),給其賦值。
參數(shù)二:用戶處理每一行的結(jié)果集,不需要判斷ResultSet.next()。
如下:注意,這是個(gè)沒(méi)有返回值的方法。
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() {@Overridepublic 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() {@Overridepublic 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)
@Overridepublic void query(String sql, @Nullable PreparedStatementSetter pss, RowCallbackHandler rch) throws DataAccessException {query(sql, pss, new RowCallbackHandlerResultSetExtractor(rch));}第一個(gè)參數(shù):需要查詢的sql。
第二個(gè)參數(shù):對(duì)sql中的參數(shù)處理,如果沒(méi)有則不處理。
第三個(gè)參數(shù):對(duì)結(jié)果集的每一行進(jìn)行處理,轉(zhuǎn)換成想要的對(duì)象。不需要做ResultSet.next()判斷。
String sql = "select id,customer_name,sex,bill_date from T_HAO_COALA_ACCOUNT where sex = ? and bill_date > ?"; // 查詢多條數(shù)據(jù) ArrayList<CoalaAccount> list = new ArrayList<>(); jdbcTemplate.query(sql, new PreparedStatementSetter() {@Overridepublic void setValues(PreparedStatement ps) throws SQLException {ps.setString(1, "1");ps.setInt(2, 10);} }, new RowCallbackHandler() {@Overridepublic 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);} }); // 查詢單條數(shù)據(jù) 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() {@Overridepublic void setValues(PreparedStatement ps) throws SQLException {// sql中沒(méi)有參數(shù)需要處理,故不作任何處理} }, new RowCallbackHandler() {@Overridepublic 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)
@Overridepublic void query(String sql, Object[] args, int[] argTypes, RowCallbackHandler rch) throws DataAccessException {query(sql, newArgTypePreparedStatementSetter(args, argTypes), rch);}第一個(gè)參數(shù):要查詢的sql。
第二個(gè)參數(shù):如果sql中有動(dòng)態(tài)參數(shù),則此為sql中占位符參數(shù)的數(shù)組,注意順序保持一致。如果沒(méi)有則為null。
第三個(gè)參數(shù):如果sql有占位符需要處理參數(shù),則此為參數(shù)的數(shù)據(jù)類(lèi)型,如果sql中沒(méi)有參數(shù),則為null。
第四個(gè)參數(shù):對(duì)結(jié)果集的每一行進(jìn)行處理,轉(zhuǎn)換成想要的對(duì)象。不需要做ResultSet.next()判斷。
// 查詢單條數(shù)據(jù) 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() {@Overridepublic 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));} });// 查詢多條數(shù)據(jù) 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() {@Overridepublic 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)
@Overridepublic void query(String sql, Object[] args, RowCallbackHandler rch) throws DataAccessException {query(sql, newArgPreparedStatementSetter(args), rch);}?此方法省略了占位符在sql中參數(shù)值的類(lèi)型數(shù)組。所以使用的時(shí)候一定要保證sql的參數(shù)和占位符的順序一致。如果查詢結(jié)果為空則例子中的list結(jié)果為空。
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() {@Overridepublic 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)
@Overridepublic void query(String sql, RowCallbackHandler rch, @Nullable Object... args) throws DataAccessException {query(sql, newArgPreparedStatementSetter(args), rch);}和上面的方法一樣,只不過(guò)把參數(shù)數(shù)組改為多個(gè)參數(shù)數(shù)組的形式。如果沒(méi)有占位符則不需要最后的參數(shù)。
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() {@Overridepublic 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)
@Overridepublic <T> List<T> query(PreparedStatementCreator psc, RowMapper<T> rowMapper) throws DataAccessException {return result(query(psc, new RowMapperResultSetExtractor<>(rowMapper)));}第一個(gè)參數(shù):創(chuàng)建一個(gè)預(yù)編譯的sql,如果sql中有占位符,則需要進(jìn)行處理。
第二個(gè)參數(shù):查詢的每一行結(jié)果集,需要手動(dòng)進(jìn)行轉(zhuǎn)換為想要的對(duì)象。
?注意:這個(gè)方法和后面的幾個(gè)query()方法返回的是List<T>對(duì)象。無(wú)論查詢時(shí)單條記錄還是多條記錄,返回的都是List。
// 查詢多條數(shù)據(jù),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() {@Overridepublic 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<>();@Overridepublic 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;} });// 查詢單條數(shù)據(jù) ,sql中沒(méi)有占位符 String queryById = "select id,customer_name,sex,bill_date from T_HAO_COALA_ACCOUNT where id='2'"; List<CoalaAccount> accounts = jdbcTemplate.query(new PreparedStatementCreator() {@Overridepublic PreparedStatement createPreparedStatement(Connection con) throws SQLException {return con.prepareStatement(queryById);} }, new RowMapper<CoalaAccount>() {@Overridepublic 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)
@Overridepublic <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() {@Overridepublic void setValues(PreparedStatement ps) throws SQLException {} }, new RowMapper<CoalaAccount>() {@Overridepublic 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)
@Overridepublic <T> List<T> query(String sql, Object[] args, int[] argTypes, RowMapper<T> rowMapper) throws DataAccessException {return result(query(sql, args, argTypes, new RowMapperResultSetExtractor<>(rowMapper)));}?第一個(gè)參數(shù):需要執(zhí)行的查詢sql。
第二個(gè)參數(shù):有sql中占位符參數(shù)構(gòu)成的數(shù)組。如果沒(méi)有則為傳null。注意順序保持一致。
第三個(gè)參數(shù):參數(shù)值的數(shù)據(jù)庫(kù)類(lèi)型。如果沒(méi)有則為傳null。
第四個(gè)參數(shù):查詢結(jié)果的每一行結(jié)果集。
例如:
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>() {@Overridepublic 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)
@Overridepublic <T> List<T> query(String sql, @Nullable Object[] args, RowMapper<T> rowMapper) throws DataAccessException {return result(query(sql, args, new RowMapperResultSetExtractor<>(rowMapper)));}第一個(gè)參數(shù):需要執(zhí)行的查詢sql。
第二個(gè)參數(shù):有sql中占位符參數(shù)構(gòu)成的數(shù)組。如果沒(méi)有則為傳null。注意順序保持一致。
第三個(gè)參數(shù):查詢結(jié)果的每一行結(jié)果集。
例如:
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>() {@Overridepublic 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)
@Overridepublic <T> List<T> query(String sql, RowMapper<T> rowMapper, @Nullable Object... args) throws DataAccessException {return result(query(sql, args, new RowMapperResultSetExtractor<>(rowMapper)));}?第一個(gè)參數(shù):需要執(zhí)行的查詢sql。
第二個(gè)參數(shù):查詢結(jié)果的每一行結(jié)果集。
第三個(gè)參數(shù):采用多參數(shù)組的形式,指sql中占位符的參數(shù)值,沒(méi)有則不寫(xiě)。
例如:
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>() {@Overridepublic 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的形式返回結(jié)果,如果指定elementType類(lèi)型,則只能查詢單列,否則報(bào)錯(cuò):
org.springframework.jdbc.IncorrectResultSetColumnCountException: Incorrect column count: expected 1, actual 4?且類(lèi)型只能時(shí)8中基本數(shù)據(jù)類(lèi)型,否則報(bào)錯(cuò):
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]如果經(jīng)常查詢一些數(shù)據(jù),建議使用queryForList()。
需要注意的是:如果查詢結(jié)果為空則返回空集合,也就是
list.isEmpty() == true不會(huì)報(bào)錯(cuò)。
1.queryForList(String sql, Class<T> elementType)
@Overridepublic <T> List<T> queryForList(String sql, Class<T> elementType) throws DataAccessException {return query(sql, getSingleColumnRowMapper(elementType));}此方法用于sql中沒(méi)有動(dòng)態(tài)參數(shù),且查詢結(jié)果為單列多行,返回一個(gè)指定類(lèi)型的List集合,指定的類(lèi)型只能是8個(gè)基本數(shù)據(jù)類(lèi)型。
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)
@Overridepublic List<Map<String, Object>> queryForList(String sql) throws DataAccessException {return query(sql, getColumnMapRowMapper());}可以查詢多行多列,返回一個(gè)List集合,List元素是Map,也就是查詢結(jié)果中每一行的數(shù)據(jù),只不過(guò)以map的形式返回。?
如果sql中沒(méi)有動(dòng)態(tài)參數(shù),推薦使用。
比如以下查詢
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);查詢結(jié)果maps為(我這里以JSON形式展示):
[{"ID": "65536F6490C44D45B149F6C1BB54EE3F","CUSTOMER_NAME": "測(cè)試22","SEX": "1","BILL_DATE": 15},{"ID": "DC78F9F3698F4BE1AA4A3DEF39509271","CUSTOMER_NAME": "測(cè)試22","SEX": "1","BILL_DATE": 15},{"ID": "8078AF90A83548C28886F218930CB334","CUSTOMER_NAME": "測(cè)試22","SEX": "1","BILL_DATE": 15},{"ID": "834747A641D24410BF602FE448C61801","CUSTOMER_NAME": "測(cè)試","SEX": "1","BILL_DATE": 15} ]?
3.queryForList(String sql, Object[] args, int[] argTypes, Class<T> elementType)
@Overridepublic <T> List<T> queryForList(String sql, Object[] args, int[] argTypes, Class<T> elementType) throws DataAccessException {return query(sql, args, argTypes, getSingleColumnRowMapper(elementType));}查詢多行單列,sql中可以有動(dòng)態(tài)參數(shù),。
第二個(gè)參數(shù):如果sql中有動(dòng)態(tài)參數(shù),則此為sql中占位符參數(shù)的數(shù)組,注意順序保持一致。如果沒(méi)有則為null。
第三個(gè)參數(shù):如果sql有占位符需要處理參數(shù),則此為參數(shù)的數(shù)據(jù)庫(kù)類(lèi)型,如果sql中沒(méi)有參數(shù),則為null。
第三個(gè)參數(shù):必須是8個(gè)基本數(shù)據(jù)類(lèi)型其一。
比如:
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);結(jié)果如下:
["測(cè)試22","測(cè)試22","測(cè)試22","測(cè)試" ]?
4.queryForList(String sql, Object[] args, Class<T> elementType)
@Overridepublic <T> List<T> queryForList(String sql, Object[] args, Class<T> elementType) throws DataAccessException {return query(sql, args, getSingleColumnRowMapper(elementType));}同上,只不過(guò)少了個(gè)?argTypes參數(shù),這個(gè)參數(shù)其實(shí)可有可無(wú),就不舉例了。
5.queryForList(String sql, Class<T> elementType, @Nullable Object... args)
@Overridepublic <T> List<T> queryForList(String sql, Class<T> elementType, @Nullable Object... args) throws DataAccessException {return query(sql, args, getSingleColumnRowMapper(elementType));}查詢多行單列,第二個(gè)參數(shù)的類(lèi)型必須是八個(gè)基本數(shù)據(jù)類(lèi)型之一,動(dòng)態(tài)占位符參數(shù)采用多個(gè)參數(shù)傳參的方式。如:
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)
@Overridepublic List<Map<String, Object>> queryForList(String sql, Object[] args, int[] argTypes) throws DataAccessException {return query(sql, args, argTypes, getColumnMapRowMapper());}查詢多行多列,sql中可以傳多個(gè)動(dòng)態(tài)參數(shù) ,如:
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);結(jié)果如下:
[{"ID": "65536F6490C44D45B149F6C1BB54EE3F","CUSTOMER_NAME": "測(cè)試22","SEX": "1","BILL_DATE": 15},{"ID": "DC78F9F3698F4BE1AA4A3DEF39509271","CUSTOMER_NAME": "測(cè)試22","SEX": "1","BILL_DATE": 15},{"ID": "8078AF90A83548C28886F218930CB334","CUSTOMER_NAME": "測(cè)試22","SEX": "1","BILL_DATE": 15},{"ID": "834747A641D24410BF602FE448C61801","CUSTOMER_NAME": "測(cè)試","SEX": "1","BILL_DATE": 15} ]?
7.queryForList(String sql, @Nullable Object... args)
@Overridepublic List<Map<String, Object>> queryForList(String sql, @Nullable Object... args) throws DataAccessException {return query(sql, args, getColumnMapRowMapper());}如果sql中有動(dòng)態(tài)參數(shù),推薦使用這個(gè),比較方便。如:
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);?如果參數(shù)過(guò)多的話,可以采用數(shù)組的形式,其實(shí)都一樣的,上面的查詢也可以這樣:
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);?結(jié)果都是一樣的。
[{"ID": "65536F6490C44D45B149F6C1BB54EE3F","CUSTOMER_NAME": "測(cè)試22","SEX": "1","BILL_DATE": 15},{"ID": "DC78F9F3698F4BE1AA4A3DEF39509271","CUSTOMER_NAME": "測(cè)試22","SEX": "1","BILL_DATE": 15},{"ID": "8078AF90A83548C28886F218930CB334","CUSTOMER_NAME": "測(cè)試22","SEX": "1","BILL_DATE": 15},{"ID": "834747A641D24410BF602FE448C61801","CUSTOMER_NAME": "測(cè)試","SEX": "1","BILL_DATE": 15} ]?
queryForObject 系列
queryForObject()方法只能查詢單個(gè)列且結(jié)果只有一行。否則報(bào)錯(cuò)。這一點(diǎn)尤其注意。
如果查詢結(jié)果為空也會(huì)報(bào)錯(cuò):
org.springframework.dao.EmptyResultDataAccessException: Incorrect result size: expected 1, actual 0 。也就是說(shuō)查詢的結(jié)果必須有且只有一行一列的值。
如果查詢結(jié)果是多行,則報(bào)錯(cuò):
org.springframework.dao.IncorrectResultSizeDataAccessException: Incorrect result size: expected 1, actual 121.queryForObject(String sql, RowMapper<T> rowMapper)
@Override@Nullablepublic <T> T queryForObject(String sql, RowMapper<T> rowMapper) throws DataAccessException {List<T> results = query(sql, rowMapper);return DataAccessUtils.nullableSingleResult(results);}返回一個(gè)泛型對(duì)象。且查詢sql不能動(dòng)態(tài)傳參,除非將參數(shù)在查詢之前動(dòng)態(tài)的拼接好,RowMapper用于處理查詢的結(jié)果。
下面是幾個(gè)例子。
// 查詢對(duì)象中的單個(gè)屬性 String sql = "select customer_name from T_HAO_COALA_ACCOUNT where id= '2'"; CoalaAccount account = jdbcTemplate.queryForObject(sql, new RowMapper<CoalaAccount>() {@Overridepublic CoalaAccount mapRow(ResultSet rs, int rowNum) throws SQLException {CoalaAccount account = new CoalaAccount();account.setCustomerName(rs.getString(1));return account;} });// 查詢總數(shù) sql = "select count(*) from T_HAO_COALA_ACCOUNT where sex = '1'"; Integer count = jdbcTemplate.queryForObject(sql, new RowMapper<Integer>() {@Overridepublic Integer mapRow(ResultSet rs, int rowNum) throws SQLException {return rs.getInt(1);} }); logger.info("總數(shù)量:[{}]", count);// 查詢某一列總和 sql = "select sum(bill_date) from T_HAO_COALA_ACCOUNT where sex = '1'"; Integer sum = jdbcTemplate.queryForObject(sql, new RowMapper<Integer>() {@Overridepublic 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>() {@Overridepublic String mapRow(ResultSet rs, int rowNum) throws SQLException {return rs.getString(1);} }); logger.info("客戶姓名:[{}]", customerName);?
2.queryForObject(String sql, Class<T> requiredType)
@Override@Nullablepublic <T> T queryForObject(String sql, Class<T> requiredType) throws DataAccessException {return queryForObject(sql, getSingleColumnRowMapper(requiredType));}?這個(gè)方法就是用上面的那個(gè)方法,只不過(guò)把第二個(gè)參數(shù)封裝了。requiredType必須是常用的8個(gè)基本類(lèi)型,否則報(bào)錯(cuò)。
推薦使用。
String customerName = jdbcTemplate.queryForObject("select customer_name from T_HAO_COALA_ACCOUNT where id= '2'", String.class);// 下面這個(gè)會(huì)報(bào)錯(cuò): // 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@Nullablepublic <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);}?查詢帶有參數(shù)的sql。
第一個(gè)參數(shù):查詢sql。
第二個(gè)參數(shù):如果sql中有動(dòng)態(tài)參數(shù),則此為sql中占位符參數(shù)的數(shù)組,注意順序保持一致。如果沒(méi)有則為null。
第三個(gè)參數(shù):如果sql有占位符需要處理參數(shù),則此為參數(shù)在數(shù)據(jù)庫(kù)中的類(lèi)型,如果sql中沒(méi)有參數(shù),則為null。
第四個(gè)參數(shù):手動(dòng)處理結(jié)果集。
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>() {@Overridepublic 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>() {@Overridepublic String mapRow(ResultSet rs, int rowNum) throws SQLException {return rs.getString(1);} });4.queryForObject(String sql, @Nullable Object[] args, RowMapper<T> rowMapper)
@Override@Nullablepublic <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);}和上面方法類(lèi)似,少了個(gè)sql參數(shù)類(lèi)型。如果查詢時(shí)多列,則只會(huì)返回第一列的值。
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>() {@Overridepublic Integer mapRow(ResultSet rs, int rowNum) throws SQLException {return rs.getInt(1);}});// 只會(huì)返回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>() {@Overridepublic String mapRow(ResultSet rs, int rowNum) throws SQLException {return rs.getString(1);}});?
5.queryForObject(String sql, RowMapper<T> rowMapper, @Nullable Object... args)
@Override@Nullablepublic <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);}?和上面的幾個(gè)方式一樣,只不過(guò)把參數(shù)以數(shù)組的形式改成多個(gè)參數(shù)的形式,就不舉例了 。
6.queryForObject(String sql, Object[] args, int[] argTypes, Class<T> requiredType)
@Override@Nullablepublic <T> T queryForObject(String sql, Object[] args, int[] argTypes, Class<T> requiredType)throws DataAccessException {return queryForObject(sql, args, argTypes, getSingleColumnRowMapper(requiredType));}可以傳多個(gè)參數(shù),參數(shù)以數(shù)組的形式傳入,查詢結(jié)果以第四個(gè)參數(shù)的Class類(lèi)型返回。不用我們手動(dòng)去處理結(jié)果。
推薦使用。?
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)
@Overridepublic <T> T queryForObject(String sql, Object[] args, Class<T> requiredType) throws DataAccessException {return queryForObject(sql, args, getSingleColumnRowMapper(requiredType));}和上面一樣,只不過(guò)少了個(gè)占位符參數(shù)值類(lèi)型的數(shù)組。?推薦使用。?不舉例了。
8.queryForObject(String sql, Class<T> requiredType, @Nullable Object... args)
@Overridepublic <T> T queryForObject(String sql, Class<T> requiredType, @Nullable Object... args) throws DataAccessException {return queryForObject(sql, args, getSingleColumnRowMapper(requiredType));}和上面一樣,將數(shù)組參數(shù)改為多個(gè)參數(shù)的傳參方式。如果參數(shù)不多的話推薦使用這個(gè)。?不舉例了。?
?
update 系列
update()方法可以執(zhí)行所有execute()能執(zhí)行的sql,幾乎涵蓋了所有常用的sql。
1.update(final String sql)
@Overridepublic 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 {@Overridepublic Integer doInStatement(Statement stmt) throws SQLException {int rows = stmt.executeUpdate(sql);if (logger.isTraceEnabled()) {logger.trace("SQL update affected " + rows + " rows");}return rows;}@Overridepublic String getSql() {return sql;}}return updateCount(execute(new UpdateStatementCallback()));}?可以看到這個(gè)方法其實(shí)就是調(diào)用execute(StatementCallback<T> action)他的。故此update()方法也能執(zhí)行很多操作類(lèi)的sql,不過(guò)sql中不能處理動(dòng)態(tài)參數(shù)。如:
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)
@Overridepublic int update(PreparedStatementCreator psc) throws DataAccessException {return update(psc, (PreparedStatementSetter) null);}此方法執(zhí)行sql時(shí)可以傳遞動(dòng)態(tài)的參數(shù),使用?PreparedStatement 對(duì)象操作參數(shù)。
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() {@Overridepublic PreparedStatement createPreparedStatement(Connection con) throws SQLException {PreparedStatement ps = con.prepareStatement(insertIntoSql);return ps;}});jdbcTemplate.update(new PreparedStatementCreator() {@Overridepublic 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)
@Overridepublic 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;}));}此方法對(duì)于執(zhí)行insert sql語(yǔ)句時(shí),可查詢執(zhí)行的主鍵id的值。也就是最重要的一點(diǎn)根據(jù)KeyHolder獲取插入記錄的ID。
不過(guò)獲取主鍵的時(shí)候需要注意數(shù)據(jù)庫(kù)類(lèi)別,oracle和mySql是不一樣的。
我這里用的時(shí)oracle數(shù)據(jù)庫(kù),版本:Oracle Database 19c Enterprise Edition??19.0.0.0.0
MySql沒(méi)測(cè)試,不過(guò)個(gè)人認(rèn)為Mysql支持自增長(zhǎng)ID,所以如果操作的是Mysql數(shù)據(jù)庫(kù)插入動(dòng)作,獲取Id應(yīng)該是:
Number key = keyHolder.getKey(); int intValue = key.intValue();具體怎么獲取可以自己測(cè)試一下。
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() {@Overridepublic 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)
@Overridepublic int update(String sql, @Nullable PreparedStatementSetter pss) throws DataAccessException {return update(new SimplePreparedStatementCreator(sql), pss);}此方法可執(zhí)行帶有動(dòng)態(tài)參數(shù)的sql,參數(shù)由PreparedStatement對(duì)象操作,無(wú)需ps.execute();方法,否則sql會(huì)被執(zhí)行兩次。如:
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() {@Overridepublic void setValues(PreparedStatement ps) throws SQLException {}});jdbcTemplate.update(deleteSql, new PreparedStatementSetter() {@Overridepublic void setValues(PreparedStatement ps) throws SQLException {ps.setString(1, "09CCE5E3E7D14C118B6B624AD8E7BA24");}});5.update(String sql, Object[] args, int[] argTypes)
@Overridepublic int update(String sql, Object[] args, int[] argTypes) throws DataAccessException {return update(sql, newArgTypePreparedStatementSetter(args, argTypes));}執(zhí)行帶有動(dòng)態(tài)參數(shù)的sql,通過(guò)兩個(gè)數(shù)組入?yún)ⅰ?/p>
對(duì)于此方法中:
第一個(gè)參數(shù):執(zhí)行的sql。
第二個(gè)參數(shù):sql中參數(shù)的值。
第三個(gè)數(shù)組:動(dòng)態(tài)參數(shù)的各個(gè)類(lèi)型。
如:
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)
@Overridepublic int update(String sql, @Nullable Object... args) throws DataAccessException {return update(sql, newArgPreparedStatementSetter(args));}推薦使用。
方法比較簡(jiǎn)單。
其中第二個(gè)多參參數(shù)形式為sql中動(dòng)態(tài)參數(shù)的值數(shù)組。
如:
String updateSql = "update T_HAO_COALA_ACCOUNT set CUSTOMER_NAME =? where id =? ";Object[] param = {"李四", "2"};jdbcTemplate.update(updateSql, param);?
batchUpdate 系列
同update()方法一樣,batchUpdate()也能處理很多批量操作的sql,比如:insert語(yǔ)句、update語(yǔ)句、delete語(yǔ)句等等。
1.batchUpdate(final String... sql)
源碼太長(zhǎng),就不貼了使用方法如下,對(duì)于執(zhí)行的sql?不能帶有動(dòng)態(tài)參數(shù)。
String updateSql = "update T_HAO_COALA_ACCOUNT set BILL_DATE = 26 where id = '2'";jdbcTemplate.batchUpdate(updateSql);2.batchUpdate(String sql, final BatchPreparedStatementSetter pss)
源碼太長(zhǎng),不貼了?動(dòng)態(tài)參數(shù)通過(guò)BatchPreparedStatementSetter接口的匿名類(lèi)實(shí)現(xiàn)。如:
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() {@Overridepublic void setValues(PreparedStatement ps, int i) throws SQLException {ps.setBigDecimal(1, list.get(i).getPrincipal());ps.setString(2, list.get(i).getId());}@Overridepublic int getBatchSize() {return list.size();}});3.batchUpdate(String sql, List<Object[]> batchArgs)
不貼源碼了對(duì)于第二個(gè)參數(shù)?List<Object[]> batchArgs用于存放sql中的動(dòng)態(tài)參數(shù)對(duì)應(yīng)的值,如下:
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)
不貼源碼了。
同上面的方法一樣,采用數(shù)組泛型的List存放參數(shù)值,第三個(gè)參數(shù)為數(shù)據(jù)庫(kù)中對(duì)應(yīng)字段的屬性。比如:
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)
個(gè)人覺(jué)得這個(gè)批量操作的方法比較好用。
第一個(gè)參數(shù):要執(zhí)行的sql。
第二個(gè)參數(shù):sql參數(shù)的對(duì)象集合。
第三個(gè)參數(shù):需要處理數(shù)據(jù)的數(shù)量。
第四個(gè)參數(shù):根據(jù)第二個(gè)參數(shù)泛型取對(duì)應(yīng)的值賦值給PreparedStatement對(duì)象,用于執(zhí)行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>() {@Overridepublic void setValues(PreparedStatement ps, CoalaAccount argument) throws SQLException {ps.setBigDecimal(1, argument.getPrincipal());ps.setDate(2, new Date(argument.getBirthday().getTime())); // 注意Date類(lèi)型的轉(zhuǎn)換ps.setString(3, argument.getId());}});?
call 系列
call(CallableStatementCreator csc, List<SqlParameter> declaredParameters)
?
其它方法
?
總結(jié)
以上是生活随笔為你收集整理的Spring中JdbcTemplate各个方法的使用介绍(持续更新中....)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: viper4android md,【xp
- 下一篇: Spring Cloud Data Fl