溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Spring Boot項(xiàng)目中使用mysql數(shù)據(jù)庫的具體演示

發(fā)布時(shí)間:2020-06-08 11:32:50 來源:網(wǎng)絡(luò) 閱讀:323 作者:三月 欄目:編程語言

下文給大家?guī)碛嘘P(guān)Spring Boot項(xiàng)目中使用mysql數(shù)據(jù)庫的具體演示內(nèi)容,相信大家一定看過類似的文章。我們給大家?guī)淼挠泻尾煌??一起來看看正文部分吧,相信看完Spring Boot項(xiàng)目中使用mysql數(shù)據(jù)庫的具體演示你一定會(huì)有所收獲。

1.建立數(shù)據(jù)庫連接(database connection)

在上篇文章中我們新建了一個(gè)Spring Boot應(yīng)用程序,添加了jdbc和data-jpa等starters,以及一個(gè)h3數(shù)據(jù)庫依賴,這里我們將配置一個(gè)H2數(shù)據(jù)庫。

對(duì)于H2、HSQL或者Derby這類嵌入型數(shù)據(jù)庫,只要在pom文件中添加對(duì)應(yīng)的依賴就可以,不需要額外的配置。當(dāng)spring boot在classpath下發(fā)現(xiàn)某個(gè)數(shù)據(jù)庫依賴存在且在代碼中有關(guān)于Datasource Bean的定義時(shí),就會(huì)自動(dòng)創(chuàng)建一個(gè)數(shù)據(jù)庫連接。我們通過修改之前的bookpub程序說明這個(gè)問題,需要修改StartupRunner.java文件,代碼如下:

package org.test.bookpub;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.CommandLineRunner;import javax.sql.DataSource;public class StartupRunner implements CommandLineRunner {    protected static final Logger logger = LoggerFactory.getLogger(StartupRunner.class);    @Autowired
    private DataSource ds;    @Override
    public void run(String... strings) throws Exception {
        logger.info("Datasource: " + ds.toString());
    }
}

啟動(dòng)應(yīng)用程序,可以看到如下輸出:driverClassName=org.h3.Driver;因此,可以證明,Spring Boot根據(jù)我們自動(dòng)織入DataSource的代碼,自動(dòng)創(chuàng)建并初始化了一個(gè)H2數(shù)據(jù)庫。不過,這個(gè)數(shù)據(jù)庫并沒什么用,因?yàn)榇娣牌渲械臄?shù)據(jù)會(huì)在系統(tǒng)停止后就丟失。通過修改配置,我們可以將數(shù)據(jù)存放在磁盤上。關(guān)于H2數(shù)據(jù)庫的配置文件如下:

spring.datasource.url = jdbc:h3:~/test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
spring.datasource.username = sa
spring.datasource.password =

然后啟動(dòng)應(yīng)用程序,并檢查你的home目錄下是否存在test.mv.db文件。通過“~/test”,就告訴Spring Boot,H2數(shù)據(jù)庫的數(shù)據(jù)會(huì)存放在test.mv.db這個(gè)文件中。

綜上,可以看出,Spring Boot試圖通過spring.datasource分組下的一系列配置項(xiàng)來簡化用戶對(duì)數(shù)據(jù)庫的使用,我們經(jīng)常使用的配置項(xiàng)有:url,username,password以及driver-class-name等等。PS:driverClassName或者driver-class-name都可以,Spring Boot會(huì)在內(nèi)部進(jìn)行統(tǒng)一處理。

最常用的開源數(shù)據(jù)庫是Mysql,在Spring Boot通過下列配置項(xiàng)來配置mysql:

spring.datasource.driver-class-name=com.mysql.jdbc.Driverspring.datasource.url=jdbc:mysql://localhost:3306/springbootcookbookspring.datasource.username=root
spring.datasource.password=

如果希望通過Hibernate依靠Entity類自動(dòng)創(chuàng)建數(shù)據(jù)庫和數(shù)據(jù)表,則還需要加上配置項(xiàng)——spring.jpa.hibernate.ddl-auto=create-drop。PS:在生產(chǎn)環(huán)境中不要使用create-drop,這樣會(huì)在程序啟動(dòng)時(shí)先刪除舊的,再自動(dòng)創(chuàng)建新的,最好使用update;還可以通過設(shè)置spring.jpa.show-sql = true來顯示自動(dòng)創(chuàng)建表的SQL語句,通過spring.jpa.database = MYSQL指定具體的數(shù)據(jù),如果不明確指定Spring boot會(huì)根據(jù)classpath中的依賴項(xiàng)自動(dòng)配置。

