【SpringBoot】數據持久化——JPA(1)搭建環境

如果餓了就吃,困了就睡,渴了就喝,人生就太無趣了
源碼地址:https://github.com/keer123456789/springbootstudy/tree/master/jpa_demo
本人剛剛接觸jpa,如有錯誤,歡迎大家指正!!


1.JPA介紹

JPA(Java Persistence API)Java持久化API,是 Java 持久化的標準規範,Hibernate是持久化規範的技術實現,而Spring Data JPA是在 Hibernate 基礎上封裝的一款框架。JPA作爲標準,實際上並沒有說侷限於某個固定的數據源,事實上mysql,mongo, solr都是ok的。接下來我們將介紹下springboot結合jpa 來實現mysql的curd以及更加複雜一點的sql支持

2.環境配置

2.1 數據庫配置

數據庫選擇mysql數據庫。並新建一個數據庫jpademo1。如圖

在這裏插入圖片描述

2.2 SpringBoot pom 配置

mysql依賴中的版本根據自己的mysql版本配置。

	<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.11</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

2.3 MySQL數據源配置

mysql的基本配置,不再過多解釋。

spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/jpademo?useSSL=false&serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

2.4 jpa配置

每個屬性的解釋都在註釋中,

  • spring.jpa.show-sql建議開啓,這個會在日誌中打印sql語句,對之後的調試很有幫助。
  • ddl-auto:update 每次運行程序,沒有表格會新建表格,表內有數據不會清空,只會更新
# JPA配置
spring.jpa.database=mysql
# 在控制檯打印SQL
spring.jpa.show-sql=true
# 數據庫平臺
spring.jpa.database-platform=mysql
# 每次啓動項目時,數據庫初始化策略
spring.jpa.hibernate.ddl-auto=update
# 指定默認的存儲引擎爲InnoDB
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect

3.Entity介紹

JPA提供了實體與庫表的映射關係。只需要使用@Entity註解即可。

  • @Entity
    • 聲明這個POJO是一個與數據庫中叫做 user 的表關聯的對象.
    • 參數name,用於指定表名,如果不主動指定時,默認用類名,即上面如果不指定那麼,那麼默認與表 user 綁定
  • @Column
    • 這個註解就是用來解決我們pojo成員名和數據庫列名不一致的問題的
    • name參數填寫表名
    • nullable參數是表示該列是否可以爲空
  • 主鍵註解
    • @Id 註解 表示這個列是主鍵,關係型數據中很重的。
    • @GeneratedValue設置初始值,談到主鍵,我們一般會和”自增“這個一起說,所以你經常會看到的取值爲 strategy = GenerationType.IDENTITY(由數據庫自動生成)
      這個註解提供了四種形式,關於這幾種使用姿勢,這裏不詳細展開了,有興趣的可以可以看一下這博文: @GeneratedValue
取值 說明
GenerationType.TABLE 使用一個特定的數據庫表格來保存主鍵
GenerationType.SEQUENCE 根據底層數據庫的序列來生成主鍵,條件是數據庫支持序列
GenerationType.IDENTITY 主鍵由數據庫自動生成(主要是自動增長型)
GenerationType.AUTO 主鍵由程序控制
@Entity(name = "user")
public class User {
    @Column(name = "name", nullable = false)
    private String name;
    @Column(name = "password", nullable = false)
    private String password;
    @Column(name = "address", nullable = false)
    private String address;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    public User() {
    }

    public String getName() {
        return name;
    }

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

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public int getId() {
        return id;
    }

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

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", password='" + password + '\'' +
                ", address='" + address + '\'' +
                ", id=" + id +
                '}';
    }
}

4.增刪改查

jpa只需要繼承一個接口即可完成DB的操作。這次繼承的CrudRepository類。這樣就可以實現很多操作。

@Component
public interface UserDao extends CrudRepository<User, Integer> {
}

4.1 Select

由於繼承了CrudRepository接口,這個接口提供了三個查詢方法,如圖

  • 查詢表中所有User信息
  • 根據主鍵查詢相應的User
  • 根據一組主鍵查詢相應的信息。

在這裏插入圖片描述

這單單是此接口實現的根據主鍵查詢的方法,jpa具有強大的查詢功能,實現了GroupBy,having等等高級的sql查詢功能,這些功能會在之後的博客中介紹……

這次簡單的介紹findAll()的功能。在Service層進行查詢。查尋完成之後返回給controller,即可,webResult返回請求的自定義的值。具體的就不在介紹,可以自行去項目中查看。

