- 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