Modelo de Tarea Academica 2 POO
Modelo de Tarea Academica 2 POO
Modelo de Tarea Academica 2 POO
Tarea Académica 2:
Clases persistentes con base de datos. Python, C# y Scala
AUTORES
Gonzales Salas Nazly
Salazar de Paz Massimo
Docente
Curso:
Programación Orientada a Objetos
1
ÍNDICE
I. INTRODUCCIÓN
II. DESARROLLO
a. Clases persistentes con base de datos
b. Clases persistentes con base de datos en Python
c. Clases persistentes con base de datos en C#
d. Clases persistentes con base de datos en Scala
III. CONCLUSIONES
IV. REFERENCIA
2
I. INTRODUCCIÓN
3
II. DESARROLLO
a) Clases persistentes con base de datos
Implementar un constructor sin argumentos, todas las clases persistentes deben tener un
constructor predeterminado (el cual puede ser no-público) de modo que pueda
instanciarlas usando Constructor.newInstance().
Proporcionar una propiedad identificadora o id, que relaciona la llave principal con la tabla
de la base de datos. Esta propiedad mapea a la columna de la llave principal de la tabla de
la base de datos. La propiedad podría llamarse de cualquier manera y su tipo podría haber
sido cualquier tipo primitivo, java.lang.String o java.util.Date. Si su tabla de
base de datos heredada tiene claves compuestas, puede utilizar una clase definida por el
usuario con propiedades de estos tipos. Declarar métodos de acceso y de modificación
para los campos persistentes, se puede implementar interfaces donde se declaren
métodos públicos; así mismo, se pueden declarar métodos de acceso y de modificación,
métodos getter y setter. Se puede implementar herencia, equals() y hascode(); garantiza la
equivalencia de identidad persistente y de identidad Java, dentro del ámbito de una sesión
en particular de modo que en el momento en que mezcla instancias recuperadas en
sesiones diferentes, tiene que implementar equals() y hashCode()
Soporta modelos dinámicos, usando mapeos en tiempo de ejecución; las entidades
persistentes no necesariamente tienen que estar representadas como clases POJO o
como objetos JavaBean en tiempo de ejecución. Soporta modelos dinámicos (utilizando
mapeos tiempo de ejecución). Una de las ventajas principales de un mapeo dinámico es el
rápido tiempo de entrega del prototipado sin la necesidad de implementar clases de
entidad, el esquema de base de datos se puede normalizar y volver sólido, permitiendo
añadir una implementación apropiada del modelo de dominio más adelante.
4
Debido, a que el módulo shelve está respaldado por pickle , es inseguro para cargar un
estante de una fuente no fiable. Al igual que con Pickle, cargar un estante puede ejecutar
código arbitrario. Una desventaja de shelve, es que cuando se utiliza el valor interfaz por
defecto no hay manera de predecir qué formato DBM se utilizará, ya que selecciona uno
basado en las bibliotecas disponibles en el sistema donde se crea la base de datos. El
formato no importa si la aplicación no necesitará compartir los archivos de la base de datos
entre hosts con diferentes bibliotecas, pero si la portabilidad es un requisito, usa una de las
clases en el módulo para asegurar que se seleccione un formato específico. Sin embargo,
json es otra librería y se usa con más frecuencia para aplicaciones Web, ya que se integra
mejor con herramientas existentes de almacenamiento de servicios web. Para las
aplicaciones web que ya trabajan con datos en JSON, utilizar json y dbm proporciona otro
mecanismo de persistencia. Usar dbm directamente es un poco más de trabajo que shelve
porque las claves y los valores de la base de datos deben ser cadenas, y los objetos no se
volverán a crear automáticamente cuando el valor sea accedido en la base de datos.
Restricciones
La elección del paquete de base de datos que se utilizará (como dbm.ndbm o dbm.gnu)
depende de la interfaz disponible. Por lo tanto, no es seguro abrir la base de datos
directamente usando dbm. La base de datos también está sujeta a las limitaciones de dbm,
si esto se usa, significa que los objetos almacenados en la base de datos deberían ser
bastante pequeños, y en casos raros, las colisiones de claves pueden hacer que la base
de datos rechace actualizaciones. El módulo de archivado no admite el acceso simultáneo
de lectura / escritura a objetos archivados. (Múltiples accesos de lectura simultáneos son
seguros.) Cuando un programa tiene un estante abierto para escribir, ningún otro programa
debería tenerlo abierto para leer o escribir. El bloqueo de archivos de Unix se puede usar
para resolver esto, pero esto difiere entre las versiones de Unix y requiere conocimiento
sobre la implementación de la base de datos utilizada
Ejercicios en Python
d = {'var1':'desperados'} d2
= {'var2':'coronita'}
# Escribimos los datos asociandoles una llave
with shelve.open('file.data', 'c') as shelf:
shelf["uno"] = d
shelf["dos"] = d1
# Leemos los datos y los mostramos with
shelve.open('file.data', 'r') as shelf: for
key in shelf.keys():
print(repr(shelf[key])))
5
Ejem 1.2 import
shelve
d = shelve.open(filename) # open - el archivo puede tener el sufijo agregado por bajo nivel
# library
d.close() # cierralo
shelve
filename='/tmp/shelve.out'
my_shelf = shelve.open(filename,'n') # 'n' for new
6
print('ERROR shelving: {0}'.format(key)) my_shelf.close()
Para restaurar:
cPickle /
pickle
Ejem 2.1
import
cPickle
as pickle
#o
import
pickle
d = {'var1':'desperados','var2':'coronita'}
# Abrimos el archivo donde almacenaremos el
# resultado de la serialización
with open('file.data', 'w') as f:
# Almacenamos el diccionario en el fichero con
dump() pickle.dump(d, f) f.close()
# Con load leemos el contenido almacenado
en el # archivo donde almacenamos la
información. with pickle.load(open('file.data',
'r')) as spd: print spd
Ejem 2.2
import pickle
def __str__(self):
return "{} {} {}".format(self.nombre, self.genero, self.edad)
class ListaPersonas:
personas = []
7
def __init__(self):
fichero = open ("lista_de_personas", "ab+”)
fichero.seek(0) # Desplazamos cursor al principio
try:
fichero. close
() del fichero
def mostrar_personas(self):
for persona in self. personas:
print(persona.__str__())
def guardar_personas(self):
fichero = open("lista_de_personas", "wb")
pickle.dump(self.personas, fichero)
fichero.close()
del fichero
def mostrar_informacion(self):
print("La información del fichero externo es la
siguiente:") for persona in self.personas:
print(persona.__str__())
Ejem 2.3
import pickle
def recuperar_puntajes(nombre_archivo):
8
""" Recupera los puntajes a partir del archivo provisto.
Devuelve una lista con los valores de los puntajes.
Lo primero que debemos hacer es crear una conexión a la base de datos utilizando el método de
conexión. Después de eso, se necesitará un cursor que operará con esa conexión.
Se utiliza el método de ejecución del cursor para interactuar con la base de datos y, de vez en
cuando, confirme los cambios utilizando el método de confirmación del objeto de conexión.
Dbconnect(object):
def __init__(self):
self.dbconection = MySQLdb.connect(host='host_example',
port=int('port_example'),
user='user_example',
passwd='pass_example',
db='schema_example') self.dbcursor = self.dbconection.cursor()
def commit_db(self):
self.dbconection.commit()
def close_db(self):
self.dbcursor.close()
self.dbconection.close()
Interactuar con la base de datos es simple. Después de crear el objeto, simplemente use el
método de ejecución.
9
db = Dbconnect() db.dbcursor.execute('SELECT * FROM %s' %
'table_example')
db = Dbconnect() db.callproc('stored_procedure_name',
[parameters] )
Una vez que se realiza la consulta, puede acceder a los resultados de varias maneras. El objeto del
cursor es un generador que puede obtener todos los resultados o ser enlazado.
db. commit_db ()
db.close_db()
10
c) Clases persistentes con base de datos en C#
11
Clase Persistente. Una clase persistente en C# abarca las mismas funciones que
en Python solo tomando el detalle de que se implementaría los atributos,
declaración de los get y set y finalmente implementación del constructor en dicha
clase. Además, se debe tomar en cuenta que estas clases en este lenguaje de
programación viene a aplicar las cuatro reglas esenciales ya mencionadas
anteriormente:
T* puntero = valor-devuelto-por-el-operador;
Los objetos creados con new son persistentes, es decir, la vida del nuevo objeto es desde
el punto de creación hasta el final del programa o hasta que el programador lo destruya
explícitamente con el operador delete. Este último desasigna la zona de memoria ocupada
por el objeto, de forma que queda disponible para nuevo uso. Las sucesivas invocaciones
de este operador van reservando zonas de memoria en el montón para los objetos
sucesivamente creados. El gestor de memoria del compilador se encarga de mantener una
tabla con los sitios ocupados y libres sin que haya conflictos hasta que la memoria se ha
agota, o no existe espacio contiguo suficiente para el nuevo objeto. En cuyo caso se lanza
una excepción como indicativo del error.
Peligros La persistencia de los objetos creados con new y su independencia del ámbito
desde el que han sido creados, es muy importante y de tener en cuenta, pues suele ser
12
motivo de pérdidas de memoria en el programa si olvidamos destruirlos cuando ya no son
necesarios. Hay que prestar especial atención, porque en una sentencia como:
voidfunc() {
...
tipoX* Xptr = new tipoX;
...
}
el área de almacenamiento señalada por el puntero es persistente, pero Xptr que es una
variable local automática no lo es. Si olvidamos destruir el objeto creado (con delete) antes
de salir del ámbito, el área de almacenamiento permanecerá ocupando espacio en el
montón y no podrá ser recuperada nunca, pues el puntero Xptr habrá desaparecido. La
cuestión de pérdida de memoria no es solo cuestión de que el programador "recuerde"
utilizar delete antes de salir del ámbito del puntero. También puede producirse por otras
circunstancias. Por ejemplo, el mecanismo de lanzamiento y captura de excepciones C++
puede funcionar como un salto, goto o break multinivel, que saque abruptamente de
ámbito al puntero con la consiguiente pérdida irreparable. La situación puede ser
esquematiza como sigue (la figura adjunta muestra el estado de la pila y el alcance del
desmontaje -"Stack unwinding"- caso de producirse un error).
fun1() { try {
fun2(); }
catch (...) {
...
} }
fun2() {
A* aptr = new A; // crear objeto
foo();
...
delete aptr; // Ok. destruir el objeto }
// antes de salir de ámbito foo() { ...
if (x) throw "Error";
...
}
Ventajas:
Desventajas:
13
La persistencia es muy difícil de implementar puesto que es muy compleja ya que le exige
al programador el manejo de Puntero. Todo objeto creado de forma persistente debe de
ser destruido cuando ya no se lo necesita puesto que ocasiona pérdidas de memoria en el
programa si olvidamos destruirlos.
Ejemplo en C++:
#include<conio.h>
#include<iostream.h>
#include <vcl.h>
#pragma hdrstop #include <fstream.h> class persona { private:
String nombre; public:
III.
14