简体   繁体   中英

how to invoke a pl/pgsql from java

my PL/pgSQL function works fine. I tested it

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

I want to invoke it from spring boot, here is my DAO:

public interface TopRepository {
    public List getTopsAlert()throws Throwable;
}

here is my service(interface implementation):

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

and for my controller :

  @RestController
  public class topController {

      @Autowired
      TopRepository topRepository;

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

the list shows the names of the max values ,so it have to contain the values of the table "tops" when running the server with : mvn spring-boot: run the log show exception :

Field topRepository in com.Friendly_road.Flight.controller.topController required a bean of type 'com.Friendly_road.Flight.dao.TopRepository' that could not be found.

This way to use stored procedures within your DAO is some kind of "handmade" and dangerous. Your implemented configuration steps are done on every method invocation and very error-prone. It's even not configurable anymore related to database configuration and so on.

The text says you are using Spring Boot, so why just don't use the DataSourceAutoConfiguration and maintain your database configuration within an application.properties / application.yml file? This way you could let Spring manage your datasource. That would ease transactional handling and using connection pooling and it's a lot more convenient.

Here is a nice article about that.

In addition to that, if you would use the Spring Data JPA repositories interface you would not have the need to implement the procedure invocation on your own. Your stored procedure call could be easy realized in a manner like (assuming you have something like a Top Entity):

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

    ...

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

    ...

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM