SpringBoot第二講利用Spring Data JPA實(shí)現(xiàn)數(shù)據(jù)庫(kù)的訪(fǎng)問(wèn)(一)

在基本了解了springboot的運(yùn)行流程之后,我們需要逐個(gè)來(lái)突破springboot的幾個(gè)關(guān)鍵性問(wèn)題,我們首先解決的是springboot訪(fǎng)問(wèn)數(shù)據(jù)庫(kù)的問(wèn)題。java訪(fǎng)問(wèn)數(shù)據(jù)庫(kù)經(jīng)歷了幾個(gè)階段,第一個(gè)階段是直接通過(guò)JDBC訪(fǎng)問(wèn),這種方式工作量極大,而且會(huì)做大量的重復(fù)勞動(dòng),之后出現(xiàn)了一些現(xiàn)成的ORM框架,如Hibernate、Mybatis等,這些框架封裝了大量的數(shù)據(jù)庫(kù)的訪(fǎng)問(wèn)操作,但是我們依然要對(duì)這些框架進(jìn)行二次封裝。如今Spring Data幫助我們解決了數(shù)據(jù)庫(kù)的操作的問(wèn)題,Spring Data還提供了一套JPA接口幫助我們可以非常簡(jiǎn)單實(shí)現(xiàn)基于關(guān)系數(shù)據(jù)庫(kù)的訪(fǎng)問(wèn)操作。如下圖所示:

利用spring DATA JPA實(shí)現(xiàn)數(shù)據(jù)庫(kù)訪(fǎng)問(wèn)
利用spring DATA JPA實(shí)現(xiàn)數(shù)據(jù)庫(kù)訪(fǎng)問(wèn)

Spring Data JPA等于在ORM之上又進(jìn)行了一次封裝,但具體的對(duì)數(shù)據(jù)庫(kù)的訪(fǎng)問(wèn)依然要依賴(lài)于底層的ORM框架,Spring Data JPA默認(rèn)是通過(guò)Hibernate實(shí)現(xiàn)的,接下來(lái)我們就來(lái)看看Spring Data JPA如何訪(fǎng)問(wèn)我們的數(shù)據(jù)庫(kù)和如何簡(jiǎn)化我們的操作的。

第一步創(chuàng)建一個(gè)Springboot的項(xiàng)目,并且添加Spring Data JPA的支持

這個(gè)操作可以直接在start.spring.io網(wǎng)站中創(chuàng)建,并且添加JPA的支持。這個(gè)項(xiàng)目我們可以考慮不使用Web。

利用spring DATA JPA實(shí)現(xiàn)數(shù)據(jù)庫(kù)訪(fǎng)問(wèn)
利用spring DATA JPA實(shí)現(xiàn)數(shù)據(jù)庫(kù)訪(fǎng)問(wèn)

之后創(chuàng)建一個(gè)項(xiàng)目,拷貝maven的依賴(lài)。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.konghao</groupId>
    <artifactId>hello-jpa</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.4.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!-- spring data jpa的依賴(lài)-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

pom.xml設(shè)置完成之后,我們會(huì)發(fā)現(xiàn)依賴(lài)包中有了hibernate的jar文件,這就說(shuō)明spring data jpa默認(rèn)就是使用hibernate框架來(lái)作為底層的ORM。

為了可以相對(duì)快速的上手spring Data,我們這里就創(chuàng)建一個(gè)Student的Model對(duì)象。

//Student
*/
/*
* 以下兩個(gè)代碼其實(shí)就是Hiberate聲明實(shí)體的annotation
* */
@Entity
@Table(name="t_stu")
public class Student {

    @Id()
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;
    private String name;
    private String address;
    private int age;
    ....
}

以上代碼我省略其中的getter和settter方法,創(chuàng)建完實(shí)體類(lèi)之后,這個(gè)實(shí)體類(lèi)上的annotation都是原來(lái)hibernate中常用的,就不一一講解了。之后在resources文件夾中配置appication.properties文件,這是springboot的主配置文件,此時(shí)我們配置和數(shù)據(jù)庫(kù)訪(fǎng)問(wèn)相關(guān)的內(nèi)容,我們使用的是hibernate,所以就配置和hibernate相關(guān)的內(nèi)容


