Campos autoincrementables

Siempre me ha llamado la atención de como se declaran los famosos campos auto incrementables en las distintas bases de datos por lo menos en las que he usado, y ahora mas ya que he estado usando intensamente JPA.



Acá pondré un resumen de como se declaran:

MySQL

campo [(longitud)] [not null] auto_increment primary key

Es necesario definir un campo autoincrementable de llave primaria en MySQL ya que este asi lo requiere de lo contrario no se puede declarar este tipo de campo.
Ejemplo:

create table prueba (
id int not null auto_increment primary key
)


PostgreSQL

campo serial [not null]

En PostgreSQL por el contrario que MySQL no requiere que un campo de tipo serial sea una llave primaria ejemplo:

create table prueba (
id serial not null
)

SQL Server / Sybase

En el caso de SQL Server / Sybase es mucho mas simple solo basta utilizar esta sintaxis:


campo int identity [(inicio,incremento)]

Ejemplo:

create table prueba (
id int identity
)

O sino si queremos que comience desde 3 y su incremento sea de dos en dos lo declaramos asi:

create table prueba (
id int identity(3,2)
)

Apache Derby

campo int [not null] generated always as identity [(start with [cantidad], increment by [cantidad])]

Derby es el gestor de base de datos de Apache, que viene incluido en el JDK 1.6, y lo podemos usar a traves de Netbeans, dos ejemplos de declaracion serian:

create table prueba (
id int not null generated always as identity
)

En el ejemplo anterior el campo id se generara como campo auto incrementable, con los valores por defecto que comienza a contar desde uno y su incremento es de uno en uno.

Ahora veamos este otro:

create table prueba (
id int not null generated always as identity (start with 5, increment by 2)
)

En la declaracion anterior estoy creando un campo de tipo autoincrementable que comience en cinco y su incremento sera de dos en dos.

Oracle

En el caso de Oracle es un poco mas trabajoso ya que no existe un tipo auto incrementable. Lo que se debe de hacer es primero crear un campo de tipo Number, luego crear una secuencia y por ultimo crear un trigger que realizara el autoincremento cada vez se haga un insert.

Ejemplo de todo esto seria:

create table prueba (
id number not null primary key,
descripcion varchar2(20)
)

Ya creada la tabla ahora crearemos una secuencia que comience desde uno y que se incremento en uno tambien.

create sequence seq_id_prueba
start with 1
increment by 1
nomaxvalue;

Hecha la secuencia debemos crear el trigger para que se utilice la secuencia para cada insert que le hagamos a la tabla.

create trigger trig_id_prueba
before insert on prueba
for each row
begin
select seq_id_prueba.nexval into :new.id from dual;

end;

Ahora cada vez que hagamos un insert podremos hacerlo asi:

insert into prueba(descripcion) values('Una fila');

Espero que les sirva este pequeno resumen ya que me costo un webo terminarlo aun cuando se ve sencillo ya que lo empece desde el domingo y hasta el dia de hoy logre terminarlo.

Comentarios (3)

Obteniendo una Conexion a partir de un EntityManager

Hace unos dias cuando estaba realizando unos reportes con la herramienta iReport, me tope con la necesidad que para poder invocar los reportes elaborados era necesario enviar una instancia de un objeto Connection para el metodo que genera el reporte.

Crear una conexion es sencillo pero yo no estaba manejando mi conexion de la manera tradicional pues estaba usando JPA que es la API de persistencia de datos de Java y esta es la que maneja las conexiones y la configuracion de la cadena de conexion se guardda en la unidad de persistencia que es nada mas y nada menos que un XML.

En un principio pense en acceder al XML directamente, pero como sabia que la conexion se maneja a traves del objeto EntityManager decidi averiguar como se hacia y pues la forma fue la siguiente asi de simple:

public Connection getConnection() {
EntityManagerFactory emf=Persistence.createEntityManagerFactory("NombreUnidadPersistencia");
EntityManager em=emf.createEntityManager();
return ((oracle.toplink.essentials.ejb.cmp3.EntityManager)em)
.getServerSession()
.getDefaultConnectionPool()
.acquireConnection()
.getConnection();
}


Espero que esto le sirva cuando se tenga la necesidad de obtener una instancia de la conexion que esta utilizando a travez de un EntityManager.

