spring boot data jdbc_java连接数据库详细步骤

spring boot data jdbc_java连接数据库详细步骤Spring Boot入门(五):使用JDBC访问MySql数据库

大家好,又见面了,我是你们的朋友全栈君。

本系列博客记录自己学习Spring Boot的历程,如帮助到你,不胜荣幸,如有错误,欢迎指正!

在程序开发的过程中,操作数据库是必不可少的部分,前面几篇博客中,也一直未涉及到数据库的操作,本篇博客

就讲解下在Spring Boot中如何使用JDBC操作数据库。

1.前期准备

假设你的机器已经安装好了MySql,我们先执行如下语句创建数据库和表:

CREATE DATABASE springbootdemo_db

create table book_list
(
  book_id       int auto_increment primary key,
  book_name     varchar(50) not null comment '书名',
  book_author   varchar(20) not null comment '作者',
  purchase_date date        not null comment '购买日期'
)
comment '书单';
复制代码

2.修改pom文件

pom文件引入jdbc的starter pom和mysql的驱动,因后面要编写控制器,因此也引入下阿里巴巴的fastjson:

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

<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
	<version>5.1.35</version>
</dependency>
<dependency>
	<groupId>com.alibaba</groupId>
	<artifactId>fastjson</artifactId>
	<version>1.2.47</version>
</dependency>
复制代码

3.配置数据源

在resources/application.yml中配置数据源:

spring:
 datasource:
 driver-class-name: com.mysql.jdbc.Driver
 url: jdbc:mysql://localhost:3306/springbootdemo_db
 username: root
 password:
复制代码

4.定义数据库实体

定义数据库实体Book:

package com.zwwhnly.springbootdemo.jdbc;

import java.util.Date;

public class Book {
    private Integer bookId;
    private String bookName;
    private String bookAuthor;
    private Date purchaseDate;

    public Integer getBookId() {
        return bookId;
    }

    public void setBookId(Integer bookId) {
        this.bookId = bookId;
    }

    public String getBookName() {
        return bookName;
    }

    public void setBookName(String bookName) {
        this.bookName = bookName;
    }

    public String getBookAuthor() {
        return bookAuthor;
    }

    public void setBookAuthor(String bookAuthor) {
        this.bookAuthor = bookAuthor;
    }

    public Date getPurchaseDate() {
        return purchaseDate;
    }

    public void setPurchaseDate(Date purchaseDate) {
        this.purchaseDate = purchaseDate;
    }
}
复制代码

5.编写Dao层代码

定义接口BookDao:

package com.zwwhnly.springbootdemo.jdbc;

import java.util.List;

public interface BookDao {
    int add(Book book);

    int update(Book book);

    int delete(Integer id);

    Book findBook(Integer id);

    List<Book> findBookList();
}
复制代码

定义接口实现类BookDaoImpl:

package com.zwwhnly.springbootdemo.jdbc;

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 BookDaoImpl implements BookDao {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public int add(Book book) {
        return jdbcTemplate.update("INSERT INTO book_list values (NULL, ?, ?, ?);",
                book.getBookName(), book.getBookAuthor(), book.getPurchaseDate());
    }

    @Override
    public int update(Book book) {
        return jdbcTemplate.update("UPDATE book_list SET book_name=?,book_author=?,purchase_date=? WHERE book_id = ?;",
                new Object[]{book.getBookName(), book.getBookAuthor(), book.getPurchaseDate(), book.getBookId()});
    }

    @Override
    public int delete(Integer id) {
        return jdbcTemplate.update("DELETE FROM book_list where book_id = ?", id);
    }

    @Override
    public Book findBook(Integer id) {
        List<Book> list = jdbcTemplate.query("SELECT * FROM book_list where book_id = ?", new Object[]{id}, new BeanPropertyRowMapper<Book>(Book.class));
        if (null != list && list.size() > 0) {
            Book book = list.get(0);
            return book;
        } else {
            return null;
        }
    }

    @Override
    public List<Book> findBookList() {
        List<Book> list = jdbcTemplate.query("SELECT * FROM book_list", new Object[]{}, new BeanPropertyRowMapper<Book>(Book.class));
        return list;
    }
}
复制代码

注意:实现类添加@Repository注解,以便 Spring Boot实现自动装配。

关于自动装配的问题,可以参考之前的博客Spring入门(二):自动化装配bean

6.编写Service层代码

定义接口BookService:

package com.zwwhnly.springbootdemo.jdbc;

import java.util.List;

public interface BookService {
    int add(Book book);

    int update(Book book);

    int delete(Integer id);

    Book findBook(Integer id);

    List<Book> findBookList();
}
复制代码