public WebResult selectAllUsers(){
    List<User> users= (List<User>) userDao.findAll();
    WebResult webResult=new WebResult();
    webResult.setStatus(WebResult.SUCCESS);
    webResult.setMessage("查詢成功");
    webResult.setData(users);
    logger.info("查詢成功,數據:"+users.toString());
    return webResult;
}

如圖,可以看到查詢語句

在這裏插入圖片描述

數據庫中的數據和日誌打印出來的數據:
在這裏插入圖片描述

4.2 Insert

1.插入單個數據

public WebResult addUser(User user) {
        User res = userDao.save(user);
        WebResult result = new WebResult();
        if (res != null) {
            result.setData(user);
            result.setMessage("增加成功");
            result.setStatus(WebResult.SUCCESS);
            return result;
        }
        return null;
    }
  • 調用接口的save()方法。入參是需要增加的User信息

進行測試:
測試數據:

#增加用戶信息
POST http://127.0.0.1:8080/jpa/addUser
Content-Type: application/json

{
  "id": 4,
  "name": "keer",
  "password": "133333",
  "address": "北京市平谷區"
}

測試結果:
在這裏插入圖片描述

  • 先根據id進行查詢(防止主鍵重複,這是一種可能,原因在update的時候在深入解釋)。
  • 然後在進行插入操作

2.批量插入
同樣是調用接口已經有的方法,saveAll()方法,入參是User的list數組

public WebResult addUsers(List list) {
    WebResult webResult = new WebResult();
    userDao.saveAll(list);
    List<User> failUsers = new ArrayList<>();
    for (Object o : list) {
        User user = (User) o;
        if (!userDao.existsById(user.getId())) {
            failUsers.add(user);
        }
    }
    if (failUsers.size() == 0) {
        webResult.setStatus(WebResult.SUCCESS);
        webResult.setMessage("插入成功");
    } else {
        webResult.setMessage("部分插入失敗");
        webResult.setData(failUsers);
        webResult.setStatus(WebResult.ERROR);
    }
    return webResult;
}

進行測試:
測試數據:

#批量增加用戶
POST http://127.0.0.1:8080/jpa/addUsers
Content-Type: application/json

[
  {
    "name": "可耳",
    "password": "love",
    "address": "北京市"
  },
  {
    "name": "java",
    "password": "hello world",
    "address": "main()"
  }

]

測試結果:
在這裏插入圖片描述

  • 這次沒有指明主鍵id,因爲是自增主鍵,所以就自動生成了
  • 日誌中的select語句,是因爲調用了existsById()方法進行查詢是否存在。

4.3 Delete

刪除操作直接調用接口中的delete()方法,入參是user實例

public WebResult removeUser(User user) {
    userDao.delete(user);
    WebResult webResult = new WebResult();
    if (!userDao.existsById(user.getId())) {
        webResult.setStatus(WebResult.SUCCESS);
        webResult.setMessage("刪除用戶信息成功!");
    } else {
        webResult.setStatus(WebResult.ERROR);
        webResult.setMessage("刪除用戶信息失敗!");
    }
    return webResult;
}

進行測試:
測試數據:

#刪除用戶
POST http://127.0.0.1:8080/jpa/deleteUser
Content-Type: application/json

{
  "name": "java",
  "password": "hello world",
  "address": "main()",
  "id": 6
}

測試結果:
在這裏插入圖片描述

  • 日誌中首先使用主鍵進行了查詢
  • 之後再進行刪除
  • 日誌中的select語句,是因爲調用了existsById()方法進行查詢是否存在。

4.4 Updata

1.使用save()方法,數據必須帶有主鍵,而且需要user中帶有全部數據,這樣才能進行update。

public WebResult updateUser(User user) {
    WebResult webResult = new WebResult();
    User newUser = userDao.save(user);
    logger.info("更新信息:" + newUser.toString());
    webResult.setMessage("更新操作成功");
    webResult.setData(newUser);
    webResult.setStatus(WebResult.SUCCESS);
    return webResult;
}

進行測試:
測試數據:

POST http://127.0.0.1:8080/jpa/updateUser
Content-Type: application/json

{
  "id": 1,
  "name": "keer",
  "password": "133333",
  "address": "北京市平谷區"
}

測試結果:

在這裏插入圖片描述

  • 日誌中首先使用主鍵進行了查詢(回答上面的問題,查詢這個id對應的記錄是否存在,存在就是update,不存在就是insert)

參考博客:http://spring.hhui.top/spring-blog/2019/06/14/190614-SpringBoot%E7%B3%BB%E5%88%97%E6%95%99%E7%A8%8BJPA%E4%B9%8B%E6%96%B0%E5%A2%9E%E8%AE%B0%E5%BD%95%E4%BD%BF%E7%94%A8%E5%A7%BF%E5%8A%BF/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章