国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
07 | 數(shù)據(jù)訪問:如何使用 JdbcTemplate 訪問關(guān)系型數(shù)據(jù)庫(kù)?

06 講我們?cè)敿?xì)介紹了 JDBC 規(guī)范的相關(guān)內(nèi)容,JDBC 規(guī)范是 Java 領(lǐng)域中使用最廣泛的數(shù)據(jù)訪問標(biāo)準(zhǔn),目前市面上主流的數(shù)據(jù)訪問框架都是構(gòu)建在 JDBC 規(guī)范之上。

因?yàn)?JDBC 是偏底層的操作規(guī)范,所以關(guān)于如何使用 JDBC 規(guī)范進(jìn)行關(guān)系型數(shù)據(jù)訪問的實(shí)現(xiàn)方式有很多(區(qū)別在于對(duì) JDBC 規(guī)范的封裝程度不同),而在 Spring 中,同樣提供了 JdbcTemplate 模板工具類實(shí)現(xiàn)數(shù)據(jù)訪問,它簡(jiǎn)化了 JDBC 規(guī)范的使用方法,今天我們將圍繞這個(gè)模板類展開討論。

數(shù)據(jù)模型和 Repository 層設(shè)計(jì)

引入 JdbcTemplate 模板工具類之前,我們回到 SpringCSS 案例,先給出 order-service 中的數(shù)據(jù)模型為本講內(nèi)容的展開做一些鋪墊。

我們知道一個(gè)訂單中往往涉及一個(gè)或多個(gè)商品,所以在本案例中,我們主要通過一對(duì)多的關(guān)系來展示數(shù)據(jù)庫(kù)設(shè)計(jì)和實(shí)現(xiàn)方面的技巧。而為了使描述更簡(jiǎn)單,我們把具體的業(yè)務(wù)字段做了簡(jiǎn)化。Order 類的定義如下代碼所示:

復(fù)制代碼
  1. public class Order{
  2.     private Long id; //訂單Id
  3.     private String orderNumber; //訂單編號(hào)
  4.     private String deliveryAddress; //物流地址
  5.     private List<Goods> goodsList;  //商品列表
  6.     //省略了 getter/setter
  7. }

其中代表商品的 Goods 類定義如下:

復(fù)制代碼
  1. public class Goods {
  2.     private Long id; //商品Id
  3.     private String goodsCode; //商品編號(hào)
  4.     private String goodsName; //商品名稱
  5.     private Double price; //商品價(jià)格
  6.     //省略了 getter/setter
  7. }

從以上代碼,我們不難看出一個(gè)訂單可以包含多個(gè)商品,因此設(shè)計(jì)關(guān)系型數(shù)據(jù)庫(kù)表時(shí),我們首先會(huì)構(gòu)建一個(gè)中間表來保存 Order 和 Goods 這層一對(duì)多關(guān)系。在本課程中,我們使用 MySQL 作為關(guān)系型數(shù)據(jù)庫(kù),對(duì)應(yīng)的數(shù)據(jù)庫(kù) Schema 定義如下代碼所示:

復(fù)制代碼
  1. DROP TABLE IF EXISTS `order`;
  2. DROP TABLE IF EXISTS `goods`;
  3. DROP TABLE IF EXISTS `order_goods`;
  4. create table `order` (
  5.     `id` bigint(20) NOT NULL AUTO_INCREMENT,
  6.     `order_number` varchar(50) not null,
  7.     `delivery_address` varchar(100) not null,
  8.   `create_time` timestamp not null DEFAULT CURRENT_TIMESTAMP,
  9.     PRIMARY KEY (`id`)
  10. );
  11. create table `goods` (
  12.   `id` bigint(20) NOT NULL AUTO_INCREMENT,
  13.   `goods_code` varchar(50) not null,
  14.   `goods_name` varchar(50) not null,
  15.   `goods_price` double not null,
  16.   `create_time` timestamp not null DEFAULT CURRENT_TIMESTAMP,
  17.     PRIMARY KEY (`id`)
  18. );
  19. create table `order_goods` (
  20.     `order_id` bigint(20) not null,
  21.     `goods_id` bigint(20) not null,
  22.     foreign key(`order_id`) references `order`(`id`),
  23.     foreign key(`goods_id`) references `goods`(`id`)
  24. );

基于以上數(shù)據(jù)模型,我們將完成 order-server 中的 Repository 層組件的設(shè)計(jì)和實(shí)現(xiàn)。首先,我們需要設(shè)計(jì)一個(gè) OrderRepository 接口,用來抽象數(shù)據(jù)庫(kù)訪問的入口,如下代碼所示:

