SpringBoot整合Spring Data Jpa(快速入門,自定義查詢)

1.Spring Data Jpa是什麼?
答:我也不知道。
2.Spring Data Jpa可以做什麼?
答:我還是不知道。
3.爲什麼使用Spring Data Jpa?
答:不是很清楚
4.那你能幹嘛?
答:我只想說一下怎麼快速上手Jpa

那麼請開始你的表演

  • 1.快速搭建環境,和簡單查詢
  • 1-1.加入Jpa依賴
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
  • 1-2.加入相關配置(數據庫自己改)
server.port=80 
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/m5?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true
spring.datasource.username=root
spring.datasource.password=root

#Jpa的配置 有興趣可以百度一個ddl-auto 這是對數據庫操作的,有創建,更新等等,,,
#spring.jpa.hibernate.ddl-auto=create-drop
#更新數據庫
spring.jpa.hibernate.ddl-auto=update
  • 1-3.創建一個實體類
@Data
@Entity
public class MyOrder {

    @Id                         //數據庫id
    Long id;                    //數據庫主鍵
    Boolean isDispose;          //是否處理
    String selectFrom;          //庫存組織
    String departmaent;         //部門
    @Column(name = "warehouse",unique = true,nullable=false)  //數據庫指定名稱,不能重複,且不能爲空
    String warehouse;           //倉庫
    Date outTime;               //出庫時間
    ...

}

@Data:lombok插件,建華代碼
@Entity:標註此類爲實體類,根據我們的配置文件配置會進行對數據庫的更新或者創建等
@Column:標註在實體類屬性上,還有其他屬性等待老鐵們自行發覺

另外更多的屬性的註解老鐵們可以百度,比如主鍵自增啥的。

  • 1-4.創建一個接口,繼承已經定義好的JpaRepository,MongoRepository,CrudRepository,Repository等(接口可以多繼承,當然繼承JpaRepository基本上就差不多了)
//我們創建一個接口繼承JpaRepository<T, ID> 
//其中T指的是我們剛那個實體類,ID指的是我們實體類的主鍵的類型
//當然我們可以多繼承,比如上面那幾個,Repository是根
public interface MyOrderRepo extends JpaRepository<MyOrder,Long> {
}

好了這樣我們就可以使用MyOrderRepo 進行簡單的CRUD(增刪改查)操作了,但是有人說,我這個接口不是什麼都沒寫嗎?怎麼進行增刪改查?
我沒寫,但是並不代表我繼承的接口沒寫哦!老鐵們可以點進JpaRepository進行查看,裏面爲我們寫好了常見的增刪改查操作,比如save,saveAll,findAll,findAllById,自己點進去看一下就明白了,到時候我們只需要調用父類的接口就可以完成簡單的增刪改查。

  • 1-5.開始使用接口完成增刪改
@Service
public class MyOrderServiceImpl implements MyOrderService {

	//注入我們剛剛寫好的接口 這裏的service 可以自己創一個 這個跟主題無關,我就不累述
    @Autowired
    private MyOrderRepo myOrderRepo;

	//新增一個MyOrder
	public void saveOrder(MyOrder myOrder){
		//調用save方法 可以拿到剛新增的數據
		MyOrder save = myOrderRepo.save(myOrder);
	}
	
	//新增一個MyOrder
	public void saveOrders(List<MyOrder > myOrders){
		//調用saveAll方法 可以拿到剛新增的數據
		List<MyOrder > saves = myOrderRepo.saveAll(myOrders);
	}
	
	//根據id查詢
	public void findById(Long id){
		//因爲返回值是Optional<T>  所以要調用get()
		MyOrder myOrder = myOrderRepo.findById(id).get();
	}
	
	//根據id刪除
	public void deleteById(Long id){
		//因爲返回值是Optional<T>  所以要調用get()
		myOrderRepo.deleteById(id);
	}

}

因爲沒有提供關於update的接口,所以我們還需要自己一會來自己寫語句進行執行update語句,以上就是簡單的使用增加,查詢,和刪除,其中還有很多的方法需要老鐵們自己發掘。

因爲上面簡單的一些CRUD語句顯然是不滿足我們的業務需求的,那這個時候怎麼辦呢?那當然是自定義接口使用啦

  • 2.自定義接口,實現更復雜的查詢
  • 2-1.請參考1-4的,創建一個接口,並繼承一些藉口
//這裏我們就不多說了哈 之所以前面要使用這種方式,是因爲後面會用到
//因爲一個項目不可能是他提供的那些接口就能解決的,所以接口遲早要創建
public interface MyOrderRepo extends JpaRepository<MyOrder,Long> {

	//好了我們可以在這裏自定義接口啦
	//根據isDispose(MyOrder中的字段) 來查詢出相關的MyOrder
	//這樣我們就可以在我們的serviceImpl層調用findByIsDispose這個接口了
    MyOrder findByIsDispose(@Param("isDispose")Boolean  isDispose);

