如何从 java 调用 pl/pgsql

Posted

技术标签:

【中文标题】如何从 java 调用 pl/pgsql【英文标题】:how to invoke a pl/pgsql from java 【发布时间】:2017-04-06 11:39:34 【问题描述】:

我的 PL/pgSQL 函数工作正常。我测试过了

    CREATE OR REPLACE FUNCTION topAlerte()
          RETURNS void AS
          $$

          DECLARE

            max_var_risk varchar(70);
            max_mvar_risk varchar(70);
            max_incvar_risk varchar(70);
            max_cvar_risk varchar(70);
            amount varchar(70);
            delta varchar(70);
            net_exposure varchar(70);

          BEGIN

            truncate tops;

            select names from risk where risk.var_mc_risk =(select                max(risk.var_mc_risk) from risk) into max_var_risk ;
            select names from risk where risk.mvar_mc_risk =(select max(risk.mvar_mc_risk) from risk) into max_mvar_risk ;
            select names from risk where risk.inc_var_mc_risk =(select max(risk.inc_var_mc_risk) from risk) into max_incvar_risk ;
            select names from risk where risk.cvar_mc_risk =(select max(risk.cvar_mc_risk) from risk) into max_cvar_risk ;
            select names from risk where risk.amount =(select max(risk.amount) from risk) into amount ;
            select names from risk where risk.delta =(select max(risk.delta) from risk) into delta;
            select names from risk where risk.net_exposure =(select max(risk.net_exposure) from risk) into net_exposure  ;

            INSERT INTO tops VALUES 
              (max_var_risk, max_mvar_risk, max_incvar_risk,   max_cvar_risk,amount,delta,net_exposure);

          END ;

          $$

          LANGUAGE 'plpgsql';

我想从 Spring Boot 中调用它,这是我的 DAO:

public interface TopRepository 
    public List getTopsAlert()throws Throwable;

这是我的服务(接口实现):

public class TopAlertMetier implements TopRepository

        @Override
        public List getTopsAlert() throws Throwable 
        List<String> myList= new ArrayList<>();
        Class.forName("org.postgresql.Driver");
        Connection connect= null;
        connect = (Connection)           DriverManager.getConnection("jdbc:postgresql://localhost:5432/bourse","postgres","123456");
        java.sql.CallableStatement proc =  connect.prepareCall("topAlerte()");
        proc.registerOutParameter(1, java.sql.Types.VARCHAR);
        proc.executeQuery(); 
        ResultSet results = (ResultSet) proc.getObject(1);
        myList.add(results.getString(0));
        myList.add(results.getString(1));
        myList.add(results.getString(2));
        myList.add(results.getString(3));
        myList.add(results.getString(4));
        myList.add(results.getString(5));
        myList.add(results.getString(6));

        return myList;
  

对于我的控制器:

  @RestController
  public class topController 

      @Autowired
      TopRepository topRepository;

      @RequestMapping(value="/alert",method = RequestMethod.GET)
      public  @ResponseBody List alert() throws Throwable
          return topRepository.getTopsAlert();
      

列表显示最大值的名称,因此它必须包含表“tops”的值 使用以下命令运行服务器时: mvn spring-boot: run 日志显示异常:

字段 topRepository in com.Friendly_road.Flight.controller.topController 需要一个 bean 输入 'com.Friendly_road.Flight.dao.TopRepository' 那不可能 找到了。

【问题讨论】:

这不是PostgreSQL问题,而是Spring问题。我不是 Spring 用户,所以我只能猜测您的班级 TopAlertMetier 需要一个 @Repository 注释。有关注释的更多信息,请参阅***.com/questions/19414734/…。 我修复了它'缺少@Component @MBennani 很高兴我能帮上忙 【参考方案1】:

这种在 DAO 中使用存储过程的方式是某种“手工”并且很危险。您实现的配置步骤是在每次方法调用时完成的,并且非常容易出错。它甚至不再与数据库配置等相关的可配置。

文本说您正在使用 Spring Boot,那么为什么不使用 DataSourceAutoConfiguration 并在 application.properties / application.yml 文件中维护您的数据库配置?这样你就可以让 Spring 管理你的数据源。这将简化事务处理和使用连接池,并且更加方便。

这是一个很好的article。

除此之外,如果您使用 Spring Data JPA 存储库接口,您将不需要自己实现过程调用。您的存储过程调用可以通过以下方式轻松实现(假设您有类似***实体的东西):

@Repository
public interface TopRepository extends CrudRepository<Top, Long> 

    ...

    @Procedure(procedureName = "topAlerte")
    List getTopAlerte();

    ...


【讨论】:

以上是关于如何从 java 调用 pl/pgsql的主要内容,如果未能解决你的问题,请参考以下文章

为啥我不能从 pgAdmin pgScript 调用 PL/pgSQL 函数?

将数组传递给 PostgreSQL PL/pgSQL 函数

从 Ruby on Rails 调用 PL/pgSQL 存储过程

如何使用 pl/pgsql 将具有动态元素名称的 JSON 数据转换为行?

如何在 PL/pgSQL 中创建嵌套函数?

如何在 PostgreSQL、PL/pgSQL 上执行匿名代码块切换 CASE 语句?