成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

關(guān)于 Spring JdbcTemplate 的一些總結(jié)

Pikachu / 612人閱讀

摘要:關(guān)于的一些總結(jié)一個(gè)小問(wèn)題的思考起因當(dāng)前項(xiàng)目中一直使用的都是,即這種用法考慮到確實(shí)有一定的局限性,在部分查詢中使用到了進(jìn)行復(fù)雜查詢操作由于本人年也曾使用過(guò),古語(yǔ)溫故而知新,所以做此總結(jié)梳理。

關(guān)于 Spring JdbcTemplate 的一些總結(jié) 一個(gè)小問(wèn)題的思考 起因

當(dāng)前項(xiàng)目中一直使用的都是 SpringData JPA ,即 public interface UserRepository extends JpaRepository 這種用法;

考慮到 SpringData JPA 確實(shí)有一定的局限性,在部分查詢中使用到了 JdbcTemplate 進(jìn)行復(fù)雜查詢操作;
由于本人16年也曾使用過(guò) JdbcTemplate,古語(yǔ)溫故而知新,所以做此總結(jié)梳理。

首先列出同事的做法:

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;
    }

}
個(gè)人愚見(jiàn)

個(gè)人感覺(jué)讓 WishDTO 再實(shí)現(xiàn)實(shí)現(xiàn)一遍 RowMapper 有點(diǎn)麻煩,畢竟 WishDTO 實(shí)體類的所有字段都是需要賦值的,并沒(méi)有定制化需求。

所以想著有沒(méi)有更好地寫(xiě)法,然后就翻了一下 jdbcTemplate 的方法,找到了一個(gè)自認(rèn)為滿足自己這個(gè)需求的方法:

public  List queryForList(String sql, Class elementType)
即 將代碼改為:
public class xxx{

    xxx method(){
        ...
        List list = jdbcTemplate.queryForList(sql, WishDTO.class);
        ...
    }
}

@Data
public class WishDTO implements Serializable {
    String xxx;
    Long xxx;
    Date xxx;
    BigDecimal xxx;
}

一切看起來(lái)都很完美,但執(zhí)行卻報(bào)錯(cuò)了:Incorrect column count: expected 1, actual 13

思考

經(jīng)過(guò)一番對(duì)源碼進(jìn)行debug,結(jié)合網(wǎng)上的一些資料,大概知道了是什么原因了,分析如下;

    public  List queryForList(String sql, Class elementType) throws DataAccessException {
        return query(sql, getSingleColumnRowMapper(elementType));
    }

其本質(zhì)是還是調(diào)用public List query(String sql, RowMapper rowMapper) ,只是將 Class elementType 封裝成一個(gè) RowMapper 實(shí)現(xiàn)實(shí)例;

    protected  RowMapper getSingleColumnRowMapper(Class requiredType) {
        return new SingleColumnRowMapper<>(requiredType);
    }

現(xiàn)在我們可以看一下 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. */

其實(shí)從類名也可以看出,這是一個(gè) RowMapper 的 簡(jiǎn)單實(shí)現(xiàn),且僅能接收一個(gè)字段的數(shù)據(jù),如 String.class 和 Integer.class 等基礎(chǔ)類型;

網(wǎng)上的參考資料:https://blog.csdn.net/qq_4014...

解決方案

使用 BeanPropertyRowMapper 進(jìn)行封裝 ;
即 將代碼改為:

public class xxx{

    xxx method(){
        ...
        List list = jdbcTemplate.query(sql, new BeanPropertyRowMapper(WishDTO.class));
        ...
    }
}

@Data
public class WishDTO implements Serializable {
    String xxx;
    Long xxx;
    Date xxx;
    BigDecimal xxx;
}

接下來(lái)看一下 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. */

其作用就是講一個(gè)Bean class 轉(zhuǎn)化成相對(duì)應(yīng)的 Bean RowMapper 實(shí)現(xiàn)類。

JdbcTemplate

https://docs.spring.io/spring...

Query
int 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 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;
            }
        });

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;
    }
}
Updating (INSERT, UPDATE, and DELETE)
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...

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/75400.html

