La mayoría de aplicaciones requieren acceso a una base de datos. En java existe JDBC que nos permite realizar esta tarea.
En una aplicación distribuida y escalable nos vemos en la necesidad de utilizar un pool de conexiones para no causar un problema de rendimiento. Por ejemplo, he creado servicios web (REST) que deseo sean consumidos desde dispositivos móviles, para ello necesito que los servicios sean escalables.
Ya que utilicé Spring Roo para crear la plantilla inicial del proyecto, este me agregó la siguiente configuración inicial.
applicationContext.xml
... <bean class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" id="dataSource"> <property name="driverClassName" value="${database.driverClassName}"/> <property name="url" value="${database.url}"/> <!--<property name="username" value="${database.username}"/>--> <!--<property name="password" value="${database.password}"/>--> <property name="testOnBorrow" value="true"/> <property name="testOnReturn" value="true"/> <property name="testWhileIdle" value="true"/> <property name="timeBetweenEvictionRunsMillis" value="1800000"/> <property name="numTestsPerEvictionRun" value="3"/> <property name="minEvictableIdleTimeMillis" value="1800000"/> <property name="validationQuery" value="SELECT 1 FROM DUAL"/> </bean> ...
como podemos ver, esta configuración crea un DataSource de tipo org.apache.commons.dbcp.BasicDataSource. Este tipo de DataSource crea un pool de conexiones automáticamente. Genial!
Ahora, ¿cómo lo utilizamos en nuestras clases para poder ejecutar una consulta SQL?
Podríamos utilizarlo de la forma tradicional con JDBC
... @Autowired public DistritosServiceImpl(DataSource dataSource) { this.dataSource = dataSource; } @Override public List<Distrito> getDistritos() { List<Distrito> distritos = new ArrayList<Distrito>(); String sql = "select id, nombre " + "from distritos"; Connection con = null; try{ con = this.dataSource.getConnection(); PreparedStatement stmt = con.prepareStatement(sql); ResultSet rs = stmt.executeQuery(); while(rs.next()){ distritos.add(new Distrito(rs.getInt("id"), rs.getString("nombre"))); } }catch (Exception e){ e.printStackTrace(); if(con != null){ try { con.close(); } catch (SQLException e1) { e1.printStackTrace(); } } } return distritos; } ...
pero existe una mejor manera, utilizando JdbcTemplate
... @Autowired public DistritosServiceImpl(DataSource dataSource) { this.dataSource = dataSource; this.jdbcTemplate = new JdbcTemplate(dataSource); } @Override public List<Distrito> getDistritos() { String sql = "select id, nombre " + "from distritos"; return jdbcTemplate.query(sql, new RowMapper<Distrito>() { @Override public Distrito mapRow(ResultSet rs, int i) throws SQLException { return new Distrito(rs.getInt("id"), rs.getString("nombre")); } }); } ...
Fuentes: