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:

Lo más común es desarrolllar nuestras aplicaciones en un ambiente de desarrollo, es decir, utilizar servidores de prueba para después implementarlo en un ambiente de produción. Si el código de tu proyecto se encuentra en un sistema de control de código (git, svn, etc.) es díficil, si no tedioso, cambiar entre un ambiente y otro. Tienes que modificar los archivos de configuración para que se conecte a la base de datos de producción cada vez que actualizas el sistema y debes tener cuidado de no incluir en el control de código las conexiones de prueba o visceversa.

Para resolver este problema podemos utilizar JNDI, pero se vuelve complicado el mantener un entorno replicado en nuestra máquina de desarrollador. Eixsten plataformas para desarrollar y ejecutar aplicaciones web de forma escalable -tales como- Heroku, Google App Engine o Microsoft Azure. Para resolver este problema de contextos, Heroku ha optado por utilizar variables de ambiente para cambiar entre el contexto de desarrollo y el de producción.

Esta solución me pareció adecuada y decidí implementarla en un proyecto Java. Realmente es muy sencillo, normalmente creamos una conexión a la base de datos de la siguiente forma:

DriverManager.getConnection(dbUrl, dbUser,dbPassword);

Necesitamos 3 cosas: url a la base de datos, usuario y contraseña.
Opcionalmente podemos incluir el usuario y contraseña en la URL de la base de datos si el controlador lo permite.En el caso de Oracle es de la siguiente manera:

jdbc:oracle:thin:[USER/PASSWORD]@[HOST][:PORT]:SID
jdbc:oracle:thin:[USER/PASSWORD]@//[HOST][:PORT]/SERVICE

Para leer la configuración de las variables de ambiente sería

DriverManager.getConnection(System.getenv(“DATABASE_URL”));

En nuestro caso utilizamos diferentes conexiones de acuerdo al usuario y la base de datos, por lo que seguimos una nomenclatura de la siguiente manera

USUARIO_AT_DATABASE

así por ejemplo, podríamos conectarnos a distintas bases de datos

   DriverManager.getConnection(System.getenv("RH_AT_QUERETARO"));
   DriverManager.getConnection(System.getenv("RH_AT_AMEALCO"));
   DriverManager.getConnection(System.getenv("USRCIVQRO_AT_QUERETARO"));

Por último necesitas configurar estas variables de ambiente en tu sistema operativo.

En Ubuntu lo puedes hacer de diferentes formas.
A mi me funcionó creando un archivo env.sh en la carpeta /etc/profile.d

   #!/usr/bin/bash
   export RH_AT_CENTRO_DE_JUSTICIA=jdbc:oracle:thin:rh/secret@127.0.0.1:1521:dbtest
   export COMPRAS_AT_AMEALCO=jdbc:oracle:thin:compras/secret@127.0.0.1:1521:dbtest

Fuentes:
https://devcenter.heroku.com/articles/heroku-postgresql#connecting-in-java
http://stackoverflow.com/questions/5547224/username-password-in-jdbc-connection-url
https://help.ubuntu.com/community/EnvironmentVariables
http://askubuntu.com/questions/307023/command-not-working-in-profile

Si tienes un proyecto de Maven en el cual quieres conectarte a una base de datos PostgreSQL, puedes utilizar el controlador JDBC de PostgreSQL agregando la siguiente dependencia a tu archivo pom.xml
<dependency>
<groupId>postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>${postgresql.version}</version>
</dependency>
Fuentes:
http://jdbc.postgresql.org/
http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22postgresql%22%20AND%20a%3A%22postgresql%22

Estaba trabajando en un reporte de BIRT que utiliza una conexión JDBC a una base de datos de Oracle y me arrojaba la siguiente excepción:

java.lang.NoClassDefFoundError: oracle/sql/CharacterSet$CharacterConverterBehavior

