日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 前端技术 > javascript >内容正文

javascript

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

發(fā)布時(shí)間:2024/8/1 javascript 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring中JdbcTemplate各个方法的使用介绍(持续更新中....) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

目錄

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 12

1.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)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

亚洲欧美日韩国产精品一区午夜 | 日本久久免费电影 | 911久久香蕉国产线看观看 | 国产色女 | 91精品国产电影 | 91成年人视频 | 久久久久 | 色在线亚洲 | 久久精品中文视频 | 日韩在线观看第一页 | 欧洲视频一区 | 精品毛片一区二区免费看 | 久热爱| 五月婷婷久久丁香 | 欧美精品一区二区蜜臀亚洲 | 久久久久久激情 | 成人在线视频免费看 | 日韩sese | 天天综合网在线 | 日韩高清在线一区二区 | 免费麻豆网站 | 久久情侣偷拍 | 久久久高清免费视频 | 亚州精品成人 | 精品久久久影院 | 永久中文字幕 | 欧美成人999 | 久久人人干 | 久久蜜臀av| 最新日韩精品 | 99热最新在线 | 国产婷婷一区二区 | 亚洲丁香日韩 | 在线国产日韩 | 97超碰在线视 | 日本动漫做毛片一区二区 | 韩日色视频 | 欧美日韩亚洲在线观看 | 国产麻豆视频免费观看 | 婷婷中文字幕综合 | 毛片网站在线观看 | 久久久一本精品99久久精品 | 狠狠狠狠狠狠天天爱 | 日韩色av色资源 | 99爱精品视频 | 91九色在线视频观看 | 天天艹天天干天天 | 一区二区电影网 | 国产精品久久久久久久久久久久午夜片 | 色吊丝在线永久观看最新版本 | 日韩在线观看网址 | 国产福利免费在线观看 | 91爱爱免费观看 | 久久久精品视频成人 | a级成人毛片 | 国产精品久久久久久久久久久久久 | 国产精品网红直播 | 亚洲精品天天 | 最新的av网站 | 成人a免费看 | 日日干天天干 | 日韩激情影院 | 热久久99这里有精品 | 免费观看一区 | 亚洲乱码精品久久久 | 国产精品国产三级国产aⅴ9色 | av电影在线观看完整版一区二区 | 亚洲有 在线 | 国产日本高清 | 99久热精品 | 911精品视频 | 亚洲91精品在线观看 | 婷婷去俺也去六月色 | 中文字幕久久精品 | 中文在线字幕观看电影 | 色视频一区 | a爱爱视频 | 五月天久久狠狠 | 97精品国产91久久久久久久 | 激情综合网五月 | 日韩欧美一区二区三区视频 | 国产精品96久久久久久吹潮 | 久久精品国产一区二区三 | 日韩在线中文字幕视频 | 日本精品视频在线 | 九九电影在线 | 九九热免费精品视频 | 欧美精品久久久久性色 | 福利一区在线视频 | www四虎影院 | 久久人人97超碰精品888 | 麻豆传媒视频在线免费观看 | 综合色婷婷 | 精品国产一区二区三区av性色 | 日韩欧美国产精品 | 园产精品久久久久久久7电影 | 国产黄色在线看 | 成人免费在线观看电影 | 波多野结衣视频一区二区三区 | 日本中文字幕在线看 | 久久久久久97三级 | 伊人亚洲综合网 | 免费看国产视频 | 青青河边草免费视频 | 亚洲欧美国产精品va在线观看 | 日韩免费观看av | 亚洲色影爱久久精品 | 久久av在线 | 在线观看视频免费播放 | av在线免费网 | 国产精品美女在线 | 国产视频亚洲视频 | 成年人电影免费看 | 丁香久久综合 | 人交video另类hd | 国产在线观看不卡 | 黄色看片| 国产精品美女久久久久久久久久久 | 激情综合六月 | 天天操天天射天天插 | 午夜黄色 | 正在播放一区二区 | www.夜色.com | 国产99久久久国产精品成人免费 | 久热这里有精品 | 天堂视频中文在线 | 五月婷婷一区二区三区 | 国产福利午夜 | 欧美动漫一区二区三区 | 一区二区三区四区五区六区 | 在线视频观看成人 | 欧美日韩激情视频8区 | 欧美另类人妖 | 丁香六月婷婷综合 | 国产免费视频在线 | 天干啦夜天干天干在线线 | 久久人人爽人人爽人人 | 国内精品久久久久久中文字幕 | 毛片区| 夜色资源站wwwcom | 亚洲女人av | 日韩电影中文字幕在线 | 亚洲美女视频在线 | 精品无人国产偷自产在线 | 精品专区| 国产做爰视频 | 免费在线观看av | 蜜臀av性久久久久蜜臀aⅴ流畅 | 99久久久成人国产精品 | 久久在线影院 | 在线观看av小说 | 啪啪免费视频网站 | 在线网站黄 | 久久久久久黄色 | 中文字幕乱码亚洲精品一区 | 亚洲精品视频免费在线观看 | 日韩在线观看小视频 | 婷婷在线免费 | 国产美女主播精品一区二区三区 | 成人av资源 | 国产一级片网站 | 夜夜看av| 国产一级电影免费观看 | 在线观看的av | 亚洲成色777777在线观看影院 | 免费婷婷 | 国产精品国产三级国产 | 77国产精品| 久操伊人 | 久久免费视频3 | 丁香六月婷 | 992tv在线观看 | 黄色软件大全网站 | 亚洲区视频在线观看 | 99色资源 | 丁香六月天 | 精品黄色片| 91插插影库| 6080yy午夜一二三区久久 | 99人成在线观看视频 | 国产高清av在线播放 | 最近中文字幕国语免费高清6 | 国产成人精品网站 | 2018好看的中文在线观看 | av中文字幕在线看 | 午夜精品一区二区三区可下载 | 精品免费 | 黄网站色视频 | 91精品在线视频 | 丝袜美腿亚洲综合 | 91黄色视屏| 国产成人99av超碰超爽 | 久久免费在线视频 | 精品中文字幕在线观看 | 91禁在线观看 | 中文字幕在线观看完整版电影 | 午夜影院三级 | 天天干天天做 | 免费的国产精品 | 973理论片235影院9 | 在线观看视频黄 | 操操操干干干 | 国产色综合天天综合网 | 天天色中文 | 最新日韩在线观看视频 | 久久综合福利 | 中文字幕免费高清 | 国产日韩一区在线 | 久久人人添人人爽添人人88v | 国产原创在线 | 黄色一级大片在线免费看产 | 久久精品2 | 国产亚洲精品bv在线观看 | 五月综合色 | 久久婷婷一区二区三区 | 中文字幕中文字幕中文字幕 | 欧美一区二区在线刺激视频 | 91视频在线观看免费 | 久久96 | 亚洲天天摸日日摸天天欢 | 欧美一区在线观看视频 | 天天操天天操天天操天天操天天操天天操 | 五月婷婷开心 | 五月综合| 成人在线播放视频 | 亚洲精品 在线视频 | 日韩精品一区在线观看 | 国产精品久久久网站 | 日韩欧美高清不卡 | 五月综合激情网 | 一区三区在线欧 | 五月丁色| 中文字幕在线看视频国产中文版 | 欧美a级在线播放 | 91夫妻视频| 丁香高清视频在线看看 | 久草在线资源免费 | 中文在线资源 | 日日精品 | 激情伊人| 最新亚洲视频 | 91pony九色丨交换 | 激情欧美丁香 | 免费色av| www.狠狠 | 午夜视频色 | 国产精品久久久久久久久岛 | 在线观看黄网 | 最新av网址在线观看 | 久久久久久久国产精品视频 | 97人人人人 | 亚洲另类人人澡 | 亚洲最大在线视频 | 人人澡人人草 | 国产精彩视频一区二区 | 亚洲电影网站 | 一区二区三区免费在线观看 | 2019天天干天天色 | 日日夜夜婷婷 | 三级黄色理论片 | 国产精品国产自产拍高清av | 美女中文字幕 | 欧美日韩视频精品 | 97偷拍视频| 公开超碰在线 | 久久av观看 | 久久国内精品视频 | 国产精品久久久久久久久久白浆 | 大荫蒂欧美视频另类xxxx | 日韩三级在线观看 | 久影院 | 黄污网| 国产破处在线视频 | 国产精品久久久久永久免费 | 亚洲精品国产精品国 | 国产精品亚洲a | 国产精品自在线拍国产 | 九色在线视频 | 一区精品久久 | 精品久久国产 | 在线视频 影院 | 精品国产123 | 精品国产一区二区久久 | 日韩精品免费一区二区三区 | 日韩免费网址 | 亚州中文av| 97在线观看| 精品999在线| 亚洲精品在线播放视频 | 亚洲九九精品 | av导航福利 | 亚洲成aⅴ人片久久青草影院 | 在线视频日韩一区 | 欧美色操 | 成在线播放 | 色成人亚洲 | 成人av高清| 三级黄色在线观看 | 日韩免费电影一区二区 | 日韩av成人在线 | 久久国产91| 精品国产亚洲在线 | 99久久精品国产亚洲 | 性色av香蕉一区二区 | 亚洲精品黄色在线观看 | 欧美日韩视频观看 | www四虎影院 | 午夜久久久久久久 | 午夜av日韩 | 波多野结衣资源 | 欧美精品久久久久久久亚洲调教 | 国产精品麻豆视频 | 日韩免费一级电影 | 亚洲高清视频在线观看 | 国产亚洲欧美一区 | 天天拍天天操 | 在线视频中文字幕一区 | 黄色三级免费网址 | 狠狠干夜夜操天天爽 | 精品国产一区二区三区免费 | 狠狠操天天射 | 国产日韩在线一区 | 久久综合操 | 日韩久久久久久 | 97视频一区 | 在线免费看黄色 | 亚洲性xxxx | 久久影院精品 | 天堂av在线网| 亚州国产精品久久久 | 四虎永久精品在线 | 韩国视频一区二区三区 | 国产高清av| 久久国产系列 | 激情丁香久久 | 午夜久久精品 | 日韩欧美视频在线播放 | 国产成人精品久久久久 | 日韩一级电影网站 | 中文区中文字幕免费看 | 91亚瑟视频 | 麻豆免费观看视频 | 999视频在线播放 | 亚洲九九九在线观看 | 久久精品福利 | 狠狠干天天射 | 中文字幕av网站 | 久久久噜噜噜久久久 | 久久久久久欧美二区电影网 | 国产精品porn | 日韩高清在线一区二区 | 亚洲精品国产精品国自产观看 | 一区免费视频 | 日韩视频1| 久久男人免费视频 | 黄色中文字幕在线 | 久久久网站| 超碰国产在线观看 | 狠狠色丁香久久婷婷综 | 日韩欧美精品在线观看视频 | 美女视频黄免费的 | 国产精品成人在线观看 | 日韩精品高清不卡 | 久章草在线观看 | 亚洲午夜精| 国产精品免费在线视频 | 一区二区三区日韩在线 | 久久国语露脸国产精品电影 | 国产精品女同一区二区三区久久夜 | 日日婷婷夜日日天干 | 日日夜夜免费精品视频 | 国产传媒中文字幕 | 97福利在线 | 欧美精品在线视频观看 | 蜜臀久久99静品久久久久久 | 免费又黄又爽的视频 | 亚洲精品日韩在线观看 | 日韩网站中文字幕 | 免费日韩电影 | 99在线视频观看 | 成人黄色在线看 | 欧美另类69 | 国产乱码精品一区二区蜜臀 | 蜜臀久久99静品久久久久久 | 日日夜夜草| 日韩精品三区四区 | 五月婷婷视频在线 | 高清av免费观看 | 亚洲精品午夜一区人人爽 | 久久综合精品国产一区二区三区 | 日韩欧美在线高清 | 色视频网站在线 | 蜜臀久久99精品久久久酒店新书 | 蜜臀aⅴ国产精品久久久国产 | 最近日本韩国中文字幕 | 免费激情在线电影 | 91综合久久一区二区 | 中文字幕日韩一区二区三区不卡 | 精品亚洲免费视频 | 最新中文字幕在线资源 | 国产日本三级 | 亚洲人在线7777777精品 | 亚洲精品女人久久久 | 毛片网站在线观看 | 亚洲视频专区在线 | 国产精品女同一区二区三区久久夜 | 最近日本中文字幕a | 久99久久| 成人资源在线观看 | a级黄色片视频 | 午夜123 | 久久亚洲视频 | 欧美伊人网 | www.久久视频 | 日本一区二区三区视频在线播放 | 天天激情天天干 | 成人免费观看完整版电影 | 亚洲jizzjizz日本少妇 | 99爱爱 | www.黄色片.com| 97超碰免费 | 91亚洲精品国偷拍自产在线观看 | 国产精品视频区 | 精品国产欧美 | 九九九九九九精品任你躁 | 黄污在线观看 | 91精品黄色| 青青草在久久免费久久免费 | 中文av在线免费观看 | 欧美在线视频一区二区 | 欧美日韩一区三区 | 麻花豆传媒mv在线观看 | 国产精品久久久久久久免费大片 | 亚洲黄色免费电影 | 一区二区三区福利 | 国产精品久久久久久久婷婷 | 色福利网 | 亚洲精品国精品久久99热一 | 日韩综合在线观看 | 综合久久久久久久久 | 91亚洲精品久久久蜜桃网站 | 亚色视频在线观看 | 国产又粗又猛又色又黄视频 | www.夜夜爱 | 性色va| 91一区一区三区 | 丁香婷婷基地 | 免费视频区 | a级片在线播放 | 精品在线观看一区二区 | 亚洲欧美在线观看视频 | 综合视频在线 | 天天拍天天爽 | 成人h在线播放 | 日日爱网址 | 免费福利在线观看 | 久久福利影视 | 人人精品久久 | 亚洲婷婷在线 | 天天操天天爽天天干 | 夜夜躁狠狠躁 | 91精品毛片| 婷婷网五月天 | 狠狠躁日日躁狂躁夜夜躁 | 中文字幕一区av | 午夜视频在线观看一区二区 | 激情视频免费在线观看 | 色伊人网 | 亚洲精品国产视频 | 日韩电影在线一区 | 久久国产精品第一页 | 久久国产精品99久久久久久丝袜 | 美女久久久久久久久久 | 国产 成人 久久 | 美女久久99 | 日日夜夜免费精品视频 | 免费黄色在线网址 | 一级成人免费视频 | 天天拍天天干 | 国产精品国产三级在线专区 | 日韩视 | 91少妇精拍在线播放 | 亚洲视频在线免费观看 | 日日爱夜夜爱 | 久免费| 在线免费av播放 | 国产99久久久精品视频 | 久久伊人精品一区二区三区 | 免费亚洲精品 | 久久免费片| 久久久精品免费看 | 久久国产精品免费观看 | 中文字幕在线一区观看 | 永久免费观看视频 | 久久视了 | 最近中文字幕免费 | 黄色av电影 | 亚洲香蕉在线观看 | 美女一级毛片视频 | 久久天天操 | 又湿又紧又大又爽a视频国产 | www.国产高清 | 在线看日韩av | 91视频免费网站 | 伊人久久婷婷 | 国产一级二级在线观看 | 最新av在线播放 | 色综合国产| 国产91精品高清一区二区三区 | 日本天天色 | 精品国产三级a∨在线欧美 免费一级片在线观看 | 最新91在线视频 | 日韩欧美一区二区三区视频 | 人人爽夜夜爽 | 成人免费91 | 中文字幕一区2区3区 | 婷婷激情欧美 | 99色视频 | aaa毛片视频 | 久久久久久久久久久网 | 日韩动漫免费观看高清完整版在线观看 | 日本在线观看视频一区 | 992tv在线观看网站 | 国产在线一区观看 | 伊人亚洲综合网 | 亚洲精品午夜久久久久久久 | 久久久69 | 欧美一级专区免费大片 | 91成人精品一区在线播放69 | 久草在线视频精品 | 日韩资源在线观看 | 91精品网站| 国产午夜精品一区二区三区在线观看 | 在线观看国产高清视频 | 亚洲少妇自拍 | 亚洲精品欧美专区 | 日韩欧美精品在线视频 | 天天色天天操天天爽 | 久久精品视频在线免费观看 | 亚洲区另类春色综合小说 | 一本一本久久a久久精品综合 | 亚洲最大激情中文字幕 | 日日干综合 | 在线观看午夜av | 97在线观看免费高清 | 全黄网站 | 一级性av| 国产成人精品一区在线 | 91精品国产乱码在线观看 | 欧美视频一区二 | 日韩综合视频在线观看 | 91精品国产91久久久久久三级 | 久久精品国产免费 | 色噜噜狠狠狠狠色综合久不 | 欧美一区二区精品在线 | 一区二区三区四区五区在线视频 | av导航福利 | 国外调教视频网站 | 夜夜骑天天操 | 日本婷婷色 | 草久电影 | 国产99在线免费 | 99在线观看免费视频精品观看 | 中文字幕一区二区三区四区久久 | 欧美91精品国产自产 | 毛片永久免费 | 黄色在线看网站 | 黄色www在线观看 | 久久综合五月天婷婷伊人 | 亚洲在线日韩 | 久久99网 | 91尤物在线播放 | 国产美女精品视频免费观看 | 91成人看片| 国产精品久久久久一区二区三区共 | 日韩欧美在线播放 | 亚洲精品456在线播放第一页 | 欧美一区二区在线看 | 成人在线一区二区三区 | 色a综合 | 国产第一福利 | 在线免费高清一区二区三区 | 久青草视频在线观看 | 欧美激情视频一区二区三区免费 | 日韩性xxx| 久久精品视频免费观看 | 九九视频这里只有精品 | 中文字幕在线观看网址 | 日日夜夜草 | 天天操天天干天天 | 五月天亚洲激情 | 久久久久一区二区三区 | 久久国产精品色婷婷 | av大片免费 | 五月天综合色激情 | 久久精彩| 97视频入口免费观看 | 日韩久久精品一区二区三区 | 一区二区三区精品在线视频 | 色com| 国产精品人人做人人爽人人添 | 97视频在线观看免费 | 亚洲一区网 | 福利在线看片 | 久久人91精品久久久久久不卡 | 91污视频在线观看 | 成人播放器| 天天干夜夜爽 | 91看片看淫黄大片 | 亚洲免费公开视频 | 日韩区欧美久久久无人区 | 狠狠躁18三区二区一区ai明星 | 狠狠干狠狠色 | 蜜桃视频日韩 | 国内精品在线一区 | 午夜男人影院 | 91精品国自产在线偷拍蜜桃 | 国产二区电影 | 久久久久亚洲国产精品 | 欧美日韩xxx | 国产1级视频 | 成人黄色小视频 | 国产 视频 久久 | 国产高清视频色在线www | 国产精品一区二区免费视频 | 婷婷在线免费观看 | 国产专区精品视频 | 国产精品久久久久久久av电影 | 久久综合色婷婷 | 欧美精品在线视频 | 麻豆免费在线播放 | 国产成人精品午夜在线播放 | 久久成人一区 | 91观看视频 | 开心激情五月婷婷 | 亚洲精品www久久久 www国产精品com | 超碰av在线| 日本丶国产丶欧美色综合 | 国内精品福利视频 | 亚州精品视频 | 色综合久久久久综合体 | 免费看麻豆 | 久久亚洲免费视频 | 国产精品久久久久久久久久ktv | 亚洲一区二区三区毛片 | 国产高清专区 | 欧美日韩在线精品一区二区 | 国产小视频在线 | 亚洲精品国产成人av在线 | 久久综合中文字幕 | 狠狠操综合网 | 97电影手机 | 国产精品国产三级国产aⅴ无密码 | 天天射天天射天天 | 91新人在线观看 | 国产一级黄色免费看 | 一级黄色a视频 | 91成人网在线播放 | 97人人艹 | 日韩欧美久久 | 日韩中文字幕免费电影 | 日本女人逼 | 日韩免费电影在线观看 | 国产97视频在线 | 中文字幕 国产视频 | 2019天天干天天色 | 国产美女在线精品免费观看 | 亚洲高清91 | 黄色影院在线免费观看 | www.久久免费视频 | 国产亚洲精品久久久久久无几年桃 | 久久天天躁狠狠躁夜夜不卡公司 | 99国产情侣在线播放 | 日韩美女一级片 | 久久xxxx| 天天搞天天干天天色 | 久久y | 久久综合成人网 | 国产亚洲人成网站在线观看 | 国产精品资源网 | 中文字幕在线视频网站 | 日韩女同一区二区三区在线观看 | 亚洲理论视频 | 欧美在线资源 | 人人射av| 亚洲国产精品久久久久久 | 四虎影视8848dvd | 日韩一区二区三区在线观看 | 亚洲国产无 | 久久午夜国产精品 | 日韩视频在线播放 | 一本大道久久精品懂色aⅴ 五月婷社区 | 在线观看亚洲成人 | 成人久久久久久久久 | 91九色网址 | 在线观看中文字幕网站 | 日本美女xx | 最新av在线播放 | 91成人短视频在线观看 | 久久精品播放 | 综合在线亚洲 | www国产亚洲精品 | 亚州中文av | 伊人永久在线 | 天天色综合三 | 国产在线观看国语版免费 | 久久久久一区二区三区 | 亚洲欧美日韩中文在线 | 久热色超碰 | 欧美午夜性 | 97超碰成人在线 | 日韩精品视频免费在线观看 | 日韩综合一区二区三区 | 日韩不卡高清 | 草草草影院| 91福利视频免费 | 6699私人影院 | 2022中文字幕在线观看 | 国产做aⅴ在线视频播放 | 日韩在线不卡视频 | 手机看片午夜 | 中文字幕在线观看第一页 | 日日操操 | 色综合久久88色综合天天人守婷 | 婷婷福利影院 | 黄a在线看 | 波多野结衣电影一区 | 欧美性爽爽 | 久久久久久久久久久网 | 亚洲天堂网视频在线观看 | 91精品久久久久久 | 国产热re99久久6国产精品 | 97超碰免费| 91在线精品秘密一区二区 | 免费三级黄 | 黄色三级免费网址 | 亚洲最新视频在线播放 | 欧美大码xxxx | 久久99久久99精品免观看粉嫩 | 久久夜视频 | 久久久久久久久精 | av先锋中文字幕 | 国产在线小视频 | 国产亚洲综合在线 | 欧美日韩久久久 | 日韩美在线观看 | 久草在线| 中文字幕丰满人伦在线 | 国产一区二区三区久久久 | 亚洲精品国偷拍自产在线观看 | 日韩毛片在线免费观看 | 一区二区免费不卡在线 | www.伊人色.com | 六月丁香激情综合色啪小说 | 夜夜操天天干 | 天天夜夜亚洲 | 亚洲欧美国产精品va在线观看 | 色综合天天视频在线观看 | 色丁香婷婷| 三级av在线免费观看 | 久久成人18免费网站 | 日韩欧美国产免费播放 | 黄色视屏在线免费观看 | 欧美黑人巨大xxxxx | 日韩精品视频免费在线观看 | 伊人久久国产精品 | 91激情在线视频 | 日韩大片免费在线观看 | 国产中文字幕视频 | 国产一区二区在线观看视频 | 亚洲九九影院 | 欧美一级特黄高清视频 | 国内精品久久久久久久影视简单 | 午夜国产在线 | 国产手机在线观看视频 | 欧美成人91 | 国产无遮挡猛进猛出免费软件 | 中文字幕在线观看不卡 | 天天操天天操天天操天天操天天操 | 97免费在线观看 | 狠狠色丁香婷婷综合久小说久 | 亚洲欧美日本A∨在线观看 青青河边草观看完整版高清 | 国产中文在线播放 | 91亚·色 | 日韩欧美精品免费 | 在线探花 | 中文字幕在线播放av | 欧美精品少妇xxxxx喷水 | 国产精品久久亚洲 | 日韩精品视频一二三 | 中文免费在线观看 | 在线观看视频免费播放 | 人人射人人射 | 夜色资源站wwwcom | 人人草在线视频 | 久久精品麻豆 | 日韩在线电影观看 | 丝袜av网站| 中文字幕在线久一本久 | 日韩网站在线免费观看 | 24小时日本在线www免费的 | 久久综合色8888 | 91香蕉国产 | 精品国产一区二区三区日日嗨 | 亚洲 综合 国产 精品 | 国产中文字幕视频在线观看 | 日韩中文免费视频 | 国产在线不卡精品 | 国产在线观看高清视频 | 一区二区av | 国产高清视频在线播放一区 | 亚洲伊人第一页 | 欧美激情综合五月色丁香小说 | 99热在线精品观看 | 免费在线观看一区 | av观看久久久 | 99精品欧美一区二区三区 | 粉嫩av一区二区三区入口 | 亚洲国产成人精品在线 | 日韩中文字幕在线看 | 日日天天av | 91成人黄色 | 成人高清av在线 | 日日夜夜免费精品 | 久久精品五月 | 91禁在线观看 | 黄色tv视频| 日日草视频 | 免费观看的黄色 | 色偷偷88888欧美精品久久久 | 中文字幕有码在线 | 91综合视频在线观看 | 丁香六月激情 | 国产精品 中文在线 | 人人澡人人爽 | 99久久久久成人国产免费 | 久色婷婷 | a级国产乱理论片在线观看 特级毛片在线观看 | 国产二区电影 | av电影免费| 日韩在线资源 | 久久国产午夜精品理论片最新版本 | 91亚瑟视频 | 手机av电影在线观看 | 午夜电影 电影 | 日韩中文字幕在线观看 | 美女视频a美女大全免费下载蜜臀 | 少妇bbbb | 日韩在线观看视频在线 | 精品成人a区在线观看 | 久久久不卡影院 | 欧美成人性网 | 96久久精品 | 国产高清日韩 | 密桃av在线| 欧美成人中文字幕 | 国产中文字幕视频在线 | 亚洲精品xx | 国产美女视频免费观看的网站 | 国产精品成人自产拍在线观看 | 中文字幕影片免费在线观看 | 亚洲美女视频在线观看 | 四虎成人精品永久免费av | 亚洲精品视频在 | 欧美色精品天天在线观看视频 | 中文字幕视频 | 色婷婷婷| 亚洲黄色大片 | 日韩成人高清在线 | 欧美日韩国产页 | 欧美日韩精品在线播放 | 特级西西444www大精品视频免费看 | 久久精品99北条麻妃 | 精品一区在线 | 久久久一本精品99久久精品66 | 91在线在线观看 | 亚洲丁香日韩 | 成人毛片在线观看视频 | 亚洲成av人影院 | 伊人宗合网 | 特级毛片爽www免费版 | 四虎海外影库www4hu | 91九色视频| 99re6热在线精品视频 | 久久免费av电影 | 夜夜躁日日躁狠狠久久av | 黄色成人影院 | 在线观看一区 | 成人国产精品久久久 | 91精品久久香蕉国产线看观看 | 最新日本中文字幕 | 91九色性视频 | 日本精品中文字幕 | 国产97色在线 | 日本韩国在线不卡 | 国产又黄又爽又猛视频日本 | av视屏在线播放 | 成人作爱视频 | 在线观看av网 | 日韩欧美高清免费 | 色婷婷www| 性色av免费在线观看 | 久久久久久久av麻豆果冻 | 久久国产精品成人免费浪潮 | 国产精品私人影院 | 久久成人精品视频 | 日本xxxxav | 亚洲国产中文字幕 | 国产成人在线观看 | 一区 在线观看 | 成人免费观看网址 | 在线观看电影av | 欧美欧美| 免费视频区 | 国产成人福利在线 | 在线观看mv的中文字幕网站 | 国产中文字幕视频在线观看 | 日韩一区二区免费在线观看 | 久久精品国产一区 | 黄色免费网站大全 | 国产女做a爱免费视频 | 天天操天天操天天操 | 亚洲国产视频a | 国产高清在线观看 | 国产一区二区三区免费在线观看 | 天天干夜夜擦 | 久久久精品网站 | 五月天六月色 | 久久爱资源网 | 日韩毛片在线播放 | 97国产大学生情侣酒店的特点 | 波多野结衣电影一区二区三区 | 97超碰人人在线 | 午夜久久久久久久久久影院 | 亚洲精品大全 | 操碰av| 狠狠干天天操 | 天天草天天草 | 91精品在线免费观看 | 精品一区二区av | 丁香婷婷激情五月 | 精品欧美日韩 | 五月天激情视频在线观看 | av电影免费在线看 | 韩国一区二区av | 国产无限资源在线观看 | 福利视频 | 国产91精品在线播放 | 国产精品成人一区二区 | 免费精品国产 | 亚洲 精品在线视频 | 500部大龄熟乱视频使用方法 | 三级av网站| 精品视频免费看 | 色婷婷视频在线观看 | 久久影视网 | 91av国产视频 | 天堂av在线 | 久久视频在线观看中文字幕 | 97福利在线观看 | 国产免费黄视频在线观看 | 中文字幕在线一区二区三区 | 国产精品国产三级国产aⅴ无密码 | 天天爽人人爽夜夜爽 | 久久99深爱久久99精品 | 亚洲四虎在线 | 国产最新视频在线观看 | 一级电影免费在线观看 | 中文字幕视频网站 | 99热国产在线 | 一本一道久久a久久精品蜜桃 | 中文字幕第一页在线 | 精品国产免费一区二区三区五区 | 草免费视频| 亚洲国产成人精品电影在线观看 | 91成人黄色 | 国产精品免费久久久久久久久久中文 | 国产999精品 | 日韩免费一级电影 | 五月婷婷六月丁香激情 | 成片视频免费观看 | 国产三级精品三级在线观看 | 成人亚洲精品国产www | 国产69精品久久久久99 | 国产精品专区在线 | 欧美一二在线 | 欧美少妇xx | 一级黄色视屏 | 亚洲激情中文 | 日韩美女黄色片 | 伊人资源站 | 欧美在线99 | 国产在线探花 | 国产小视频在线观看免费 | 玖玖999 | 一区二区三区动漫 | 五月天高清欧美mv | 国产在线成人 |