復(fù)制代碼
  1. public interface OrderRepository {
  2.     Order addOrder(Order order);
  3.     Order getOrderById(Long orderId);
  4.     Order getOrderDetailByOrderNumber(String orderNumber);
  5. }

這個(gè)接口非常簡(jiǎn)單,方法都是自解釋的。不過請(qǐng)注意,這里的 OrderRepository 并沒有繼承任何父接口,完全是一個(gè)自定義的、獨(dú)立的 Repository。

針對(duì)上述 OrderRepository 中的接口定義,我們將構(gòu)建一系列的實(shí)現(xiàn)類。

  • OrderRawJdbcRepository:使用原生 JDBC 進(jìn)行數(shù)據(jù)庫(kù)訪問

  • OrderJdbcRepository:使用 JdbcTemplate 進(jìn)行數(shù)據(jù)庫(kù)訪問

  • OrderJpaRepository:使用 Spring Data JPA 進(jìn)行數(shù)據(jù)庫(kù)訪問

上述實(shí)現(xiàn)類中的 OrderJpaRepository 我們會(huì)放到 10 講《ORM 集成:如何使用 Spring Data JPA 訪問關(guān)系型數(shù)據(jù)庫(kù)?》中進(jìn)行展開,而 OrderRawJdbcRepository 最基礎(chǔ),不是本課程的重點(diǎn),因此 07 講我們只針對(duì) OrderRepository 中 getOrderById 方法的實(shí)現(xiàn)過程重點(diǎn)介紹,也算是對(duì) 06 講的回顧和擴(kuò)展。

OrderRawJdbcRepository 類中實(shí)現(xiàn)方法如下代碼所示:

復(fù)制代碼
  1. @Repository("orderRawJdbcRepository")
  2. public class OrderRawJdbcRepository implements OrderRepository {
  3.     @Autowired
  4.     private DataSource dataSource;
  5.     @Override
  6.     public Order getOrderById(Long orderId) {
  7.         Connection connection = null;
  8.         PreparedStatement statement = null;
  9.         ResultSet resultSet = null;
  10.         try {
  11.             connection = dataSource.getConnection();
  12.             statement = connection.prepareStatement("select id, order_number, delivery_address from `order` where id=?");
  13.             statement.setLong(1, orderId);
  14.             resultSet = statement.executeQuery();
  15.             Order order = null;
  16.             if (resultSet.next()) {
  17.                 order = new Order(resultSet.getLong("id"), resultSet.getString("order_number"),
  18.                         resultSet.getString("delivery_address"));
  19.             }
  20.             return order;
  21.         } catch (SQLException e) {
  22.             System.out.print(e);
  23.         } finally {
  24.             if (resultSet != null) {
  25.                 try {
  26.                     resultSet.close();
  27.                 } catch (SQLException e) {
  28.                 }
  29.             }
  30.             if (statement != null) {
  31.                 try {
  32.                     statement.close();
  33.                 } catch (SQLException e) {
  34.                 }
  35.             }
  36.             if (connection != null) {
  37.                 try {
  38.                     connection.close();
  39.                 } catch (SQLException e) {
  40.                 }
  41.             }
  42.         }
  43.         return null;
  44.     }
  45.     //省略其他 OrderRepository 接口方法實(shí)現(xiàn)
  46. }

這里,值得注意的是,我們首先需要在類定義上添加 @Repository 注解,標(biāo)明這是能夠被 Spring 容器自動(dòng)掃描的 Javabean,再在 @Repository 注解中指定這個(gè) Javabean 的名稱為"orderRawJdbcRepository",方便 Service 層中根據(jù)該名稱注入 OrderRawJdbcRepository 類。

可以看到,上述代碼使用了 JDBC 原生 DataSource、Connection、PreparedStatement、ResultSet 等核心編程對(duì)象完成針對(duì)“order”表的一次查詢。代碼流程看起來比較簡(jiǎn)單,其實(shí)也比較煩瑣,學(xué)到這里,我們可以結(jié)合上一課時(shí)的內(nèi)容理解上述代碼。

請(qǐng)注意,如果我們想運(yùn)行這些代碼,千萬別忘了在 Spring Boot 的配置文件中添加對(duì) DataSource 的定義,如下代碼所示:

復(fù)制代碼
  1. spring:
  2.   datasource:
  3.     driver-class-name: com.mysql.cj.jdbc.Driver
  4.     url: jdbc:mysql://127.0.0.1:3306/appointment
  5.     username: root
  6.     password: root

