1. 程式人生 > >springboot學習:初識在Spring Boot中使用JPA

springboot學習:初識在Spring Boot中使用JPA

使用流程

建立工程並新增相關依賴

在Spring Boot中使用JPA,我們在建立工程的時候需要選擇JPA依賴,如下: 
這裡寫圖片描述 
其他的步驟和我們建立一個普通的Spring Boot專案是一樣的,如果小夥伴不瞭解如何建立一個Spring Boot專案可以參考這篇文章初識Spring Boot框架。 
專案建立成功之後,我這裡是使用MySql做演示,因此還需要新增MySql驅動,在pom.xml檔案中新增如下依賴:

        <dependency>
            <groupId>mysql</groupId>
            <artifactId
>
mysql-connector-java</artifactId> <version>5.1.40</version> </dependency>
  • 1
  • 2
  • 3
  • 4
  • 5

配置基本屬性

接下來需要我們在application.properties中配置資料來源和jpa的基本的相關屬性,如下:

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/jpatest
spring.datasource
.username=root spring.datasource.password=123456 spring.jpa.hibernate.ddl-auto=update spring.jpa.show-sql=true spring.jackson.serialization.indent_output=true
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

關於這裡的配置我說如下幾點:

1.第一行表示驅動的名稱,這個和具體的資料庫驅動有關,視情況而定,我這裡使用了MySql資料庫,所以驅動名為com.mysql.jdbc.Driver 
2.第二行表示資料庫連線地址,當然也是視情況而定 
3.第三四行表示資料庫連線的使用者名稱和密碼 
4.第五行則配置了實體類維護資料庫表結構的具體行為,update表示當實體類的屬性發生變化時,表結構跟著更新,這裡我們也可以取值create,這個create表示啟動的時候刪除上一次生成的表,並根據實體類重新生成表,這個時候之前表中的資料就會被清空;還可以取值create-drop,這個表示啟動時根據實體類生成表,但是當sessionFactory關閉的時候表會被刪除;validate表示啟動時驗證實體類和資料表是否一致;none表示啥都不做。 
5.第六行表示hibernate在操作的時候在控制檯列印真實的sql語句 
6.第七行表示格式化輸出的json字串

OK,以上就是我們在application.properties中對JPA進行的一個簡單配置。

定義對映實體類

接下來,定義相應的實體類,在Project啟動時,系統會根據實體類建立相應的資料表,我的實體類如下:

@Entity
@NamedQuery(name = "Person.withNameAndAddressNamedQuery",
        query = "select p from Person p where p.name=?1 and p.address=?2")
public class Person {
    @Id
    @GeneratedValue
    private Long id;
    private String name;
    private Integer age;
    private String address;

    public Person() {
    }

    public Person(Long id, String name, Integer age, String address) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.address = address;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}
  • 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
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53

首先在實體類上我們使用了@Entity註解,這個表示這是一個和資料庫表對映的實體類,在屬性id上我們添加了@Id註解,表示該欄位是一個id,@GeneratedValue註解則表示該欄位自增。@NamedQuery註解表示一個NamedQuery查詢,這裡一個名稱代表一個查詢語句,我們一會可以在控制器中直接呼叫@NamedQuery中的withNameAndAddressNamedQuery方法,該方法代表的查詢語句是select p from Person p where p.name=?1 and p.address=?2。

定義資料訪問介面

OK,做好上面幾個步驟之後,接下來我們就可以定義資料訪問介面了,我們的資料訪問介面需要繼承JpaRepository類,我在資料訪問介面中一共定義了四個方法,如下:

public interface PersonRepository extends JpaRepository<Person, Long> {
    List<Person> findByAddress(String name);

    Person findByNameAndAddress(String name, String address);

    @Query("select p from Person p where p.name=:name and p.address=:address")
    Person withNameAndAddressQuery(@Param("name") String name, @Param("address") String address);

    Person withNameAndAddressNamedQuery(String name, String address);

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

關於這個資料訪問介面,我說如下幾點:

1.當我們繼承JpaRepository介面後,我們就自動具備瞭如下資料訪問方法:

List<T> findAll();
List<T> findAll(Sort var1);
List<T> findAll(Iterable<ID> var1);
<S extends T> List<S> save(Iterable<S> var1);
void flush();
<S extends T> S saveAndFlush(S var1);
void deleteInBatch(Iterable<T> var1);
void deleteAllInBatch();
T getOne(ID var1);
<S extends T> List<S> findAll(Example<S> var1);
<S extends T> List<S> findAll(Example<S> var1, Sort var2);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

2.我們可以在介面中定義查詢方法,可以按照屬性名來查詢,但是方法的命名方式是固定的,比如第一個方法和第二個方法,第一個方法表示根據一個屬性查詢,第二個方法表示根據多個屬性查詢,findBy、And等可以算作是這裡的查詢關鍵字了,如果寫作其他名稱則系統不能識別,類似的關鍵字還有Like、Or、Is、Equals、Between等,而這裡的findBy關鍵字又可以被find、read、readBy、query、queryBy、get、getBy等來代替。

3.在查詢的過程中我們也可以限制查詢結果,這裡使用的關鍵字是top、first等,比如查詢前10條資料我們可以寫作:

List<Person> findFirst10ByName(String name);
  • 1

4.使用NamedQuery來查詢,就是我們直接在實體類上使用@NamedQuery註解來定義查詢方法和方法名,一個名稱對應一個查詢語句,具體可以參考我們上文的實體類 
5.我們也可以向第三個方法那樣新增@Query註解,當我呼叫這個方法的時候使用這個註解中的sql語句進行查詢,方法的引數則是註解中的佔位符的值。

編寫測試Controller

資料訪問介面都有了,接下來就是一個Controller了,我們寫一個簡單的Controller,用來測試一下上文中的資料訪問介面是否正確,如下:

@RestController
public class DataController {
    @Autowired
    PersonRepository personRepository;

    @RequestMapping("/save")
    public Person save(String name,String address,Integer age) {
        Person person = personRepository.save(new Person(null, name, age, address));
        return person;
    }

    @RequestMapping("/q1")
    public List<Person> q1(String address) {
        List<Person> people = personRepository.findByAddress(address);
        return people;
    }

    @RequestMapping("/q2")
    public Person q2(String name, String address) {
        Person people = personRepository.findByNameAndAddress(name, address);
        return people;
    }

    @RequestMapping("/q3")
    public Person q3(String name, String address) {
        Person person = personRepository.withNameAndAddressQuery(name, address);
        return person;
    }

    @RequestMapping("/q4")
    public Person q4(String name, String address) {
        Person person = personRepository.withNameAndAddressNamedQuery(name, address);
        return person;
    }
    @RequestMapping("/sort")
    public List<Person> sort() {
        List<Person> people = personRepository.findAll(new Sort(Sort.Direction.ASC, "age"));
        return people;
    }
    @RequestMapping("/page")
    public Page<Person> page(int page,int size){
        Page<Person> all = personRepository.findAll(new PageRequest(page, size));
        return all;
    }
    @RequestMapping("/all")
    public List<Person> all(){
        return personRepository.findAll();
    }
}
  • 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
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

這裡的程式碼都很簡單,我就不再一一進行解釋了,值得說的是第36行程式碼表示根據age對查詢結果進行排序然後顯示出來,第40行的方法表示一個分頁查詢,第一個引數表示頁數,從0開始計,第二個引數表示每頁的資料量。最後在瀏覽器中分別測試這幾個介面就可以了,我這裡就不再展示測試頁面了,小夥伴們自行測試。