歡迎光臨
每天分享高質量文章

一起來學 SpringBoot 2.x | 第五篇:使用 JdbcTemplate 訪問資料庫

點擊上方“芋道原始碼”,選擇“置頂公眾號”

技術文章第一時間送達!

原始碼精品專欄

 

摘要: 原創出處 http://blog.battcn.com/2018/05/07/springboot/v2-orm-jdbc/ 「唐亞峰」歡迎轉載,保留摘要,謝謝!

  • 匯入依賴

  • 連接資料庫

  • 具體編碼

  • 表結構

  • 物體類

  • restful 風格接口

  • 測試

  • 總結

  • 說點什麼


SpringBoot 是為了簡化 Spring 應用的創建、運行、除錯、部署等一系列問題而誕生的產物,自動裝配的特性讓我們可以更好的關註業務本身而不是外部的XML配置,我們只需遵循規範,引入相關的依賴就可以輕易的搭建出一個 WEB 工程

Spring Framework對資料庫的操作在JDBC上面做了深層次的封裝,通過依賴註入功能,可以將 DataSource 註冊到JdbcTemplate之中,使我們可以輕易的完成物件關係映射,並有助於規避常見的錯誤,在SpringBoot中我們可以很輕鬆的使用它。

特點

  • 速度快,對比其它的ORM框架而言,JDBC的方式無異於是最快的

  • 配置簡單,Spring自家出品,幾乎沒有額外配置

  • 學習成本低,畢竟JDBC是基礎知識,JdbcTemplate更像是一個DBUtils

匯入依賴

在 pom.xml 中添加對 JdbcTemplate 的依賴


<dependency>
    <groupId>org.springframework.bootgroupId>


    <artifactId>spring-boot-starter-jdbcartifactId>
dependency>

<dependency>
    <groupId>mysqlgroupId>
    <artifactId>mysql-connector-javaartifactId>
dependency>

<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-webartifactId>
dependency>

連接資料庫

application.properties中添加如下配置。值得註意的是,SpringBoot預設會自動配置DataSource,它將優先採用HikariCP連接池,如果沒有該依賴的情況則選取tomcat-jdbc,如果前兩者都不可用最後選取Commons DBCP2通過spring.datasource.type屬性可以指定其它種類的連接池

spring.datasource.url=jdbc:mysql://localhost:3306/chapter4?useUnicode=true&characterEncoding;=UTF-8&zeroDateTimeBehavior;=convertToNull&allowMultiQueries;=true&useSSL;=false
spring.datasource.password=root
spring.datasource.username=root
#spring.datasource.type
#更多細微的配置可以通過下列前綴進行調整
#spring.datasource.hikari
#spring.datasource.tomcat
#spring.datasource.dbcp2

啟動專案,通過日誌,可以看到預設情況下註入的是HikariDataSource

2018-05-07 10:33:54.021  INFO 9640 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Bean with name 'dataSource' has been autodetected for JMX exposure
2018-05-07 10:33:54.026  INFO 9640 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Located MBean 'dataSource': registering with JMX server as MBean [com.zaxxer.hikari:name=dataSource,type=HikariDataSource]
2018-05-07 10:33:54.071  INFO 9640 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2018-05-07 10:33:54.075  INFO 9640 --- [           main] com.battcn.Chapter4Application           : Started Chapter4Application in 3.402 seconds (JVM running for 3.93)

具體編碼

完成基本配置後,接下來進行具體的編碼操作。為了減少代碼量,就不寫UserDao、UserService之類的接口了,將直接在Controller中使用JdbcTemplate進行訪問資料庫操作,這點是不規範的,各位別學我…

表結構

創建一張 t_user 的表

