spring boot jpa學習:2.DAO和Service的自增id、刪、查、改操作


  • Model:User
  • DAO:UserDAO接口(繼承JpaRepository<User, Integer>)
    只用寫關於查找的自定義操作。
  • Service:UserService
    基本調用DAO的默認繼承方法就行。

spring boot jpa學習:1.Model類的註釋annatation

spring boot jpa學習:2.DAO和Service的自增id、刪、查、改操作

spring boot jpa學習:3.Controller層的入門


一、自增操作

1.數據庫中的表是自增的

AI表示Auto Increme
在這裏插入圖片描述

2.Entity類的annatation和setter、getter方法

  1. 關鍵是@GeneratedValue(strategy = GenerationType.IDENTITY)的聲明,表示自增。如果沒用這個的話,saveAndFlush()返回的對象中是不會獲得自增的值的。

  2. setter、getter方法也是必須的。

  3. 其他基本的也得ok@Entity@Id@Column(name = "userid")

package com.sand.alphon.model;

import com.fasterxml.jackson.annotation.JsonProperty;
import jdk.nashorn.internal.objects.annotations.Getter;

import javax.persistence.*;

@Entity
public class User {
    @Id
    @Column(name = "userid")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int userId;

    private String password;

    private String name;

    private int sex;

    private int age;

    private String email;

    @Column(name = "phonenum")
    private String phoneNum;

    private String type;

    public int getUserId() {
        return userId;
    }

    public void setUserId(int userId) {
        this.userId = userId;
    }

    public String getPassword() {
        return password;
    }

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

    public String getName() {
        return name;
    }

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

    public int getSex() {
        return sex;
    }

    public void setSex(int sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

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

    public String getEmail() {
        return email;
    }

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

    public String getPhoneNum() {
        return phoneNum;
    }

    public void setPhoneNum(String phoneNum) {
        this.phoneNum = phoneNum;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }
}

3.Service

不需要在DAO中寫,默認生成的方法saveAndFlush()就好。

@Service
public class UserService {
    @Autowired
    UserDAO userDAO;

    /*
     * 增
     * 因爲是不指定userId,而是自增,所以不檢查存在與否
     * 使用save()不能獲得新增的主鍵userId,因爲沒真正提交,要使用saveAndFlush
     */
    public User add(User user){
        return userDAO.saveAndFlush(user);
    }
}

(1)saveAndFlush

區別:

  • 使用saveAndFlush():此命令中的更改將立即刷新到DB。
  • 使用save():不一定了,它可能只暫時保留在內存中,直到發出flush或commit命令。

所以:

  • 使用saveAndFlush()方法就可以立即獲取到這條數據的自增id
  • 使用save()方法,你不flush()或者commit,你得數據是暫時只在內存中保存,所以此時這條數據是沒有主鍵id的。

(2)爲何自增的id是非null

這樣我在調用的時候,不用傳userId,調用自增後就能獲得自增的userId。(其實默認實例化後是0,但userId是主鍵非null,所以數據庫判斷後幫助我們自增一個非null 的useId。)

User user = new User();
user.setName(map.get("name").toString());
user.setPassword(map.get("password").toString());
user.setEmail(map.get("email").toString());
user.setPhoneNum(map.get("phonenum").toString());
user.setSex((int)Double.parseDouble(map.get("sex").toString()));
user.setAge((int)Double.parseDouble(map.get("age").toString()));
user.setType("reader");
// System.out.println(user.getUserId());	// 其實是0

User resultUser = userService.add(user);
System.out.println(resultUser.getUserId());

在這裏插入圖片描述

二、刪除操作

1.service

直接用默認的deleteByXXX()existsByXXX()

/*
 * 刪
 * 先返回存在與否(不存在就是刪除失敗),然後刪除
 */
public boolean delete(int userId){
    // 表示沒有,你刪錯了
    if(!userDAO.existsById(userId)){
        return false;
    }
    userDAO.deleteById(userId);
    return true;
}

三、查找操作

1.根據主鍵查找

如果只用根據主鍵查找的話,不用DAO中寫東西。
因爲有默認的查找主鍵的方法,findById()

這個函數返回一個容器Optional對象。
optional.orElse(null)的意思是:

  • 如果要查找的userId存在,則返回對應的User對象;
  • 如果不存在,則返回orElse()中的東西,我這裏讓返回null

代碼:

  • Service:
/*
 * 查
 * 返回User類
 */
public User findByUserId(User user){
    return userDAO.findById(user.getUserId()).orElse(null);
}

2.獲取所有

不用DAO中寫東西,用默認的findAll()

userDAO.findAll()

3.自定義查找

(1)按規則

在這裏插入圖片描述
按照findByXXX,組合列名和邏輯舊行了,都不用實現。比如,

public interface UserDAO extends JpaRepository<User,Integer> {
    // 根據userName查找
    List<User> findAllByName(String name);

    // 根據userId和name一起查找都符合的
    User findByUserIdAndName(int userId,String name);	
}

在這裏插入圖片描述

四、更新操作

1.service

直接用默認的existsByXXX()saveAndFlush()

/*
 * 改
 * saveAndFlush()本來就能做到不存在插入新的,存在更新舊的。
 * 我們只想更新一箇舊值,而不是整一個新的輸錯的值。
 */
public boolean edit(User user){
    if(userDAO.existsById(user.getUserId())){
        userDAO.saveAndFlush(user);
        return true;
    }else {
        return false;
    }
}

2.saveAndFlush()機制

我們之所以不直接使用saveAndFlush(),是因爲它的機制:

  • 如果沒有這個userId,即要插入新記錄:那麼就會調用DB的insert語句
    在這裏插入圖片描述
  • 如果已有這個userId,即要更新舊記錄:那麼就會調用DB的update語句
    在這裏插入圖片描述

所以,先判斷userId存在嗎,再決定更新。

五、自定義查詢

1.不傳入參數

@Query(value = "select * from book",nativeQuery = true)
List<String> myFindCategory();

函數名不要和默認函數重複。
兩個:value是sql語句和nativeQuery=true表示使用sql原生語句

2.指定靜態參數

@Query(value = "select * from book where book.bookname = '高數1'", nativeQuery = true)
List<Book> findAllByBookName(String bookName);

將其值用''包括起來。

3.傳入動態參數

@Query(value = "select * from book where bookid = ?1",nativeQuery = true)
List<String> myFindCategory(int bookid);

?1就是函數傳進來的第一個參數,以此類推?2……


Reference

SpringData JPA save和saveAndFlush方法區別
spring jpa 獲取自增id

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