#開(kāi)啟包的自動(dòng)掃描
entitymanager.packagesToScan= org.konghao.model
# 數(shù)據(jù)庫(kù)連接
spring.datasource.url=jdbc:mysql://localhost:3306/springboot
# 用戶(hù)名
spring.datasource.username=root
# 密碼
spring.datasource.password=123456
# 數(shù)據(jù)庫(kù)驅(qū)動(dòng)
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
# 自動(dòng)更新表
spring.jpa.properties.hibernate.hbm2ddl.auto=update
# 使用MYSQL5作為數(shù)據(jù)庫(kù)訪(fǎng)問(wèn)方言
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
#顯示sql語(yǔ)句
spring.jpa.properties.hibernate.show_sql=true

注意原來(lái)和hibernate的配置都改成了以spring.jpa.properties.hiberate.xx,此時(shí)由于使用了mysql,所以還得導(dǎo)入mysql的connector

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

有沒(méi)有發(fā)現(xiàn)我們不用設(shè)置版本,由于繼承了org.springframework.boot,它會(huì)自動(dòng)幫助我們匹配一個(gè)合適的connector來(lái)項(xiàng)目中的。到此和數(shù)據(jù)庫(kù)配置相關(guān)的所有任務(wù)就結(jié)束了。

接下來(lái)就讓我們開(kāi)始訪(fǎng)問(wèn)數(shù)據(jù)庫(kù)吧,在原來(lái)的方式中,我們需要為每一個(gè)對(duì)象創(chuàng)建自己的DAO接口,然后寫(xiě)一個(gè)實(shí)現(xiàn)類(lèi)基礎(chǔ)我們自己封裝好的BaseDao,然后完成數(shù)據(jù)對(duì)象的CRUD等操作,如今Spring Data JPA幫我們完成了這個(gè)工作,我們首先看一下Spring Data JPA中的幾個(gè)接口

利用spring DATA JPA實(shí)現(xiàn)數(shù)據(jù)庫(kù)訪(fǎng)問(wèn)
利用spring DATA JPA實(shí)現(xiàn)數(shù)據(jù)庫(kù)訪(fǎng)問(wèn)

最高層的Repository<T,ID>是一個(gè)空接口,我們定義的數(shù)據(jù)訪(fǎng)問(wèn)類(lèi)只要實(shí)現(xiàn)或者繼承這個(gè)接口,這個(gè)數(shù)據(jù)訪(fǎng)問(wèn)類(lèi)就可以被spring data所管理,就此可以使用spring為我們提供操作方法(在原來(lái)的spring data中我們需要配置很多和Spring Data Repository相關(guān)的設(shè)置,但是現(xiàn)在有了spring boot,全部都已經(jīng)自動(dòng)配置好了)。這個(gè)接口要實(shí)現(xiàn)有兩個(gè)泛型參數(shù),第一個(gè)T表示實(shí)體類(lèi),第二個(gè)表示主鍵的類(lèi)型,我們寫(xiě)一個(gè)數(shù)據(jù)庫(kù)訪(fǎng)問(wèn)接口。

public interface StudentRepository extends Repository<Student,Integer> {

    @Query("select s from Student s where s.id=?1")
    public Student loadById(int id);

    //根據(jù)地址和年齡進(jìn)行查詢(xún)
    public List<Student> findByAddressAndAge(String address, int age);
    //根據(jù)id獲取對(duì)象,即可返回對(duì)象,也可以返回列表
    public Student readById(int id);
    //根據(jù)id獲取列表,這里如果確定只有一個(gè)對(duì)象,也可以返回對(duì)象
    public List<Student> getById(int id);
    //根據(jù)id獲取一個(gè)對(duì)象,同樣也可以返回列表
    public Student findById(int id);
}