相關(guān)文章

  • Spring Boot - 整合JdbcTemplate、MyBatis

    摘要:更簡(jiǎn)答的說(shuō)就是要么全部執(zhí)行成功,要么撤銷(xiāo)不執(zhí)行。因此,數(shù)據(jù)庫(kù)操作的事務(wù)習(xí)慣上就稱為事務(wù)。實(shí)現(xiàn)原理單機(jī)事務(wù)事務(wù)是用對(duì)象控制的。接口提供了兩種事務(wù)模式自動(dòng)提交和手工提交。事務(wù)多機(jī)事務(wù),通過(guò)實(shí)現(xiàn),需要驅(qū)動(dòng)支持。局限于應(yīng)用使用。 Spring Boot - 數(shù)據(jù)庫(kù)配置 回顧 Spring Boot - 初識(shí) Hello World Spring Boot - Servlet、過(guò)濾器、監(jiān)聽(tīng)器、...

    Keagan 評(píng)論0 收藏0
  • 一起來(lái)學(xué)SpringBoot | 第五篇:使用JdbcTemplate訪問(wèn)數(shù)據(jù)庫(kù)

    摘要:值得注意的是,默認(rèn)會(huì)自動(dòng)配置,它將優(yōu)先采用連接池,如果沒(méi)有該依賴的情況則選取,如果前兩者都不可用最后選取。 SpringBoot 是為了簡(jiǎn)化 Spring 應(yīng)用的創(chuàng)建、運(yùn)行、調(diào)試、部署等一系列問(wèn)題而誕生的產(chǎn)物,自動(dòng)裝配的特性讓我們可以更好的關(guān)注業(yè)務(wù)本身而不是外部的XML配置,我們只需遵循規(guī)范,引入相關(guān)的依賴就可以輕易的搭建出一個(gè) WEB 工程 Spring Framework對(duì)數(shù)據(jù)...

    ssshooter 評(píng)論0 收藏0
  • 慕課網(wǎng)_《輕松愉快之玩轉(zhuǎn)SpringData》學(xué)習(xí)總結(jié)

    摘要:時(shí)間年月日星期一說(shuō)明本文部分內(nèi)容均來(lái)自慕課網(wǎng)。慕課網(wǎng)教學(xué)示例源碼個(gè)人學(xué)習(xí)源碼第一章課程介紹課程介紹什么是主旨提供一個(gè)熟悉的一致的,基于框架的數(shù)據(jù)訪問(wèn)框架。 時(shí)間:2017年04月24日星期一說(shuō)明:本文部分內(nèi)容均來(lái)自慕課網(wǎng)。@慕課網(wǎng):http://www.imooc.com教學(xué)示例源碼:https://github.com/zccodere/s...個(gè)人學(xué)習(xí)源碼:https://gith...

    skinner 評(píng)論0 收藏0
  • SpringBoot 與 Kotlin 完美交融

    摘要:環(huán)境依賴修改文件,添加依賴。使用為被標(biāo)注的類去掉,允許被繼承。數(shù)據(jù)源方案一使用默認(rèn)配置使用默認(rèn)配置,不需要在創(chuàng)建和的。相關(guān)為了展現(xiàn)效果,我們先定義一組簡(jiǎn)單的接口進(jìn)行測(cè)試。 原文地址:梁桂釗的博客博客地址:http://blog.720ui.com 歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明作者及出處,謝謝! 本文講解 Spring Boot2 基礎(chǔ)下,如何使用 Kotlin,并無(wú)縫整合與完美交融。為了讓讀...

    golden_hamster 評(píng)論0 收藏0
  • Spring、Spring Boot和TestNG測(cè)試指南 - 測(cè)試關(guān)系型數(shù)據(jù)庫(kù)

    摘要:地址提供了對(duì)的支持,能夠讓我們很方便對(duì)關(guān)系型數(shù)據(jù)庫(kù)做集成測(cè)試。如果想要在打包的時(shí)候跳過(guò)集成測(cè)試,只需要。例子使用因?yàn)槭褂昧藖?lái)做集成測(cè)試,得益于其機(jī)制,不需要自己構(gòu)建和的。 Github地址 Spring Test Framework提供了對(duì)JDBC的支持,能夠讓我們很方便對(duì)關(guān)系型數(shù)據(jù)庫(kù)做集成測(cè)試。 同時(shí)Spring Boot提供了和Flyway的集成支持,能夠方便的管理開(kāi)發(fā)過(guò)程中產(chǎn)生...

    Meils 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<