要使用MySQL,需要引入對(duì)應(yīng)的connector,因此,首先在pom文件中添加如下依賴:

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

在Spring項(xiàng)目中,如果數(shù)據(jù)比較簡單,我們可以考慮使用JdbcTemplate,而不是直接定義Datasource,配置jdbc的代碼如下:

@Autowiredprivate JdbcTemplate jdbcTemplate;

只要定義了上面這個(gè)代碼,Spring Boot會(huì)自動(dòng)創(chuàng)建一個(gè)Datasource對(duì)象,然后再創(chuàng)建一個(gè)jdbctemplate對(duì)象來管理datasource,通過jdbctemplate操作數(shù)據(jù)庫可以減少大量模板代碼。如果你對(duì)SpringBoot的原理感興趣,可以在org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration類中查看其具體實(shí)現(xiàn)。

2.創(chuàng)建數(shù)據(jù)倉庫服務(wù)(data repository service)

連接數(shù)據(jù)庫并直接執(zhí)行SQL語句這種思路非常古老,早在很多年前就已經(jīng)出現(xiàn)了ORM(Object Relational Mapping)框架來簡化這部分工作,最有名的是Hibernate,但是現(xiàn)在更火的好像是Mybatis。我們這里使用Hibernate進(jìn)行演示。我們將會(huì)增加一些實(shí)體類,這些實(shí)體類決定了數(shù)據(jù)庫的表結(jié)構(gòu),還要定義一個(gè)CrudRepository接口,用于操作數(shù)據(jù)。

示例程序是一個(gè)圖書管理系統(tǒng),顯然,數(shù)據(jù)庫中應(yīng)該具備以下領(lǐng)域?qū)ο?domain object):Book、Author、Reviewrs以及Publisher。首先在src/main/java/org/test/bookpub下建立包domain,然后再在這個(gè)包下建立相應(yīng)的實(shí)體類。具體代碼列舉如下(為了節(jié)省空間,省去了getter和setter):

  • Book.java

package com.test.bookpub.domain;import javax.persistence.*;import java.util.List;@Entitypublic class Book {    @Id
    @GeneratedValue
    private Long id;    private String isbn;    private String title;    private String description;    @ManyToOne
    private Author author;    @ManyToOne
    private Publisher publisher;    @ManyToMany
    private List<Publisher.Reviewer> reviewers;    protected Book() { }    public Book(Author author, String isbn, Publisher publisher, String title) {        this.author = author;        this.isbn = isbn;        this.publisher = publisher;        this.title = title;
    }
}
  • Author.java

package com.test.bookpub.domain;import javax.persistence.*;import java.util.List;@Entitypublic class Author {    @Id
    @GeneratedValue
    private Long id;    private String firstName;    private String lastName;    @OneToMany(mappedBy = "author")    private List<Book> books;    protected Author() {

    }    public Author(String firstName, String lastName) {        this.firstName = firstName;        this.lastName = lastName;
    }
}
  • Publisher.java

package com.test.bookpub.domain;import javax.persistence.*;import java.util.List;@Entitypublic class Publisher {    @Id
    @GeneratedValue
    private Long id;    private String name;    @OneToMany(mappedBy = "publisher")    private List<Book> books;    protected Publisher() { }    public Publisher(String name) {        this.name = name;
    }    @Entity
    public class Reviewer {        @Id
        @GeneratedValue
        private Long id;        private String firstName;        private String lastName;        protected Reviewer() { }        public Reviewer(String firstName, String lastName) {            this.firstName = firstName;            this.lastName = lastName;
        }
    }
}
  • repository層:創(chuàng)建完實(shí)體類,還需要?jiǎng)?chuàng)建BookRepository接口,該接口繼承自CrudRepository,這個(gè)接口放在src/main/java/com/test/bookpub/repository包中,具體代碼如下:

package com.test.bookpub.repository;import com.test.bookpub.domain.Book;import org.springframework.data.repository.CrudRepository;import org.springframework.stereotype.Repository;

@Repositorypublic interface BookRepository extends CrudRepository<Book, Long> {    Book findBookByIsbn(String isbn);
}
  • 織入BookRepository,最后需要再StartupRunner中定義BookRepository對(duì)象,并自動(dòng)織入。