CREATE TABLE `t_user` (
  `id` int(8NOT NULL AUTO_INCREMENT COMMENT '主鍵自增',
  `username` varchar(50NOT NULL COMMENT '用戶名',
  `password` varchar(50NOT NULL COMMENT '密碼',
  PRIMARY KEY (`id`)
ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用戶表';

物體類

package com.battcn.entity;

/**
 * @author Levin
 * @since 2018/5/7 0007
 */

public class User {

    private Long id;
    private String username;
    private String password;
    // TODO  省略get set
}

restful 風格接口

package com.battcn.controller;

import com.battcn.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @author Levin
 * @since 2018/4/23 0023
 */

@RestController
@RequestMapping("/users")
public class SpringJdbcController {

    private final JdbcTemplate jdbcTemplate;

    @Autowired
    public SpringJdbcController(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    @GetMapping
    public List queryUsers() {
        // 查詢所有用戶
        String sql = "select * from t_user";
        return jdbcTemplate.query(sql, new Object[]{}, new BeanPropertyRowMapper<>(User.class));
    }

    @GetMapping("/{id}")
    public User getUser(@PathVariable Long id) {
        // 根據主鍵ID查詢
        String sql = "select * from t_user where id = ?";
        return jdbcTemplate.queryForObject(sql, new Object[]{id}, new BeanPropertyRowMapper<>(User.class));
    }

    @DeleteMapping("/{id}")
    public int delUser(@PathVariable Long id) {
        // 根據主鍵ID刪除用戶信息
        String sql = "DELETE FROM t_user WHERE id = ?";
        return jdbcTemplate.update(sql, id);
    }

    @PostMapping
    public int addUser(@RequestBody User user) {
        // 添加用戶
        String sql = "insert into t_user(username, password) values(?, ?)";
        return jdbcTemplate.update(sql, user.getUsername(), user.getPassword());
    }


    @PutMapping("/{id}")
    public int editUser(@PathVariable Long id, @RequestBody User user) {
        // 根據主鍵ID修改用戶信息
        String sql = "UPDATE t_user SET username = ? ,password = ? WHERE id = ?";
        return jdbcTemplate.update(sql, user.getUsername(), user.getPassword(), id);
    }
}

測試

由於上面的接口是 restful 風格的接口,添加和修改無法通過瀏覽器完成,所以需要我們自己編寫junit或者使用postman之類的工具。

創建單元測試Chapter4ApplicationTests,通過TestRestTemplate模擬GET、POST、PUT、DELETE等請求操作

package com.battcn;

import com.battcn.entity.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;

/**
 * @author Levin
 */

@RunWith(SpringRunner.class)
@SpringBootTest(classes = Chapter4Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class Chapter4ApplicationTests {

    private static final Logger log = LoggerFactory.getLogger(Chapter4ApplicationTests.class);
    @Autowired
    private TestRestTemplate template;
    @LocalServerPort
    private int port;

    @Test
    public void test1() throws Exception {
        template.postForEntity("http://localhost:" + port + "/users"new User("user1""pass1"), Integer.class);
        log.info("[添加用戶成功]\n");
        // TODO 如果是傳回的集合,要用 exchange 而不是 getForEntity ,後者需要自己強轉型別
        ResponseEntity> response2 = template.exchange("http://localhost:" + port + "/users", HttpMethod.GET, nullnew ParameterizedTypeReference>() {
        });
        final List body = response2.getBody();
        log.info("[查詢所有] - [{}]\n", body);
        Long userId = body.get(0).getId();
        ResponseEntity response3 = template.getForEntity("http://localhost:" + port + "/users/{id}", User.class, userId);
        log.info("[主鍵查詢] - [{}]\n", response3.getBody());
        template.put("http://localhost:" + port + "/users/{id}"new User("user11""pass11"), userId);
        log.info("[修改用戶成功]\n");
        template.delete("http://localhost:" + port + "/users/{id}", userId);
        log.info("[刪除用戶成功]");
    }
}

總結

本章介紹了JdbcTemplate常用的幾種操作,詳細請參考JdbcTemplate API文件

目前很多大佬都寫過關於 SpringBoot 的教程了,如有雷同,請多多包涵,本教程基於最新的 spring-boot-starter-parent:2.0.1.RELEASE編寫,包括新版本的特性都會一起介紹…

說點什麼

全文代碼:https://github.com/battcn/spring-boot2-learning/tree/master/chapter4

666. 彩蛋




如果你對 Dubbo 感興趣,歡迎加入我的知識星球一起交流。

知識星球

目前在知識星球(https://t.zsxq.com/2VbiaEu)更新瞭如下 Dubbo 原始碼解析如下:

01. 除錯環境搭建
02. 專案結構一覽
03. 配置 Configuration
04. 核心流程一覽

05. 拓展機制 SPI

06. 執行緒池

07. 服務暴露 Export

08. 服務取用 Refer

09. 註冊中心 Registry

10. 動態編譯 Compile

11. 動態代理 Proxy

12. 服務呼叫 Invoke

13. 呼叫特性 

14. 過濾器 Filter

15. NIO 服務器

16. P2P 服務器

17. HTTP 服務器

18. 序列化 Serialization

19. 集群容錯 Cluster

20. 優雅停機

21. 日誌適配

22. 狀態檢查

23. 監控中心 Monitor

24. 管理中心 Admin

25. 運維命令 QOS

26. 鏈路追蹤 Tracing


一共 60 篇++

原始碼不易↓↓↓

點贊支持老艿艿↓↓

赞(0)

分享創造快樂