




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、Good is good, but better carries it.精益求精,善益求善。ORMObjectRelationalMapper-Hibernate对象映射-HYPERLINK/linzheng/archive/2011/01/03/1924852.html三、ORM(Object/RelationalMapper)-Hibernate对象映射一.ORM(Object/RelationalMapper)1.OR映射-Hibernate基本数据类型Hibernate基本类型Java类型标准SQL字段类型booleanboolean,java.lang.BooleanBITyes_n
2、oboolean,java.lang.BooleanCHAR(1)(Y/N)true_falseboolean,java.lang.BooleanCHAR(1)(Y/N)bytebyte,java.lang.ByteTINYINTshortshort,java.lang.ShortSMALLINTintegerint,java.lang.IntegerINTEGERlonglong,java.lang.LongBIGINTfloatfloat,java.lang.FloatFLOATdoubledouble,java.lang.DoubleDOUBLEbig_decimaljava.math.
3、BigDecimalNUMBERICcharacterjava.lang.StringCHAR(1)stringjava.lang.StringVARCHARdatejava.util.Date,java.sql.DateDATEtimejava.util.Date,java.sql.TimeTIMEtimestampjava.util.Date,java.sql.TimeStampTIMESTAMPcalendarjava.util.CalendarTIMESTAMPcalendar_datejava.util.CalendarDateclobjava.sql.ClobCLOBblobjav
4、a.sql.BlobBLOBbinarybyteVARBINARY,BLOBtextjava.lang.StringCLOBseralizablejava.io.SerializableVARBINARY,BLOBclassjava.lang.ClassVARCHARlocaljava.util.LocaleVARCHARtimezonejava.util.TimeZoneVARCHARcurrencyjava.util.CurrencyVARCHAR2.OR映射-实体映射示例*.hbm.xml,主体内容包含表/类映射,id映射,属性字段映射三个部分.示例文件:XML文件头定义了文件的编码方式
5、,DTD与Hibernate的版本有关,上面是使用hibernate3.x使用的DTD.3.OR映射-表/类映射name:指定了Java数据封装的POJO类类型.table:指定了数据库的表名4.OR映射-id映射name:指定了映射POJO类的属性名,type:POJO类中属性的数据类型;column:数据库表的主键字段;generator子元素:由其class属性指定主键生成方式:assigned:主键由应用程序产生,不需要hibernate干预identity:使用数据库的主键生成机制,如MySQL,DB2、SQLServer的自增主键.sequence:使用数据库的sequence机制
6、,如Oracle的sequenceuuid.hex:由Hibernate基于128位唯一值产生算法,根据ip,时间,jvm启动时间,内部自增量生成十六进制的数值,编码后成为一个32位长的字符串.该方法提供了最好的数据库插入性能和数据库平台适应性.uuid.string:与uuid.hex类似,只是生成的主键没有进行编码,只有16位长度.在某些数据库可能出错.hilo:通过hilo算法实现主键生成,需要额外的数据库表保存主键生成历史状态.seqhilo:与hilo类似,只是主键历史状态保存在sequence中,适用于支持sequence的数据库.increment:主键按数值递增,但如果多个实例
7、同时访问同一个数据库,各自生成主键,则容易造成主键重复.native:由hibernate根据数据库适配器中的定义,自动采用identity,hilo,sequence中的一种方式.foreign:外部表的字段作主键.select:hibernate3中新增的.需要提供一个唯一的标识字段进行二次读取,以获取触发器生成的主键值,通过param子元素进行定义,比如:key_field该方法主要针对遗留系统的改造工程,一些早期的系统主键依赖于触发器生成.当数据库insert时,触发器捕获这一操作,并为主键赋值,在插入数据库后,再次读取某一识别字段读取已经插入的数据,获取其主键值.5.OR映射-复合主
8、键映射(composite-id)-实体属性组成主键复合主键使用将取代id元素,并具有property属性列表.复合主键的POJO类需要实现equals和hashcode方法,可以使用apachecommonslang包中的工具类实现(commons-lang.jar),比如:mons.lang.builder.EqualsBuilder;mons.lang.builder.HashCodeBuilder;mons.lang.builder.ToStringBuilder;.publicStringtoString()returnnewToStringBuilder(this).append(
9、userid,getUserid().append(when,getWhen().toString();publicbooleanequals(Objectother)if(!(otherinstanceofMyPoJoClass)returnfalse;MyPoJoClasscastOther=(MyPoJoClass)other;returnnewEqualsBuilder().appendSuper(super.equals(other).append(this.getUserid(),castOther.getUserid().append(this.getWhen(),castOth
10、er.getWhen().isEquals();publicinthashCode()returnnewHashCodeBuilder().appendSuper(super.hashCode().append(getUserid().append(getWhen().toHashCode();装载复合主键的记录时,考虑把类对应的对象的主键值填充好后作为load的第二个参数.MyPoJoClassobj=newMyPoJoClass();obj.setUserid(.);obj.setWhen(.);obj=(MyPoJoClass)session.load(MyPoJoClass.class
11、,obj);6.OR映射-复合主键映射(composite-id)-基于主键类可以用一个独立的类来描述主键,示例:此时,需要定义一个新的类KeyClass来作为主键类,KeyClass实现equals和hashcode方法,而在POJO中,使用属性名keyClassProperty来表示主键,其类类型为KeyClass.7.OR映射-composite-id其他子节点composite-id除了key-property子节点外,还具有可选子节点.完整的节点内容:.8.OR映射-属性/字段映射name:POJO类的属性名,type:POJO类中属性的数据类型;如果是字符串,可以省略column:
12、数据库中的字段名.如果和属性同名,可以省略.9.OR映射-自定义数据类型UserType,CompositeUserType接口hibernate3中的为:org.hibernate.usertype(hibernate2中为net.sf包)下面的两个接口:UserType和CompositeUserType.它们提供自定义类型的规范,这里以UserType为例.packageorg.hibernate.usertype;importjava.io.Serializable;importjava.sql.PreparedStatement;importjava.sql.ResultSet;im
13、portjava.sql.SQLException;importorg.hibernate.HibernateException;publicinterfaceUserType/*返回本类型所映射的SQL类型,返回的是int数组.可以取java.sql.Types中的int静态常量.*比如有:publicfinalstaticintDOUBLE=8;*/publicintsqlTypes();/*定义本类型的nullSafeGet()方法返回的数据的类型*/publicClassreturnedClass();/*定义两个数据的比较方法,返回true表示相等,false表示不等.*/publi
14、cbooleanequals(Objectx,Objecty)throwsHibernateException;/*Getahashcodefortheinstance,consistentwithpersistenceequality*/publicinthashCode(Objectx)throwsHibernateException;/*定义从ResultSet中读取数据并转换成自定义类型的方法,对数据库null应该考虑*参数names包含了当前自定义类型的映射字段名称*/publicObjectnullSafeGet(ResultSetrs,Stringnames,Objectowne
15、r)throwsHibernateException,SQLException;/*Hibernate进行数据保存时被调用的方法*paramstaJDBCpreparedstatement*paramvaluetheobjecttowrite,类型应该是returnedClass()方法返回的Class指定的类型*paramindexstatementparameterindex*throwsHibernateException*throwsSQLException*/publicvoidnullSafeSet(PreparedStatementst,Objectvalue,intindex)
16、throwsHibernateException,SQLException;/*自定义的对象复制方法,用作构造返回对象.*nullSafeGet方法被调用后,Hibernate获得了自定义数据对象,*这个对象成为数据库读出的原始对象,通过deepCopy方法,Hibernate*返回一个复本给用户.脏数据检查时,如果两个对象不等(equals方法返回false),*就会执行数据库持久化操作.*paramvaluetheobjecttobecloned,whichmaybenull*returnObjectacopy*/publicObjectdeepCopy(Objectvalue)throw
17、sHibernateException;/*Areobjectsofthistypemutable?*本类型实例是否可变*returnboolean*/publicbooleanisMutable();/*把对象转化为二级缓存中保存.经常把当前对象对其他对象的引用,保存为其id值.*Transformtheobjectintoitscacheablerepresentation.Attheveryleastthis*methodshouldperformadeepcopyifthetypeismutable.Thatmaynotbeenough*forsomeimplementations,h
18、owever;forexample,associationsmustbecachedas*identifiervalues.(optionaloperation)*paramvaluetheobjecttobecached*returnacachablerepresentationoftheobject*throwsHibernateException*/publicSerializabledisassemble(Objectvalue)throwsHibernateException;/*把二级缓存中获取的数据转换为自定义的对象数据*Reconstructanobjectfromthecac
19、heablerepresentation.Attheveryleastthis*methodshouldperformadeepcopyifthetypeismutable.(optionaloperation)*paramcachedtheobjecttobecached*paramownertheownerofthecachedobject*returnareconstructedobjectfromthecachablerepresentation*throwsHibernateException*/publicObjectassemble(Serializablecached,Obje
20、ctowner)throwsHibernateException;/*Duringmerge,replacetheexisting(target)valueintheentitywearemergingto*withanew(original)valuefromthedetachedentitywearemerging.Forimmutable*objects,ornullvalues,itissafetosimplyreturnthefirstparameter.For*mutableobjects,itissafetoreturnacopyofthefirstparameter.Forob
21、jects*withcomponentvalues,itmightmakesensetorecursivelyreplacecomponentvalues.*paramoriginalthevaluefromthedetachedentitybeingmerged*paramtargetthevalueinthemanagedentity*returnthevaluetobemerged*/publicObjectreplace(Objectoriginal,Objecttarget,Objectowner)throwsHibernateException;如果一个用户具有多个email,可以
22、分别定义多个字段保存,也可以定义一个子表专门保存,但都有点大动干戈.可以考虑用一个字符串字段保存,相邻的email用一个;隔开.比如:packagecn.thinkmore.hibernate.pojo;importjava.io.Serializable;importjava.sql.PreparedStatement;importjava.sql.ResultSet;importjava.sql.SQLException;importjava.sql.Types;importjava.util.*;importorg.hibernate.Hibernate;importorg.hibern
23、ate.HibernateException;importorg.hibernate.usertype.UserType;publicclassEmailListimplementsUserTypeprivatestaticfinalStringSPLITTER=;privatestaticfinalintTYPES=newintTypes.VARCHAR;publicObjectassemble(Serializablecached,Objectowner)throwsHibernateExceptionreturnnull;publicObjectdeepCopy(Objectvalue)
24、throwsHibernateExceptionif(!(valueinstanceofList)returnnull;Listsrc=(List)value;Listtar=newArrayList();tar.addAll(src);returntar;publicSerializabledisassemble(Objectvalue)throwsHibernateExceptionreturnnull;publicbooleanequals(Objectx,Objecty)throwsHibernateExceptionif(x=y)returntrue;if(x!=null&y!=nu
25、ll)ListxList=(List)x;ListyList=(List)y;if(xList.size()!=yList.size()returnfalse;for(inti=0;ixList.size();i+)StringstrX=xList.get(i).toString();StringstrY=yList.get(i).toString();if(!strX.equals(strY)returnfalse;returnfalse;publicbooleanisMutable()returnfalse;publicObjectnullSafeGet(ResultSetrs,Strin
26、gnames,Objectowner)throwsHibernateException,SQLExceptionStringvalue=Hibernate.STRING.nullSafeGet(rs,names0).toString();if(null!=value)returnparse(value);returnnull;privateListparse(Stringvalue)Stringstrs=mons.lang.StringUtils.split(value,SPLITTER);Listemails=newArrayList();for(inti=0;istrs.length;i+
27、)emails.add(strsi);returnemails;privateStringassemble(Listlist)StringBuildersb=newStringBuilder();intmaxIndex=list.size()-1;for(inti=0;imaxIndex;i+)sb.append(list.get(i).append(SPLITTER);if(0=maxIndex)sb.append(list.get(maxIndex);returnsb.toString();publicvoidnullSafeSet(PreparedStatementst,Objectva
28、lue,intindex)throwsHibernateException,SQLExceptionif(null!=value&(valueinstanceofList)Stringstr=assemble(List)value);Hibernate.STRING.nullSafeSet(st,str,index);elseif(null!=value)Hibernate.STRING.nullSafeSet(st,value.toString(),index);elseHibernate.STRING.nullSafeSet(st,null,index);publicObjectrepla
29、ce(Objectoriginal,Objecttarget,Objectowner)throwsHibernateExceptionreturnnull;publicClassreturnedClass()returnList.class;publicintsqlTypes()returnTYPES;publicinthashCode(Objectx)throwsHibernateExceptionreturn0;数据关联关系数据关联关系在实体的子类里面不会被自动继承.10.一对一关联-主键关联one-to-one一对一的主键关联,指两个表的记录是一对一的关系,且一个表的主键取为另一个表对应
30、的记录的主键.name:属性名class:java全路径类名cascade:是否级连操作,all,noneouter-join:是否外链接,true/falsecitizenConstrained:次关联中的约束方.Sessions=HibernateSession3.getSession();Citizenone=newCitizen();one.setIdcard(123456789012345678);one.setName(Mike);one.setSex(M);Genegene=newGene();gene.setBloodType(AB);gene.setDna(Ajodjjdjo
31、a);gene.setSpecial(White);one.setGene(gene);gene.setCitizen(one);Transactiontrans=s.beginTransaction();s.saveOrUpdate(one);mit();/两条数据一起被保存,查询时也会关联查出来.Queryquery=s.createQuery(FromCitizen);Listlist=query.list();for(inti=0;ilist.size();i+)one=(Citizen)list.get(i);if(null=one)continue;gene=(Gene)one.g
32、etGene();if(null!=gene)System.out.println(gene.getId()+:+gene.getSpecial()+:+gene.getDna();11.单向一对多关联-唯一外键关联one-to-many一个用户可以多个email:12.双向一对多关联除了在主控方配置一对多,还要在被控方配置对应的多对一关系:User:Email:再有例子:一个职员(是人的子类)前后可能有多条工作(每次工作是一条记录):Usersmaybidfororsellauctionitems.!-publicstaticvoidtestOne2Many()Sessions=Hibern
33、ateSession3.getSession();Employeee=newEmployee();e.setName(一对多);e.setIdcard(123456789012345678);e.setBirth(newjava.sql.Date(System.currentTimeMillis()-24L*3600*1000*365*25);JobListjob1=newJobList();job1.setEmployee(e);job1.setCompany(Agongsi);job1.setBegin(newjava.sql.Date(System.currentTimeMillis()
34、-24L*3600*1000*365*5);job1.setEnd(newjava.sql.Date(System.currentTimeMillis()-24L*3600*1000*365*4);JobListjob2=newJobList();job2.setEmployee(e);job2.setCompany(Bgongsi);job2.setBegin(newjava.sql.Date(System.currentTimeMillis()-24L*3600*1000*365*4);job2.setEnd(newjava.sql.Date(System.currentTimeMillis()-24L*3600*1000*365*2);Setjobs=newHashSet();jobs.add(job1);jobs.add(job2);e.setJobs(jobs);Transactiontrans=s.beginTransaction();/两个表的数据一起被保存,查询时也会关联查出来.s.sav
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 河北省唐县第一中学2024-2025学年高一(3+1)下学期4月期中化学试卷(含答案)
- 曲靖市2025届三下数学期末检测模拟试题含解析
- 江西旅游商贸职业学院《计量经济及应用》2023-2024学年第二学期期末试卷
- 四川绵阳富乐园际校2024-2025学年初三下学期期末英语试题试卷含答案
- 河南省安阳市殷都区重点名校2025年中考押题预测卷(语文试题理)试卷含解析
- 原平市2025届小升初常考易错数学检测卷含解析
- 锡林郭勒职业学院《有机波谱解析》2023-2024学年第二学期期末试卷
- 四川省绵阳市达标名校2025届初三下学期3月月考语文试题试卷含解析
- 浙江省杭州市杭州风帆中学2025届初三1月联考物理试题含解析
- 苏州市职业大学《数值代数》2023-2024学年第二学期期末试卷
- 非晶态半导体
- 焊缝外观质量检查表
- 自动化生产线运行与维护完整版课件(全)
- 实验试剂耗材供应服务方案
- JJF 1211-2008 激光粒度分析仪校准规范-(高清现行)
- 新部编人教版五年级下册道德与法治期末复习全册知识点汇编
- 赣美版 二年级下册美术 第3课 画房子 课件(12张PPT)
- 土壤酸性磷酸酶活性测定方法
- 二正丁胺MSDS危险化学品安全技术说明书
- 北大刑法分论期末考题甲的一生前传
- 荥阳崔庙镇土地利用总体规划
评论
0/150
提交评论