Spring Data JPA调用存储过程实例代码实例

07-30

  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

  @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

  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);