Comentarios (3)

Introduciendo al uso de persistencia de datos JPA

Como parte de mi promesa de volver a bloguear activamente, ahora voy a escribir sobre el uso de la API de persistencia de datos de Java comunmente llamado JPA.


Pero antes de empezar este post aun recuerdo cuando Rodrigo queria implementar esta historia en nuestro proyecto de Sistemas de informacion gerencial, definitivamente si a mi no me hubiera agarrado el berrinche hubiesemos avanzado bastante en poco tiempo, ya que perdi bastante tiempo queriendo escribir mis diske reglas del negocio, por eso en ese caso se aplico bien lo que dicen la gente adulta "uno de cipote es tonto".

Este post se centrara en utilizar JPA utilizando el IDE Netbeans 6.1, ya que es el que tengo mas tiempo utilizandolo, y en mi caso la base de datos de mi preferencia es PostgreSQL.

La base de datos que cree la llame simplemente "tienda" y su estructura esta compuesta por dos tablas:

CREATE TABLE tienda
(
id serial NOT NULL,
descripcion character varying(20),
CONSTRAINT pk_tienda PRIMARY KEY (id)
)

CREATE TABLE empleado
(
nick character varying(15) NOT NULL,
nombre character varying(30),
fk_tienda integer,
CONSTRAINT pk_empleado PRIMARY KEY (nick),
CONSTRAINT tienda_empleado FOREIGN KEY (fk_tienda)
REFERENCES tienda (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)

Luego de esto nos dirigimos a nuestro Netbeans y creamos un proyecto "Java Application", creamos el nombre que nos plazca en mi caso le coloque JPAejemplo, incluso deje que el Netbeans me creara una clase con el metodo main que es alli donde mostrare su uso.


Luego de esto nos vamos a la pestana de "servicios" y creamos una nueva conexion a una base de datos, lo bueno de usar Netbeans es que ya trae el driver para PostgreSQL o si se desea tambien MySQL, si se esta usando algun otro como SQL Server, Oracle, SyBase, etc., es necesario agregarlo.


Para crear la nueva conexion hacemos clic derecho sobre el nodo que dice "Databases" en la pestana de servicios, y elegir la opcion "New Connection" del menu emergente. Ingresamos los datos necesarios para pegarnos a nuestra base de datos y damos aceptar.


Ya teniendo nuestra conexion abierta procedemos a crear nuestros objetos de reglas del negocio persistentes.

Para ello damos clic derecho sobre el proyecto, elegir nuevo y dar clic en la opcion "Entity Classes from Database", aparecera un asistence para la creacion de nuestros objetos persistentes.

El primer paso es elegir la conexion que creamos, para luego escoger las tablas que estaran involucradas.

Luego dar siguiente el asistente nos preguntara el nombre que le daremos a nuestras clases asi como tambien el paquete donde las encapsularemos.


Notese hay una alerta la cual indica que no hemos creado una unidad de persistencia debemos crearla para poder proseguir, asi que hacemos clic en el boton "Create Persistence Unit".


En la ventana de dialogo por lo general no se toca simplemente lo dejamos como esta siempre recordando el nombre de la unidad de persistencia que en este caso se llamara "JPAejemploPU", que luego la utilizaremos pero eso sera solamente una vez.

Ya generada la unidad de persistencia precionaremos el boton finalizar. Si seguimos los pasos tal cual como lo he indicado debemos tener dos clases creadas una llamada "Empleado" y la otra "Tienda".

Ahora para poder continuar debemos tener claro el tipo de dato que son las llaves primarias de las dos tablas que creamos en el caso de la tabla Tienda su llave primaria es de tipo "Serial" es equivalente a la opcion autoincrement de MySQL o IDENTITY de SQL Server.

Teniendo claro eso definimos la forma en la clase Tienda de como se generara el codigo primario cuando se indique que queremos realizar por decirlo asi un insert.

En la seccion del campo Id de la clase Tienda debemos agregar lo siguiente:

GeneratedValue(strategy=GenerationType.IDENTITY)

Esto se coloca despues de la anotacion "Column" del campo Id, que debe quedar asi:

@Id
@Column(name = "id", nullable = false)
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;


No hay que olvidar agregar los respectivos import.

import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;


Con esto que se le agrego a la clase indicamos la forma de generar el valor para el campo Id en cada insert.

Ese tipo de generacion aplica para base de datos MySQL, SQL Server, Sybase, PostgreSQL (cuando trata de campos de tipo serial).

Pero cuando usamos secuencias se debe utilizar otro tipo de generacion de valores, como es el caso para Oracle, que en otro post lo explicare con mas detalle.

Pero bien no basta con solo agregar eso a la clase, tambien es necesario crear nuestras "Consultas nombradas", por esta caracteristica es que me gusto bastante esto del JPA, ya que es bastante, bastante flexible.

Creamos una simple para mostrar todos los empleados, ahora procedemos a editar la clase Empleado y en la anotacion "NamedQueries" agregamos la nuestra tan simple como esto:

@NamedQuery(name="Empleado.verTodos", query="SELECT e FROM Empleado e")

Que al final debe quedar asi:

@NamedQueries({
@NamedQuery(name="Empleado.verTodos", query="SELECT e FROM Empleado e"),
@NamedQuery(name = "Tienda.findById", query = "SELECT t FROM Tienda t WHERE t.id = :id"), @NamedQuery(name = "Tienda.findByDescripcion", query = "SELECT t FROM Tienda t WHERE t.descripcion = :descripcion")})

Ya hecho todo esto, pasamos a la parte mas interesante, que es utilizar nuestras clases ya configuradas, para ello creamos dos clases mas para la manipulacion de las ya antes mencionadas.

Una la llamaremos ControlEmpleado.java y la otra ControlTienda.java

El objetivo de estas sera mostrar consultar, agregar, eliminar o modificar un objeto en especifico.

Pero para no hacer mas largo este post de lo que ya esta por que me estoy cagando del sueno solo mostrare como mostrar los resultados de una consulta, y realizar un insert.

Pues bien para realizar un insert nos vamos a la clase ControlTienda y agregamos el siguiente metodo:

public void insertPrueba() {
EntityManagerFactory emf=Persistence.createEntityManagerFactory("JPAejemploPU");
EntityManager em=emf.createEntityManager();

Tienda nueva = new Tienda();
nueva.setDescripcion("Otra tienda");

em.getTransaction().begin();
em.persist(nueva);
em.getTransaction().commit();
}


Eso es todo, lo mas correcto hubiera sido que el metodo recibiera una instancia de tienda y luego por medio de JPA se realizara el insert, pero el punto era mostrar como se hace.

Ahora como mostramos los registros? pues es tambien muy sencillo, y eso haciendo uso de nuestra consulta nombrada.

Creamos otro metodo en la clase ControlEmpleado, que devuelva un arreglo de Empleados.

public Empleado[] getEmpleados() {
EntityManagerFactory emf=Persistence.createEntityManagerFactory("JPAejemploPU");
EntityManager em=emf.createEntityManager();

Query q = em.createNamedQuery("Empleado.verTodos");

return (Empleado[]) q.getResultList.toArray(new Empleado[0]);
}

Ya con esto desde el metodo main hacemos un recorrido por los registros que nos devuelva nuestro metodo.

Empleado[] empleados = new ControlEmpleado().getEmpleados();

for (int i= 0 ;i
System.out.println(empleados[i].getNombre()+ " trabajo en "+empleados[i].getTienda().getDescripcion());



Y eso es todo, espero poder aportar mas con lo que he quedado pendiente en este post, saludos marachitos.

Comentarios (4)

De vuelta a la actividad

En el momento antes de escribir esta entrada me estaba fijando que la ultima vez que postee fue en Julio, definitivamente el blog estaba abandonado pero no por que yo lo quisiese asi.

En este ano ha tenido muchos cambios en mi vida, he conocido y aprendido de varias personas que siento que puedo considerarlos como amigos.

Ahorita estoy abusando de escribir esta entrada por que faltan diez minutos para la media noche y debo irme a dormir, ya que debo de estar a las ocho de la manana en Santa Elena, y viajar todos los dias desde Santa Ana, hasta el quinto culo requiere de disciplina.

Pero bien el motivo de este post es para dar senales de vida al mundo, ya que tengo muchas cosas que postear y compartir para mis amigos, asi que mi actividad bloguera va a aumentar asi como cuando estaba en el apogeo el blog.

Comentarios (7)