【Spring Boot】15.整合JPA

簡介

SpringData 項目的目的是爲了簡化構建基於Spring框架應用的數據訪問技術,包括非關係數據庫、Map-Reduce 框架、雲數據服務等等;另外也包含對關係數據庫的訪問支持。java

Spring Data包含的子項目

  • Spring Data Commons
  • Spring Data JPA
  • Spring Data KeyValue
  • Spring Data LDAP
  • Spring Data MongoDB
  • Spring Data Gemfire
  • Spring Data REST
  • Spring Data Redis
  • Spring Data for Apache Cassandra
  • Spring Data for Apache Solr
  • Spring Data Couchbase (community module)
  • Spring Data Elasticsearch (community module)
  • Spring Data Neo4j (community module)

SpringData特色

SpringData爲咱們提供使用統一的API來對數據訪問層進行操做,這主要是Spring Data Commons項目來實現的。Spring Data Commons讓咱們在使用關係型或者非關係型數據訪問技術時都基於Spring提供的統一標準,標準包含了CRUD(建立、獲取、更新、刪除)、查詢、排序和分頁的相關操做。mysql

  1. 統一的Repository接口
  • Repository<T, ID extends Serializable>:統一接口
  • RevisionRepository<T, ID extends Serializable, N extends Number & Comparable<N>>:基於樂觀鎖機制
  • CrudRepository<T, ID extends Serializable> 基本CRUD操做
  • PagingAndSortingRepository<T, ID extends Serializable>:基本CRUD及分頁
  1. 提供數據訪問模板類 xxxTemplate;如:MongoTemplate、RedisTemplate等

咱們能夠參考下圖,查看各模塊之間的關係:git

spring data結構圖

從圖中咱們不難看出:咱們只需面向spring data編程就能夠了,用好他提供的操做API就能夠了。目前咱們要理解的是JPA模塊,他是處理咱們關係型數據庫的相關模塊。github

JPA

Java Persistence API(Java 持久層 API),是用於對象持久化的API,他是JAVAEE持久化數據的規範,使得應用程序以統一的方式訪問持久層咱們之前常說的Hibernate,若是須要拿她和JPA比較一下的話(從圖中咱們其實也能夠看出他們之間的關係):web

  • JPA是Hibernate的一個抽象,就像JDBC和JDBC驅動的關係
  • JPA是一種ORM規範,是Hibernate功能的一個子集 (既然JPA是規範,Hibernate對JPA進行了擴展,那麼說JPA是Hibernate的一個子集不爲過)
  • Hibernate是JPA的一個實現(從圖中咱們也看到了,其實現還有Toplink以及OpenJAP)

JPA技術

  1. ORM映射元數據,支持XML和JDK註解兩種元數據的形式
  2. JPA的API
  3. 查詢語言JPQL

整合JPA

咱們接下來將JAP整合到spring boot項目中。spring

建立項目

選擇框架web jpa以及mysql。sql

配置文件

先加入數據庫鏈接信息,如今咱們使用springboot2.x默認的數據源hikari。數據庫

application.yml

server:
  port: 8085
spring:
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://10.21.1.47/suqing?characterEncoding=utf8
    driver-class-name: com.mysql.cj.jdbc.Driver

在此以前,記得建立一個名爲suqing(素晴)的數據庫,無需添加任何數據。編程

編寫實體類

接下來咱們編寫一個entity,有點像以前寫bean的過程,不過須要按照jpa標準進行註解。json

entity/User.class

package com.zhaoyi.jpaweb.entity;

import javax.persistence.*;
import javax.xml.ws.BindingType;

@Entity
@Table(name="suqing_user")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @Column(name = "name", length = 50)
    private String name;

    @Column(name="last_name")
    private String lastName;

    @Column
    private String email;

    private String noEffect;

    public Integer getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getNoEffect() {
        return noEffect;
    }

    public void setNoEffect(String noEffect) {
        this.noEffect = noEffect;
    }
}

其中:

  • @Entity 告訴jpa這是一個和數據表進行映射的實體類;
  • @Table(name="suqing_user") 代表該實體類對應的代表,若是省略(但不推薦),則實體類的類名全小寫就是表名;
  • @Id搭配@GeneratedValue(strategy = GenerationType.IDENTITY) 則代表該字段是自增主鍵;
  • @Column 則代表該字段對應數據表的一個列,省略name則表示列名就是屬性名

編寫repository

編寫一個dao接口來操做實體類對應的數據表。

repository/UserRepository.class

package com.zhaoyi.jpaweb.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import com.zhaoyi.jpaweb.entity.User;
public interface UserRepository extends JpaRepository<User, Integer> {
}

注意

  • 無需在添加任何代碼,查看JpaRepository相關的源碼咱們能夠發現,他們已經實現了包括crud在內的不少數據操做。
  • <User, Integer> 一個指明操做數據類,一個指明主鍵類型;

