天天看點

Spring Data JPA調用存儲過程執行個體Spring Data JPA調用存儲過程執行個體

版權聲明:本文為部落客chszs的原創文章,未經部落客允許不得轉載。 https://blog.csdn.net/chszs/article/details/50127823

Spring Data JPA調用存儲過程執行個體

作者:chszs,未經部落客允許不得轉載。經許可的轉載需注明作者和部落格首頁: http://blog.csdn.net/chszs

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 {
}
           

關鍵要點:

  • 存儲過程使用了注釋@NamedStoredProcedureQuery,并綁定到一個JPA表。
  • procedureName是存儲過程的名字
  • name是JPA中的存儲過程的名字
  • 使用注釋@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);
}
           
  • @Procedure的name參數必須比對@NamedStoredProcedureQuery的name
  • @Param必須比對@StoredProcedureParameter注釋的name參數
  • 傳回類型必須比對: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);
           

是不是很簡單。