摘要:關于的一些總結一個小問題的思考起因當前項目中一直使用的都是,即這種用法考慮到確實有一定的局限性,在部分查詢中使用到了進行復雜查詢操作由于本人年也曾使用過,古語溫故而知新,所以做此總結梳理。
關于 Spring JdbcTemplate 的一些總結 一個小問題的思考 起因
當前項目中一直使用的都是 SpringData JPA ,即 public interface UserRepository extends JpaRepository
考慮到 SpringData JPA 確實有一定的局限性,在部分查詢中使用到了 JdbcTemplate 進行復雜查詢操作;
由于本人16年也曾使用過 JdbcTemplate,古語溫故而知新,所以做此總結梳理。
首先列出同事的做法:
public class xxx{ xxx method(){ ... List個人愚見list = jdbcTemplate.query(sql, new WishDTO()); ... } } @Data public class WishDTO implements RowMapper , Serializable { String xxx; Long xxx; Date xxx; BigDecimal xxx; @Override public WishDTO mapRow(ResultSet rs, int rowNum) { WishDTO dto = new WishDTO(); Field[] fields = dto.getClass().getDeclaredFields(); for (Field field : fields) { try { field.setAccessible(true); field.set(dto, rs.getObject(field.getName())); } catch (Exception e) { e.printStackTrace(); } } return dto; } }
個人感覺讓 WishDTO 再實現實現一遍 RowMapper 有點麻煩,畢竟 WishDTO 實體類的所有字段都是需要賦值的,并沒有定制化需求。
所以想著有沒有更好地寫法,然后就翻了一下 jdbcTemplate 的方法,找到了一個自認為滿足自己這個需求的方法:
publicList queryForList(String sql, Class elementType)
即 將代碼改為:
public class xxx{ xxx method(){ ... Listlist = jdbcTemplate.queryForList(sql, WishDTO.class); ... } } @Data public class WishDTO implements Serializable { String xxx; Long xxx; Date xxx; BigDecimal xxx; }
一切看起來都很完美,但執行卻報錯了:Incorrect column count: expected 1, actual 13
思考經過一番對源碼進行debug,結合網上的一些資料,大概知道了是什么原因了,分析如下;
publicList queryForList(String sql, Class elementType) throws DataAccessException { return query(sql, getSingleColumnRowMapper(elementType)); }
其本質是還是調用public
protectedRowMapper getSingleColumnRowMapper(Class requiredType) { return new SingleColumnRowMapper<>(requiredType); }
現在我們可以看一下 SingleColumnRowMapper 類的描述:
/** * {@link RowMapper} implementation that converts a single column into a single * result value per row. Expects to operate on a {@code java.sql.ResultSet} * that just contains a single column. * *The type of the result value for each row can be specified. The value * for the single column will be extracted from the {@code ResultSet} * and converted into the specified target type. */
其實從類名也可以看出,這是一個 RowMapper 的 簡單實現,且僅能接收一個字段的數據,如 String.class 和 Integer.class 等基礎類型;
網上的參考資料:https://blog.csdn.net/qq_4014...
解決方案使用 BeanPropertyRowMapper 進行封裝 ;
即 將代碼改為:
public class xxx{ xxx method(){ ... Listlist = jdbcTemplate.query(sql, new BeanPropertyRowMapper (WishDTO.class)); ... } } @Data public class WishDTO implements Serializable { String xxx; Long xxx; Date xxx; BigDecimal xxx; }
接下來看一下 BeanPropertyRowMapper 的類描述:
/** * {@link RowMapper} implementation that converts a row into a new instance * of the specified mapped target class. The mapped target class must be a * top-level class and it must have a default or no-arg constructor. * *Column values are mapped based on matching the column name as obtained from result set * meta-data to public setters for the corresponding properties. The names are matched either * directly or by transforming a name separating the parts with underscores to the same name * using "camel" case. * *
Mapping is provided for fields in the target class for many common types, e.g.: * String, boolean, Boolean, byte, Byte, short, Short, int, Integer, long, Long, * float, Float, double, Double, BigDecimal, {@code java.util.Date}, etc. * *
To facilitate mapping between columns and fields that don"t have matching names, * try using column aliases in the SQL statement like "select fname as first_name from customer". * *
For "null" values read from the database, we will attempt to call the setter, but in the case of * Java primitives, this causes a TypeMismatchException. This class can be configured (using the * primitivesDefaultedForNullValue property) to trap this exception and use the primitives default value. * Be aware that if you use the values from the generated bean to update the database the primitive value * will have been set to the primitive"s default value instead of null. * *
Please note that this class is designed to provide convenience rather than high performance. * For best performance, consider using a custom {@link RowMapper} implementation. */
其作用就是講一個Bean class 轉化成相對應的 Bean RowMapper 實現類。
JdbcTemplatehttps://docs.spring.io/spring...
Queryint rowCount = this.jdbcTemplate.queryForObject("select count(*) from t_actor", Integer.class); int countOfActorsNamedJoe = this.jdbcTemplate.queryForObject("select count(*) from t_actor where first_name = ?", Integer.class, "Joe"); String lastName = this.jdbcTemplate.queryForObject("select last_name from t_actor where id = ?", new Object[]{1212L}, String.class); Actor actor = this.jdbcTemplate.queryForObject( "select first_name, last_name from t_actor where id = ?", new Object[]{1212L}, new RowMapperUpdating (INSERT, UPDATE, and DELETE)() { public Actor mapRow(ResultSet rs, int rowNum) throws SQLException { Actor actor = new Actor(); actor.setFirstName(rs.getString("first_name")); actor.setLastName(rs.getString("last_name")); return actor; } }); List actors = this.jdbcTemplate.query( "select first_name, last_name from t_actor", new RowMapper () { public Actor mapRow(ResultSet rs, int rowNum) throws SQLException { Actor actor = new Actor(); actor.setFirstName(rs.getString("first_name")); actor.setLastName(rs.getString("last_name")); return actor; } }); --- public List findAllActors() { return this.jdbcTemplate.query( "select first_name, last_name from t_actor", new ActorMapper()); } private static final class ActorMapper implements RowMapper { public Actor mapRow(ResultSet rs, int rowNum) throws SQLException { Actor actor = new Actor(); actor.setFirstName(rs.getString("first_name")); actor.setLastName(rs.getString("last_name")); return actor; } }
this.jdbcTemplate.update( "insert into t_actor (first_name, last_name) values (?, ?)", "Leonor", "Watling"); this.jdbcTemplate.update( "update t_actor set last_name = ? where id = ?", "Banjo", 5276L); this.jdbcTemplate.update( "delete from actor where id = ?", Long.valueOf(actorId));Other
this.jdbcTemplate.execute("create table mytable (id integer, name varchar(100))");NamedParameterJdbcTemplate
https://docs.spring.io/spring...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/75400.html
摘要:更簡答的說就是要么全部執行成功,要么撤銷不執行。因此,數據庫操作的事務習慣上就稱為事務。實現原理單機事務事務是用對象控制的。接口提供了兩種事務模式自動提交和手工提交。事務多機事務,通過實現,需要驅動支持。局限于應用使用。 Spring Boot - 數據庫配置 回顧 Spring Boot - 初識 Hello World Spring Boot - Servlet、過濾器、監聽器、...
摘要:值得注意的是,默認會自動配置,它將優先采用連接池,如果沒有該依賴的情況則選取,如果前兩者都不可用最后選取。 SpringBoot 是為了簡化 Spring 應用的創建、運行、調試、部署等一系列問題而誕生的產物,自動裝配的特性讓我們可以更好的關注業務本身而不是外部的XML配置,我們只需遵循規范,引入相關的依賴就可以輕易的搭建出一個 WEB 工程 Spring Framework對數據...
摘要:時間年月日星期一說明本文部分內容均來自慕課網。慕課網教學示例源碼個人學習源碼第一章課程介紹課程介紹什么是主旨提供一個熟悉的一致的,基于框架的數據訪問框架。 時間:2017年04月24日星期一說明:本文部分內容均來自慕課網。@慕課網:http://www.imooc.com教學示例源碼:https://github.com/zccodere/s...個人學習源碼:https://gith...
摘要:環境依賴修改文件,添加依賴。使用為被標注的類去掉,允許被繼承。數據源方案一使用默認配置使用默認配置,不需要在創建和的。相關為了展現效果,我們先定義一組簡單的接口進行測試。 原文地址:梁桂釗的博客博客地址:http://blog.720ui.com 歡迎轉載,轉載請注明作者及出處,謝謝! 本文講解 Spring Boot2 基礎下,如何使用 Kotlin,并無縫整合與完美交融。為了讓讀...
摘要:地址提供了對的支持,能夠讓我們很方便對關系型數據庫做集成測試。如果想要在打包的時候跳過集成測試,只需要。例子使用因為使用了來做集成測試,得益于其機制,不需要自己構建和的。 Github地址 Spring Test Framework提供了對JDBC的支持,能夠讓我們很方便對關系型數據庫做集成測試。 同時Spring Boot提供了和Flyway的集成支持,能夠方便的管理開發過程中產生...
閱讀 809·2021-11-25 09:43
閱讀 1673·2021-09-29 09:42
閱讀 1893·2019-08-30 15:55
閱讀 3413·2019-08-30 15:54
閱讀 2618·2019-08-30 13:20
閱讀 3500·2019-08-29 13:25
閱讀 908·2019-08-28 18:03
閱讀 1778·2019-08-26 13:44