SpringBoot學習筆記六:使用JdbcTemplate訪問數(shù)據(jù)庫

SpringJDBC框架承擔了資源管理和異常處理的工作乱陡,將數(shù)據(jù)訪問的樣板代碼抽象到模板類之中浇揩,從而簡化了JDBC代碼,使我們只需編寫從數(shù)據(jù)庫讀寫數(shù)據(jù)所必需的代碼憨颠。
SpringJDBC提供了三個模板類供選擇:

  • JdbcTemplate
    最基本的Spring JDBC模板胳徽,支持簡單的JDBC數(shù)據(jù)訪問功能以及基于索引參數(shù)的查詢,上層接口為JdbcOperations
    This is the central class in the JDBC core package. It simplifies the use of JDBC and helps to avoid common errors. It executes core JDBC workflow, leaving application code to provide SQL and extract results. This class executes SQL queries or updates, initiating iteration over ResultSets and catching JDBC exceptions and translating them to the generic, more informative exception hierarchy defined in the org.springframework.dao package.
  • NamedParameterJdbcTemplate
    使用該模板類進行查詢時可以將值以命名參數(shù)的形式綁定到sql中爽彤,而不是使用簡單的索引參數(shù)养盗,上層接口為NamedParameterJdbcOperations
    Template class with a basic set of JDBC operations, allowing the useof named parameters rather than traditional '?' placeholders.
  • SimpleJdbcTemplate
    已廢棄

導入依賴

pom.xml 中添加對 JdbcTemplate 的依賴

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

連接數(shù)據(jù)庫

application.yml中添加如下配置。值得注意的是适篙,Spring Boot默認會自動配置DataSource往核,它將優(yōu)先采用HikariCP連接池,如果沒有該依賴的情況則選取 Tomcat pooling DataSource 嚷节,如果前兩者都不可用最后選取 Commons DBCP2
聂儒。通過spring.datasource.type屬性可以指定其它種類的連接池

application.yml

spring:
  application:
    name: spring-boot-jdbc
  datasource:
    url: jdbc:mysql://localhost:3306/test_db?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&useSSL=false
    username: root
    password: mysql123
    driver-class-name: com.mysql.jdbc.Driver

啟動項目,通過日志硫痰,可以看到默認情況下注入的是HikariDataSource

2018-07-07 15:28:37.925  INFO 2316 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Bean with name 'dataSource' has been autodetected for JMX exposure
2018-07-07 15:28:37.932  INFO 2316 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Located MBean 'dataSource': registering with JMX server as MBean [com.zaxxer.hikari:name=dataSource,type=HikariDataSource]
2018-07-07 15:28:37.978  INFO 2316 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''

具體編碼

表結(jié)構(gòu)

