El objetivo de
todas las entradas anteriores dedicadas a las bases de datos, es finalmente
aprender a crear una base de datos que contenga toda la información que la
empresa necesita gestionar. Es decir, crear una base de datos.
Esta base de
datos se incluirá con el programa java que se realice. Nuestro programa java
accederá a esta base de datos continuamente para añadir nuevos datos, o
modificar datos, eliminar datos, o extraer datos según lo ordene el usuario del
programa.
En este post, se
verán los pasos necesarios para conectar un proyecto java con una base de
datos creada en SQL Server.
Pasos Generales para preparar una Aplicación Java
para acceder a una Base de Datos
Para
preparar nuestra aplicación Java para que pueda acceder a una Base de Datos, es
necesario realizar tres pasos:
1. Cargar el controlador de la base de datos:
El controlador define el tipo de base de
datos que se va a usar (base de datos de SQL Server, Access, MySQL, PostgreSQL
o de cualquier otro gestor de base de datos).
En
nuestro caso, tendremos que indicar el controlador para base de datos de SQL
Server.
2. Crear un objeto conexión (Connection):
Para
crear este objeto hay que indicar la ubicación de la base de datos, el usuario
y la contraseña de dicha base de datos. El objeto conexión abre la base de
datos.
3. Crear un objeto sentencia (Statement):
El
objeto sentencia se crea a partir del objeto conexión anterior. Los objetos
sentencia permiten realizar acciones sobre la base de datos usando
instrucciones SQL.
Es
decir, a través del objeto sentencia introduciremos datos en la base de datos,
eliminaremos datos, haremos modificaciones, y extraeremos datos de la base de
datos.
Así
pues, este objeto es vital. Este objeto es el que realmente permite el acceso a
los datos de la base de datos y la manipulación de dicha base de datos.
EJERCICIO GUIADO Nº 1
PLANTEAMIENTO:
En este
ejercicio se pretende crear una pequeña aplicación de bases de datos que
permita simplemente mostrar los datos de los trabajadores almacenados en la
base de datos AMANUVA.
- Entre en NetBeans. Crea un nuevo proyecto
llamado AccesoBaseDatos. Dentro
de este proyecto crea un paquete principal llamado paqueteVentanas y dentro de él un JFrame llamado VentanaPrincipal:
- En la parte superior de la ventana añade un
botón con el texto Mostrar
Trabajadores que se llame btnMostrarTrabajadores:
- Se pretende simplemente que al pulsar el botón
btnMostrarTrabajadores aparezcan
en un JOptionPane datos sobre los trabajadores almacenados en la base de
datos.
PREPARACIÓN DEL SQL SERVER PARA QUE PERMITA ACCEDER A LA BASE DE DATOS
AMANUVA:
- Clic derecho en la instancia y escoger
la opción Propiedades:
- En la opción Security configurar
según se indica en la siguiente pantalla:
- En la opción Connections
configurar según se indica en la siguiente pantalla y acepta los cambios:
- Luego dar clic derecho en la Logins
y escoger la opción New Login…:
- En la opción General configurar
según se indica en la siguiente pantalla:
- En la opción Server Roles
configurar según se indica en la siguiente pantalla:
- En la opción Status configurar
según se indica en la siguiente pantalla y acepta los cambios:
- En el Administrador de Configuraciones dentro
de la opción Protocols for NAMEINSTANCIIAA hacer clic derecho en TCP/IP
(el cual debe estar habilitado) y escoger la opción Propiedades:
- Al final de la pestaña IP Addresses en la
opción TCP Port escribir 1433 y acepta los cambios:
- Dentro de la opción SQL Server Services
hacer clic derecho en la opción SQL
Server (NAMEINSTANCIIAA) y escoger la opción Restart:
PREPARACIÓN DE LA APLICACIÓN JAVA PARA EL ACCESO A LA BASE DE DATOS:
- Descargar el archivo sqljdbc4.jar desde
la página de Microsoft.
- Agregarlo a las bibliotecas del proyecto AccesoBaseDatos haciendo clic derecho en Libraries
y escogiendo la opción Add JAR/Folder… y buscando el
archivo descargado (slqjdbc4.jar).
- Para poder acceder y manipular una base de
datos, es necesario tener dos objetos:
-
Un objeto del tipo Connection, al que
llamaremos conexion. Este objeto define la conexión con la base de datos.
-
Un objeto del tipo Statement, al que
llamaremos sentencia. Este objeto permite manipular la base de datos.
- Así pues, lo primero que haremos será definir
estos objetos como globales en la clase de la VentanaPrincipal,
para así poderlos usar desde cualquier lado:
Aparecerán subrayados ya que será necesario indicar el import para las
clases Connection y Statement. Estos import son
respectivamente:
java.sql.Connection
y
java.sql.Statement
Agrega los import correspondientes para eliminar los errores.
- Una vez definidos los objetos conexion
y sentencia, necesarios para el acceso a la base de datos,
prepararemos nuestro programa para que pueda acceder a la base de datos AMANUVA.
Esto se hará en el método constructor.
- En primer lugar, añade al método constructor
una llamada al método conectarBaseDatos:
- Crea el método conectarBaseDatos debajo
del método constructor y empieza a programar lo siguiente:
El
código que acabas de programar es el primer paso a realizar para el acceso a
una base de datos: La carga del controlador.
Recuerda
que el controlador le indica a Java
que tipo de base de datos usaremos: SQL Server, PostgreSQL, Access, MySQL, etc.
El controlador
que le indica a java que usaremos una base de datos de SQL Server viene
definido a través de la siguiente cadena de texto:
com.microsoft.sqlserver.jdbc.SQLServerDriver
Y la
forma de activar dicho controlador es a través de la instrucción:
Class.forName(controlador);
Donde controlador
es una variable tipo cadena que contiene la cadena anterior.
Básicamente,
lo que hacen estas dos líneas de código, es preparar a Java para poder usar SQL
Server.
En el
caso de que se quisiera usar una base de datos realizada en otro programa que
no fuera SQL Server, habría que cambiar la cadena de texto correspondiente a su
controlador.
En
nuestro caso usaremos SQL Server.
También
puedes observar que es obligatorio encerrar el código de la carga del
controlador entre try…catch para capturar cualquier error imprevisto.
- Ahora añade el siguiente código a continuación
del anterior (dentro del método conectarBaseDatos):
El
código que acabas de añadir corresponde al segundo paso para acceder a una base
de datos: Crear el objeto conexion.
El
objeto conexion es el que efectúa la conexión real con la base de
datos. Se podría decir que es el objeto que permite abrir la puerta del fichero
de base de datos para entrar en él. Para construir este objeto conexion
(el cual ya está declarado en la parte global de la clase) hacen falta tres
datos:
·
El nombre del usuario que manipulará la base de
datos:
String usuario =
"UsuarioAMANUVA";
·
El password del usuario que manipulará la base de
datos:
String clave = "123";
·
El DSN de la base de datos. DSN significa “nombre
del origen de datos” y es una cadena de texto algo compleja que contiene
información sobre la base de datos que queremos usar:
String DSN =
"jdbc:sqlserver://servidor\\nameinstanciiaa:1433;databasename=AMANUVA;";
En esta
cadena hay que indicar el nombre del ordenador donde está la base de datos, el
nombre de la instancia en SQL Server, el número de puerto de conexión y el
nombre de la base de datos. Observa la necesidad de escribir dos barras.
Finalmente
se usa la instrucción:
conexion =
DriverManager.getConnection(DSN, usuario, clave);
para
crear la conexión. Será necesario añadir un import para la clase DriverManager.
Al igual
que con el primer paso, es necesario rodear la creación de la conexión con un try…catch para
capturar cualquier error inesperado que se pueda producir en este paso.
- Ahora añade el siguiente código a continuación
del anterior (dentro del método conectarBaseDatos):
Este
código que acabas de añadir corresponde al tercer paso necesario para poder
acceder a una base de datos: Creación
del objeto sentencia.
El
objeto sentencia será el que nos permita ejecutar órdenes SQL sobre la
base de datos. Es decir, el objeto que nos permite actuar y manipular la base
de datos. Este objeto es vital, y es el objetivo de toda esta preparación.
El
objeto sentencia se crea a partir del objeto conexion creado en el
paso anterior, usando la siguiente instrucción:
sentencia =
conexion.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
conexion.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
Y como
sucedió en los dos pasos anteriores, es necesario rodear esta instrucción con
un try…catch
para capturar cualquier tipo de error inesperado que se pudiera producir.
- Así pues ya tenemos preparado nuestro programa
para acceder a la base de datos. Esta preparación se realiza en el momento
en que se ejecuta el programa, ya que hemos introducido este código en el método
constructor.
Es cierto que este código puede resultar bastante abstracto y complejo,
pero tiene la gran ventaja de que siempre es igual.
Si se quiere usar otra base de datos que se encuentre en el mismo
ordenador de la creada anteriormente solamente tendremos que cambiar el nombre
de la base de datos, nombre de usuario y la clave.
El resto del código queda igual.
Observa:
- El objetivo de todo este código de preparación
para el acceso a la base de datos es obtener un objeto llamado sentencia
que nos posibilitará la manipulación de los datos de la base de datos,
usando órdenes SQL.
25.En el
ejercicio siguiente usaremos el objeto sentencia
para averiguar información acerca de los trabajadores utilizando consultas
SQL.
- Cuando se pulse el botón Mostrar Trabajadores tendremos que extraer los
datos de la tabla Trabajadores para poder
mostrarlos. Para ello, escribe el siguiente código dentro del evento actionPerformed del botón btnMostrarTrabajadores:
Observa el código:
ResultSet
rs = sentencia.executeQuery("SELECT * FROM Trabajadores ORDER BY
nombres");
El objeto sentencia se
usa para dar órdenes a la base de datos. Esas órdenes se dan usando el lenguaje
de consulta SQL.
Se usa el método executeQuery del objeto sentencia para ejecutar la
consulta SQL “SELECT * FROM Trabajadores ORDER BY nombres”. Esta
consulta extraerá todos los datos de la tabla Trabajadores ordenados
por el campo nombres.
El método executeQuery recibe como parámetro una cadena representando la
consulta SQL.
El resultado de la consulta se guarda en un objeto del tipo ResultSet al que se ha llamado “rs”.
Los objetos de la clase ResultSet
almacenan el resultado de una consulta SQL.
(Será necesario incluir el import
necesario para la clase ResultSet).
Y como puedes observar, es necesario rodear la ejecución de una consulta
SQL con un try…catch para capturar errores inesperados al realizar la
consulta.
Los
Objetos ResultSet:
- Debes imaginarte el objeto ResultSet rs como una tabla que contiene el resultado de la consulta
SQL que se ha ejecutado. En nuestro caso, la consulta SQL que hemos
ejecutado ha extraído toda la tabla Trabajadores.
Por tanto nuestro ResultSet
contiene toda la tabla Trabajadores.
El objeto rs por tanto podría representarse así:
- La fila BOF significa “comienzo de fichero” y
representa una fila anterior al primer registro del ResultSet.
La fila EOF significa “final de fichero” y representa una fila posterior
al último registro del ResultSet.
La flecha indica la posición actual donde estamos situados dentro de la
tabla del ResultSet.
- Añade la siguiente línea al código al evento actionPerformed:
El método next del ResultSet hará que avancemos una
fila en el ResultSet. Es decir, ahora estaremos situados en la primera
fila del ResultSet (la flecha avanza una posición):
- Ahora que estamos situados en la posición del
primer trabajador (GABRIEL), podemos extraer información referente a sus
campos. Añade el siguiente código al actionPerformed del botón:
Lo que se ha
hecho primero es declarar una variable tipo cadena llamada info.
Luego, a esta
variable se le ha asignado una concatenación de cadenas:
info =
"El trabajador se llama " + rs.getString("nombres") +
" " + rs.getString("apellidos");
info +=
" y cobra " + rs.getString("sueldo");
Lo interesante de esto es el método getString del objeto ResultSet
rs.
El método getString permite extraer una cadena con el valor del campo
indicado como parámetro.
En nuestro caso:
rs.getString("nombres")
Extrae los
nombres del trabajador actual (“GABRIEL”).
rs.getString("apellidos")
Extrae los
apellidos del trabajador actual (“BENITES”).
rs.getString("sueldo")
Extrae
el sueldo del trabajador actual (“6000.00”).
Luego se muestra
la cadena info en un simple JOptionPane.
- Ya puedes ejecutar el programa:
- Sigamos haciendo cambios en el código del
botón para entender mejor el funcionamiento de los ResultSet. Añade la
siguiente línea:
- Se ha añadido un segundo next. Esto producirá
que la flecha avance dos posiciones en el ResultSet, y por
tanto se coloque en la segunda fila:
- Esto quiere decir que si se ejecuta el
programa se mostrará información sobre MARIA
SANCHEZ. Compruébalo:
- Los objetos ResultSet poseen
diversos métodos para cambiar la posición actual en la tabla del ResultSet.
Dicho de otro modo: “para mover la flecha”. Veamos algunos de estos
métodos (se supone que el objeto ResultSet se llama rs):
rs.next(); --> Mueve
la flecha a la siguiente fila
rs.previous(); --> Mueve la flecha a la fila anterior
rs.first(); --> Mueve la flecha a la primera fila
rs.last(); --> Mueve
la flecha a la última fila
rs.beforeFirst(); --> Mueve la
flecha a la fila BOF
rs.afterLast(); --> Mueve
la flecha a la fila EOF
rs.absolute(n); --> Mueve
la flecha a la fila n del ResultSet.
Las
filas se empiezan a numerar por 1.
- Haga el siguiente cambio en el actionPerformed
simplemente para experimentar:
En este caso la flecha se coloca en EOF (afterLast) y luego retrocede una fila (previous). Por tanto, al ejecutar el programa se mostrarán los
datos del último trabajador. Compruebalo:
- Otro experimento. Cambie ahora el código de
esta forma:
Este código coloca la flecha en la fila 2 ( absolute(2) ), luego avanza una fila (next), luego
retrocede una fila (previous) y
finalmente retrocede una fila (previous).
Así pues, finalmente, la flecha queda colocada en la primera fila. Por
lo tanto se muestran los datos del primer trabajador. Compruébalo:
- Como ves, podemos movernos dentro del
contenido del ResultSet gracias a todos estos métodos, para luego poder
extraer los datos de la fila correspondiente.
Ahora, estudiaremos la forma de recorrer todas las filas del ResultSet
para así extraer la información de todos sus registros.
- Vamos a modificar nuestro código para que se
muestren todos los trabajadores del ResultSet. Para ello, realiza
el siguiente cambio:
En este código se ha inicializado la variable info a la cadena vacía “”
y luego se ha añadido un bucle bastante interesante:
rs.beforeFirst();
while
(rs.next()) {
info += rs.getString("nombres") + " " +
rs.getString("apellidos") + " " +
rs.getString("sueldo") + "\n";
}
Analicemos este bucle:
-
Lo primero que se hace es colocar explícitamente la
flecha en la fila BOF, es decir, antes del primer trabajador:
rs.beforeFirst();
-
Luego tenemos un bucle mientras que comienza
así:
while
(rs.next()) {
El método next intenta colocar la flecha en la siguiente fila, y si lo
hace bien, devuelve el valor verdadero. Cuando no se puede
avanzar más, el método next devolverá falso.
Así pues, este while significa “mientras se haya podido avanzar una fila,
haz lo siguiente”. O dicho de otro modo, este bucle se repetirá para cada
fila de la tabla del ResultSet.
-
Si analizamos el contenido del bucle, básicamente
veremos una concatenación de cadenas dentro de la variable info. En cada vuelta del
bucle se concatenará los nombres, apellidos y sueldo de cada trabajador.
info +=
rs.getString("nombres") + " " +
rs.getString("apellidos") + " " +
rs.getString("sueldo") + "\n";
-
Finalmente se visualiza la variable info en un JOptionPane.
- Ejecuta el programa y comprueba su
funcionamiento.
- El bucle que acabas de programar es un código
“clásico” para manipular un ResultSet. Siempre que quieras
recorrer todas las filas del ResultSet harás algo como esto:
rs.beforeFirst();
while
(rs.next()) {
manipulación de la fila
}
- Se ha visto que para obtener un dato de la
fila actual se usa el método getString indicando como
parámetro el nombre del campo que se quiere obtener.
Por ejemplo:
rs.getString("sueldo");
Obtiene el sueldo del trabajador señalado actualmente con la flecha.
Este sueldo se obtiene convertido en cadena.
- Los ResultSet poseen otros métodos
para obtener los datos convertidos en números como son:
getInt(“campo”)
y
getDouble(“campo”)
para obtener el dato en entero o double, respectivamente.
Esto nos permite el realizar operaciones con los datos extraídos del ResultSet.
- Como ejemplo de esto último, realice la
siguiente mejora al programa:
En este nuevo código se ha añadido una variable double acumuladora
llamada totalSum, donde sumaremos todos los sueldos.
Dentro del bucle, se van acumulando el sueldo de cada trabajador.
Observa el uso del método getDouble para obtener el campo
sueldo de forma numérica, en vez de usar getString:
totalSum =
totalSum + rs.getDouble("sueldo");
Y finalmente
usamos otro JOptionPane para ver la suma de los sueldos calculada.
Ejecuta el
programa y comprueba su funcionamiento.
- Una vez finalizado el programa, es una buena
costumbre cerrar la base de datos que estamos manejando. Esto se hace
cerrando la “conexión” con la base de datos.
Para hacer esto se usa el método close del objeto conexion.
Esto se hará en el momento en que se finalice el programa, es decir, en
el evento windowClosing de la ventana principal:
Como ves, también hay que encerrar este código entre try…catch
para capturar posibles errores.
CONCLUSIONES:
Para crear un programa Java que pueda usar una base
de datos será necesario realizar los siguientes pasos:
* Preparar el acceso a la base de datos (en el método
constructor).
* Se crearán dos objetos: conexion (Connection) y sentencia (Statement).
* Se cargará el controlador del tipo de base de
datos a usar.
* Se creará el objeto conexion indicando la base de
datos.
* Se creará el objeto sentencia a partir del objeto
conexion.
* Se usará el objeto sentencia para ejecutar consultas SQL en la base de datos.
* Las consultas SQL ejecutadas en la base de datos
se almacenan en objetos del tipo ResultSet.
* Un objeto ResultSet
tiene forma de tabla conteniendo el resultado de la consulta SQL.
* Los objetos ResultSet
tienen métodos para seleccionar el registro de la tabla.
* Los objetos ResultSet
tienen métodos que permiten extraer el dato de un campo en concreto.
No hay comentarios.:
Publicar un comentario