	//這是分頁查詢 調用這個方法就會進行分頁查詢,默認頁數是0,一頁顯示數是20
  	Page<MyOrder> findAll(Pageable pageable);

	//一下代碼是寫在service中的 這裏爲了偷懶
	//這就是分頁需要的參數,第一個參數page是第幾頁,默認爲0,size是一頁顯示的數據,默認爲20
	//sort,是排序方式,ASC|DESC  兩種排序方式
	 Pageable pageable = PageRequest.of(0,20, Sort.Direction.ASC);
	 //這裏就調用了我們剛到分頁 
     myOrderRepo.findAll(pageable);
}

這裏有疑問的小夥伴們又有問題了,那就是我還是沒寫sql啊,他怎麼知道我需要的是根據isDispose進行查詢?

其實我這裏命名是有規範的,之所以能查詢出來,那是因爲我在按照他們的規則進行命名,他們當然能識別啦,具體的關鍵字可以參考下面這個圖,可以以百度:Jpa關鍵字
在這裏插入圖片描述
到了這裏我們就基本上把自定義接口,和使用接口和分頁說完了,自定義可以根據上面的圖片的關鍵字進行自定義

但是有小夥伴問了,我想自己寫sql語句咋辦。
答案是可以的,接下來我們就進入自己寫sql環節

  • 3.自己定義sql語句
  • 3-1.使用 @Query註解進行自定義sql
//同樣的 我們還需要定義一個接口參考1-4
public interface MyOrderRepo extends JpaRepository<MyOrder,Long>{

  //1.沒有參數直接查詢
    @Query(value = "select * from my_order",nativeQuery = true)
    List<MyOrder> getAll();

    //2.sql語句獲取參數方式 ?1 表示第一個參數 ?2 表示第二個參數,這裏只寫一個
    //使用 ? 的方式進行獲取參數就可以不使用 @Param 註解指定名稱
    @Query(value = "select * from my_order where id = ?1",nativeQuery = true)
    MyOrder getMyOrderById(@Param("id")Long id);

    //3.sql語句入參方式 使用 @Param 指定名稱直接按照名獲取 這裏演示是departmaent 所以使用  :departmaent即可
    //如果多個參數還是使用 :+@Param裏面的值即可 如:@Param("xxx") 那麼sql取值的時候就應該是::xxx
    @Query(value = "select * from my_order where departmaent = :departmaent",nativeQuery = true)
    MyOrder getMyOrderBydepartmaent(@Param("departmaent")String departmaent);


    //4.1.如果參數是實體類(也不一定是,這裏是用的接口指定的實體類,不是指定的實體類也是這樣使用,但是接口指定實體類還有一種,看4.2)
    //第一種::#{#xxx1.xxx2}  其中xxx1是@Param("myOrder")中指定的名稱  xxx2就是該實體類的字段名稱
    @Query(value = "select * from my_order where departmaent = :#{#myOrder.test}",nativeQuery = true)
    MyOrder newMyOrderBydepartmaent(@Param("myOrder")MyOrder myOrder);

    //4.2.如果參數實體類是本接口指定的實體類,如MyOrder
    //第二種:?#{[0]} 這裏面的 [0]指的是實體類中的第0個屬性,
    //或者可以寫成?#{myOrder.emailAddress,但是這裏的myOrder是在創建MyOrder實體類的時候使用@Entity(name="myOrder")指定的
    //這裏4.2完全是一種拓展,其實使用4.1的方式不管是不是本接口指定的實體類參數都可以完成sql語句參數的綁定
    @Query(value = "select * from my_order where departmaent = :#{#test}",nativeQuery = true)
    MyOrder newMyOrderBydepartmaent();
	

	//實戰 原始分頁 並且格式化時間進行判斷 查詢
	//根據時間查詢 並且分頁 
    @Query(value = "SELECT * FROM my_order WHERE is_dispose = 0 AND DATE_FORMAT( out_time, '%Y-%m-%d' ) " +
            "= :#{#myOrderParam.outTime} LIMIT :#{#myOrderParam.curPage} , :#{#myOrderParam.pageNum}",nativeQuery = true)
    List<MyOrder> getAllMyOrderByDepartmaentAndOutTime(@Param("myOrderParam")MyOrderParam myOrderParam);


}

||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
這一部分 推薦一定要好好看一下代碼中的註釋

這一部分完成了我想就基本上滿足很大一部分需求了把,在自定義接口自己寫sql語句的時候的名稱就可以隨便自己定義了,因爲我們已經綁定了自己執行的sql語句了,在綁定sql語句的時候nativeQuery = true標識在本地執行sql語句,推薦還是所有的都加上

||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
另外一定要記得在自己寫update語句和delete的sql語句的時候一定要加上 @Modifying 註解

好了到了這裏我想好好研究一下就基本上能對Jpa上手使用了,另外推薦大家也可以去官方文檔看看

~~謝謝大家的觀看

Spring Data Jpa官網:https://docs.spring.io/spring-data/jpa/docs/2.1.10.RELEASE/reference/html/#jpa.query.spel-expressions

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