然后定义实现类BookServiceImpl:

package com.zwwhnly.springbootdemo.jdbc;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service("bookService")
public class BookServiceImpl implements BookService {
    @Autowired
    private BookDao bookDao;

    @Override
    public int add(Book book) {
        return this.bookDao.add(book);
    }

    @Override
    public int update(Book book) {
        return this.bookDao.update(book);
    }

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

    @Override
    public Book findBook(Integer id) {
        return this.bookDao.findBook(id);
    }

    @Override
    public List<Book> findBookList() {
        return this.bookDao.findBookList();
    }
}
复制代码

注意:实现类添加@Service注解,以便 Spring Boot实现自动装配。

7.编写控制器验证

最后新建控制器BookController,验证下增删改查是否成功:

package com.zwwhnly.springbootdemo.controller;

import com.alibaba.fastjson.JSONObject;
import com.zwwhnly.springbootdemo.jdbc.Book;
import com.zwwhnly.springbootdemo.jdbc.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping(value = "/jdbc/book")
public class BookController {
    @Autowired
    private BookService bookService;

    @RequestMapping(value = "getBookList", method = RequestMethod.GET)
    public Map<String, Object> getBookList() {
        List<Book> bookList = this.bookService.findBookList();
        Map<String, Object> param = new HashMap<>();
        param.put("total", bookList.size());
        param.put("rows", bookList);
        return param;
    }

    @RequestMapping(value = "/getBook/{bookId:\\d+}", method = RequestMethod.GET)
    public Book getBook(@PathVariable Integer bookId) {
        Book book = this.bookService.findBook(bookId);
        if (book == null) {
            throw new RuntimeException("查询错误");
        }
        return book;
    }

    @RequestMapping(value = "add", method = RequestMethod.POST)
    public void add(@RequestBody JSONObject jsonObject) {
        String bookName = jsonObject.getString("bookName");
        String bookAuthor = jsonObject.getString("bookAuthor");
        String purchaseDate = jsonObject.getString("purchaseDate");

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");

        try {
            Book book = new Book();
            book.setBookName(bookName);
            book.setBookAuthor(bookAuthor);
            book.setPurchaseDate(simpleDateFormat.parse(purchaseDate));
            this.bookService.add(book);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("新增错误");
        }
    }

    @RequestMapping(value = "/update/{bookId:\\d+}", method = RequestMethod.PUT)
    public void update(@PathVariable Integer bookId, @RequestBody JSONObject jsonObject) {
        Book book = this.bookService.findBook(bookId);
        String bookName = jsonObject.getString("bookName");
        String bookAuthor = jsonObject.getString("bookAuthor");
        String purchaseDate = jsonObject.getString("purchaseDate");
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        try {
            book.setBookName(bookName);
            book.setBookAuthor(bookAuthor);
            book.setPurchaseDate(simpleDateFormat.parse(purchaseDate));
            this.bookService.update(book);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("更新错误");
        }
    }

    @RequestMapping(value = "/delete/{bookId:\\d+}", method = RequestMethod.DELETE)
    public void delete(@PathVariable Integer bookId) {
        try {
            this.bookService.delete(bookId);
        } catch (Exception e) {
            throw new RuntimeException("删除错误");
        }
    }
}
复制代码

7.1验证新增

因为新增是Post请求,因此这里我们使用下Postman工具:

调用完接口,发现数据库新增数据成功。

7.2验证更新

调用更新接口将刚刚新增数据的购买日期修改为2010-01-01:

调用完接口,发现数据库更新数据成功。

7.3验证获取列表

在浏览器访问http://localhost:8080/jdbc/book/getBookList,返回数据如下:

{
  "total": 2,
  "rows": [
    {
      "bookId": 1,
      "bookName": "平凡的世界",
      "bookAuthor": "路遥",
      "purchaseDate": "2009-12-31T16:00:00.000+0000"
    },
    {
      "bookId": 2,
      "bookName": "人生",
      "bookAuthor": "路遥",
      "purchaseDate": "2010-12-31T16:00:00.000+0000"
    }
  ]
}
复制代码

观察返回的数据,我们发现2个问题:

  1. purchaseDate字段的值比数据库中的少8个小时
  2. purchaseDate字段显示不够友好

出现原因:Spring Boot中返回json格式默认使用jackson框架转换,而jackson框架默认的时区是GMT(相比于中国是少了8小时)。

解决方案:

如果是全局统一修改,则修改resources/application.yml,添加如下配置:

spring:
  jackson:
      time-zone: GMT+8,
      date-format: yyyy-MM-dd HH:mm:ss
复制代码

如果想单个修改,则修改下实体类:

import com.fasterxml.jackson.annotation.JsonFormat;

@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
private Date purchaseDate;
复制代码

再次访问http://localhost:8080/jdbc/book/getBookList,返回数据如下:

{
  "total": 2,
  "rows": [
    {
      "bookId": 1,
      "bookName": "平凡的世界",
      "bookAuthor": "路遥",
      "purchaseDate": "2010-01-01 00:00:00"
    },
    {
      "bookId": 2,
      "bookName": "人生",
      "bookAuthor": "路遥",
      "purchaseDate": "2011-01-01 00:00:00"
    }
  ]
}
复制代码

7.4验证获取单个数据

在浏览器访问http://localhost:8080/jdbc/book/getBook/1,返回如下数据:

{
  "bookId": 1,
  "bookName": "平凡的世界",
  "bookAuthor": "路遥",
  "purchaseDate": "2010-01-01 00:00:00"
}
复制代码

7.5验证删除

调用删除接口,将bookId为2的数据删除:

此时访问http://localhost:8080/jdbc/book/getBookList,返回数据只有1条了:

{
  "total": 1,
  "rows": [
    {
      "bookId": 1,
      "bookName": "平凡的世界",
      "bookAuthor": "路遥",
      "purchaseDate": "2010-01-01 00:00:00"
    }
  ]
}
复制代码

8.源码地址

原文地址:Spring Boot入门(四):开发Web Api接口常用注解总结

博客地址:www.zwwhnly.com

源码地址:github.com/zwwhnly/spr…

欢迎大家下载,有问题可以多多交流。

9.参考链接

SpringBoot 返回json格式数据时间格式配置相差8个小时的时差问题

Spring boot Controller类返回Date时间少8小时

Spring Boot 揭秘与实战(二) 数据存储篇 – MySQL

转载于:https://juejin.im/post/5cc180355188252dca2665f4

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/106857.html原文链接:https://javaforall.net

(0)
上一篇 2022年4月22日 上午6:20
下一篇 2022年4月22日 上午6:20


相关推荐

  • 100道经典的c语言面试题[通俗易懂]

    100道经典的c语言面试题[通俗易懂]100条经典C语言笔试题目 题目来源:1、中兴、华为、慧通、英华达、微软亚洲技术中心等中外企业面试题目;2、C语言面试宝典(林锐《高质量编程第三版》)。说明:1、部分C语言面试题中可能会参杂部分和C++相关的知识,为了保持题目的灵活性故保留,但选题最终还是会以C语言题目为主体;2、以上公司的面试题目已成为国内中小型企业公司出题模板;3、由于本人的能力有限加上…

    2022年7月12日
    122
  • java常用的io流_io流java

    java常用的io流_io流javaIO流大家肯定不陌生,简单整理了一下常用IO流基本用法,其他的IO流以后有时间在整理。1.基本概念IO:Java对数据的操作是通过流的方式,IO流用来处理设备之间的数据传输,上传文件和下载文件,Java用于操作流的对象都在IO包中。2.IO流的分类图示:(主要IO流)3.字节流(1).字节流基类1).InputStreamInputStream:字节输入流基类,抽象类是表示字节输入流的所有

    2022年10月20日
    5
  • 怎么新建pytest的ini文件_python的配置文件ini

    怎么新建pytest的ini文件_python的配置文件ini前言pytest配置文件可以改变pytest的运行方式,它是一个固定的文件pytest.ini文件,读取配置信息,按指定的方式去运行查看pytest.ini的配置选项pytest-h找到以下

    2022年7月28日
    11
  • uwsgi停止[通俗易懂]

    uwsgi停止[通俗易懂]uwsgi停止和nginx配置uwsgi停止nginx配置uwsgi停止必须在uwsgi.ini中配置好pidfile=绝对路径///uwsgi.pid这样才有pid文件uwsgi–stopuwsgi.pid这样就可以停止了有一点需要注意:如果没有uwsgi.pid又需要停止uwsgi服务可以netstat…

    2025年10月29日
    9
  • 产品经理福音:腾讯云+OpenClaw,8项技能一键解锁

    产品经理福音:腾讯云+OpenClaw,8项技能一键解锁

    2026年3月13日
    3
  • python模块之psutil详解

    python模块之psutil详解python模块之psutil详解一、psutil模块:1.psutil是一个跨平台库(http://pythonhosted.org/psutil/)能够轻松实现获取系统运行的进程和系统利用率(包括CPU、内存、磁盘、网络等)信息。它主要用来做系统监控,性能分析,进程管理。它实现了同等命令行工具提供的功能,如ps、top、lsof、netstat、ifconfig、who、df、kill…

    2022年6月12日
    36

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号