Neodatis ODB es
una base de datos orientada a objetos con licencia GNU muy simple que
actualmente corre en los lenguajes Java,
.Net, Google Android, Groovy y
Scala.
Con Neodatis podemos evitar la falta de impedancia entre los
mundos orientados a objetos y los relacionales, ya que actúa como una capa de
persistencia transparente para Java, .Net y Mono.
Neodatis ODB soporta
consultas nativas, es decir, podemos lanzar una consulta directamente desde
Java, por ejemplo.
Además es bastante simple e intuitivo. Los objetos pueden
ser añadidos fácilmente a la base de datos, lo que requiere clases no
repetitivas y que las clases ya existentes no puedan modificarse.
También cuenta con un explorador ODB, una herramienta
gráfica para navegar, consultar, actualizar y borrar objetos, así como la
importación / exportación de bases de datos desde y hacía archivos XML.
Sintaxis
La sintaxis para trabajar con Neodatis vamos a verla en
Java. Desconozco como funciona en otros lenguajes como .Net o Groovy, por
ejemplo, pero nos servirá para hacernos una aproximación a esta base de datos.
Lo primero, debemos tener en cuenta que es muy importante
que después de haber abierto una conexión a la base de datos y realizar las
operaciones que deseemos, cerremos dicha conexión, si no nos fallará en futuras
ocasiones.
La conexión la realizamos con un objeto de clase ODB, en la
que indicaremos la ruta donde tenemos nuestra base de datos. Esto servirá tanto
para abrirla como para crear una nueva, en caso de que en la ruta indicada aún
no exista ninguna. En mi caso, vamos a generar una nueva en la ruta D:\ y se llamará neodatis.test.
ODB odb = ODBFactory.open("d:\\neodatis.test");
Y para cerrar la conexión, simplemente indicaremos que
queremos cerrar el objeto ODB creado.
odb.close();
No necesitamos definir en la base de datos como queremos guardar los objetos, éstos lo harán automáticamente, creándose las “tablas” respecto a las clases que vayamos almacenando. Lo que sí deberemos tener creada es una clase en Java (en mi caso) que indique las propiedades y métodos a guardar en la base de datos. Es decir, si queremos almacenar un registro de jugadores de varios deportes, deberemos crear una clase Jugadores, con sus propiedades, métodos, getters y setters correspondientes. Tal que así, por ejemplo.
public class Jugadores {
// Propiedades
private String nombre;
private String deporte;
private String ciudad;
private int edad;
//
Constructores
public Jugadores(){};
public
Jugadores(String nombre, String deporte, String ciudad, int edad) {
super();
this.nombre = nombre;
this.deporte = deporte;
this.ciudad = ciudad;
this.edad = edad;
}
// Métodos
public String
getNombre() {
return nombre;
}
public void
setNombre(String nombre) {
this.nombre = nombre;
}
public String
getDeporte() {
return deporte;
}
public void
setDeporte(String deporte) {
this.deporte = deporte;
}
public String
getCiudad() {
return ciudad;
}
public void
setCiudad(String ciudad) {
this.ciudad = ciudad;
}
public int getEdad() {
return edad;
}
public void setEdad(int edad) {
this.edad = edad;
}
} // Fin clase Jugadores
Creada la clase, la siguiente fase es generar los objetos
Jugadores que queramos almacenar en la BD e insertarlos. Tambíen bastante
intuitivo.
// Creo los jugadores
Jugadores j1= new Jugadores ("María", "voleibol", "Madrid", 14);
Jugadores j2= new Jugadores ("Miguel", "tenis", "Madrid", 15);
Jugadores j3= new Jugadores ("Mario", "baloncesto", "Guadalajara", 15);
Jugadores j4= new Jugadores ("Alicia", "tenis", "Madrid", 14);
// Inserto los objetos
odb.store(j1);
odb.store(j2);
odb.store(j3);
odb.store(j4);
Y listo. Neodatis detectará que tipo de objeto son y los
insertará en una u otra “tabla”.
Para mostrar los datos crearemos un conjunto de objetos genéricos parametrizado al tipo de objeto que queremos traernos. En este caso, Objects<Jugadores>. En él cargaremos todos los objetos del tipo Jugadores que nos traeremos desde la base de datos.
Posteriormente recorreremos el conjunto hasta el final y
accederemos a las propiedades que queramos imprimir con los getters
anteriormente configurados.
// Genero un conjunto de objetos y los traigo del ODB conectado
Objects<Jugadores> objects=odb.getObjects(Jugadores.class);
// Imprimo cuantos objetos me he traido de la BD
System.out.println(objects.size() + "
jugadores:");
int i = 1; // Meramente estético. Así muestra listados los objetos
// Mientras haya objetos, los capturo y muestro
while(objects.hasNext()){
// Creo un
objeto Jugadores y almaceno ahí el objeto
Jugadores jug= objects.next();
// Imprimo las
propiedades que me interes de ese objeto
System.out.println((i++) + "\t:
" + jug.getNombre() + "*" + jug.getDeporte() + "*" + jug.getCiudad() + "*" + jug.getEdad());
} // Fin del While
Claro, puede darse el caso de que no queramos listar todos
los objetos de un tipo determinado, sino que queramos sólos los que tengan X
propiedad o cumplan tal condición.
Para ello deberemos crear un objeto IQuery, que a su vez será un objeto CriteriaQuery, donde recibirá dos parámetros. El primero será el
tipo de objeto que queramos consutar, y el segundo la condición impuesta. Un
Where en toda regla, básicamente.
Hecho esto, nos traeremos todos los objetos igual que en
ejemplo anterior, pero pasando como parámetro del ODB nuestra consulta. Y ya
imprimiríamos los resultados como vimos en el anterior punto.
Veamos un ejemplo
/* Genero la consulta. Llamo a la clase Jugadores
* La condición será que
la propiedad deporte sea igual a tenis
*/
IQuery query = new CriteriaQuery(Jugadores.class, Where.equal("deporte", "tenis"));
// Y ya, por capricho persona, ordeno el resultado por nombre y
edad
query.orderByDesc("nombre,edad");
// Cargo los objetos pasando como parámetro del odb nuestra
consulta
Objects<Jugadores> objects = odb.getObjects(query);
También podemos separar este proceso un poco más, por si nos
resulta más claro verlo de otra forma. El único cambio que haremos será crear
un objeto ICriterion donde realizaremos
la consulta, y pasaremos ese objeto como segundo parámetro de nuestro objeto CriteriaQuery. Tal que así.
// Realizo la condición sobre la propiedad edad
ICriterion criterio = Where.equal("edad",14);
/* Creo el objeto para realizar la consulta y mando el
ICriterion
* como segundo parámetro
*/
CriteriaQuery query = new
CriteriaQuery(Jugadores.class, criterio);
// Y cargo todo en un objeto, como siempre
Objects<Jugadores> objects = odb.getObjects(query);
Y tenemos varias formas de lanzar un where. Por ejemplo
// Jugadores que empiezan por M
ICriterion criterio2 = Where.like("nombre","M%");
// Jugadores mayores de 14
// Where.ge --> mayor o igual, Where.lt --> menor que,
Where.le ---> menor o igual
// Where.Not
--> Distinto
//Where.isNull("atributo")
si un atributo es nulo
//Where.isNotNull("atributo")
si un atributo es nulo
ICriterion criterio3 = Where.gt("edad",14);
Hago
un inciso para aclarar la consulta anterior. Where.gt es para indicar mayor
que. También podemos usar :
- Where.gt à mayor o igual
- Where.lt à menor que
- Where.le à menor o igual
- Where.not à Distinto a
- Where.isNull(“atributo”) si un atributo es nulo
- Where.isNotNull(“atributo”) si un atributo es no nulo
// Jugadores que no empiezan por M
ICriterion criterio4 = Where.not(Where.like("nombre","M%"));
// Jugadores de 15 años de Madrid
ICriterion criterio = new And().add(Where.equal("ciudad", "Madrid")).add(Where.equal("edad",15));
// Jugadores >= de 15 años y de Madrid
ICriterion criterio2 = new And().add(Where.equal("ciudad", "Madrid")).add(Where.ge("edad",15));
Y también podemos realizar consultas complejas, todo lo que
queramos complicarnos es posible. Las voy a pasar un poco rápido porque esto es
una breve aproximación.
Por ejemplo, veamos las siguientes:
// Suma de edades
Values val = odb.getValues(new ValuesCriteriaQuery(Jugadores.class).sum("edad"));
ObjectValues ov= val.nextValues();
BigDecimal value = (BigDecimal)ov.getByAlias("edad");
// también valdría BigDecimal value =
(BigDecimal)ov.getByIndex(0);
// Cuenta de jugadores
Values val2 = odb.getValues(new ValuesCriteriaQuery(Jugadores.class).count("nombre"));
ObjectValues ov2= val2.nextValues();
BigInteger value2 = (BigInteger)ov2.getByAlias("nombre");
// Media de edades
Values val3 = odb.getValues(new ValuesCriteriaQuery(Jugadores.class).avg("edad"));
ObjectValues ov3= val3.nextValues();
BigDecimal value3 = (BigDecimal)ov3.getByAlias("edad");
// Edad máxima y mínima
Values val4 = odb.getValues(((ValuesCriteriaQuery) new
ValuesCriteriaQuery(Jugadores.class.max("edad", "edad_max")).min("edad", "edad_min"));
ObjectValues ov4= val4.nextValues();
BigDecimal maxima = (BigDecimal)ov4.getByAlias("edad_max");
BigDecimal minima = (BigDecimal)ov4.getByAlias("edad_min");
Para borrar un objeto crearemos un objeto IQuery para traernos a memoria los objetos a borrar. Nos posicionamos en el primero objeto y lo borramos usando el ODB.
// Hacemos la consulta para borrar a María
IQuery query = new CriteriaQuery(Jugadores.class, Where.equal("nombre", "María"));
// Cargamos los objetos que coincidan con esa consulta
Objects<Jugadores> objects = odb.getObjects(query);
// Nos posicionamos en el primer resultado
Jugadores jug=(Jugadores) odb.getObjects(query).getFirst();
// Y lo borramos
odb.delete(jug);
Como viene siendo habitual, creamos con un IQuery con los objetos que queramos modificar, cargaremos el objeto en la clase Jugadores de Java, le cambiaremos la propiedad que deseemos usando los setters que programamos al principio y volveremos a almacenar el objeto en la base de datos.
IQuery query = new CriteriaQuery(Jugadores.class, Where.equal("nombre", "María"));
// A María le ponemos Tiro de barra aragonesa como deporte
Objects<Jugadores>
objects = odb.getObjects(query);
Jugadores jug=(Jugadores) odb.getObjects(query).getFirst();
jug.setDeporte("Tiro de barra Aragonesa");
odb.store(jug);
¿Ya dije que íbamos a trabajarla con Java, cierto? Bien, la buena noticia es que instalarla es lo más fácil que hay. Basicamente que no requiere una instalación. Simplemente nos descargamos el paquete NeoDatis ODB de la siguiente dirección:
https://sourceforge.net/projects/neodatis-odb/
Y descomprimimos el paquete. Nos encontraremos con lo
siguiente:
De esta descarga nos interesan dos archivos. Neodatis-odb-1.9.30.689.jar, que será
la librería para nuestro proyecto en Java, y odb-explorer, para usar el explorador de base de datos. .bat si
usamos Windows, .sh para Linux.
Yo voy a usar el IDE Eclipse, pero emplea el que te sientas
más comodo.
Genera un nuevo proyecto Java, y crea una nueva carpeta,
llamada lib, dentro de éste. Aquí
copiaremos el .jar de NeoDatis.
Nos iremos a Propiedades
del proyecto à Java Build Path à
Libraries y elegiremos Add JAR,
desde donde añadiremos el .jar de la ruta nombreProyecto/lib
que hemos creado.
Y esa es toda la configuración previa que debemos tener.
Naturalmente, ahora toca crear la estructura de clases para leer / insertar /
modificar / borrar elementos de nuestra base de datos, tal y como explicamos en
la sección anterior.
Y listo, ya podemos trabajar con NeoDatis ODB .
Me ayudo un motón!! Mil gracias
ResponderEliminarMe alegro que te resultase util. Gracias por comentar :)
EliminarHola,
ResponderEliminarPrimero gracias por compartir tus conocimientos y ayudarnos un poco! Me gustaría hacer una consulta doble, por ejemplo buscar los jugadores de Madrid y 15 años pero en vez de hacerlo con ICreterion, hacerlo con un IQuery. ¿Es posible? Solo añadiendo otro .add?
Gracias por tu tiempo!
EliminarHola.
Cuando quieres hacer una consulta doble, o de varios campos, tienes a tu disposición los métodos and() y or(), depende de la necesidad de tu condición, y posteriormente sí, simplemente tienes que añadir otro add.
Un ejemplo de como crearlo es el siguiente:
OR:
IQuery query = new CriteriaQuery(Player.class, Where.or().add(Where.equal("equipo", "Madrid")).add(Where.like("edad", 15)));
AND:
IQuery query = new CriteriaQuery(Player.class, Where.and().add(Where.equal("equipo", "Madrid")).add(Where.like("edad", 15)));
Un saludo :)
Hola buenas tardes, algun ejemplo de como aplicar neodatis para guardar informacion en una web con jsp?
ResponderEliminarCon JSP nunca lo he probado, pero haciendo una búsqueda rápida no he encontrado mucha información. Lo más parecido ha sido este ejemplo de Spring con NeoDatis:
Eliminarhttps://github.com/jbellmann/neodatis-springextension
De todas formas, encuentro un poco complejo montarlo con Neodatis por la forma que tiene de manejar las conexiones. Te recomiendo que le pegues un vistazo a MongoDB para ver si cuadra más con la idea que quieres llevar a cabo.
Me encargaron hacer una Jframe con botones , pero aun no se como programar los botones con neodatis,
ResponderEliminarHola Itzair. Creo que no acabo de entender tu problema. Neodatis es una base de datos orientada a objetos, no tiene nada que ver con el diseño de aplicaciones en cuanto a su parte gráfica (JFrame, JButtons, etc.). ¿Puedes explicarme a que te refieres?
EliminarHola, me ha parecido muy clara esta información, no tengo nada de experiencia en bases de datos orientadas a objetos y me gustaría saber como funciona el concepto de composición en neodatis?. Me refiero a que si es que guardo un objeto compuesto por otros objetos estos se almacenan automáticamente o hay que hacerlo manualmente de alguna forma?. Espero haber sido claro con mi pregunta. Gracias de antemano.
ResponderEliminarHola! Gracias por tu comentario.
EliminarNo sé si entiendo muy bien a que te refieres.
Pongamos que tienes en Neodatis una base de datos de objetos Motor y Coche.
En tu programa tienes un una clase Coche que contiene una clase Motor.
Cuando almacenas la clase Coche, en la base de datos el registro solo se incluirá en la tabla de Coche (aunque dentro de ese registro el objeto tenga otro que sea Motor). La tabla Motor no tendrá ningún contenido a no ser que lo agregues tu igual que hiciste con Coche.
Espero que te aclare algo mi respuesta.
Saludos!
precisamente esa era mi pregunta, gracias!
EliminarSin embargo acabo de comprobarlo, y sí se guardan automáticamente. Lo probé con tu ejemplo del Coche y el Motor. Creé 3 coches con sus respectivos motores y al guardar los objetos Coche también se guardaron sus respectivos objetos Motor de manera automática.
EliminarPara comprobarlo recuperé de la base de datos todos los objetos de tipo Motor (A estos objetos no los he guardado explícitamente sino que debieron haberse guardado al almacenar el objeto Coche) y efectívamente despues de consultar a la base de datos de esta manera Objects objects = odb.getObjects(Motor.Class); obtube los objetos motor de cada Coche que almacené.
Ah, si? Pues pensaba que era justo lo contrario. Muchas gracias por la aclaración. Me facilitara la vida en las aplicaciones.
EliminarSaludos!
Este comentario ha sido eliminado por el autor.
ResponderEliminarPermite clave primaria, ajena etc?
ResponderEliminarCómo puedo importar o exportar la base de datos en xml
ResponderEliminar