Muchas veces necesitamos incrementar el valor de un campo y retornarlo, por ejemplo para atributos autoincrementable.
Por ejemplo en bases de datos NoSQL como MongoDB no existe el concepto de autoincrementable.
Métodos:
Métodos
Bases de datos NoSQL
public T findOneAndUpdate(String key, String value,String field,Integer... incremento)
MongoDB
public T findOneAndUpdate(Document doc, String field, Integer... incremento)
MongoDB
public T findOneAndUpdate(Document doc, Document inc, Integer... incremento)
MongoDB
Parámetros
Key: es el campo a buscar
value: el valor de ese campo
field: es el campo numérico a implementar
incremento: Opcional si no se pasa ningún valor incrementa en uno el campo
Nota: A partir de la versión 0.2.9 se definió esta clase dentro de JMoordb, no es necesario declarar el entity
Definir el entity: Autoincrementable
@Getter
@Setter
public class Autoincrementable {
@Id
private String documento;
private Integer contador;
public Autoincrementable() {
}
public Autoincrementable(String documento, Integer contador) {
this.documento = documento;
this.contador = contador;
}
@Override
public String toString() {
return "Autoincrementable{" + "documento=" + documento + ", contador=" + contador + '}';
}
}
Ejemplo 1:
Nota:
Recuerde que no es necesario crear la clase Autoincrementable, este pertenece al framework.
Crear el Repository.
@Stateless
public class AutoincrementableRepository extends AbstractFacade<Autoincrementable> {
@EJB
MongoClientProvider mongoClientProvider;
@Override
protected MongoClient getMongoClient() {
return mongoClientProvider.getMongoClient();
}
public AutoincrementableFacade(){
super(Autoincrementable.class,"spardjsd","autoincrementable");
}
@Override
public Object findById(String key, String value) {
return search(key,value);
}
@Override
public Object findById(String key, Integer value) {
return search(key,value);
}
}
Autoincrementable como campo llave
Contamos con una colección para almacenar facturas, y el atributo idfactura debe incrementarse automáticamente.
@Getter
@Setter
public class Facturas {
@Id
private Integer idfactura;
private Double ventas;
public Facturas() {
}
public Facturas(Integer idfactura, Double ventas) {
this.idfactura = idfactura;
this.ventas = ventas;
}
@Override
public String toString() {
return "Facturas{" + "idfactura=" + idfactura + ", ventas=" + ventas + '}';
}
}
Crear una colección para que lleve el contador de los documentos y sus id que se usan en otras colecciones.
Controller
Debemos inicializar el documento Autoincrementable, donde le indicamos el nombre del documento y el contador iniciar para llevar el control. Todos los documentos que se desee controlar su autoincrementable deben ser almacenados aquí. En el ejemplo lo inicializamos en 0.
public void iniciarAutoicrementable(){
try {
Autoincrementable autoincrementable = new Autoincrementable("facturas", 0);
if(autoincrementableRepository.save(autoincrementable)){
System.out.println("guardado ");
}else{
System.out.println("no se guardo "+autoincrementableRepository.getException());
}
} catch (Exception e) {
System.out.println("iniciarAutoincrementable() "+e.getLocalizedMessage());
}
}
public void guardarFactura() {
try {
//Busca el contador de facturas, lo incrementa en uno y devuelve el objeto.
Autoincrementable autoincrementable = new Autoincrementable();
autoincrementable = autoincrementableFacade.findOneAndUpdate("documento", "facturas", "contador");
Integer id = autoincrementable.getContador();
//Guarda la factura
Facturas facturas = new Facturas();
facturas.setIdfactura(id);
facturas.setVentas(5085.23);
if (facturasRepository.save(facturas)) {
System.out.println("guardado");
} else {
System.out.println("No se guardo " + facturasRepository.getException());
}
} catch (Exception e) {
System.out.println("guardarFactura() " + e.getLocalizedMessage());
}
}
Si consultamos la colección autoincrementable, podemos comprobar que se consulto el documento facturas y automáticamente se incremento en uno el valor del contador.
Autoincremantable en un atributo que no es llave primaria.
En el método save() , verificamos si no se ha creado un registro autoincrementable y lo creamos.
//verifica si no se ha creado el contador para proveedor
Optional<Autoincrementable> autoincrementableOptional = autoincrementableRepository.find(new Document("documento", "proveedor"));
if (!autoincrementableOptional.isPresent()) {
Autoincrementable autoincrementable = new Autoincrementable("proveedor", 0);
if (autoincrementableFacade.save(autoincrementable)) {
}
}
Autoincrementable autoincrementable = new Autoincrementable();
autoincrementable = autoincrementableRepository.findOneAndUpdate("documento", "proveedor", "contador");
Integer id = autoincrementable.getContador();
proveedor.setAutoincrementable(id);
if (proveedorRepository.save(proveedor)) {
JsfUtil.successMessage(rf.getAppMessage("info.save"));
reset();
} else {
JsfUtil.successMessage("save() " + proveedorFacade.getException().toString());
}
Análisis de autoincrementables
Ejemplo del porque se implementa findOneAndUpdate()
Existe una colección de documentos donde se maneja un campo entero que funcionara como autoincrementable:
Agenda{"Id":1,"evento":"A"},
{"Id":2,"evento":"B"},
{"Id":3,"evento":"C"}
Si se elimina el evento 3,
Agenda{"Id":1,"evento":"A"},
{"Id":2,"evento":"B"}
Cuando se desee insertar un documento con el {"evento":"D"}, se pueden producir algunas situaciones
*_1. Utilizar la función count() *_para conocer la cantidad de documentos que tiene la colección, este devolverá 2 y al sumarle 1 tendrá el valor de 3, que ya fue usado para el {"evento":"C"}. Al insertarlo quedaría de la siguiente manera:
2. Si buscamos el ultimo documento de la colección{"Id":2,"evento":"B"} , el valor del id es 2 al sumarle 1 quedara en 3, por lo tanto al insertar el evento {"evento":"D"} a la colección este tendría el valor de 3 para el id y este ya fue usado en el
{"evento" :"C"}.
Al insertarlo quedaría de la siguiente manera:
Agenda{"Id":1,"evento":"A"},
{"Id":2,"evento":"B"},
{"Id":3,"evento":"D"}
De esta manera en la colección Agenda utilizara el valor que devuelva el campo valor de la colección
Autoincrementable.
El método findOneAndUpdate() busca el documento que cumpla la condición y realiza el incremento automático y devuelve el documento actualizado.
// incrementa en 1 el campo Valor
findOneAndUpdate("documento", "agenda", "valor");
// incrementa en 8 el campo Valor, le podemos indicar el valor que deseamos de incremento