SpringBoot第二講 利用Spring Data JPA實現資料庫的訪問(一)
在基本瞭解了springboot的執行流程之後,我們需要逐個來突破springboot的幾個關鍵性問題,我們首先解決的是springboot訪問資料庫的問題。Java訪問資料庫經歷了幾個階段,第一個階段是直接通過JDBC訪問,這種方式工作量極大,而且會做大量的重複勞動,之後出現了一些現成的ORM框架,如hibernate、Mybatis等,這些框架封裝了大量的資料庫的訪問操作,但是我們依然要對這些框架進行二次封裝。如今spring Data幫助我們解決了資料庫的操作的問題,Spring Data還提供了一套JPA介面幫助我們可以非常簡單實現基於關係資料庫的訪問操作。如下圖所示:
Spring Data JPA等於在ORM之上又進行了一次封裝,但具體的對資料庫的訪問依然要依賴於底層的ORM框架,Spring Data JPA預設是通過Hibernate實現的,接下來我們就來看看Spring Data JPA如何訪問我們的資料庫和如何簡化我們的操作的。
第一步建立一個Springboot的專案,並且新增Spring Data JPA的支援
這個操作可以直接在start.spring.io網站中建立,並且新增JPA的支援。這個專案我們可以考慮不使用Web。
之後建立一個專案,拷貝maven的依賴。
<?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的依賴-->
<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>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
pom.xml設定完成之後,我們會發現依賴包中有了hibernate的jar檔案,這就說明spring data jpa預設就是使用hibernate框架來作為底層的ORM。
為了可以相對快速的上手spring Data,我們這裡就建立一個Student的Model物件。
//Student
*/
/*
* 以下兩個程式碼其實就是Hiberate宣告實體的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;
....
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
以上程式碼我省略其中的getter和settter方法,建立完實體類之後,這個實體類上的annotation都是原來hibernate中常用的,就不一一講解了。之後在resources資料夾中配置appication.properties檔案,這是springboot的主配置檔案,此時我們配置和資料庫訪問相關的內容,我們使用的是hibernate,所以就配置和hibernate相關的內容
#開啟包的自動掃描
entitymanager.packagesToScan= org.konghao.model
# 資料庫連線
spring.datasource.url=jdbc:mysql://localhost:3306/springboot
# 使用者名稱
spring.datasource.username=root
# 密碼
spring.datasource.password=123
# 資料庫驅動
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
# 自動更新表
spring.jpa.properties.hibernate.hbm2ddl.auto=update
# 使用MYSQL5作為資料庫訪問方言
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
#顯示sql語句
spring.jpa.properties.hibernate.show_sql=true
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
注意原來和hibernate的配置都改成了以spring.jpa.properties.hiberate.xx,此時由於使用了MySQL,所以還得匯入mysql的connector
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
有沒有發現我們不用設定版本,由於繼承了>org.springframework.boot
,它會自動幫助我們匹配一個合適的connector來專案中的。到此和資料庫配置相關的所有任務就結束了。
接下來就讓我們開始訪問資料庫吧,在原來的方式中,我們需要為每一個物件建立自己的DAO介面,然後寫一個實現類基礎我們自己封裝好的BaseDao,然後完成資料物件的CRUD等操作,如今Spring Data JPA幫我們完成了這個工作,我們首先看一下Spring Data JPA中的幾個介面
最高層的Repository<T,ID>
是一個空介面,我們定義的資料訪問類只要實現這個介面,這個資料訪問類就可以被spring data所管理,就此可以使用spring為我們提供操作方法(在原來的spring data中我們需要配置很多和Spring
Data Repository相關的設定,但是現在有了spring boot,全部都已經自動配置好了)。這個介面要實現有兩個泛型引數,第一個T表示實體類,第二個表示主鍵的型別,我們寫一個數據庫訪問介面。
public interface StudentRepository extends Repository<Student,Integer> {
@Query("select s from Student s where s.id=?1")
public Student loadById(int id);
//根據地址和年齡進行查詢
public List<Student> findByAddressAndAge(String address, int age);
//根據id獲取物件,即可返回物件,也可以返回列表
public Student readById(int id);
//根據id獲取列表,這裡如果確定只有一個物件,也可以返回物件
public List<Student> getById(int id);
//根據id獲取一個物件,同樣也可以返回列表
public Student findById(int id);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
這個介面實現了Repository介面,我們定義了兩個方法,這兩個方法代表Repository使用的一種基本方法,第一個方法增加了一個Query的annotation,通過這個宣告,Spring Data JPA就知道該使用什麼HQL去查詢資料,?1
表示用方法中的第一個引數。第二個函式我們並沒有定義任何的Annotation,但是它也可以查詢得出來,在Spring
Data JPA中提供了一種衍生查詢,只要函式的宣告有findBy,getBy,readBy,他就會去讀取,findByAddressAnAge
表示根據address和age進行查詢,方法的第一個引數就是address,第二個引數就是age,readByXX,getByXX都是一樣的道理,這些方法的返回值可以是一個列表,也可以是一個物件,spring
Data JPA會自動根據返回型別來進行處理。我們不用寫實現類,Spring Data JPA會自動幫助我們實現查詢。很多時候在專案中會用到這些簡單的查詢,但是不得不寫個方法來實現,但是現在使用了Spring Data JPA之後,這個操作被完全簡化了。接著看一下測試類的實現。
@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());
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
現在應該對Spring Data JPA有了基本瞭解了吧,我們再看看剛才那張圖,CRUDRepository
實現了CRUD的方法,PagingAndSortingRepository
在CRUD的基礎上擴充套件了分頁和排序的功能,而JpaRepository
同樣擴充套件了一些方法方便我們查詢。
我們先看看CRUDRepository
這個介面,這個接口裡面提供了CRUD的基本操作,使用非常的簡單。
public interface StudentCrudRepository extends CrudRepository<Student,Integer>{
//增加了一個countByXX的方法
public long countByAge(int age);
}
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
測試程式碼
@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() {
//取數量操作
Assert.assertEquals(3,studentCrudRepository.count());
Assert.assertEquals(2,studentCrudRepository.countByAge(22));
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
通過這個例子我們應該已經感受了Spring Data JPA如何簡化了我們的資料庫訪問操作了吧!這一部分先講到這裡,下一講我們實現分頁,排序和更多的JPA查詢功能。