Al parecer, esto se debe a que en la configuración de Drivers de BIRT tenía configurado el driver de la conexión con “oracle.jdbc.driver.OracleDriver”, pero este paquete dejó de ser soportado después de la versión 10.2. Es necesario cambiar la configuración a “oracle.jdbc.OracleDriver”.

Este problema fue a partir de que actualice el JAR de Oracle, ojdbc6.jar, en BIRT.

Fuentes:
https://forums.oracle.com/forums/thread.jspa?threadID=697209 

I had a report which connects to an Oracle Database through JDBC to get data. Since I reinstalled eclipse and BIRT, my JDBC configuration was lost. Therefore when I tried to preview my report the following error was thrown:

Table TBL_EXPEDIENTES_ASIGNADOS:
An exception occurred during processing. Please see the following message for details:
Cannot open the connection for the driver: org.eclipse.birt.report.data.oda.jdbc.
    org.eclipse.birt.report.data.oda.jdbc.JDBCException: Cannot load JDBC Driver class: oracle.jdbc.OracleDriver

The only way I’ve found to manage your JDBC drivers is to open the new datasource dialog and select “JDBC Datasource”, put whatever name you like and press next. You should see a button with the label “Manage Drivers…”. Then you could add the ojdbc6.jar or whatever JDBC driver you need.

Java – JDBC valores nulos

diciembre 13, 2010

Si tuvieramos una consulta como la siguiente

select nombre, salario
from empleados;

y luego quisieramos leer los valores mediante un ResultSet de la siguiente forma

ResulSet rst=command.executeQuery(sql);
String nombre;
Float salario;
while(rst.next()){
   nombre=rst.getString(“nombre”);
   salario=rst.getFloat(“salario”);
}

Si tuvieramos registros con valores nulos en la tabla de empleados, la variable nombre si sería nula pero la variable salario tendría el valor cero. Esto tal vez no sea lo que esperabamos, así que, ¿cómo evitamos esto? Bueno, pues para verificar si un campo tiene el valor nulo lo hariamos de la siguiente forma

ResulSet rst=command.executeQuery(sql);
String nombre;
Float salario;
while(rst.next()){
   nombre=rst.getString(“nombre”);
   if(rst.wasNull()){
      nombre=null; //aqui no es necesario, ya que para las cadenas si nos regresa el valor “null”
   }
   salario=rst.getFloat(“salario”);
   if(rst.wasNull()){
      salario=null; //aqui si es necesario, de lo contrario, salario tendría el valor cero
   }
}

Fuentes:
http://archives.postgresql.org/

Habia escuchado que sqldeveloper te deja trabajar con MySQL pero nunca lo habia intentado. Decidi probarlo el dia de hoy y no fue tan facil como pense.

Primero crei que mediante las actualizaciones iba a poder instalar el soporte para MySQL asi que di clic en el menu Help->Check for Updates… y seleccione los 3 centros de actualizacion: Oracle SQL Developer, Oracle Extensions y Third Party SQL Developer Extensions. Despues busque “mysql” y me aparecio casi inmediatamente “MySQL JDBC Driver 11.1.1.58.17” en los resultados asi que segui el asistente esperando que todo quedara listo para crear una conexion a MySQL. Me pidio que aceptara la licencia del controlador y que ingresara mis datos de OTN para desargar los archivos necesarios. No me marco ningun error y me pidio que reiniciara la aplicacion. Una vez hecho esto quise crear mi conexion pero ups!… no aparecia ninguna opcion de MySQL en el asistente de conexion. Lo intente varias veces sin obtener resultados positivos.

Asi que buscando en internet encontre este sitio donde se explica como descargar e instalar manualmente el controlador JDBC de MySQL.

En resumen, descarga y descomprime el archivo Connector/J de esta pagina y ve a las preferencias de SQLDeveloper (Tools->Preferences) en la seccion de Database->Third Party JDBC Drivers, da clic en Add Entry y selecciona el archivo mysql-connector-java-5.1.13-bin.jar de la carpeta que descomprimiste. Listo, ya tendras disponible una pestaña de MySQL a la hora de crear una nueva conexion.