回顧完原生 JDBC 的使用方法,接下來就引出今天的重點(diǎn),即 JdbcTemplate 模板工具類,我們來看看它如何簡(jiǎn)化數(shù)據(jù)訪問操作。

使用 JdbcTemplate 操作數(shù)據(jù)庫(kù)

要想在應(yīng)用程序中使用 JdbcTemplate,首先我們需要引入對(duì)它的依賴,如下代碼所示:

復(fù)制代碼
  1. <dependency>
  2.     <groupId>org.springframework.boot</groupId>
  3.     <artifactId>spring-boot-starter-jdbc</artifactId>
  4. </dependency>

JdbcTemplate 提供了一系列的 query、update、execute 重載方法應(yīng)對(duì)數(shù)據(jù)的 CRUD 操作。

使用 JdbcTemplate 實(shí)現(xiàn)查詢

基于 SpringCSS 案例,我們先來討論一下最簡(jiǎn)單的查詢操作,并對(duì) OrderRawJdbcRepository 中的 getOrderById 方法進(jìn)行重構(gòu)。為此,我們構(gòu)建了一個(gè)新的 OrderJdbcRepository 類并同樣實(shí)現(xiàn)了 OrderRepository 接口,如下代碼所示:

復(fù)制代碼
  1. @Repository("orderJdbcRepository")
  2. public class OrderJdbcRepository implements OrderRepository {
  3.     private JdbcTemplate jdbcTemplate;
  4.     @Autowired
  5.     public OrderJdbcRepository(JdbcTemplate jdbcTemplate) {
  6.         this.jdbcTemplate = jdbcTemplate;
  7. }
  8. }

可以看到,這里通過構(gòu)造函數(shù)注入了 JdbcTemplate 模板類。

而 OrderJdbcRepository 的 getOrderById 方法實(shí)現(xiàn)過程如下代碼所示:

復(fù)制代碼
  1. @Override
  2. public Order getOrderById(Long orderId) {
  3.         Order order = jdbcTemplate.queryForObject("select id, order_number, delivery_address from `order` where id=?",
  4.                 this::mapRowToOrder, orderId);
  5.         return order;
  6. }

顯然,這里使用了 JdbcTemplate 的 queryForObject 方法執(zhí)行查詢操作,該方法傳入目標(biāo) SQL、參數(shù)以及一個(gè) RowMapper 對(duì)象。其中 RowMapper 定義如下:

復(fù)制代碼
  1. public interface RowMapper<T> {
  2.     T mapRow(ResultSet rs, int rowNum) throws SQLException;
  3. }

從 mapRow 方法定義中,我們不難看出 RowMapper 的作用就是處理來自 ResultSet 中的每一行數(shù)據(jù),并將來自數(shù)據(jù)庫(kù)中的數(shù)據(jù)映射成領(lǐng)域?qū)ο?。例如,使?getOrderById 中用到的 mapRowToOrder 方法完成對(duì) Order 對(duì)象的映射,如下代碼所示:

復(fù)制代碼
  1. private Order mapRowToOrder(ResultSet rs, int rowNum) throws SQLException {
  2.         return new Order(rs.getLong("id"), rs.getString("order_number"), rs.getString("delivery_address"));
  3. }

講到這里,你可能注意到 getOrderById 方法實(shí)際上只是獲取了 Order 對(duì)象中的訂單部分信息,并不包含商品數(shù)據(jù)。

接下來,我們?cè)賮碓O(shè)計(jì)一個(gè) getOrderDetailByOrderNumber 方法,根據(jù)訂單編號(hào)獲取訂單以及訂單中所包含的所有商品信息,如下代碼所示:

復(fù)制代碼
  1. @Override
  2. public Order getOrderDetailByOrderNumber(String orderNumber) {
  3.         //獲取 Order 基礎(chǔ)信息
  4.         Order order = jdbcTemplate.queryForObject(
  5.                 "select id, order_number, delivery_address from `order` where order_number=?", this::mapRowToOrder,
  6.                 orderNumber);
  7.         if (order == null)
  8.             return order;
  9.         //獲取 Order 與 Goods 之間的關(guān)聯(lián)關(guān)系,找到給 Order 中的所有 GoodsId
  10.         Long orderId = order.getId();
  11.         List<Long> goodsIds = jdbcTemplate.query("select order_id, goods_id from order_goods where order_id=?",
  12.                 new ResultSetExtractor<List<Long>>() {
  13.                     public List<Long> extractData(ResultSet rs) throws SQLException, DataAccessException {
  14.                         List<Long> list = new ArrayList<Long>();
  15.                         while (rs.next()) {
  16.                             list.add(rs.getLong("goods_id"));
  17.                         }
  18.                         return list;
  19.                     }
  20.                 }, orderId);
  21.         //根據(jù) GoodsId 分別獲取 Goods 信息并填充到 Order 對(duì)象中
  22.         for (Long goodsId : goodsIds) {
  23.             Goods goods = getGoodsById(goodsId);
  24.             order.addGoods(goods);
  25.         }
  26.         return order;
  27. }