這個(gè)接口實(shí)現(xiàn)了Repository接口,我們定義了兩個(gè)方法,這兩個(gè)方法代表Repository使用的一種基本方法,第一個(gè)方法增加了一個(gè)Query的annotation,通過(guò)這個(gè)聲明,Spring Data JPA就知道該使用什么HQL去查詢(xún)數(shù)據(jù),?1表示用方法中的第一個(gè)參數(shù)。第二個(gè)函數(shù)我們并沒(méi)有定義任何的Annotation,但是它也可以查詢(xún)得出來(lái),在Spring Data JPA中提供了一種衍生查詢(xún),只要函數(shù)的聲明有findBy,getBy,readBy,他就會(huì)去讀取,findByAddressAnAge表示根據(jù)address和age進(jìn)行查詢(xún),方法的第一個(gè)參數(shù)就是address,第二個(gè)參數(shù)就是age,readByXX,getByXX都是一樣的道理,這些方法的返回值可以是一個(gè)列表,也可以是一個(gè)對(duì)象,spring Data JPA會(huì)自動(dòng)根據(jù)返回類(lèi)型來(lái)進(jìn)行處理。我們不用寫(xiě)實(shí)現(xiàn)類(lèi),Spring Data JPA會(huì)自動(dòng)幫助我們實(shí)現(xiàn)查詢(xún)。很多時(shí)候在項(xiàng)目中會(huì)用到這些簡(jiǎn)單的查詢(xún),但是不得不寫(xiě)個(gè)方法來(lái)實(shí)現(xiàn),但是現(xiàn)在使用了Spring Data JPA之后,這個(gè)操作被完全簡(jiǎn)化了。接著看一下測(cè)試類(lèi)的實(shí)現(xiàn)。

@RunWith(SpringRunner.class)
@SpringBootTest
public class DemoApplicationTests {
    //注入剛才定義的接口
    @Autowired
    private StudentRepository studentRepository;

    @Test
    public void testStudent() {
        Assert.assertEquals("foo",studentRepository.findById(1).getName());
        Assert.assertEquals("foo",studentRepository.readById(1).getName());
        Assert.assertEquals(1,studentRepository.getById(1).size());
        Assert.assertEquals("foo",studentRepository.loadById(1).getName());
        Assert.assertEquals(2,studentRepository.findByAddressAndAge("zt",22).size());
    }
}

現(xiàn)在應(yīng)該對(duì)Spring Data JPA有了基本了解了吧,我們?cè)倏纯磩偛拍菑垐D,CRUDRepository實(shí)現(xiàn)了CRUD的方法,PagingAndSortingRepository在CRUD的基礎(chǔ)上擴(kuò)展了分頁(yè)和排序的功能,而JpaRepository同樣擴(kuò)展了一些方法方便我們查詢(xún)。

我們先看看CRUDRepository這個(gè)接口,這個(gè)接口里面提供了CRUD的基本操作,使用非常的簡(jiǎn)單。

public interface StudentCrudRepository extends CrudRepository<Student,Integer>{
    //增加了一個(gè)countByXX的方法
    public long countByAge(int age);
}

測(cè)試代碼

@Test
    public void testAddStudent() {
        //添加操作
        Student stu = new Student("foo1","km",22);
        studentCrudRepository.save(stu);
    }

    @Test
    public void testUpdateStudent() {
        /*修改的操作*/
        Student stu = studentCrudRepository.findOne(1);
        stu.setName("bar1");
        studentCrudRepository.save(stu);
    }

    @Test
    public void testDelete() {
        //刪除操作
        studentCrudRepository.delete(1);
    }

    @Test
    public void testCount() {
        //取數(shù)量操作
        Assert.assertEquals(3,studentCrudRepository.count());
        Assert.assertEquals(2,studentCrudRepository.countByAge(22));
    }

通過(guò)這個(gè)例子我們應(yīng)該已經(jīng)感受了Spring Data JPA如何簡(jiǎn)化了我們的數(shù)據(jù)庫(kù)訪(fǎng)問(wèn)操作了吧!這一部分先講到這里,下一講我們實(shí)現(xiàn)分頁(yè),排序和更多的JPA查詢(xún)功能。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容