創(chuàng)建tb_user

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for tb_user
-- ----------------------------
DROP TABLE IF EXISTS `tb_user`;
CREATE TABLE `tb_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用戶id',
  `username` varchar(64) NOT NULL COMMENT '用戶名',
  `password` varchar(64) NOT NULL COMMENT '用戶密碼',
  `birthday` date DEFAULT NULL COMMENT '用戶生日',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

-- ----------------------------
-- Records of tb_user
-- ----------------------------
BEGIN;
INSERT INTO `tb_user` VALUES (1, 'aaa', '123456', '1994-08-10');
INSERT INTO `tb_user` VALUES (2, 'bbb', '123456', '1996-07-25');
INSERT INTO `tb_user` VALUES (3, 'ccc', '123456', '2000-05-01');
INSERT INTO `tb_user` VALUES (4, 'ddd', '123456', '1997-05-10');
COMMIT;

SET FOREIGN_KEY_CHECKS = 1;

實體類

package com.example.springbootjdbc.pojo;

import java.util.Date;

public class User {

    /** 用戶id */
    private Integer id;

    /** 用戶名 */
    private String username;

    /** 用戶密碼 */
    private String password;

    /** 用戶生日 */
    private Date birthday;
    
    // setters and getters ...
}

Dao層

com.example.springbootjdbc.dao.IUserDao

package com.example.springbootjdbc.dao;

import com.example.springbootjdbc.pojo.User;

import java.util.List;

public interface IUserDao {

    int save(User user);

    int delete(Integer id);

    int update(User user);

    User findById(Integer id);

    List<User> findAll();

    List<User> findList(Integer page, Integer pageSize);

}

com.example.springbootjdbc.dao.impl.UserDaoImpl

package com.example.springbootjdbc.dao.impl;

import com.example.springbootjdbc.dao.IUserDao;
import com.example.springbootjdbc.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public class UserDaoImpl implements IUserDao {

    private final JdbcTemplate jdbcTemplate;

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

    @Override
    public int save(User user) {
        String sql = "INSERT INTO tb_user(username, password, birthday) VALUES(?, ?, ?)";
        return jdbcTemplate.update(sql, user.getUsername(), user.getPassword(), user.getBirthday());
    }

    @Override
    public int delete(Integer id) {
        String sql = "DELETE FROM tb_user WHERE id = ?";
        return jdbcTemplate.update(sql, id);
    }

    @Override
    public int update(User user) {
        String sql = "UPDATE tb_user u SET u.username = ?, u.password = ?, u.birthday = ? WHERE u.id = ?";
        return jdbcTemplate.update(sql, user.getUsername(), user.getPassword(), user.getBirthday(), user.getId());
    }

    @Override
    public User findById(Integer id) {
        String sql = "SELECT * FROM tb_user WHERE id = ?";
        return jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>(User.class), id);
    }

    @Override
    public List<User> findAll() {
        String sql = "SELECT * FROM tb_user";
        return jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(User.class));
    }

    @Override
    public List<User> findList(Integer page, Integer pageSize) {
        String sql = "SELECT * FROM tb_user LIMIT ?, ?";
        Integer offset = (page - 1) * pageSize;
        return jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(User.class), offset, pageSize);
    }

}

Service層

com.example.springbootjdbc.service.IUserService

package com.example.springbootjdbc.service;

import com.example.springbootjdbc.pojo.User;

import java.util.List;

public interface IUserService {

    int save(User user);

    int delete(Integer id);

    int update(User user);

    User findById(Integer id);

    List<User> findAll();

    List<User> findList(Integer page, Integer pageSize);

}

com.example.springbootjdbc.service.impl.UserServiceImpl

package com.example.springbootjdbc.service.impl;

import com.example.springbootjdbc.dao.IUserDao;
import com.example.springbootjdbc.pojo.User;
import com.example.springbootjdbc.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class UserServiceImpl implements IUserService {

    private final IUserDao userDao;

    @Autowired
    public UserServiceImpl(IUserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public int save(User user) {
        return userDao.save(user);
    }

    @Override
    public int delete(Integer id) {
        return userDao.delete(id);
    }

    @Override
    public int update(User user) {
        return userDao.update(user);
    }

    @Override
    public User findById(Integer id) {
        return userDao.findById(id);
    }

    @Override
    public List<User> findAll() {
        return userDao.findAll();
    }

    @Override
    public List<User> findList(Integer page, Integer pageSize) {
        return userDao.findList(page, pageSize);
    }
}

Rest 接口

package com.example.springbootjdbc.controller;

import com.example.springbootjdbc.pojo.User;
import com.example.springbootjdbc.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.List;

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

    private final IUserService userService;

    @Autowired
    public UserController(IUserService userService) {
        this.userService = userService;
    }

    @PostMapping("")
    public String saveUser(@RequestBody User user) {
        int count = userService.save(user);
        return count > 0 ? "success" : "fail";
    }

    @DeleteMapping("/{id}")
    public String deleteUser(@PathVariable Integer id) {
        int count = userService.delete(id);
        return count > 0 ? "success" : "fail";
    }

    @PutMapping("/{id}")
    public String updateUser(@PathVariable Integer id, @RequestParam(value = "username", required = true) String username,
                          @RequestParam(value = "password", required = true) String password,
                          @RequestParam(value = "birthday", required = true) String birthday) throws ParseException {
        User updateUser = new User();
        updateUser.setId(id);
        updateUser.setUsername(username);
        updateUser.setPassword(password);
        updateUser.setBirthday(new SimpleDateFormat("yyyy-MM-dd").parse(birthday));
        int count = userService.update(updateUser);
        return count > 0 ? "success" : "fail";
    }

    @GetMapping("")
    public List<User> findList(@RequestParam(value = "page", defaultValue = "1") Integer page,
                               @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
        return userService.findList(page, pageSize);
    }

    @GetMapping("{id}")
    public User findById(@PathVariable Integer id) {
        return userService.findById(id);
    }

}


JdbcTemplate API文檔

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末衩婚,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子效斑,更是在濱河造成了極大的恐慌非春,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,816評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鳍悠,死亡現(xiàn)場離奇詭異税娜,居然都是意外死亡,警方通過查閱死者的電腦和手機藏研,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評論 3 385
  • 文/潘曉璐 我一進店門敬矩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蠢挡,你說我怎么就攤上這事弧岳。” “怎么了业踏?”我有些...
    開封第一講書人閱讀 158,300評論 0 348
  • 文/不壞的土叔 我叫張陵禽炬,是天一觀的道長。 經(jīng)常有香客問我勤家,道長腹尖,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,780評論 1 285
  • 正文 為了忘掉前任伐脖,我火速辦了婚禮热幔,結(jié)果婚禮上乐设,老公的妹妹穿的比我還像新娘。我一直安慰自己绎巨,他們只是感情好近尚,可當我...
    茶點故事閱讀 65,890評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著场勤,像睡著了一般戈锻。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上和媳,一...
    開封第一講書人閱讀 50,084評論 1 291
  • 那天格遭,我揣著相機與錄音,去河邊找鬼窗价。 笑死如庭,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的撼港。 我是一名探鬼主播坪它,決...
    沈念sama閱讀 39,151評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼帝牡!你這毒婦竟也來了往毡?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,912評論 0 268
  • 序言:老撾萬榮一對情侶失蹤靶溜,失蹤者是張志新(化名)和其女友劉穎开瞭,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體罩息,經(jīng)...
    沈念sama閱讀 44,355評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡嗤详,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,666評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了瓷炮。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片葱色。...
    茶點故事閱讀 38,809評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖娘香,靈堂內(nèi)的尸體忽然破棺而出苍狰,到底是詐尸還是另有隱情,我是刑警寧澤烘绽,帶...
    沈念sama閱讀 34,504評論 4 334
  • 正文 年R本政府宣布淋昭,位于F島的核電站,受9級特大地震影響安接,放射性物質(zhì)發(fā)生泄漏翔忽。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,150評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望歇式。 院中可真熱鬧矢赁,春花似錦、人聲如沸贬丛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽豺憔。三九已至,卻和暖如春够庙,著一層夾襖步出監(jiān)牢的瞬間恭应,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評論 1 267
  • 我被黑心中介騙來泰國打工耘眨, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留昼榛,地道東北人。 一個月前我還...
    沈念sama閱讀 46,628評論 2 362
  • 正文 我出身青樓剔难,卻偏偏與公主長得像胆屿,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子偶宫,可洞房花燭夜當晚...
    茶點故事閱讀 43,724評論 2 351

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理非迹,服務發(fā)現(xiàn),斷路器纯趋,智...
    卡卡羅2017閱讀 134,638評論 18 139
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,778評論 6 342
  • 2018年3月28日 周三 天氣晴p68 今天這天氣穿襯衣憎兽,明天又得換上毛衣了。下午接...
    童心_依舊閱讀 194評論 0 0
  • 一路走過 有陣回聲繚繞 不知道是什么存在勾起了記憶 或許是風吧 畢竟是飄過的曲調(diào) 路過之后 總感覺有一種滋味 吹拂...
    醉酒的靈魂閱讀 137評論 0 0
  • 《茶之書》| 小曼解讀 《茶之書》| 小曼解讀 關于作者 岡倉天心吵冒,是日本明治時期著名的美術活動家纯命、美術教育家、文...
    鴨梨山大哎閱讀 875評論 0 1