上述代碼有點(diǎn)復(fù)雜,我們分成幾個(gè)部分來講解。

首先,我們獲取 Order 基礎(chǔ)信息,并通過 Order 中的 Id 編號(hào)從中間表中獲取所有 Goods 的 Id 列表,通過遍歷這個(gè) Id 列表再分別獲取 Goods 信息,最后將 Goods 信息填充到 Order 中,從而構(gòu)建一個(gè)完整的 Order 對(duì)象。

這里通過 Id 獲取 Goods 數(shù)據(jù)的實(shí)現(xiàn)方法也與 getOrderById 方法的實(shí)現(xiàn)過程一樣,如下代碼所示:

復(fù)制代碼
  1. private Goods getGoodsById(Long goodsId) {
  2.         return jdbcTemplate.queryForObject("select id, goods_code, goods_name, price from goods where id=?",
  3.                 this::mapRowToGoods, goodsId);
  4. }
  5. private Goods mapRowToGoods(ResultSet rs, int rowNum) throws SQLException {
  6.         return new Goods(rs.getLong("id"), rs.getString("goods_code"), rs.getString("goods_name"),
  7.                 rs.getDouble("price"));
  8. }

使用 JdbcTemplate 實(shí)現(xiàn)插入

在 JdbcTemplate 中,我們可以通過 update 方法實(shí)現(xiàn)數(shù)據(jù)的插入和更新。針對(duì) Order 和 Goods 中的關(guān)聯(lián)關(guān)系,插入一個(gè) Order 對(duì)象需要同時(shí)完成兩張表的更新,即 order 表和 order_goods 表,因此插入 Order 的實(shí)現(xiàn)過程也分成兩個(gè)階段,如下代碼所示的 addOrderWithJdbcTemplate 方法展示了這一過程:

復(fù)制代碼
  1. private Order addOrderDetailWithJdbcTemplate(Order order) {
  2.         //插入 Order 基礎(chǔ)信息
  3.         Long orderId = saveOrderWithJdbcTemplate(order);
  4.         order.setId(orderId);
  5.         //插入 Order 與 Goods 的對(duì)應(yīng)關(guān)系
  6.         List<Goods> goodsList = order.getGoods();
  7.         for (Goods goods : goodsList) {
  8.             saveGoodsToOrderWithJdbcTemplate(goods, orderId);
  9.         }
  10.         return order;
  11. }

可以看到,這里同樣先是插入 Order 的基礎(chǔ)信息,然后再遍歷 Order 中的 Goods 列表并逐條進(jìn)行插入。其中的 saveOrderWithJdbcTemplate 方法如下代碼所示:

復(fù)制代碼
  1. private Long saveOrderWithJdbcTemplate(Order order) {
  2.         PreparedStatementCreator psc = new PreparedStatementCreator() {
  3.             @Override
  4.             public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
  5.                 PreparedStatement ps = con.prepareStatement(
  6.                         "insert into `order` (order_number, delivery_address) values (?, ?)",
  7.                         Statement.RETURN_GENERATED_KEYS);
  8.                 ps.setString(1, order.getOrderNumber());
  9.                 ps.setString(2, order.getDeliveryAddress());
  10.                 return ps;
  11.             }
  12.         };
  13.         KeyHolder keyHolder = new GeneratedKeyHolder();
  14.         jdbcTemplate.update(psc, keyHolder);
  15.         return keyHolder.getKey().longValue();
  16. }

