Documentos de Académico
Documentos de Profesional
Documentos de Cultura
1.- Que es NHibernate y para qu sirve.........................................................................3 2.- Instalacin de NHibernate.........................................................................................6 3.- Con i!uracin de NHibernate..................................................................................." #.- $%e&plos sencillos de &apeo '(..............................................................................) 4.1 Mapeo de clases sencillo.......................................................................................11 4.2 Mapeo con herencia...............................................................................................12 4.3 Mapeo de composiciones.......................................................................................16 4.4 Mapeo de relaciones uno a muchos.......................................................................20 4.5 Mapeo de relaciones muchos a muchos................................................................24 *.- +anipulacin de datos persistentes........................................................................26 5.1 Recuperando un ob e!o de la base de da!os. .........................................................26 5.2 Reali"ando consul!as simples................................................................................27
#n!roducci$n a %&iberna!e
#n!roducci$n a %&iberna!e
1odemos no!ar /ue la aplicaci$n !raba ar* con ob e!os persis!en!es- pero sin comunicarse direc!amen!e con la base de da!os. 'n su lu(ar- la comunicaci$n ser* con el +rame,or> %hiberna!e- el cual se compone de una secci$n de con+i(uraci$n ;puede ser archi)o App.config o Web.config se(Dn nues!ro pro.ec!o sea Eindo,s Forms o Eeb< . un con un!o de mapeos Ob e!oFRelacionales. G!ili"ando es!os elemen!os- %hiberna!e se comunicar* con la base de da!os . reali"ar* las acciones re/ueridas por los ob e!os persis!en!es ;inserci$n- ac!uali"aci$n- borrado- selecci$n<. 'n!rando un poco m*s en de!alle- una ar/ui!ec!ura Hli(eraI de %&iberna!e es cuando la aplicaci$n proporciona sus propias cone5iones :DO.%'9 . mane a lo /ue son !ransacciones- en!onces la ar/ui!ec!ura ser*C
#n!roducci$n a %&iberna!e
Bos ob e!os persis!en!es re/uieren almacenar es!ados- para es!o es necesario u!ili"ar una sesi$n ;canal de comunicaci$n en!re la aplicaci$n . la base de da!os<. Ba sesi$n de comunicaci$n ser* creada por una SessionFactory- /ue es un cach4 de los mapeos de una base de da!os en par!icular. Ba SessionFactory puede ser con+i(urada u!ili"ando c$di(o o con+i(urando los archi)os App.config o Web.config. :hora- si deseamos u!ili"ar !odas las carac!er3s!icas /ue pro)ee %&iberna!epodemos u!ili"ar una ar/ui!ec!ura como la /ue se mues!ra a con!inuaci$nC
'n es!a ar/ui!ec!ura- %&iberna!e pro)ee lo /ue es el con!rol de !ransacciones ;u!ili"ando Transactions creadas por una TransactionFactory< . con!rol de cone5iones :DO.%'9 /ue no es!*n e5pues!as a la aplicaci$n- sin embar(o pueden ser e5!endidas o implemen!adas por los desarrolladores. 'n resumen- %&iberna!e es un Frame,or> /ue pre!ende abs!raer por comple!o al desarrollador de lo /ue es el mane o de persis!encia en las aplicaciones. :l u!ili"ar %&iberna!e el desarrollador s$lo !raba ar* con ob e!os capaces de almacenar . recuperar es!ados- con !odo lo /ue ello si(ni+ica ;mane o de relaciones en!re ob e!os- erar/u3a de ob e!os- e!c.<.
#n!roducci$n a %&iberna!e
#n!roducci$n a %&iberna!e
'n la "ona de con+i(uraci$n es posible a(re(ar las con+i(uraciones espec3+icas para cada aplicaci$n u!ili"ada en la soluci$n ac!ual. 'n es!e caso es necesario con+i(urar las opciones de %&iberna!e para /ue acceda a la base de da!os u!ili"ada. : con!inuaci$n un e emplo de la con+i(uraci$n de %&iberna!e para acceder a una base de da!os.
<nhibernate> <add +e =hibernate.connection.!rovider value=#hibernate."onnection.4river"onnection(rovider1> <add +e =hibernate.dialect value=#hibernate.4ialect.555 1> <add +e =hibernate.connection.driver6class value=#hibernate.4river.7771> <add +e =hibernate.connection.connection6string value=888 1> <1nhibernate>
Donde se debe reempla"ar los )alores $$$- %%% . &&& se(Dn sea la base de da!os /ue es!emos u!ili"ando para almacenar los da!os de nues!ra aplicaci$n. Ba )ersi$n 1.2 de %hiberna!e sopor!a las bases de da!os m*s u!ili"adas ho. en d3a. : con!inuaci$n se lis!an al(unas de las bases de da!os sopor!adas por %hiberna!e 1.2 . los )alores de con+i(uraci$n de las )ariables $$$- %%% . &&& del e emplo an!erior.
#n!roducci$n a %&iberna!e
+icroso t -Q. -erver 2/// 000, Ms8/l2000Dialec! 111, 8/l2lien!Dri)er 222, 38er)erLdb8er)erM#ni!ial ca!alo(LdbM#n!e(ra!ed 8ecuri!.L881#I +icroso t -Q. -erver 2//* 000, Ms8/l2005Dialec! 111, 8/l2lien!Dri)er 222, H8er)erL8er)erMDa!abaseL' emplos%&iberna!eMGser #dLusuarioM1ass,ordLp,dI +y-Q. 000, M.8@BDialec! o M.8@B5Dialec! ;M.8@B 5< 111, M.8/lDa!aDri)er 222, H8er)erLser)erMDa!abaseLda!abaseMGser #DLuserM 1ass,ordLpass,ordI 'racle 000, OracleDialec! / OracleNDialec! 111, Oracle2lien!Dri)er 222, HDa!a 8ourceL+uen!eMGser #dLuserM1ass,ordLp,dMI 4ost!re-Q. 000, 1os!(re8@BDialec! 111, %p(slDri)er 222, H8er)erL8er)erMDa!abaseLdbMGser #dLuserM1ass,ordLp,dM 'ncodin(LG%#2OD'I 9eniendo la con+i(uraci$n del archi)o App.config de+inida- s$lo nos /ueda ob!ener el dri)er necesario para la cone5i$n . a(re(ar una re+erencia a 4l en nues!ro pro.ec!o. -Q. -erver 2///-2//*, 8.s!em.Da!a.8/l2lien! en 8.s!em.Da!a.dll ;J82005<. +y-Q., h!!pC//de).m.s/l.com/do,nloads/connec!or/ne!/1.0.h!ml 'racle, 8.s!em.Da!a.Oracle2lien!.dll ;en J82005<. 4ost!re-Q., h!!pC//p(+oundr..or(/pro ec!s/np(s/l/
#n!roducci$n a %&iberna!e
#n!roducci$n a %&iberna!e
!ublic void Save:; < #hibernate9anager nhm = ne@ #%ibernate9anager:;? =Session session = #%ibernate9anager.#%Session? session.Save:this;? session."lose:;? #%ibernate9anager."loseSession>actor :;? D '5is!e la posibilidad de mane ar el acceso a la base de da!os en base a !ransacciones- es decir los cambios en la base de da!os se reali"an de manera a!$mica con!rolados por una !ransacci$n. 'n caso de suceder al(una anomal3a duran!e una !ransacci$n abier!a- se puede indicar a la aplicaci$n /ue abor!e la !ransacci$n . es!o anular* cual/uier posible cambio en la base de da!os. 1ara u!ili"ar !ransacciones en el m4!odo 8a)e de los ob e!os persis!en!es se puede u!ili"ar el si(uien!e c$di(o de e emplo. !ublic void Save:; < #hibernate9anager nhm = ne@ #%ibernate9anager:;? =Session session = #%ibernate9anager.#%Session? =*ransaction tx = session.*ransaction? tx.Cegin:;? tr < session.Save:this;? tx."ommit:;? D catch < tx.FollCac+:;? D session."lose:;? #%ibernate9anager."loseSession>actor :;? D O!ro re/uerimien!o para el mapeo Ob e!oFRelacional es el poseer un archi)o de mapeo- es!e archi)o es!* en +orma!o -ml . su nombre por con)enci$n es clase.ersistente./bm.-ml. 9odo archi)o de mapeo debe con!ener como nodo ra3" lo si(uien!eC <hibernate-ma!!ing xmlns=urnGnhibernate-ma!!ing-H.H names!ace=mi#ames!ace assembl =miAssembl default-laI =false > <class . . . > <2-- ma!eo de la clase --> <1class> #n!roducci$n a %&iberna!e 10
<1hibernate-ma!!ing> Donde se hace re+erencia al assembl. donde es!ar* con!enida la clase mapeada . su archi)o de mapeo. :dem*s se re+erencia el namespace de la clase mapeada. %&iberna!e 1.2 considera por de+ec!o la opci$n default0la1y23true3- lo /ue re/uiere /ue !odas las propiedades pDblicas de las clases persis!en!es sean )ir!uales- si /ueremos e)i!ar es!a opci$n se!eamos el a!ribu!o a false.
"FNA*N *ACMN gato: id"at varchar:/H; #E* #OMM& name varchar:/0; #E* #OMM ;?
#n!roducci$n a %&iberna!e
11
9eniendo ambas par!es del sis!ema- es decir- la clase persis!en!e . la !abla s/l correspondien!e a dicha clase- ahora debemos reali"ar el mapeo de a!ribu!os de la clase a columnas de la !abla. 1ara es!o debemos crear un archi)o llamado 4at./bm.-ml- /ue ser* el archi)o por el cual %&iberna!e pre(un!e cuando se re/uiera (uardar un nue)o ob e!o 4at en la base de da!os. Gn e emplo del archi)o 4at./bm.-ml para mapear la clase 4at a la base de da!os es el /ue se mues!ra a con!inuaci$nC <class name=P"atP table=PgatoP> <id name==d> <column name=id"at sQl-t !e=char:/H; not-null=true1> <generator class=uuid.hex1> <1id> <!ro!ert name=P#ombreP column=PnameP1> <1class> 9eniendo !odo es!o lis!o- (uardar un ob e!o 2a! en la base de da!os es al(o !an simple comoC "at tom = ne@ "at:;? tom.#ombre = B*om? tom.Save:;?
#n!roducci$n a %&iberna!e
12
!ublic string =d < get < return id? D set < id = value?D D !ublic string #ombre < get < return nombre? D set < nombre = value? D D !ublic int Ndad < get < return edad? D set < edad = value? D D (ublic void Save:; < 1J im!lementacion J1 D D !ublic class Nm!leado G (ersona < !rivate int sueldo? !ublic int Sueldo< get < return sueldo? D set < sueldo = value? D D D !ublic class "liente G (ersona < !rivate string ti!o"liente? !ublic string *i!o"liente< get < return ti!o"liente? D set < ti!o"liente = value? D D D Ba primera es!ra!e(ia es llamada table0per0class0/ierarc/y- es decir- en el modelo de da!os se !iene s$lo una !abla por erar/u3a de da!os- lo /ue si(ni+ica /ue en la base de da!os s$lo habr* una !abla llamada- por e emplo- tbl.ersona. 's!a !abla con!endr* los campos necesarios para almacenar a la clase persona . !odos los campos necesarios para mapear los a!ribu!os de !oda las subclases de persona- en es!e caso se re/uiere /ue tbl.ersona a(re(ue los campos sueldo . tipo4liente a su de+inici$n. Gn campo e5!ra es re/uerido para mane ar polimor+ismo- es!e campo se conocer* como
#n!roducci$n a %&iberna!e
13
discriminador e indicar* a %&iberna!e a /u4 clase corresponde una +ila par!icular de la !abla tbl.ersona. Gn e emplo de la de+inici$n de la !abla !bl1ersona para la es!ra!e(ia table0per0 class0/ierarc/y ser*C "FNA*N *ACMN tbl(ersona: id(ersona varchar:/H; #E* #OMM& name varchar:/0; #E* #OMM& edad int& *i!o(ersona varchar:H'';& sueldo int& ti!ocliente varchar:/0; ;? 'n es!e caso el discriminador ser* la columna Tipo.ersona . ser* de !ipo s!rin( /ue carac!erice a la clase a la cual per!enece la +ila correspondien!e en la !abla. 'l discriminador puede ser de cual/uier !ipo %&iberna!e. <class name=P(ersonaP table=Ptbl(ersonaP discriminator-value=(NFSE#A> <id name==d> <column name=id(ersona sQl-t !e=char:/H; not-null=true1> <generator class=uuid.hex1> <1id> <discriminator column=P*i!o(ersonaP t !e=PStringP1> <!ro!ert name=P#ombreP column=PnameP1> <!ro!ert name=PNdadP column=PedadP1> <subclass name=P"lienteP discriminator-value=P"M=N#*NP> <!ro!ert name=P*i!o"lienteP column=Pti!oclienteP1> <1subclass> <subclass name=PNm!leadoP discriminator-value=PN9(MP> < !ro!ert name=PSueldoP column=PsueldoP1> <1subclass> <1class> Ba se(unda es!ra!e(ia es llamada table0per0subclass /ue- !al como lo indicau!ili"a una !abla por cada clase de la erar/u3a. 'n es!e caso !endremos las !ablas .ersona- 4liente . Empleado- las cuales se de+inen a con!inuaci$n. "FNA*N *ACMN (ersona: id(ersona varchar:/H; #E* #OMM& name varchar:/0; #E* #OMM& edad int ;? "FNA*N *ACMN "liente: #n!roducci$n a %&iberna!e 14
!ersona=d varchar:/H; #E* #OMM& ti!ocliente varchar:/0; ;? "FNA*N *ACMN Nm!leado: !ersona=d varchar:/H; #E* #OMM& sueldo int ;? 1ara mane ar la relaci$n de erar/u3a en!re las clases- es necesario a(re(ar un campo a las !ablas 4liente . Empleado /ue ser* una re+erencia a la +ila en la !abla .ersona donde es!ar*n sus da!os personales. 's!e campo e5!ra puede ser una cla)e +or*nea en la base de da!os- pero eso es !area del D0:- por lo /ue no se de!allar* sobre ese !ema en es!a secci$n. :hora- el mapeo de las clases per!enecien!es a es!a erar/u3a se mues!ra a con!inuaci$nC <class name=P(ersonaP table=P(ersonaP> <id name==d> <column name=id(ersona sQl-t !e=char:/H; not-null=true1> <generator class=uuid.hex1> <1id> <!ro!ert name=P#ombreP column=PnameP1> <!ro!ert name=PNdadP column=PedadP1> <Roined-subclass name=P"lienteP table=Ptbl"lienteP> <+e column=P(ersona=dP1> <!ro!ert name=P*i!o"lienteP column=Pti!oclienteP1> <1Roined-subclass> <Roined-subclass name=PNm!leadoP table=PtblNm!leadoP> <+e column=P(ersona=dP1> <!ro!ert name=PSueldoP column=PsueldoP1> <1Roined-subclass> <1class> 2abe se=alar /ue- por e emplo- si 1ersona +uese una clase abs!rac!a- ambas es!ra!e(ias no su+ren cambios- el Dnico cambio ser* /ue no podremos ins!anciar un ob e!o de !ipo 1ersona- pero es!a es una res!ricci$n de la OO. 'n cambio- si op!amos por la es!ra!e(ia table0per0concrete0class !endremos /ue s$lo reali"aremos mapeos de las clases concre!as ;no abs!rac!as<. Reali"ado el mapeo OR de la erar/u3a 1ersona- u!ili"ar las clases persis!en!es es !an simple comoC (ersona ! = ne@ (ersona:;? !.#ombre = BFosa? !.Ndad = /'? !.Save:;?
#n!roducci$n a %&iberna!e
15
Nm!leado e = ne@ Nm!leado:;? e.#ombre = B(aulina 9ondaca? e.Ndad = H0? e.Sueldo = 1H0000? ::(ersona;e;.Save:;? Nm!leado e = ne@ Nm!leado:;? c.#ombre = BSorge Tara ? c.Ndad = /0? c.*i!o"liente = Bbasico? ::(ersona;c;.Save:;?
's posible represen!ar es!a composici$n en una !abla 8@B a(re(ando los a!ribu!os de la clase 'irecci5n a la !abla /ue corresponde a la clase .ersona. &aciendo es!o- nues!ra !abla tbl.ersona /uedar3a de la si(uien!e maneraC
#n!roducci$n a %&iberna!e
16
Bo /ue pre!ende es!e mapeo es /ue si una clase con!iene a o!ra- en!onces la !abla 8@B debe con!ener un campo de un !ipo de da!o comple o- lo /ue se represen!a como un con un!o de columnas /ue en realidad corresponden a una misma columna- en es!e caso las columnas '6789 corresponden a un !ipo de da!os comple o ;!ipo de da!os 'ireccion< . deben !ra!arse como un !odo. 8i bien se pierde la relaci$n de e/ui)alencia direc!a en!re modelos- es!e mapeo !iene sen!ido .a /ue al eliminar una ins!ancia de .ersona e+ec!i)amen!e se eliminar* la ins!ancia 'irecci5n asociada a dicha 1ersona. :hora )eremos como lle)ar a la pr*c!ica el mapeo del e emplo reci4n e5pues!o. 1ara es!e caso primero debemos crear una clase 'irecci5n: la cual se de+ine a con!inuaci$n. !ublic class 4ireccion < !rivate string region? !rivate string ciudad? !rivate string calle? !rivate int numero? !ublic string Fegion < get < return region? D set < region = value?D D !ublic string "iudad < get < return ciudad? D set < ciudad = value?D D !ublic string "alle < get < return calle? D set < calle = value?D D
!ublic int #umero < get < return numero? D set < numero = value?D D D 1ara represen!ar una composici$n de 'irecci5n en la clase .ersona- debemos a(re(ar un a!ribu!o a .ersona /ue sea de !ipo 'irecci5n como se mues!ra a con!inuaci$n. !ublic class (ersona #n!roducci$n a %&iberna!e 17
< !rivate !rivate !rivate !rivate !rivate !rivate !rivate string id? string rut? string nombre? string a!ellido? int edad? char sexo? 4ireccion dir?
1J =m!lementacion de !ro!iedades !Ublicas J1 D 9eniendo es!as de+iniciones para ambas clases ahora s$lo +al!a con+i(urar correc!amen!e el archi)o .ersona./bm.-ml para mapear la clase .ersona . su relaci$n con la clase 'irecci5n. 1ara indicarle a %&iberna!e /ue es!a es una relaci$n de 2omposici$n el con!enido de .ersona./bm.-ml debe ser similar al si(uien!eC <class name=P(ersonaP table=Ptbl(ersonaP> <id name==d> <column name=(ers=d sQl-t !e=char:/H; not-null=true1> <generator class=uuid.hex1> <1id> <!ro!ert name=PFutP column=PrutP1> <!ro!ert name=P#ombreP column=PnombreP1> <!ro!ert name=PA!ellidoP column=Pa!ellidoP1> ... <com!onent name=dir class=4ireccion > <!ro!ert name=Fegion column=4=F6FNT=E#1> <!ro!ert name="iudad column=4=F6"=O4A41> <!ro!ert name="alle column=4=F6"AMMN1> <!ro!ert name=#umero column=4=F6#O9NFE1> <1com!onent> <1class> Gn e emplo de c$mo crear una nue)a persona es el si(uien!eC (ersona ! = ne@ (ersona:;? !.Fut = B1'000000-0? !.#ombre = B#ombre (ersona? !.A!ellido = BA!ellido? !.Ndad = 01? !.Sexo = B9? !.4ir = ne@ 4ireccion:;? !.4ir.Fegion = B9etro!olitana? !.4ir."iudad = BSantiago? !.4ir."alle = BAgustinas? !.4ir.#umero = 1H/?
#n!roducci$n a %&iberna!e
1O
's posible implemen!ar una a(re(aci$n de dos maneras- dependiendo de las propiedades de la a(re(aci$n /ue se re/uieran. 5na relacin 1 a 1 entre las clases, 'n es!e caso el ob e!o Ha(re(adoI s$lo es!ar* li(ado al ob e!o con!enedor- pero al borrar el ob e!o con!enedor no es necesario borrar el ob e!o a(re(ado. 5na relacin n a 1 entre las clases, 'n es!e caso el ob e!o a(re(ado podr* es!ar li(ado a cero o m*s ob e!os con!enedores. 9ambi4n es posible de!erminar si al eliminar el ob e!o a(re(ado se debe eliminar !odo ob e!o /ue lo con!en(a ;eliminaci$n en cascada<.
Dadas las mismas de+iniciones de clases )is!as para el caso de composici$nen!onces necesi!amos crear los archi)os .ersona./bm.-ml . 'ireccion./bm.-ml. 'l con!enido del archi)o de mapeo de 'ireccion debe ser un mapeo de una clase simple- es decirC <class name=P4ireccionP table=Ptbl4ireccionP> <id name==d4ireccion> <column name==d4ireccion sQl-t !e=char:/H; not-null=true1> <generator class=uuid.hex1> <1id> <!ro!ert name=Fegion column=region1> <!ro!ert name="iudad column=ciudad1> <!ro!ert name="alle column=calle1> <!ro!ert name=#umero column=numero1> <1class>
#n!roducci$n a %&iberna!e
1N
1ara el caso del mapeo de 1ersona- en la !abla 8@B debemos a(re(ar un campo /ue sea del mismo !ipo /ue el campo 6d'ireccion de la !abla tbl'ireccion- /ue mane ar* la relaci$n en!re las !ablas ;a ni)el l$(ico<. Debemos a(re(ar una direc!i)a /ue indi/ue la relaci$n /ue /ueramos cons!ruir en!re .ersona . 'irecci5n. 1ara es!o mapeamos !odos los a!ribu!os de manera simple ;sal)o el a!ribu!o direcci$n< . a(re(amos el mapeo de 'irecci5n dependiendo del !ipo de relaci$n /ue /ueramos cons!ruirC (elacin 1 a 1, :(re(amos.
<one-to-one name=P4irP class=P4ireccionP column=P=d4ireccionP 1>
(elacin n a 1, :(re(amos.
<man -to-one name=P4irP class=P4ireccionP column=P=d4ireccionP 1>
: con!inuaci$n se e5pone un e emplo del c$di(o asociado al modelo de clasesC !ublic class (ro ecto < !rivate string id(ro ecto? !rivate string descri!cion? !ublic string =d(ro ecto < get < return id(ro ecto? D set < id(ro ecto = value? D D !ublic string 4escri!cion < get < return descri!cion? D set < descri!cion = value? D D D
#n!roducci$n a %&iberna!e
20
=m!orts =esi."ollections? !ublic class Sefe(ro ecto < !rivate string idSefe(ro ecto? !rivate =Set !ro ectos? 11reQuiere =esi."ollections !ublic string =dSefe(ro ecto < get < return id(ro ecto? D set < id(ro ecto = value? D D !ublic =Set (ro ectos < get < return !ro ectos? D set < !ro ectos = value? D D D Bas colecciones pueden ser implemen!adas como Bis!as- :rre(los- Diccionarios o cual/uier clase /ue implemen!e la in!er+a" System.4ollections.6'ictionary: Systems.4ollections.6;ist o 6esi.4ollections.6Set. 's!a Dl!ima se encuen!ra en la librer3a #esi.2ollec!ions- /ue se dis!ribu.e un!o con %&iberna!e- por lo !an!o es necesario a(re(ar la re+erencia correspondien!e a nues!ro pro.ec!o. '5is!e un de!alle al implemen!ar una colecci$n en una clase . es /ue en la propiedad la colecci$n debe de+inirse del !ipo de la in!er+a" correspondien!e a la clase de colecci$n- es decir una propiedad puede ser de !ipo 6;ist- 6'ictionary o 6Set pero no- por e emplo- de !ipo 8e!. 9eniendo idea de las posibles de+iniciones en el c$di(o de la clase para los dis!in!os !ipos de colecciones ahora es necesario conocer c$mo reali"ar el mapeo en!re nues!ra clase con colecci$n . nues!ra base de da!os. 1ara es!o- primero es necesario modelar la base de da!os- pero es!o no es !area di+3cil. 'n el caso /ue es!udiamos- una relaci$n uno a muchos puede ser represen!ada por una !abla tbl<efe.royecto /ue con!en(a el id del e+e de pro.ec!o . )arias !ablas tbl.royecto /ue ha(an re+erencia al id del e+e del pro.ec!o como cla)e +or*nea. 'n pocas palabras un es/uema relacional puede ser el si(uien!eC
Bue(o- el mapeo de la clase .royecto se reali"a de manera simple- como se mues!ra en el si(uien!e c$di(o. <class name=P(ro ectoP table=Ptbl(ro ectoP> <id name==d(ro ecto>
#n!roducci$n a %&iberna!e
21
<column name==d(ro ecto sQl-t !e=char:/H; not-null=true1> <generator class=uuid.hex1> <1id> <!ro!ert name=4escri!cion column=descri!cion1> <1class> 1or o!ro lado- el mapeo de la clase <efe.royecto re/uiere de una e!i/ue!a e5!ra /ue ha(a re+erencia a la relaci$n en!re un e+e de pro.ec!o con )arios pro.ec!os. 's!a e!i/ue!a depender* del !ipo de colecci$n /ue se ha.a implemen!ado. : con!inuaci$n el mapeo para la clase <efe.royecto /ue implemen!a una colecci$n de !ipo 6Set. <class name=PSefe(ro ectoP table=PtblSefe(ro ectoP> <id name==dSefe(ro ecto> <column name==dSefe(ro ecto sQl-t !e=char:/H; not-null=true1> <generator class=uuid.hex1> <1id> <set name=P(ro ectosP> <+e column=PidSefe(ro ectoP 1> <one-to-man class=P(ro ectoP 1> <1set> <1class> Bo /ue se indica en la e!i/ue!a =set> es el nombre de la propiedad de la colecci$n de pro.ec!os. Bue(o se indica /ue la relaci$n en!re pro.ec!os . e+e de pro.ec!o se har* median!e la columna id<efe.royecto de la !abla asociada a la clase .royecto. 2on es!a con+i(uraci$n es posible crear pro.ec!os . asociarlos a un e+e de pro.ec!o en par!icular. Gn e emplo de c$mo reali"ar es!a acci$n es el si(uien!eM Sefe(ro ecto R! = ne@ Sefe(ro ecto:;? S!.(ro ectos = ne@ =esi."ollections.%ashedSet:;? (ro ecto !1 = ne@ (ro !1.4escri!cion = B!ro (ro ecto !H = ne@ (ro !H.4escri!cion = B!ro (ro ecto !1 = ne@ (ro !1.4escri!cion = B!ro !1.Save:;? !H.Save:;? !/.Save:;? R!.(ro ectos.Add:!1;? R!.(ro ectos.Add:!H;? R!.(ro ectos.Add:!/;? R!.Save:;? ecto:;? ecto 1? ecto:;? ecto H? ecto:;? ecto /?
#n!roducci$n a %&iberna!e
22
1J Se !uede im!lementar Que en el mVtodo Save de Sefe(ro ecto se guarden !rimero los !ro ectos luego el obReto Sefe(ro ecto. J1 ')en!ualmen!e- la clase .royecto puede !ener el o!ro e5!remo de la relaci$n uno0 a0muc/os- es decir !endr* un elemen!o de relaci$n muchosFaFuno ;como el )is!o en a(re(aci$n<. 's!o implica a(re(ar una propiedad de !ipo <efe.royecto en la clase .royecto . lue(o de+inir el si(uien!e archi)o de mapeo de la clase .royecto. <class name=P(ro ectoP table=Ptbl(ro ectoP> <id name==d(ro ecto> <column name==d(ro ecto sQl-t !e=char:/H; not-null=true1> <generator class=uuid.hex1> <1id> <!ro!ert name=4escri!cion column=descri!cion1> <man -to-one name=R!=d class=Sefe(ro ecto column==dSefe(ro ecto1> <1class> 'n es!e e emplo- la clase .royecto !iene un a!ribu!o llamado ?p6d de !ipo <efe.royecto- el cual ser* una re+erencia al con!enido de la columna 6d<efe.royecto de la !abla asociada a la clase <efe.royecto.
=set>. =bag>. 2ada una de es!as e!i/ue!as es!* orien!ada a sopor!ar un !ipo de colecci$n en par!icular. : con!inuaci$n se lis!an las principales carac!er3s!icas de cada uno de es!os elemen!osC =list>- =map>
<set>: 2olecci$n desordenada sin duplicados. 2ompa!ible con la in!er+a" 6esi.4ollections.6Set. <list>: 2olecci$n ordenada- re/uiere una columna 3ndice. 2ompa!ible con la in!er+a" System.4ollections.6;ist. <map>: 2olecci$n /ue almacena pares de elemen!os. 2ompa!ible con la in!er+a" System.4ollections.6'ictionary. <bag>: 2olecci$n desordenada /ue permi!e elemen!os duplicados. 8ir)e para represen!ar lis!as no ordenadas. 9ambi4n es posible u!ili"ar las e!i/ue!as =array> . =primiti)e0array> pero no se ha encon!rando in+ormaci$n sobre es!as e!i/ue!as. Gna propiedad impor!an!e del mapeo de colecciones de ob e!os es conocida como iniciali1aci5n pere1osa o carga pere1osa *la1y loading: la1y initiali1ation+ . 's!a es!ra!e(ia indica /ue si un ob e!o $ !iene una colecci$n de ob e!os %- en!onces al recuperar K desde la base de da!os- s$lo se recuperar*n las propiedades a!$micas de $ ;!ipo 8!rin(- #n!- 2har- 0oolean- e!c< pero no las colecciones de ob e!os % asociados a $ sino has!a /ue realmen!e se /uiera u!ili"ar la colecci$n de ob e!os %. 'n el caso de <efe.royecto s$lo se recupera el iden!i+icador del e+e de pro.ec!o- . lue(o- si en al(Dn momen!o se re/uiere recorrer la colecci$n de pro.ec!os car(o de es!e e+e de pro.ec!os$lo en!onces se recuperar* la colecci$n de pro.ec!os desde la base de da!os. 's!a
#n!roducci$n a %&iberna!e
23
carac!er3s!ica se puede de+inir en el archi)o de mapeo indicando elemen!os =set>- =list>- =map> o =bag>.
lazy=true
en los
's!a relaci$n muchos a muchos debe ser represen!ada en un modelo relacional a=adiendo una !ercera !abla /ue ha(a de N,@ en!re @anco . 4liente- es decir es!a !ercera !abla relacionar* a los clien!es con los bancos- !eniendo plena liber!ad de relacionar cual/uier clien!e con cual/uier banco ;claro sin permi!ir repe!ici$n<.
9eniendo es!e modelo de clases . su respec!i)o modelo relacional podemos reali"ar el mapeo OR cosa de poder persis!ir nues!ras clases. <class name=Canco table=Canco> <id name==4> <generator class=identit 1> <1id> <set name="lientes laI =true
#n!roducci$n a %&iberna!e
24
table=Canco6"liente> <+e column=Canco=41> <man -to-man class="liente column="liente=41> <1set> <1class> <class name="liente table="liente> <id name==4> <generator class=identit 1> <1id> <!ro!ert name=#ombre column=#ombre 1> <!ro!ert name=A!ellido column=A!ellido 1> <1class> 1ara e5plicar c$mo se reali"a el mapeo muchosFaFmuchos )eremos en de!alle la e!i/ue!a de la colecci$nC <set name="lientes laI =true table=Canco6"liente> <+e column=Canco=41> <man -to-man class="liente column="liente=41> <1set> Ba relaci$n en!re @anco . 4liente se reali"a buscando una ins!ancia en la !abla @anco84liente /ue con!en(a en la columna @anco6' el iden!i+icador del banco . en la columna 4liente6' el iden!i+icador asociado a la clase 4liente. Bas colecciones sopor!adas por las relaciones muc/os0a0muc/os son las mismas /ue para el caso de uno0a0muc/os . las re(las de de+inici$n son las mismas ;a!ribu!os de clase de+inidos como de !ipo de la in!er+a" correspondien!e ;6Set- 6;ist- e!c.<.
#n!roducci$n a %&iberna!e
25
#n!roducci$n a %&iberna!e
26
#n!roducci$n a %&iberna!e
27