基于XDoclet的Hibernate3企业级开发教程(1)——one2one映射类型的书写要点
摘要:此为我给公司内部新员工培训的实战演示例子,傻瓜级教程,讲述了开发中的注意要点和常见错误,目的主要是让他们适应企业级快速流水作业。由于是面对面讲解,所以没有详细的文档,现在简单整理如下,希望对入门者有帮助。
培训的目标:对下面的开发过程和模式快速理解和应用。基于我的UML架构-----〉Java POJOs代码------〉在pojos中做xdoclet标识-------〉基于ant生成*.hbm.xml文件(借助于eclipse可以自动化配置)------〉生成database schma和数据库sql语句。逐步可以让新员工过渡到java5的annotation来开发EJB3 .
说明:下面是我们用到的例子,学生和自己学籍上的照片是一对一关系。下面是使用IBM RSA得到的一个模型,途中用的是两个用途,表示的意思比较泛,最佳表示应该是一条无方向的线段,两边各标上1,代表一对一关系。(现在时间比较紧,所以没来的急修改,这也是IBM反向工程的一个弱点,就好比目标是北京,但是现在目标指向了中国,不够精确,但是可以反映这个意思)
<shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"></path><lock v:ext="edit" aspectratio="t"></lock></shapetype><shape id="_x0000_i1025" style="WIDTH: 317.25pt; HEIGHT: 259.5pt" type="#_x0000_t75"><imagedata src="file:///C:%5CDOCUME~1%5CADMINI~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image001.jpg" o:title="Model1"><img height="346" alt="Model1.jpg" src="http://www.blogjava.net/images/blogjava_net/asktalk/images/Model1.jpg" width="423" border="0"></imagedata></shape>
下面是生成的数据库E-R图:
<shape id="_x0000_i1026" style="WIDTH: 276.75pt; HEIGHT: 84.75pt" type="#_x0000_t75"><imagedata src="file:///C:%5CDOCUME~1%5CADMINI~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image002.jpg" o:title="one2one2主键映射-1"><img height="113" alt="one2one2主键映射-1.jpg" src="http://www.blogjava.net/images/blogjava_net/asktalk/images/one2one2%E4%B8%BB%E9%94%AE%E6%98%A0%E5%B0%84-1.jpg" width="369" border="0"></imagedata></shape>
问题:初学者总是对pojos对象中的字段和数据库中的字段做对比,对pojos对象中多出的propertity感到不解,其实这也是hibernate的关键所在,在那个表增加字段,增加外键,都是有规律的,也是完全符合数据库的规则的,详细看代码.
1,
/**
*@hibernate.classtable="image"schema="hibernate_tutorial"
*@authorAdministrator
*
*/
schema
对
mysql
数据库来说,是数据库名字,这点注意
2,
你可以在关联属性上都定义外键,你看一下最后那边的设置在数据库
sql
语句中体现了,那个没体现,我想你会有收获的。
3, /**
*@hibernate.one-to-oneclass="com.javawebside.one2one.p1.Image"
*constrained="false"outer-join="true"cascade="all"
*@returnReturnstheimage.
*/
注意cascade
的设置,如果没有级联,那么你可以最后
save student,
或者
save image
,或者,两者都保存,你看一下数据库中实际存入的数据,你一定会对
cascade
有更加深入的认识。
Image
类
package
com.javawebside.one2one.p1;
importjava.sql.Blob;
/**
*@hibernate.classtable="image"schema="hibernate_tutorial"
*@authorAdministrator
*
*/
publicclassImage{
privateLongid;
privateStringname;
privateBlobvalue=null;
/**
*@linkassociation
*/
privateStudentstudent;
publicImage(){}
publicImage(Longid,Stringname,Blobvalue){
super();
this.id=id;
this.name=name;
this.value=value;
}
/**
*@hibernate.idcolumn="id"generator-class="foreign"
*@hibernate.generator-paramname="property"value="student"
*@returnReturnstheid.
*/
publicLonggetId(){
returnid;
}
/**
*@paramid
*Theidtoset.
*/
publicvoidsetId(Longid){
this.id=id;
}
/**
*@hibernate.propertycolumn="name"not-null="false"unique="false"
*@returnReturnsthename.
*/
publicStringgetName(){
returnname;
}
/**
*@paramname
*Thenametoset.
*/
publicvoidsetName(Stringname){
this.name=name;
}
/**
*@hibernate.propertycolumn="value"not-null="false"unique="false"
*@returnReturnsthevalue.
*/
publicBlobgetValue(){
returnvalue;
}
/**
*@paramvalue
*Thevaluetoset.
*/
publicvoidsetValue(Blobvalue){
this.value=value;
}
/**
*@hibernate.one-to-oneclass="com.javawebside.one2one.p1.Student"constrained="true"
*foreign-key="forein_key_name"
*@return
*/
publicStudentgetStudent(){
returnstudent;
}
publicvoidsetStudent(Studentstudent){
this.student=student;
}
}
Student
类
package
com.javawebside.one2one.p1;
/**
*
*@hibernate.classtable="student"schema="hibernate_tutorial"
*@authorAdministrator
*
*/
publicclassStudent{
privateLongid;
privateStringname;
privateStringintro;
privateImageimage;
publicStudent(){
}
publicStudent(Longid,Stringname,Stringintro,Imageimage){
super();
this.id=id;
this.name=name;
this.intro=intro;
this.image=image;
}
/**
*@hibernate.idcolumn="id"generator-class="native"
*@returnReturnstheid.
*/
publicLonggetId(){
returnid;
}
/**
*@paramid
*Theidtoset.
*/
publicvoidsetId(Longid){
this.id=id;
}
/**
*@hibernate.propertycolumn="intro"not-null="false"unique="false"
*@returnReturnstheintro.
*/
publicStringgetIntro(){
returnintro;
}
/**
*@paramintro
*Theintrotoset.
*/
publicvoidsetIntro(Stringintro){
this.intro=intro;
}
/**
*@hibernate.propertycolumn="name"not-null="false"unique="false"
*@returnReturnsthename.
*/
publicStringgetName(){
returnname;
}
/**
*@paramname
*Thenametoset.
*/
publicvoidsetName(Stringname){
this.name=name;
}
/**
*@hibernate.one-to-oneclass="com.javawebside.one2one.p1.Image"
*constrained="false"outer-join="true"cascade="all"
*@returnReturnstheimage.
*/
publicImagegetImage(){
returnimage;
}
/**
*@paramimage
*Theimagetoset.
*/
publicvoidsetImage(Imageimage){
this.image=image;
}
}
下面是实际的操作类
BusinessService
类用于增加和删除数据操作
package
com.javawebside.one2one.p1;
importjava.sql.Blob;
importorg.hibernate.*;
//importorg.hibernate.cfg.Configuration;
//importjava.util.*;
publicclassBusinessService{
privateSessionsession;
publicvoidsetSession(Sessionse){
session=se;
}
publicSessiongetSession(){
returnsession;
}
publicvoidsaveStudent(StudentStudent)throwsException{
Transactiontx=null;
try{
tx=session.beginTransaction();
session.save(Student);
tx.commit();
}catch(Exceptione){
if(tx!=null){
tx.rollback();
}
throwe;
}finally{
//Nomatterwhat,closethesession
session.close();
}
}
publicStudentloadStudent(Longid)throwsException{
Transactiontx=null;
try{
tx=session.beginTransaction();
StudentStudent=(Student)session.load(Student.class,id);
tx.commit();
returnStudent;
}catch(Exceptione){
if(tx!=null){
tx.rollback();
}
throwe;
}finally{
//Nomatterwhat,closethesession
session.close();
}
}
publicvoidprintStudent(StudentStudent)throwsException{
Imageimage=Student.getImage();
System.out.println("Imageof"+Student.getName()+"is:"
+image.getValue());
if(image.getStudent()==null)
System.out.println("CannotnaviagtefromImagetoStudent.");
}
publicvoidtest()throwsException{
Studentstudent=newStudent();
Imageimage=newImage();
image.setName("
王东照片
"
);
student.setName("Tom");
student.setIntro("
王东
"
);
image.setStudent(student);
student.setImage(image);
saveStudent(student);
//student=loadStudent(student.getId());
//printStudent(student);
}
publicstaticvoidmain(Stringargs[])throwsException{
BusinessServicebs=newBusinessService();
bs.setSession(HibernateSessionFactory.currentSession());
if(bs.getSession()==null)
System.out.println("Sessionisnull");
bs.test();
//bs.getSession().close();
}
}
hibernate
配置类
package
com.javawebside.one2one.p1;
importorg.hibernate.HibernateException;
importorg.hibernate.Session;
importorg.hibernate.cfg.Configuration;
/**
*ConfiguresandprovidesaccesstoHibernatesessions,tiedtothe
*currentthreadofexecution.FollowstheThreadLocalSession
*pattern,see{@linkhttp://hibernate.org/42.html}.
*/
publicclassHibernateSessionFactory{
/**
*Locationofhibernate.cfg.xmlfile.
*NOTICE:LocationshouldbeontheclasspathasHibernateuses
*#resourceAsStreamstylelookupforitsconfigurationfile.That
*isplacetheconfigfileinaJavapackage-thedefaultlocation
*isthedefaultJavapackage.<br><br>
*Examples:<br>
*<code>CONFIG_FILE_LOCATION="/hibernate.conf.xml".
*CONFIG_FILE_LOCATION="/com/foo/bar/myhiberstuff.conf.xml".</code>
*/
privatestaticStringCONFIG_FILE_LOCATION="com/javawebside/one2one/p1/hibernate.cfg.xml";
/**HoldsasingleinstanceofSession*/
privatestaticfinalThreadLocal<Session>threadLocal=newThreadLocal<Session>();
/**Thesingleinstanceofhibernateconfiguration*/
privatestaticfinalConfigurationcfg=newConfiguration();
/**ThesingleinstanceofhibernateSessionFactory*/
privatestaticorg.hibernate.SessionFactorysessionFactory;
/**
*ReturnstheThreadLocalSessioninstance.Lazyinitialize
*the<code>SessionFactory</code>ifneeded.
*
*@returnSession
*@throwsHibernateException
*/
publicstaticSessioncurrentSession()throwsHibernateException{
Sessionsession=(Session)threadLocal.get();
if(session==null||!session.isOpen()){
if(sessionFactory==null){
try{
cfg.configure(CONFIG_FILE_LOCATION);
sessionFactory=cfg.buildSessionFactory();
}catch(Exceptione){
System.err
.println("%%%%ErrorCreatingSessionFactory%%%%");
e.printStackTrace();
}
}
session=(sessionFactory!=null)?sessionFactory.openSession()
:null;
threadLocal.set(session);
}
returnsession;
}
/**
*Closethesinglehibernatesessioninstance.
*
*@throwsHibernateException
*/
publicstaticvoidcloseSession()throwsHibernateException{
Sessionsession=(Session)threadLocal.get();
threadLocal.set(null);
if(session!=null){
session.close();
}
}
/**
*Defaultconstructor.
*/
privateHibernateSessionFactory(){
}
}