上述 saveOrderWithJdbcTemplate 的方法比想象中要復(fù)雜,主要原因在于我們需要在插入 order 表的同時(shí)返回?cái)?shù)據(jù)庫(kù)中所生成的自增主鍵,因此,這里使用了 PreparedStatementCreator 工具類封裝 PreparedStatement 對(duì)象的構(gòu)建過程,并在 PreparedStatement 的創(chuàng)建過程中設(shè)置了 Statement.RETURN_GENERATED_KEYS 用于返回自增主鍵。然后我們構(gòu)建了一個(gè) GeneratedKeyHolder 對(duì)象用于保存所返回的自增主鍵。這是使用 JdbcTemplate 實(shí)現(xiàn)帶有自增主鍵數(shù)據(jù)插入的一種標(biāo)準(zhǔn)做法,你可以參考這一做法并應(yīng)用到日常開發(fā)過程中。

至于用于插入 Order 與 Goods 關(guān)聯(lián)關(guān)系的 saveGoodsToOrderWithJdbcTemplate 方法就比較簡(jiǎn)單了,直接調(diào)用 JdbcTemplate 的 update 方法插入數(shù)據(jù)即可,如下代碼所示:

復(fù)制代碼
  1. private void saveGoodsToOrderWithJdbcTemplate(Goods goods, long orderId) {
  2.         jdbcTemplate.update("insert into order_goods (order_id, goods_id) " + "values (?, ?)", orderId, goods.getId());
  3. }

接下來,我們需要實(shí)現(xiàn)插入 Order 的整個(gè)流程,先實(shí)現(xiàn) Service 類和 Controller 類,如下代碼所示:

復(fù)制代碼
  1. @Service
  2. public class OrderService {
  3.     @Autowired
  4.     @Qualifier("orderJdbcRepository")
  5.     private OrderRepository orderRepository;
  6.     public Order addOrder(Order order) {
  7.         return orderRepository.addOrder(order);
  8.     }
  9. }
  10. @RestController
  11. @RequestMapping(value="orders")
  12. public class OrderController {
  13.     @RequestMapping(value = "", method = RequestMethod.POST)
  14.     public Order addOrder(@RequestBody Order order) {
  15.         Order result = orderService.addOrder(order);
  16.     return result;
  17.     }
  18. }

這兩個(gè)類都是直接對(duì) orderJdbcRepository 中的方法進(jìn)行封裝調(diào)用,操作非常簡(jiǎn)單。然后,我們打開 Postman,并在請(qǐng)求消息體中輸入如下內(nèi)容:

復(fù)制代碼
  1. {
  2.     "orderNumber" : "Order10002",
  3.     "deliveryAddress" : "test_address2",
  4.     "goods": [
  5.         {
  6.             "id": 1,
  7.             "goodsCode": "GoodsCode1",
  8.             "goodsName": "GoodsName1",
  9.             "price": 100.0
  10.         }
  11.     ]
  12. }

通過 Postman 向http://localhost:8081/orders端點(diǎn)發(fā)起 Post 請(qǐng)求后,我們發(fā)現(xiàn) order 表和 order_goods 表中的數(shù)據(jù)都已經(jīng)正常插入。

使用 SimpleJdbcInsert 簡(jiǎn)化數(shù)據(jù)插入過程

雖然通過 JdbcTemplate 的 update 方法可以完成數(shù)據(jù)的正確插入,我們不禁發(fā)現(xiàn)這個(gè)實(shí)現(xiàn)過程還是比較復(fù)雜,尤其是涉及自增主鍵的處理時(shí),代碼顯得有點(diǎn)臃腫。那么有沒有更加簡(jiǎn)單的實(shí)現(xiàn)方法呢?

答案是肯定的,Spring Boot 針對(duì)數(shù)據(jù)插入場(chǎng)景專門提供了一個(gè) SimpleJdbcInsert 工具類,SimpleJdbcInsert 本質(zhì)上是在 JdbcTemplate 的基礎(chǔ)上添加了一層封裝,提供了一組 execute、executeAndReturnKey 以及 executeBatch 重載方法來簡(jiǎn)化數(shù)據(jù)插入操作。

通常,我們可以在 Repository 實(shí)現(xiàn)類的構(gòu)造函數(shù)中對(duì) SimpleJdbcInsert 進(jìn)行初始化,如下代碼所示:

復(fù)制代碼
  1. private JdbcTemplate jdbcTemplate;
  2. private SimpleJdbcInsert orderInserter;
  3. private SimpleJdbcInsert orderGoodsInserter;
  4. public OrderJdbcRepository(JdbcTemplate jdbcTemplate) {
  5.         this.jdbcTemplate = jdbcTemplate;
  6.         this.orderInserter = new SimpleJdbcInsert(jdbcTemplate).withTableName("`order`").usingGeneratedKeyColumns("id");
  7.         this.orderGoodsInserter = new SimpleJdbcInsert(jdbcTemplate).withTableName("order_goods");
  8. }