package com.test.bookpub;import com.test.bookpub.repository.BookRepository;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.CommandLineRunner;public class StartupRunner implements CommandLineRunner {    protected final Logger logger = LoggerFactory.getLogger(StartupRunner.class);    @Autowired
    private BookRepository bookRepository;    @Override
    public void run(String... strings) throws Exception {
        logger.info("Number of books: " + bookRepository.count());
    }
}

可能讀者朋友你也注意到了,到此為止,我們都沒有寫一行SQL語句,也沒有在代碼中涉及到數(shù)據(jù)庫連接、建立查詢等方面的內(nèi)容。只有實(shí)體類上的各種注解表明我們?cè)谟跀?shù)據(jù)庫做交互:@Entity,@Repository,@Id,@GeneratedValue,@ManyToOne,@ManyToMany以及@OneToMany,這些注解屬于Java Persistance API。我們通過CrudRespository接口的子接口與數(shù)據(jù)庫交互,同時(shí)由Spring建立對(duì)象與數(shù)據(jù)庫表、數(shù)據(jù)庫表中的數(shù)據(jù)之間的映射關(guān)系。下面依次說明這些注解的含義和使用:

  • @Entity,說明被這個(gè)注解修飾的類應(yīng)該與一張數(shù)據(jù)庫表相對(duì)應(yīng),表的名稱可以由類名推斷,當(dāng)然了,也可以明確配置,只要加上@Table(name = "books")即可。需要特別注意,每個(gè)Entity類都應(yīng)該有一個(gè)protected訪問級(jí)別的無參構(gòu)造函數(shù),用于給Hibernate提供初始化的入口。

  • @Id and @GeneratedValue:@Id注解修飾的屬性應(yīng)該作為表中的主鍵處理、@GeneratedValue修飾的屬性應(yīng)該由數(shù)據(jù)庫自動(dòng)生成,而不需要明確指定。

  • @ManyToOne, @ManyToMany表明具體的數(shù)據(jù)存放在其他表中,在這個(gè)例子里,書和作者是多對(duì)一的關(guān)系,書和出版社是多對(duì)一的關(guān)系,因此book表中的author和publisher相當(dāng)于數(shù)據(jù)表中的外鍵;并且在Publisher中通過@OneToMany(mapped = "publisher")定義一個(gè)反向關(guān)聯(lián)(1——>n),表明book類中的publisher屬性與這里的books形成對(duì)應(yīng)關(guān)系。

  • @Repository 用來表示訪問數(shù)據(jù)庫并操作數(shù)據(jù)的接口,同時(shí)它修飾的接口也可以被component scan機(jī)制探測(cè)到并注冊(cè)為bean,這樣就可以在其他模塊中通過@Autowired織入。

  • CrudRepository,直接查看源代碼,CrudRepository的代碼如下:

public interface CrudRepository<T, ID extends Serializable>    extends Repository<T, ID> {

    <S extends T> S save(S entity); //保存給定的entity

    T findOne(ID primaryKey);//根據(jù)給定的id查詢對(duì)應(yīng)的entity

    Iterable<T> findAll(); //查詢所有entity          

    Long count();//返回entity的個(gè)數(shù)

    void delete(T entity); //刪除給定的entity   

    boolean exists(ID primaryKey); //判斷給定id的entity是否存在

    // … more functionality omitted.}

我們可以添加自定義的接口函數(shù),JPA會(huì)提供對(duì)應(yīng)的SQL查詢,例如,在本例中的BookRepository中可以增加findBookByIsbn(String isbn)函數(shù),JPA會(huì)自動(dòng)創(chuàng)建對(duì)應(yīng)的SQL查詢——根據(jù)isbn查詢圖書,這種將方法名轉(zhuǎn)換為SQL語句的機(jī)制十分方便且功能強(qiáng)大,例如你可以增加類似findByNameIgnoringCase(String name)這種復(fù)雜查詢。

最后,我們利用mvn spring-boot:run運(yùn)行應(yīng)用程序,觀察下Hibernate是如何建立數(shù)據(jù)庫連接,如何檢測(cè)數(shù)據(jù)表是否存在以及如何自動(dòng)創(chuàng)建表的過程。

對(duì)于上文關(guān)于Spring Boot項(xiàng)目中使用mysql數(shù)據(jù)庫的具體演示,大家覺得是自己想要的嗎?如果想要了解更多相關(guān),可以繼續(xù)關(guān)注我們的行業(yè)資訊板塊。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI