SpringBoot入門(IDEA篇)(三)


一、什么是JPA

  JPA(Java Persistence API)定義了一系列對象持久化的標准,目前實現這一規范的產品有Hibernate、TopLink等。

二、Mysql數據庫示例

  1、在application.yml文件中增加數據庫訪問的配置

  

  ddl-auto:可選屬性有以下幾種。

  

  create   每次創建一個新表,那么之前表中的數據都會丟掉

  update  表不存在的時候才會建立新表,如果存在則不會新建,所以原有數據不會丟

  create-drop  每次新建一個表,而且服務停掉,那么所建立的表會隨之刪除

  none   見名知意,就是什么都不做,不會給幫你建表,只能使用現有的表

  validate  會將實體類和表進行一個驗證,如果不一致會報錯

  2、新建實體類

  

package com.zmfx.jpa;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;


@Entity
public class Dog {
    /*
        如果這些注解所在的包,javax.persistence不能導入。可能是缺少依賴
        可以在pom中加入Javax Persistence API 的依賴
     */
    @Id
    @GeneratedValue
    private Integer id;//編號
    private Integer age;//年齡
    private String name;//名字

    public Dog() {
    }

    public Dog(Integer id, Integer age, String name) {
        this.id = id;
        this.age = age;
        this.name = name;
    }

    public Integer getId() {
        return id;
    }

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

    public Integer getAge() {
        return age;
    }

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

    public String getName() {
        return name;
    }

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

  3、編寫Repository接口類

    這里需要繼承JpaRepository這個類,這樣我們就可以使用底層幫我們實現好的一些代碼

    相當於我們之前了解到的持久層(數據訪問層),用於獲取數據庫中的數據。

  4、編寫Serivce層

    按照策略模式,我們應當一個接口,然后對應實現類。由於這里業務比較簡單,我們就不那么費事了。可能這層我在下面都不寫。

  5、編寫Controller層

    根據訪問信息,進行相應的業務處理,頁面展示。

 

三、RestFul API

  1、查詢所有,findAll()方法的使用。GET請求

    Repository接口類

package com.zmfx.jpa;

import org.springframework.data.jpa.repository.JpaRepository;

/**
 * 這個接口需要繼承一個接口JpaRepository
 * 這樣就可以使用底層為我們編寫好的一些通用方法
 */
public interface DogRepository extends JpaRepository<Dog,Integer> {
}

    Controller層

package com.zmfx.jpa;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * 控制層
 */
@RestController
public class DogController {
    //因為業務太簡單,所有我們省略service層,直接調用數據訪問層的代碼
    @Autowired
    private DogRepository dogRepository;
    /**
     * 查詢所有女生列表
     * @return
     */
    @GetMapping(value="/dogs")
    public List<Dog> dogList(){
        return dogRepository.findAll();//findAll()方法是底層幫我沒實現好的
    }
}

  這里推薦一個軟件PostMan,可以模擬前端的http訪問,可以不用編寫頁面

 

 2、根據id查詢一條記錄,findById()的使用,GET請求

   在controller中新加以下代碼

 /**
     * 根據id查詢指定的Dog
     * @param id
     * @return
     */
    @GetMapping(value = "/dog/{id}")
    public Optional<Dog> findDogById(@PathVariable("id") Integer id){
        return dogRepository.findById(id);//注意這個方法的返回值
    }

然后,使用PostMan進行訪問,展示如下:

  

 

 3、添加一個Dog,save()方法的使用,POST請求

  controller層中新加以下代碼

 /**
     * 添加一個Dog
     * @param age
     * @param name
     * @return
     */
    @PostMapping(value = "/addDog")
    public Dog addDog(@RequestParam("age") Integer age,
                      @RequestParam("name") String name){
        Dog dog=new Dog();
        dog.setAge(age);
        dog.setName(name);
        return dogRepository.save(dog);
    }

然后用PostMan進行訪問,展示效果如下:

 

 4、更新dog的信息,save()方法的使用,Put請求

  在controller增加下面代碼

/**
     * 更新Dog信息
     * @param id
     * @param age
     * @param name
     * @return
     */
    @PutMapping(value = "updateDog/{id}")
    public Dog updateDog(@PathVariable("id") Integer id,
                         @RequestParam("age") Integer age,
                         @RequestParam("name") String name){
        Dog dog=new Dog();
        dog.setId(id);
        dog.setName(name);
        dog.setAge(age);
        System.out.println(dog);
        return dogRepository.save(dog);//注意這里使用save()方法,根據主鍵,所以主鍵不能更改
    }

  這里使用PostMan的PUT請求,注意使用x-www-form-urlencoded進行傳參

  訪問后的效果應當如下:

 

 5、刪除一條記錄,deleteById()方法,DELETE請求

  controller中加入以下代碼:

/**
     * 刪除一條記錄
     * @param id
     */
    @DeleteMapping(value = "/del/{id}")
    public void delDogById(@PathVariable("id") Integer id){
        dogRepository.deleteById(id);
    }

  PostMan中使用DELETTE請求,因為沒有返回值,所以需要到數據庫中查看效果

 

  6、根據年齡來查詢,自己在Repository中定義

  DogRepository中變為

package com.zmfx.jpa;

import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

/**
 * 這個接口需要繼承一個接口JpaRepository
 * 這樣就可以使用底層為我們編寫好的一些通用方法
 */
public interface DogRepository extends JpaRepository<Dog,Integer> {
    //通過年齡來查詢
    List<Dog>  findByAge(Integer age);//注意方法名的格式,findBy+屬性名。

}

  Controller中新增代碼

/**
     * 根據年齡來查詢
     */
    @GetMapping(value = "/dogs/{age}")
    public List<Dog> dogList(@PathVariable("age")Integer age){
        return dogRepository.findByAge(age);
    }

  然后使用PostMan進行訪問,展示如下:

  

 四、事務管理

  1、加入事務之前

  controller層加入代碼

//這里涉及到事務,所以我們加入service的依賴
    @Autowired
    private DogService dogService;
    /**
     * 事務測試的方法
     */
    @GetMapping(value = "/dogs/tx")
    public void txTest(){
        System.out.println("進入了controller");
        dogService.addTwoDog();
    }

  service層代碼,這里用到了事務,所以要新建一個DogService類

package com.zmfx.jpa;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class DogService {
    @Autowired
    private DogRepository dogRepository;
    /**
     * 同時添加兩條記錄
     */
    public void addTwoDog(){
        //模擬兩條數據
        Dog dog1=new Dog();
        dog1.setAge(2);
        dog1.setName("小黑1");
        //模擬第二條數據
        Dog dog2=new Dog();
        dog2.setAge(2);
        dog2.setName("小黑2");
        System.out.println("進入了service");
        //將數據插入到數據庫
        dogRepository.save(dog1);
        System.out.println(5/0);//模擬異常
        dogRepository.save(dog2);
    }
}

  然后使用 http://127.0.0.1:8083/dev/dogs/tx 進行訪問,我們發現后台拋出異常,但是數據庫還是添加了第一條的記錄。

  

 

 2、加入事務之后

  我們就能夠讓小黑1 和 小黑2 同生共死了。

  其它的都不變,然后再需要添加事務的方法上,添加一個@Transactional注解。也就是service的 public void addTwoDog()上加入注解

  

package com.zmfx.jpa;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class DogService {
    @Autowired
    private DogRepository dogRepository;
    /**
     * 同時添加兩條記錄
     */
    @Transactional  //加入事務控制
    public void addTwoDog(){
        //模擬兩條數據
        Dog dog1=new Dog();
        dog1.setAge(2);
        dog1.setName("小黑1");
        //模擬第二條數據
        Dog dog2=new Dog();
        dog2.setAge(2);
        dog2.setName("小黑2");
        System.out.println("進入了service");
        //將數據插入到數據庫
        dogRepository.save(dog1);
        System.out.println(5/0);//模擬異常
        dogRepository.save(dog2);
    }
}

  然后刪除數據庫中,小黑1這條記錄,重啟springboot服務,再次訪問 http://127.0.0.1:8083/dev/dogs/tx 。

  還是那個異常,然后去看數據庫,發現兩條記錄都沒有添加進來。事務控制添加成功。

 

 

   


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM