1. 程式人生 > >Spring Data JPA進階-呼叫儲存過程

Spring Data JPA進階-呼叫儲存過程

JPA連線到資料庫,呼叫儲存過程,這樣的需求很常見。本文就針對這一點,講述如何使用spring Data JPA呼叫儲存過程的方法。

1、儲存過程

假設儲存過程如下:

CREATE OR REPLACE PACKAGE test_pkg AS
  PROCEDURE in_only_test (inParam1 IN VARCHAR2);
  PROCEDURE in_and_out_test (inParam1 IN VARCHAR2, outParam1 OUT VARCHAR2);
END test_pkg;
/
CREATE OR REPLACE PACKAGE BODY test_pkg AS
  PROCEDURE in_only_test(inParam1 IN VARCHAR2) AS
  BEGIN
   DBMS_OUTPUT.PUT_LINE('in_only_test');
  END in_only_test;
  PROCEDURE in_and_out_test(inParam1 IN VARCHAR2, outParam1 OUT VARCHAR2) AS
  BEGIN
   outParam1 := 'Woohoo Im an outparam, and this is my inparam ' || inParam1;
  END in_and_out_test;
END test_pkg;

這裡有兩個儲存過程:

1)in_only_test 

它需要一個輸入引數inParam1,但不返回值

2)in_and_out_test 

它需要一個輸入引數inParam1,且返回值outParam1

2、@NamedStoredProcedureQueries

我們可以使用@NamedStoredProcedureQueries註釋來呼叫儲存過程。

@Entity
@Table(name = "MYTABLE")
@NamedStoredProcedureQueries({
    @NamedStoredProcedureQuery(name = "in_only_test", procedureName = "test_pkg.in_only_test", parameters = {
        @StoredProcedureParameter(mode = ParameterMode.IN, name = "inParam1", type = String.class) }),
    @NamedStoredProcedureQuery(name = "in_and_out_test", procedureName = "test_pkg.in_and_out_test", parameters = {
        @StoredProcedureParameter(mode = ParameterMode.IN, name = "inParam1", type = String.class),
        @StoredProcedureParameter(mode = ParameterMode.OUT, name = "outParam1", type = String.class) }) })
public class MyTable implements Serializable {
}

關鍵要點:

  1. 儲存過程使用了註釋@NamedStoredProcedureQuery,並繫結到一個JPA表。
  2. procedureName是儲存過程的名字
  3. name是JPA中的儲存過程的名字
  4. 使用註釋@StoredProcedureParameter來定義儲存過程使用的IN/OUT引數

3、建立Spring Data JPA資料庫

下面我們來建立Spring Data JPA資料庫:

public interface MyTableRepository extends CrudRepository<MyTable, Long> {
  @Procedure(name = "in_only_test")
  void inOnlyTest(@Param("inParam1") String inParam1);

  @Procedure(name = "in_and_out_test")
  String inAndOutTest(@Param("inParam1") String inParam1);
}

關鍵要點:

  1. @Procedure的name引數必須匹配@NamedStoredProcedureQuery的name
  2. @Param必須匹配@StoredProcedureParameter註釋的name引數
  3. 返回型別必須匹配:in_only_test儲存過程返回是void,in_and_out_test儲存過程必須返回String

4、呼叫

我們可以這樣呼叫儲存過程:

  // 向儲存過程傳遞引數並返回值
  String inParam = "Hi Im an inputParam";
  String outParam = myTableRepository.inAndOutTest(inParam);
  Assert.assertEquals(outParam, "Woohoo Im an outparam, and this is my inparam Hi Im an inputParam");
  // 向儲存過程傳遞引數不返回值
  myTableRepository.inOnlyTest(inParam);

5、其它技巧

如果上面的程式碼不工作,可以這麼解決。定義自定義的Repository來呼叫儲存過程昨晚本地查詢。

定義自定義的Repository:

public interface MyTableRepositoryCustom {
  void inOnlyTest(String inParam1);
}

然後要確保主Repository類繼承了這個介面。

複製程式碼程式碼如下:
public interface MyTableRepository extends CrudRepository<MyTable, Long>, MyTableRepositoryCustom {}

6、建立Repository實現類

接著該建立Repository實現類了:

public class MyTableRepositoryImpl implements MyTableRepositoryCustom { 
@PersistenceContext 
private EntityManager em;

@Override
public void inOnlyTest(String inParam1) {
  this.em.createNativeQuery("BEGIN in_only_test(:inParam1); END;").setParameter("inParam1", inParam1)
      .executeUpdate();
}
}

可以以常規的方式進行呼叫:

@Autowired
MyTableRepository myTableRepository;
// 呼叫儲存過程
myTableRepository.inOnlyTest(inParam1)