El manejo de base de datos en cualquier lenguaje de programación creo que es esencial, ahora, se que no e tenido mucha presencia en el blog últimamente, pero como anteriormente comente en una entrada, estoy en proceso de certificación, ya solo me faltan dos y estamos dandole con todo, para tener muchas cosas para bloguear, así que apenas termine mis certificaciones me verán mas seguido por acá, blogueando sobre python, django, node.js, backbone.js, jquery y muchas cosas más, por lo pronto, estuve preparando esta entrada durante tiempo y no había tenido tiempo de terminarla, gracias a mi amigo Mxrck por no dejar abandonado el blog y por tener fé en mi que no lo dejaré solo aunque me desaparezca por ratos, pero bueno, sin tanto preámbulo, veamos el tema.
Antes que nada, creo que toda aquella persona que quiera saber mas que nada como conectar Java con SQLite, primero que nada debe de saber como es que va a trabajar con este pequeño motor de base de datos y como funciona, así mismo, donde conseguir el JDBC para trabajarlo, etc, así que primero que nada, hablemos un poco con SQLite, más que nada de su utilidad.
Una de las ventajas que tiene SQLite sobre los motores de bases de datos comunes, es que no necesita ser instalado para poder ejecutarlo, simplemente se necesita el archivo binario de ejecución, agregarlo a las variables del sistema, para que posteriormente lo podamos utilizar donde queramos, ahora bien, los comandos de consulta, de inserción, y de creación son exactamente idénticos a los de SQL, sin embargo, comandos como el show databases y show tables de mysql no existen, para esto utilizamos .tables, aún así como en cada buen motor, podemos consultar la ayuda con .help para ver todos los comandos posibles, no se preocupe si en este momento no entiende del todo como’ hacerlo, conforme vaya leyendo posteriormente se dará cuenta de que en realidad es algo muy sencillo de hacer.
Ahora bien, si, es verdad que SQLite es tan sencillo que podemos crear toda la arquitectura de la base de datos desde la consola, digo, lo he hecho, pero todo buen programador sabe, que para fines practicos a veces si es necesario utilizar un IDE para manejar las consultas, entre otras cosas, en este post les recomendare dos que para mi son los que e estado utilizando gratificantemente sin ningún problema, que son SQLiteMan y un plugin de firefox llamado SQLite Manager, ahora bien, el que seleccionen ustedes no tiene nada que ver con el contenido del post, en este caso yo utilizare SQLiteMan no por que sea mas potente, o tenga mejor soporte o por todas aquellas ventajas o desventajas que pueda tener uno sobre el otro, sino por que me gusta que sea portable y soy de los que la da flojera abrir el navegador solo para abrir el plugin de firefox, en fin, solo es cuestión de gustos.
Antes de instalar, lo que necesitaremos será ahora el driver JDBC para poder conectar Java con SQLite, este lo podremos obtener de la siguiente página, del cual descargarán el archivo de nombre: sqlite-jdbc-3.7.15-M1.jar, una vez que esté a la mano, podremos comenzar.
Descarga e instalación:
Ahora bien, lo primero que necesitamos para trabajar con SQLite es descargarlo, para esto, nos dirigiremos a la página oficial de SQLite, donde podremos encontrar los binarios para Windows, en el caso de Linux, basta con un apt-get install sqlite.
Ahora bien, una vez descargado, necesitaremos ubicar el archivo sqlite3 que descargamos en algún lugar donde sepamos que no lo vamos a mover posteriormente, por ejemplo en C:\SQLite, una vez hecho esto, será necesario agregar la ruta del archivo SQLite3 a las variables del entorno del sistema, osea al path:
Teniendo esto agregado, ¿Como sabemos que funciona? fácil, entraremos al cmd de Windows y teclearemos algo sencillo, «sqlite3 nuevo»:
Si todo sale bien, sin necesidad de estar en la ruta donde se encuentra el binario de SQLite entraremos a la interfaz en consola, y bien, todo habrá salido a la perfeccion.
Creando una base de datos SQLite
Bien, este tema me saco un poco de onda la primera vez que genere una base de datos en SQLite, en primera instancia mi error fue pensar que en todo era como en MYSQL, por consecuente, lo que intente hacer fue crear una pequeña base de datos y guardarla, y vaya! no se guardaba, por consecuente veo necesario introducir esta pequeña sección antes de continuar avanzando.
Primero que nada hay algunas cosas que deben de saber sobre SQLite, la creación de las bases de datos con comandos como CREATE DATABASE no existe, eso lo aprendí a la mala, ¿Que es lo que hay que hacer? pues sencillo, lo primero que tiene que hacer, si estuviéramos trabajando con puras lineas de comandos, sería teclear el comando:
sqlite3 nueva_base_de_datos
Con esto, técnicamente ya esta creada una nueva base de datos, si se fijan, no fue necesario entrar al motor a crear una nueva base de datos, por que no funcionan de esta manera, ¿que es lo que sucede?, cuando nosotros tecleamos este comando lo que hace SQLite es crear la base de datos en un pequeño archivo temporal, y ¿cuando se hace visible totalmente para el usuario?, fácil, cuando creamos la primera tabla, por consecuente, una vez dentro de la base de datos, basta con hacer un:
create table test(id integer primary key autoincrement, descripcion varchar(140));
Y listo, veremos que la base de datos aparece en la ruta que nos dice nuestra consola, y con esto chicos, tenemos nuestra primera base de datos en sqlite, para finles practicos, e creado una pequeña base de datos llamada test.db donde puse una tabla alumnos con un id, nombre y apellidos, solo para conectar, y ahora, pasemos a lo interesante, ¿como conectamos sqlite con Java?, para esto vamos a trabajar con el IDE de netbeans, ya que por constumbre es el que más utilizo al programar en Java.
Conexión con Java desde Netbeans
Bien, para hacer esto es algo muy sencillo, vamos a crear un proyecto con dos clases, una clase Main y una clase Conector, la cual se encargará de realizar las conexiones necesarias y las consultas.
Ahora bien, en las librerías agregaremos el conector JDBC para SQLite como un Jar:
Listo, con esto podemos empezar a trabajar, ahora bien, ¿que es lo primero que vamos a hacer? , vamos a la clase conector y vamos a definir una variable String que represente la ruta donde estamos ubicando la base de datos sqlite, en mi caso es D:\test.db, y un objeto Connection que usaremos posteriormente:
String url = "D:\\test.db"; Connection connect;
Tengan en claro que utilizo doble diagonal por que estoy trabajando con windows, y como las rutas son con diagonal invertida, y la diagonal invertida es un caracter de escape en Java, tengo que utilizar dos diagonales invertidas para que me detecte una. Ahora, vamos a crear un metodo connect(), el cual realizará la conexión correspondiente, y un método close que cerrará la conexión cada vez que la abramos, estos métodos serán de esta manera:
public void connect(){ try { connect = DriverManager.getConnection("jdbc:sqlite:"+url); if (connect!=null) { System.out.println("Conectado"); } }catch (SQLException ex) { System.err.println("No se ha podido conectar a la base de datos\n"+ex.getMessage()); } } public void close(){ try { connect.close(); } catch (SQLException ex) { Logger.getLogger(Conector.class.getName()).log(Level.SEVERE, null, ex); } }
Ahora bien, explicación rápida, lo que hace este pedazo de código es que tenemos dos métodos, el método connect crea un objeto Connection(que declaramos anteriormente) que sera el que gestionará nuestra conexión a la base de datos, para esto necesita como parametro el controlador de sqlite añadiendole la ruta, una vez creado esto, verificacmos, si la conexión es diferente de nula, se imprime conectado,y cualquier error lo controlamos con un tryCatch. Ahora, el método close lo único que hace es cerrar la conexión, siempre que habramos una conexión a la base de datos no olvidemos cerrarla.
Ahora, desde la clase Main, lo único que haremos será crear un método main y dentro instanciaremos una clase de nuestro objeto Connect y posteriormente mandaremos a hablar a este método para probar la conexión:
Conector con = new Conector(); con.connect(); con.close();
Ahora bien, si todo sale bién, tendremos una impresión muy bonita en consola que dirá:
Conectado
Insercciones
Bueno, para esto utilizaremos algo de programación orientada a objetos para crear un modelo de Alumno, ya que les comente que mi base de datos solo tiene 3 campos, un id autoincrement, un nombre y los apellidos del alumno:
public class Alumno { private int id; private String nombre, apellidos; public Alumno(String nombre, String apellidos) { this.nombre = nombre; this.apellidos = apellidos; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getNombre() { return nombre; } public void setNombre(String nombre) { this.nombre = nombre; } public String getApellidos() { return apellidos; } public void setApellidos(String apellidos) { this.apellidos = apellidos; } }
Ahora bíen, agregaremos un método más a nuestro conector que nos permitirá guardar un alumno en la base de datos:
public void saveAlumno(Alumno alumno){ try { PreparedStatement st = connect.prepareStatement("insert into alumnos (nombre, apellidos) values (?,?)"); st.setString(1, alumno.getNombre()); st.setString(2, alumno.getApellidos()); st.execute(); } catch (SQLException ex) { System.err.println(ex.getMessage()); } }
Esté método hace lo siguiente, teniendo en cuenta que antes tendriamos que ejecutar el método connect para que se conecte a la base de datos, crearemos un objeto prepareStatement, que lo que hace es preparar una sentencia SQL que nos permita solo mandarle los datos que vamos a sustituir en los parentesis, luego con setString mando, el número de parentesis que sustituiré, por eso el 1 y 2, y el dato que llevará, una vez que termine este método si todo sale bien, tendremos los datos en la base de datos, lo único que nos hace falta, es que el alumno tenga un método para pasarse a si mismo como parametro y se guarde técnicamente solo:
public void save(){ Conector con = new Conector(); con.connect(); con.saveAlumno(this); con.close(); }
Y listo, tenemos todo lo necesario, ahora, vamos a borrar lo que tenemos en nuestro método main, y crearemos una instancia de un Alumno, para ver si se guarda en la base de datos.
Alumno alumno = new Alumno("Atxy2k", "SerProgramador.es"); alumno.save();
Ahora bien, el ejecutar el programa, si todo sale bien, nos debiese simplemente decir la consola, conectado, mientras no haya salido una excepcion significa que todo va bien, ahora bien, lo único que necesitamos, es un método para sacar los datos o mostrarlos desde la base de datos, para esto, agregamos un sencillo método a nuestro conector.
Consultas
Realizar consultas es muy sencillo, observemos el siguiente código:
public void mostrarAlumnos(){ ResultSet result = null; try { PreparedStatement st = connect.prepareStatement("select * from alumnos"); result = st.executeQuery(); while (result.next()) { System.out.print("ID: "); System.out.println(result.getInt("id")); System.out.print("Nombre: "); System.out.println(result.getString("nombre")); System.out.print("Apellidos: "); System.out.println(result.getString("apellidos")); System.out.println("======================="); } } catch (SQLException ex) { System.err.println(ex.getMessage()); } }
Esté codigo es sencillito, lo primero que necesitamos es un objeto ResultSet, este objeto es un objeto especial de SQL que nos permite acceder a los datos una vez que tenemos una respuesta de la base de datos, ahora bien, teniendo esto, utilizaremos de nuevo el objeto prepareStatement para crear nuestra sentencia SQL, y una vez que la tenemos la executamos y guardamos la respuesta en el ResultSet, ahora bien, como ¿accedo a los datos uno por uno? con un ciclo While ? , entonces , el objeto ResultSet nos da un método.next que nos dice, que mientras existan datos, haremos lo siguiente, y solo es cuestión de abstraer las cosas como si fueramos columna por columna, si es un ID de tipo INT, le pedimos al ResultSet un Int de la columna que tenga el nombre(«id»), y vamos haciendo lo que querramos con los datos, no puede ser más sencillo. ?