可以看到,這里首先注入了一個(gè) JdbcTemplate 對(duì)象,然后我們基于 JdbcTemplate 并針對(duì) order 表和 order_goods 表分別初始化了兩個(gè) SimpleJdbcInsert 對(duì)象 orderInserter 和 orderGoodsInserter。其中 orderInserter 中還使用了 usingGeneratedKeyColumns 方法設(shè)置自增主鍵列。

基于 SimpleJdbcInsert,完成 Order 對(duì)象的插入就非常簡(jiǎn)單了,實(shí)現(xiàn)方式如下所示:

復(fù)制代碼
  1. private Long saveOrderWithSimpleJdbcInsert(Order order) {
  2.         Map<String, Object> values = new HashMap<String, Object>();
  3.         values.put("order_number", order.getOrderNumber());
  4.         values.put("delivery_address", order.getDeliveryAddress());
  5.         Long orderId = orderInserter.executeAndReturnKey(values).longValue();
  6.         return orderId;
  7. }

我們通過構(gòu)建一個(gè) Map 對(duì)象,然后把需要添加的字段設(shè)置成一個(gè)個(gè)鍵值對(duì)。通過SimpleJdbcInsert 的 executeAndReturnKey 方法在插入數(shù)據(jù)的同時(shí)直接返回自增主鍵。同樣,完成 order_goods 表的操作只需要幾行代碼就可以了,如下代碼所示:

復(fù)制代碼
  1. private void saveGoodsToOrderWithSimpleJdbcInsert(Goods goods, long orderId) {
  2.         Map<String, Object> values = new HashMap<>();
  3.         values.put("order_id", orderId);
  4.         values.put("goods_id", goods.getId());
  5.         orderGoodsInserter.execute(values);
  6. }

這里用到了 SimpleJdbcInsert 提供的 execute 方法,我們可以把這些方法組合起來對(duì) addOrderDetailWithJdbcTemplate 方法進(jìn)行重構(gòu),從而得到如下所示的 addOrderDetailWithSimpleJdbcInsert 方法:

復(fù)制代碼
  1. private Order addOrderDetailWithSimpleJdbcInsert(Order order) {
  2.         //插入 Order 基礎(chǔ)信息
  3.         Long orderId = saveOrderWithSimpleJdbcInsert(order);
  4.         order.setId(orderId);
  5.         //插入 Order 與 Goods 的對(duì)應(yīng)關(guān)系
  6.         List<Goods> goodsList = order.getGoods();
  7.         for (Goods goods : goodsList) {
  8.             saveGoodsToOrderWithSimpleJdbcInsert(goods, orderId);
  9.         }
  10.         return order;
  11. }

詳細(xì)的代碼清單可以參考課程的案例代碼,你也可以基于 Postman 對(duì)重構(gòu)后的代碼進(jìn)行嘗試。

小結(jié)與預(yù)告

JdbcTemplate 模板工具類是一個(gè)基于 JDBC 規(guī)范實(shí)現(xiàn)數(shù)據(jù)訪問的強(qiáng)大工具,是一個(gè)優(yōu)秀的工具類。它對(duì)常見的 CRUD 操作做了封裝并提供了一大批簡(jiǎn)化的 API。今天我們分別針對(duì)查詢和插入這兩大類數(shù)據(jù)操作給出了基于 JdbcTemplate 的實(shí)現(xiàn)方案,特別是針對(duì)插入場(chǎng)景,我們還引入了基于 JdbcTemplate 所構(gòu)建的 SimpleJdbcInsert 簡(jiǎn)化這一操作。

這里給你留一道思考題:在使用 JdbcTemplate 時(shí),如果想要返回?cái)?shù)據(jù)庫(kù)的自增主鍵值有哪些實(shí)現(xiàn)方法?

在 Spring 中存在一組以 -Template 結(jié)尾的模板工具類,這些類都是模板方法這一設(shè)計(jì)模式的典型應(yīng)用,同時(shí)還充分利用了回調(diào)機(jī)制完成解耦和擴(kuò)展。在 08 講中,我們將對(duì) JdbcTemplate 的具體實(shí)現(xiàn)機(jī)制進(jìn)行詳細(xì)剖析。

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Spring中模板模式和回調(diào)模式的講解
Spring JDBC
JDBC快速入門
JDBC使用+數(shù)據(jù)庫(kù)連接池+springJDBC
Spring 中的JdbcTemplate使用_阿郎
JDBC后傳
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服