配置JPA

如今回到咱們的全局配置文件,配置JPA相關信息。

server:
  port: 8085
spring:
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://10.21.1.47/suqing?characterEncoding=utf8
    driver-class-name: com.mysql.cj.jdbc.Driver
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true

其中:

  • ddl-auto: update 表明更新或者建立數據表
  • show-sql: true 打印sql查詢語句日誌

運行項目,咱們發現,表已經自動爲咱們建立了。接下來咱們來測試簡單的增刪改查。

編寫測試crud

編寫UserController.

controller/UserController.class

package com.zhaoyi.jpaweb.controller;

import com.zhaoyi.jpaweb.entity.User;
import com.zhaoyi.jpaweb.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Optional;

@RestController
public class UserController {
    @Autowired
    private UserRepository userRepository;

    @RequestMapping("/user/insert")
    public User insertUser(User user){
        User save = userRepository.save(user);
        return user;
    }


    @RequestMapping("/user/delete/{id}")
    public void deleteUser(@PathVariable("id") Integer id){
        userRepository.deleteById(id);
    }

    //
    @RequestMapping("/user/select/{id}")
    public User getUser(@PathVariable("id") Integer id){
        // 這是1.x版本了
        //User user =  userRepository.findOne(id);
        User condition = new User();
        condition.setId(id);
        Example example = Example.of(condition);
        Optional<User> user =  userRepository.findOne(example);
        return  user.get();
    }

    @RequestMapping("/user/update")
    public User updateUser(User user){
        User save = userRepository.save(user);
        return user;
    }
}

2.x廣泛採用了大量的java8特性,因此不少操做和spring data 1.x的不一樣了,這些能夠在代碼中看到.

增長和修改都是統一個save方法,取決於咱們提供的id在數據庫中是否能查詢到數據,如有,則更新;不然,新增。

  1. 訪問:http://localhost:8085/user/insert?email=123456&lastName=zhaoyi&name=zhaoyi
{"id":2,"name":"zhaoyi","lastName":"zhaoyi","email":"123456","noEffect":null}
  1. 訪問: http://localhost:8085/user/select/2
{"id":2,"name":"zhaoyi","lastName":"zhaoyi","email":"123456","noEffect":null}
  1. 訪問:http://localhost:8085/user/update?id=2&email=123456&lastName=zhaoyi11&name=zhaoyi
{"id":3,"name":"zhaoyi","lastName":"zhaoyi11","email":"123456","noEffect":null}

注意此處指明的id的值,須要在數據庫中找到一個對應的進行設置。

4.訪問:http://localhost:8085/user/delete/2

(無打印信息)

刪除id=2的數據.

在進行以上操做的過程當中,能夠看到控制檯也打印了SQL語句信息:

Hibernate: select user0_.id as id1_0_, user0_.email as email2_0_, user0_.last_name as last_nam3_0_, user0_.name as name4_0_, user0_.no_effect as no_effec5_0_ from suqing_user user0_ where user0_.id=1
Hibernate: insert into suqing_user (email, last_name, name, no_effect) values (?, ?, ?, ?)
Hibernate: select user0_.id as id1_0_, user0_.email as email2_0_, user0_.last_name as last_nam3_0_, user0_.name as name4_0_, user0_.no_effect as no_effec5_0_ from suqing_user user0_ where user0_.id=2
Hibernate: insert into suqing_user (email, last_name, name, no_effect) values (?, ?, ?, ?)
Hibernate: select user0_.id as id1_0_0_, user0_.email as email2_0_0_, user0_.last_name as last_nam3_0_0_, user0_.name as name4_0_0_, user0_.no_effect as no_effec5_0_0_ from suqing_user user0_ where user0_.id=?
Hibernate: update suqing_user set email=?, last_name=?, name=?, no_effect=? where id=?
Hibernate: select user0_.id as id1_0_0_, user0_.email as email2_0_0_, user0_.last_name as last_nam3_0_0_, user0_.name as name4_0_0_, user0_.no_effect as no_effec5_0_0_ from suqing_user user0_ where user0_.id=?
Hibernate: insert into suqing_user (email, last_name, name, no_effect) values (?, ?, ?, ?)
Hibernate: select user0_.id as id1_0_0_, user0_.email as email2_0_0_, user0_.last_name as last_nam3_0_0_, user0_.name as name4_0_0_, user0_.no_effect as no_effec5_0_0_ from suqing_user user0_ where user0_.id=?
Hibernate: delete from suqing_user where id=?
...

至此,咱們就完成了JPA的整合了,其實只是其冰山一角的使用方式,包括JSR標準的註解還有許多沒有提到,更重要的是JAP體系的其餘模塊,之後有時間,再一一介紹了。

另外,這裏提供一個SpringBoot整合各類案例的參考Github項目:前往

相關文章
相關標籤/搜索