我們在數據庫中進行復雜的操作時會用到存儲過程,在數據庫中存儲過程是可被外部調用的一種數據對象,可以用來封裝復雜的sql邏輯,那么我們在Spring Data JPA中是如何調用存儲過程的呢?這就需要我們今天要講的@Procedure注解了
1、首先我們來看一下@Procedure注解的源碼,通過源碼可以學習JPA對存儲過程的支持。下圖中value表示數據庫里面存儲過程的名稱,procedureName也是數據庫里面存儲過程的名稱。
2、接下來我們在數據庫中創建一個存儲過程,這個存儲過程有兩個參數,分別是輸入和輸出。
CREATE PROCEDURE `procinout`(IN arg int, OUT res int) BEGIN SELECT(arg + 10) into res; END
我們還可以創建有一個只有輸入的存儲過程,如下所示:
CREATE PROCEDURE `procin`(IN arg int) BEGIN SELECT(arg + 10) into arg; END
3、存儲過程的調用,在UserRepository中,使用@Procedure(name="procinout")和@Procedure(name="procin")去調用存儲過程。
package cn.zh.dao; import cn.zh.domain.User; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.query.Procedure; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; @Repository public interface UserRepository extends JpaRepository<User,Long> ,JpaSpecificationExecutor<User> { @Procedure(name = "procinout") int procInOut(@Param("arg") Integer arg); @Procedure(procedureName = "procin") void procIn(@Param("arg") Integer arg); }
4、在User實體類中存儲過程需要使用@NamedStoredProcedureQueries注解,將存儲過程綁定到JPA的數據庫表中,procedureName是存儲過程的名字,name是JPA中存儲過程的名字,寫成一致即可。@StoredProcedureParameter注解指定存儲過程中使用的IN、/OUT參數。
package cn.zh.domain; import javax.persistence.*; @Entity @NamedStoredProcedureQueries( {@NamedStoredProcedureQuery(name = "procinout", procedureName = "procinout", parameters={ @StoredProcedureParameter(mode=ParameterMode.IN,name="arg",type=Integer.class), @StoredProcedureParameter(mode=ParameterMode.OUT,name="res",type=Integer.class) }) ,@NamedStoredProcedureQuery(name="procin", procedureName="procin", parameters = { @StoredProcedureParameter(mode=ParameterMode.IN,type=Integer.class,name="arg")})}) public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY)//自動增遞 private Long id; private String name; private String email; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } @Override public String toString() { return "User{" + "id=" + id + ", name='" + name + '\'' + ", email='" + email + '\'' + '}'; } }
controller類:
package cn.zh.controller; import cn.zh.dao.UserRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RequestMapping("/user") @RestController public class UserController { @Autowired private UserRepository userRepository; @RequestMapping("/procInOut") public Integer proceInOut(Integer arg){ return userRepository.procInOut(arg); } @RequestMapping("/procIn") public void proceIn(Integer arg){ userRepository.procIn(arg); } }