Oracle
 sql >> Base de données >  >> RDS >> Oracle

Spring JPA Hibernate :requête SELECT lente

J'ai testé différents types de DAO (je ne publie pas de code ici car c'est tellement sale) :

  • Avec Hibernation  :~200 ms
  • Avec Spring JDBCTemplate et RowMapper (injectés)  :~70 ms
  • Avec déclaration Java :~2 ms
  • Avec Java OracleStatement :~5 ms
  • Avec Java PreparedStatement  :~100 ms
  • Avec Java PreparedStatement ajusté avec Fetch size =5000 :~50ms
  • Avec Java OraclePreparedStatement  :~100 ms
  • Avec Java OraclePreparedStatement ajusté avec la taille PreFetch =5000 :~170ms

Remarques :

  • DAO injecté par Spring au lieu de new ClientDao() :+30ms perdus (-malade-)
  • Temps de connexion à la BD :46 ms

Je pourrais utiliser :

  • Déclaration Java avec champs nettoyés manuellement.
  • Pré-connexion au lancement de l'application
  • Ne pas utiliser Spring Injection

Mais :

  • Pas vraiment sécurisé/sûr
  • Rapide pour un petit nombre de lignes, lent pour mapper ResultSet à l'entité sur un grand nombre de lignes (j'ai aussi ce cas d'utilisation)

Alors :

Le modèle JDBC de printemps avec RowMapper semble être la meilleure solution pour augmenter les performances sur des cas spécifiques. Et nous pouvons garder une sécurité sur les requêtes SQL. Mais il faut écrire un RowMapper spécifique pour transformer ResultSet en Entity.

Exemple de Spring JDBCTemplate

@Repository
public class ClientJdbcTemplateDao {


    private final Logger logger = LoggerFactory.getLogger(ClientJdbcTemplateDao.class);

    private JdbcTemplate jdbcTemplate;

    @Autowired
    public void setDataSource(DataSource dataSource) {
        this.jdbcTemplate = new JdbcTemplate(dataSource);
    }

    public List<Client> find() {
        List<Client> c = this.jdbcTemplate.query( "SELECT login FROM Client WHERE LOGIN='xxxx' AND PASSWORD='xxx'", new ClientRowMapper());
        return c;
    }
}

Exemple de client RowMapper

public class ClientRowMapper implements RowMapper<Client> {

    @Override
    public Client mapRow(ResultSet arg0, int arg1) throws SQLException {
        // HERE IMPLEMENTS THE CONVERTER
        // Sample : 
        // String login = arg0.getString("LOGIN")
        // Client client = new Client(login);
        // return client;
    }
}

Peut-être mieux, toute suggestion est la bienvenue.