《精通Hibernate》学习(1) 《精通Hibernate》学习(1)——第一个Hibernate应用



转自:http://blog.csdn.net/yu422560654/article/details/7028748



《精通Hibernate》学习(1)——第一个Hibernate应用

一、在Java应用中使用Hibernate的步骤

  • 创建Hibernate的配置文件
  • 创建持久化类
  • 创建对象-关系映射文件
  • 通过Hibernate API编写访问数据库的代码

二、Helloapp应用的结构

三、Hibernate的配置文件(hibernate.properties)

  1. hibernate.dialect=org.hibernate.dialect.MySQLDialect
  2. hibernate.connection.driver_class=com.mysql.jdbc.Driver
  3. hibernate.connection.url=jdbc:mysql://localhost:3306/SAMPLEDB
  4. hibernate.connection.username=root
  5. hibernate.connection.password=1234
  6. hibernate.show_sql=true


四、创建持久化类Customer

  • 持久化类符合JavaBean的规范,包含一些属性,以及与之对应的getXXX()和setXXX()方法。
  • 持久化类有一个id属性,用来惟一标识Customer类的每个对象。在面向对象术语中,这个id属性被称为对象标识符(OID,Object Identifier),通常它都用整数表示
  • Hibernate要求持久化类必须提供一个不带参数的默认构造方法
  1. packagemypack;
  2. importjava.io.Serializable;
  3. importjava.sql.Date;
  4. importjava.sql.Timestamp;
  5. publicclassCustomerimplementsSerializable{
  6. privateLongid;
  7. privateStringname;
  8. privateStringemail;
  9. privateStringpassword;
  10. privateintphone;
  11. privateStringaddress;
  12. privatecharsex;
  13. privatebooleanmarried;
  14. privateStringdescription;
  15. privatebyte[]image;
  16. privateDatebirthday;
  17. privateTimestampregisteredTime;
  18. publicCustomer(){}
  19. publicLonggetId(){
  20. returnid;
  21. }
  22. privatevoidsetId(Longid){
  23. this.id=id;
  24. }
  25. publicStringgetName(){
  26. returnname;
  27. }
  28. publicvoidsetName(Stringname){
  29. this.name=name;
  30. }
  31. publicStringgetEmail(){
  32. returnemail;
  33. }
  34. publicvoidsetEmail(Stringemail){
  35. this.email=email;
  36. }
  37. publicStringgetPassword(){
  38. returnpassword;
  39. }
  40. publicvoidsetPassword(Stringpassword){
  41. this.password=password;
  42. }
  43. publicintgetPhone(){
  44. returnphone;
  45. }
  46. publicvoidsetPhone(intphone){
  47. this.phone=phone;
  48. }
  49. publicStringgetAddress(){
  50. returnaddress;
  51. }
  52. publicvoidsetAddress(Stringaddress){
  53. this.address=address;
  54. }
  55. publicchargetSex(){
  56. returnsex;
  57. }
  58. publicvoidsetSex(charsex){
  59. this.sex=sex;
  60. }
  61. publicbooleanisMarried(){
  62. returnmarried;
  63. }
  64. publicvoidsetMarried(booleanmarried){
  65. this.married=married;
  66. }
  67. publicStringgetDescription(){
  68. returndescription;
  69. }
  70. publicvoidsetDescription(Stringdescription){
  71. this.description=description;
  72. }
  73. publicbyte[]getImage(){
  74. returnthis.image;
  75. }
  76. publicvoidsetImage(byte[]image){
  77. this.image=image;
  78. }
  79. publicDategetBirthday(){
  80. returnthis.birthday;
  81. }
  82. publicvoidsetBirthday(Datebirthday){
  83. this.birthday=birthday;
  84. }
  85. publicTimestampgetRegisteredTime(){
  86. returnthis.registeredTime;
  87. }
  88. publicvoidsetRegisteredTime(TimestampregisteredTime){
  89. this.registeredTime=registeredTime;
  90. }
  91. }

注意:

  • getXXX()和setXXX()方法可以采用任意的访问级别,他的命名规则必须符合特定的命名规则,“get”和“set”后面紧跟属性的名字,并且属性名的首字母为大写,如name属性的get方法为getName()。
  • 如果持久化类的属性为boolean类型,那么它的get方法名可以用get做前缀也可以用is做前缀。

五、创建数据库Schema

  1. dropdatabaseifexistsSAMPLEDB;
  2. createdatabaseSAMPLEDB;
  3. useSAMPLEDB;
  4. createtableCUSTOMERS(
  5. IDbigintnotnullprimarykey,
  6. NAMEvarchar(15)notnull,
  7. EMAILvarchar(128)notnull,
  8. PASSWORDvarchar(8)notnull,
  9. PHONEint,
  10. ADDRESSvarchar(255),
  11. SEXchar(1),
  12. IS_MARRIEDbit,
  13. DESCRIPTIONtext,
  14. IMAGEblob,
  15. BIRTHDAYdate,
  16. REGISTERED_TIMEtimestamp
  17. );


六、创建对象-关系映射文件Customer.hbm.xml
  1. <?xmlversion="1.0"?>
  2. <!DOCTYPEhibernate-mappingPUBLIC"-//Hibernate/HibernateMappingDTD3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
  3. <hibernate-mapping>
  4. <classname="mypack.Customer"table="CUSTOMERS">
  5. <idname="id"column="ID"type="long">
  6. <generatorclass="increment"/>
  7. </id>
  8. <propertyname="name"column="NAME"type="string"not-null="true"/>
  9. <propertyname="email"column="EMAIL"type="string"not-null="true"/>
  10. <propertyname="password"column="PASSWORD"type="string"not-null="true"/>
  11. <propertyname="phone"column="PHONE"type="int"/>
  12. <propertyname="address"column="ADDRESS"type="string"/>
  13. <propertyname="sex"column="SEX"type="character"/>
  14. <propertyname="married"column="IS_MARRIED"type="boolean"/>
  15. <propertyname="description"column="DESCRIPTION"type="text"/>
  16. <propertyname="image"column="IMAGE"type="binary"/>
  17. <propertyname="birthday"column="BIRTHDAY"type="date"/>
  18. <propertyname="registeredTime"column="REGISTERED_TIME"type="timestamp"/>
  19. </class>
  20. </hibernate-mapping>

  • <id>元素映射OID

<generator>子元素用来设定标识符生成器。Hibernate提供了提供了多种内置的实现。

  • <property>元素映射值类型属性
name属性:指定持久化类的属性的名字。
column属性:指定与类的属性映射的表的字段名。
type属性:指定Hibernate映射类型。Hibernate映射类型是Java类型与SQL类型的桥梁。

采用XML文件来配置对象-关系映射的优点:
  • Hibernate既不会渗透到上层域模型中,也不会渗透到下层数据模型中。
  • 软件开发人员可以独立设计域模型,不必强迫遵守任何规范。
  • 数据库设计人员可以独立设计数据模型,不必强迫遵守任何规范。
  • 对象-关系映射不依赖于任何程序代码,如果需要修改对象-关系映射,只需修改XML文件,不需要修改任何程序,提高了软件的灵活性,并且使维护更加方便。

七、创建BusinessService类

  1. packagemypack;
  2. importjavax.servlet.*;
  3. importorg.hibernate.*;
  4. importorg.hibernate.cfg.Configuration;
  5. importjava.io.*;
  6. importjava.sql.Date;
  7. importjava.sql.Timestamp;
  8. importjava.util.*;
  9. publicclassBusinessService{
  10. publicstaticSessionFactorysessionFactory;
  11. /**初始化Hibernate,创建SessionFactory实例*/
  12. static{
  13. try{
  14. //根据默认位置的Hibernate配置文件的配置信息,创建一个Configuration实例
  15. Configurationconfig=newConfiguration();
  16. //加载Customer类的对象-关系映射文件
  17. config.addClass(Customer.class);
  18. //创建SessionFactory实例*/
  19. sessionFactory=config.buildSessionFactory();
  20. }catch(RuntimeExceptione){e.printStackTrace();throwe;}
  21. }
  22. /**查询所有的Customer对象,然后调用printCustomer()方法打印Customer对象信息*/
  23. publicvoidfindAllCustomers(ServletContextcontext,PrintWriterout)throwsException{
  24. Sessionsession=sessionFactory.openSession();//创建一个会话
  25. Transactiontx=null;
  26. try{
  27. tx=session.beginTransaction();//开始一个事务
  28. Queryquery=session.createQuery("fromCustomerascorderbyc.nameasc");
  29. Listcustomers=query.list();
  30. for(Iteratorit=customers.iterator();it.hasNext();){
  31. printCustomer(context,out,(Customer)it.next());
  32. }
  33. tx.commit();//提交事务
  34. }catch(RuntimeExceptione){
  35. if(tx!=null){
  36. tx.rollback();
  37. }
  38. throwe;
  39. }finally{
  40. session.close();
  41. }
  42. }
  43. /**持久化一个Customer对象*/
  44. publicvoidsaveCustomer(Customercustomer){
  45. Sessionsession=sessionFactory.openSession();
  46. Transactiontx=null;
  47. try{
  48. tx=session.beginTransaction();
  49. session.save(customer);
  50. tx.commit();
  51. }catch(RuntimeExceptione){
  52. if(tx!=null){
  53. tx.rollback();
  54. }
  55. throwe;
  56. }finally{
  57. session.close();
  58. }
  59. }
  60. /**按照OID加载一个Customer对象,然后修改它的属性*/
  61. publicvoidloadAndUpdateCustomer(Longcustomer_id,Stringaddress){
  62. Sessionsession=sessionFactory.openSession();
  63. Transactiontx=null;
  64. try{
  65. tx=session.beginTransaction();
  66. Customerc=(Customer)session.get(Customer.class,customer_id);
  67. c.setAddress(address);
  68. tx.commit();
  69. }catch(RuntimeExceptione){
  70. if(tx!=null){
  71. tx.rollback();
  72. }
  73. throwe;
  74. }finally{
  75. session.close();
  76. }
  77. }
  78. /**删除Customer对象*/
  79. publicvoiddeleteCustomer(Customercustomer){
  80. Sessionsession=sessionFactory.openSession();
  81. Transactiontx=null;
  82. try{
  83. tx=session.beginTransaction();
  84. session.delete(customer);
  85. tx.commit();
  86. }catch(RuntimeExceptione){
  87. if(tx!=null){
  88. tx.rollback();
  89. }
  90. throwe;
  91. }finally{
  92. session.close();
  93. }
  94. }
  95. /**选择向控制台还是Web网页输出Customer对象的信息*/
  96. privatevoidprintCustomer(ServletContextcontext,PrintWriterout,Customercustomer)throwsException{
  97. if(context!=null)
  98. printCustomerInWeb(context,out,customer);
  99. else
  100. printCustomer(out,customer);
  101. }
  102. /**把Customer对象的信息输出到控制台,如DOS控制台*/
  103. privatevoidprintCustomer(PrintWriterout,Customercustomer)throwsException{
  104. byte[]buffer=customer.getImage();
  105. FileOutputStreamfout=newFileOutputStream("photo_copy.gif");
  106. fout.write(buffer);
  107. fout.close();
  108. out.println("------以下是"+customer.getName()+"的个人信息------");
  109. out.println("ID:"+customer.getId());
  110. out.println("口令:"+customer.getPassword());
  111. out.println("E-Mail:"+customer.getEmail());
  112. out.println("电话:"+customer.getPhone());
  113. out.println("地址:"+customer.getAddress());
  114. Stringsex=customer.getSex()=='M'?"男":"女";
  115. out.println("性别:"+sex);
  116. StringmarriedStatus=customer.isMarried()?"已婚":"未婚";
  117. out.println("婚姻状况:"+marriedStatus);
  118. out.println("生日:"+customer.getBirthday());
  119. out.println("注册时间:"+customer.getRegisteredTime());
  120. out.println("自我介绍:"+customer.getDescription());
  121. }
  122. /**把Customer对象的信息输出到动态网页*/
  123. privatevoidprintCustomerInWeb(ServletContextcontext,PrintWriterout,Customercustomer)throwsException{
  124. //保存照片
  125. byte[]buffer=customer.getImage();
  126. Stringpath=context.getRealPath("/");
  127. FileOutputStreamfout=newFileOutputStream(path+"photo_copy.gif");
  128. fout.write(buffer);
  129. fout.close();
  130. out.println("------以下是"+customer.getName()+"的个人信息------"+"<br>");
  131. out.println("ID:"+customer.getId()+"<br>");
  132. out.println("口令:"+customer.getPassword()+"<br>");
  133. out.println("E-Mail:"+customer.getEmail()+"<br>");
  134. out.println("电话:"+customer.getPhone()+"<br>");
  135. out.println("地址:"+customer.getAddress()+"<br>");
  136. Stringsex=customer.getSex()=='M'?"男":"女";
  137. out.println("性别:"+sex+"<br>");
  138. StringmarriedStatus=customer.isMarried()?"已婚":"未婚";
  139. out.println("婚姻状况:"+marriedStatus+"<br>");
  140. out.println("生日:"+customer.getBirthday()+"<br>");
  141. out.println("注册时间:"+customer.getRegisteredTime()+"<br>");
  142. out.println("自我介绍:"+customer.getDescription()+"<br>");
  143. out.println("<imgsrc='photo_copy.gif'border=0><p>");
  144. }
  145. publicvoidtest(ServletContextcontext,PrintWriterout)throwsException{
  146. Customercustomer=newCustomer();
  147. customer.setName("Tom");
  148. customer.setEmail("[email protected]");
  149. customer.setPassword("1234");
  150. customer.setPhone(55556666);
  151. customer.setAddress("Shanghai");
  152. customer.setSex('M');
  153. customer.setDescription("Iamveryhonest.");
  154. //设置Customer对象的image属性,它是字节数组,存放photo.gif文件中的二进制数据
  155. //photo.gif文件和BusinessService.class文件位于同一个目录下
  156. InputStreamin=this.getClass().getResourceAsStream("photo.gif");
  157. byte[]buffer=newbyte[in.available()];
  158. in.read(buffer);
  159. customer.setImage(buffer);
  160. //设置Customer对象的birthday属性,它是java.sql.Date类型
  161. customer.setBirthday(Date.valueOf("1980-05-06"));
  162. saveCustomer(customer);
  163. findAllCustomers(context,out);
  164. loadAndUpdateCustomer(customer.getId(),"Beijing");
  165. findAllCustomers(context,out);
  166. deleteCustomer(customer);
  167. }
  168. publicstaticvoidmain(Stringargs[])throwsException{
  169. newBusinessService().test(null,newPrintWriter(System.out,true));
  170. sessionFactory.close();
  171. }
  172. }

  • saveCustomer()方法
该方法调用Session的save()方法,把Customer对象持久化到数据库中。
  1. tx=session.beginTransaction();
  2. session.save(customer);
  3. tx.commit();

当运行session.save()方法时,Hibernate执行以下SQL语句:
  1. insertintoCUSTOMERS(ID,NAME,EMAIL,PASSWORD,PHONE,ADDRESS,SEX,
  2. IS_MARRIED,DESCRIPTION,IMAGE,BIRTHDAY,REGISTERED_TIME)
  3. values(1,'Tom','[email protected]','1234',55556666,'Shanghai','M',0,'Iamveryhonest.',☺,'1980-05-06',null)

在test()方法中并没有设置Customer对象的id属性,Hibernate会根据映射文件的配置,采用increment标识符生成器自动以递增的方式为OID赋值。在Customer.hbm.xml文件中相关的映射代码如下:
  1. <idname="id"column="ID"type="long">
  2. <generatorclass="increment"/>
  3. </id>
  • findAllCustomers()方法
该方法通过Query接口查询所有的Customer对象。
  1. tx=session.beginTransaction();//开始一个事务
  2. Queryquery=session.createQuery("fromCustomerascorderbyc.nameasc");
  3. Listcustomers=query.list();
  4. for(Iteratorit=customers.iterator();it.hasNext();){
  5. printCustomer(context,out,(Customer)it.next());
  6. }
  7. tx.commit();//提交事务

Session的createQuery()方法的参数“from Customer as c order by c.name asc”使用的是Hibernate查询语言。运行Query.list()方法时, Hibernate执行以下SQL语句:
  1. select*fromCUSTOMERSorderbyNAMEasc;
  • loadAndUpdateCustomer ()方法
该方法调用Session的get()方法,加载Customer对象,然后再修改Customer对象的属性。
  1. tx=session.beginTransaction();
  2. Customerc=(Customer)session.get(Customer.class,customer_id);
  3. c.setAddress(address);//修改内存中Customer对象的address属性
  4. tx.commit();
以上代码先调用Session的get()方法,它按照参数指定的OID从数据库中检索出匹配的Customer对象,Hibernate会执行以下SQL语句:
  1. select*fromCUSTOMERSwhereID=1;

loadAndUpdateCustomer()方法接着修改Customer对象的address属性。那么,Hibernate会不会同步更新数据库中相应的CUSTOMERS表的记录呢?答案是肯定的。Hibernate采用脏检查机制,按照内存中的Customer对象的状态的变化,来同步更新数据库中相关的数据,Hibernate会执行以下SQL语句:
  1. updateCUSTOMERSsetNAME="Tom",EMAIL="[email protected]"…ADDRESS="Beijing"
  2. whereID=1;

尽管只有Customer对象的address属性发生了变化,但是Hibernate执行的update语句中会包含所有的字段。

  • deleteCustomer()方法
该方法调用Session的delete()方法,删除特定的Customer对象:
  1. tx=session.beginTransaction();
  2. session.delete(customer);
  3. tx.commit();

运行session.delete()方法时,Hibernate根据Customer对象的OID,执行以下SQL delete语句:
  1. deletefromCUSTOMERSwhereID=1;

八、效果图







一、在Java应用中使用Hibernate的步骤

  • 创建Hibernate的配置文件
  • 创建持久化类
  • 创建对象-关系映射文件
  • 通过Hibernate API编写访问数据库的代码

二、Helloapp应用的结构

三、Hibernate的配置文件(hibernate.properties)

  1. hibernate.dialect=org.hibernate.dialect.MySQLDialect
  2. hibernate.connection.driver_class=com.mysql.jdbc.Driver
  3. hibernate.connection.url=jdbc:mysql://localhost:3306/SAMPLEDB
  4. hibernate.connection.username=root
  5. hibernate.connection.password=1234
  6. hibernate.show_sql=true


四、创建持久化类Customer

  • 持久化类符合JavaBean的规范,包含一些属性,以及与之对应的getXXX()和setXXX()方法。
  • 持久化类有一个id属性,用来惟一标识Customer类的每个对象。在面向对象术语中,这个id属性被称为对象标识符(OID,Object Identifier),通常它都用整数表示
  • Hibernate要求持久化类必须提供一个不带参数的默认构造方法
  1. packagemypack;
  2. importjava.io.Serializable;
  3. importjava.sql.Date;
  4. importjava.sql.Timestamp;
  5. publicclassCustomerimplementsSerializable{
  6. privateLongid;
  7. privateStringname;
  8. privateStringemail;
  9. privateStringpassword;
  10. privateintphone;
  11. privateStringaddress;
  12. privatecharsex;
  13. privatebooleanmarried;
  14. privateStringdescription;
  15. privatebyte[]image;
  16. privateDatebirthday;
  17. privateTimestampregisteredTime;
  18. publicCustomer(){}
  19. publicLonggetId(){
  20. returnid;
  21. }
  22. privatevoidsetId(Longid){
  23. this.id=id;
  24. }
  25. publicStringgetName(){
  26. returnname;
  27. }
  28. publicvoidsetName(Stringname){
  29. this.name=name;
  30. }
  31. publicStringgetEmail(){
  32. returnemail;
  33. }
  34. publicvoidsetEmail(Stringemail){
  35. this.email=email;
  36. }
  37. publicStringgetPassword(){
  38. returnpassword;
  39. }
  40. publicvoidsetPassword(Stringpassword){
  41. this.password=password;
  42. }
  43. publicintgetPhone(){
  44. returnphone;
  45. }
  46. publicvoidsetPhone(intphone){
  47. this.phone=phone;
  48. }
  49. publicStringgetAddress(){
  50. returnaddress;
  51. }
  52. publicvoidsetAddress(Stringaddress){
  53. this.address=address;
  54. }
  55. publicchargetSex(){
  56. returnsex;
  57. }
  58. publicvoidsetSex(charsex){
  59. this.sex=sex;
  60. }
  61. publicbooleanisMarried(){
  62. returnmarried;
  63. }
  64. publicvoidsetMarried(booleanmarried){
  65. this.married=married;
  66. }
  67. publicStringgetDescription(){
  68. returndescription;
  69. }
  70. publicvoidsetDescription(Stringdescription){
  71. this.description=description;
  72. }
  73. publicbyte[]getImage(){
  74. returnthis.image;
  75. }
  76. publicvoidsetImage(byte[]image){
  77. this.image=image;
  78. }
  79. publicDategetBirthday(){
  80. returnthis.birthday;
  81. }
  82. publicvoidsetBirthday(Datebirthday){
  83. this.birthday=birthday;
  84. }
  85. publicTimestampgetRegisteredTime(){
  86. returnthis.registeredTime;
  87. }
  88. publicvoidsetRegisteredTime(TimestampregisteredTime){
  89. this.registeredTime=registeredTime;
  90. }
  91. }

注意:

  • getXXX()和setXXX()方法可以采用任意的访问级别,他的命名规则必须符合特定的命名规则,“get”和“set”后面紧跟属性的名字,并且属性名的首字母为大写,如name属性的get方法为getName()。
  • 如果持久化类的属性为boolean类型,那么它的get方法名可以用get做前缀也可以用is做前缀。

五、创建数据库Schema

  1. dropdatabaseifexistsSAMPLEDB;
  2. createdatabaseSAMPLEDB;
  3. useSAMPLEDB;
  4. createtableCUSTOMERS(
  5. IDbigintnotnullprimarykey,
  6. NAMEvarchar(15)notnull,
  7. EMAILvarchar(128)notnull,
  8. PASSWORDvarchar(8)notnull,
  9. PHONEint,
  10. ADDRESSvarchar(255),
  11. SEXchar(1),
  12. IS_MARRIEDbit,
  13. DESCRIPTIONtext,
  14. IMAGEblob,
  15. BIRTHDAYdate,
  16. REGISTERED_TIMEtimestamp
  17. );


六、创建对象-关系映射文件Customer.hbm.xml
  1. <?xmlversion="1.0"?>
  2. <!DOCTYPEhibernate-mappingPUBLIC"-//Hibernate/HibernateMappingDTD3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
  3. <hibernate-mapping>
  4. <classname="mypack.Customer"table="CUSTOMERS">
  5. <idname="id"column="ID"type="long">
  6. <generatorclass="increment"/>
  7. </id>
  8. <propertyname="name"column="NAME"type="string"not-null="true"/>
  9. <propertyname="email"column="EMAIL"type="string"not-null="true"/>
  10. <propertyname="password"column="PASSWORD"type="string"not-null="true"/>
  11. <propertyname="phone"column="PHONE"type="int"/>
  12. <propertyname="address"column="ADDRESS"type="string"/>
  13. <propertyname="sex"column="SEX"type="character"/>
  14. <propertyname="married"column="IS_MARRIED"type="boolean"/>
  15. <propertyname="description"column="DESCRIPTION"type="text"/>
  16. <propertyname="image"column="IMAGE"type="binary"/>
  17. <propertyname="birthday"column="BIRTHDAY"type="date"/>
  18. <propertyname="registeredTime"column="REGISTERED_TIME"type="timestamp"/>
  19. </class>
  20. </hibernate-mapping>

  • <id>元素映射OID

<generator>子元素用来设定标识符生成器。Hibernate提供了提供了多种内置的实现。

  • <property>元素映射值类型属性
name属性:指定持久化类的属性的名字。
column属性:指定与类的属性映射的表的字段名。
type属性:指定Hibernate映射类型。Hibernate映射类型是Java类型与SQL类型的桥梁。

采用XML文件来配置对象-关系映射的优点:
  • Hibernate既不会渗透到上层域模型中,也不会渗透到下层数据模型中。
  • 软件开发人员可以独立设计域模型,不必强迫遵守任何规范。
  • 数据库设计人员可以独立设计数据模型,不必强迫遵守任何规范。
  • 对象-关系映射不依赖于任何程序代码,如果需要修改对象-关系映射,只需修改XML文件,不需要修改任何程序,提高了软件的灵活性,并且使维护更加方便。

七、创建BusinessService类

  1. packagemypack;
  2. importjavax.servlet.*;
  3. importorg.hibernate.*;
  4. importorg.hibernate.cfg.Configuration;
  5. importjava.io.*;
  6. importjava.sql.Date;
  7. importjava.sql.Timestamp;
  8. importjava.util.*;
  9. publicclassBusinessService{
  10. publicstaticSessionFactorysessionFactory;
  11. /**初始化Hibernate,创建SessionFactory实例*/
  12. static{
  13. try{
  14. //根据默认位置的Hibernate配置文件的配置信息,创建一个Configuration实例
  15. Configurationconfig=newConfiguration();
  16. //加载Customer类的对象-关系映射文件
  17. config.addClass(Customer.class);
  18. //创建SessionFactory实例*/
  19. sessionFactory=config.buildSessionFactory();
  20. }catch(RuntimeExceptione){e.printStackTrace();throwe;}
  21. }
  22. /**查询所有的Customer对象,然后调用printCustomer()方法打印Customer对象信息*/
  23. publicvoidfindAllCustomers(ServletContextcontext,PrintWriterout)throwsException{
  24. Sessionsession=sessionFactory.openSession();//创建一个会话
  25. Transactiontx=null;
  26. try{
  27. tx=session.beginTransaction();//开始一个事务
  28. Queryquery=session.createQuery("fromCustomerascorderbyc.nameasc");
  29. Listcustomers=query.list();
  30. for(Iteratorit=customers.iterator();it.hasNext();){
  31. printCustomer(context,out,(Customer)it.next());
  32. }
  33. tx.commit();//提交事务
  34. }catch(RuntimeExceptione){
  35. if(tx!=null){
  36. tx.rollback();
  37. }
  38. throwe;
  39. }finally{
  40. session.close();
  41. }
  42. }
  43. /**持久化一个Customer对象*/
  44. publicvoidsaveCustomer(Customercustomer){
  45. Sessionsession=sessionFactory.openSession();
  46. Transactiontx=null;
  47. try{
  48. tx=session.beginTransaction();
  49. session.save(customer);
  50. tx.commit();
  51. }catch(RuntimeExceptione){
  52. if(tx!=null){
  53. tx.rollback();
  54. }
  55. throwe;
  56. }finally{
  57. session.close();
  58. }
  59. }
  60. /**按照OID加载一个Customer对象,然后修改它的属性*/
  61. publicvoidloadAndUpdateCustomer(Longcustomer_id,Stringaddress){
  62. Sessionsession=sessionFactory.openSession();
  63. Transactiontx=null;
  64. try{
  65. tx=session.beginTransaction();
  66. Customerc=(Customer)session.get(Customer.class,customer_id);
  67. c.setAddress(address);
  68. tx.commit();
  69. }catch(RuntimeExceptione){
  70. if(tx!=null){
  71. tx.rollback();
  72. }
  73. throwe;
  74. }finally{
  75. session.close();
  76. }
  77. }
  78. /**删除Customer对象*/
  79. publicvoiddeleteCustomer(Customercustomer){
  80. Sessionsession=sessionFactory.openSession();
  81. Transactiontx=null;
  82. try{
  83. tx=session.beginTransaction();
  84. session.delete(customer);
  85. tx.commit();
  86. }catch(RuntimeExceptione){
  87. if(tx!=null){
  88. tx.rollback();
  89. }
  90. throwe;
  91. }finally{
  92. session.close();
  93. }
  94. }
  95. /**选择向控制台还是Web网页输出Customer对象的信息*/
  96. privatevoidprintCustomer(ServletContextcontext,PrintWriterout,Customercustomer)throwsException{
  97. if(context!=null)
  98. printCustomerInWeb(context,out,customer);
  99. else
  100. printCustomer(out,customer);
  101. }
  102. /**把Customer对象的信息输出到控制台,如DOS控制台*/
  103. privatevoidprintCustomer(PrintWriterout,Customercustomer)throwsException{
  104. byte[]buffer=customer.getImage();
  105. FileOutputStreamfout=newFileOutputStream("photo_copy.gif");
  106. fout.write(buffer);
  107. fout.close();
  108. out.println("------以下是"+customer.getName()+"的个人信息------");
  109. out.println("ID:"+customer.getId());
  110. out.println("口令:"+customer.getPassword());
  111. out.println("E-Mail:"+customer.getEmail());
  112. out.println("电话:"+customer.getPhone());
  113. out.println("地址:"+customer.getAddress());
  114. Stringsex=customer.getSex()=='M'?"男":"女";
  115. out.println("性别:"+sex);
  116. StringmarriedStatus=customer.isMarried()?"已婚":"未婚";
  117. out.println("婚姻状况:"+marriedStatus);
  118. out.println("生日:"+customer.getBirthday());
  119. out.println("注册时间:"+customer.getRegisteredTime());
  120. out.println("自我介绍:"+customer.getDescription());
  121. }
  122. /**把Customer对象的信息输出到动态网页*/
  123. privatevoidprintCustomerInWeb(ServletContextcontext,PrintWriterout,Customercustomer)throwsException{
  124. //保存照片
  125. byte[]buffer=customer.getImage();
  126. Stringpath=context.getRealPath("/");
  127. FileOutputStreamfout=newFileOutputStream(path+"photo_copy.gif");
  128. fout.write(buffer);
  129. fout.close();
  130. out.println("------以下是"+customer.getName()+"的个人信息------"+"<br>");
  131. out.println("ID:"+customer.getId()+"<br>");
  132. out.println("口令:"+customer.getPassword()+"<br>");
  133. out.println("E-Mail:"+customer.getEmail()+"<br>");
  134. out.println("电话:"+customer.getPhone()+"<br>");
  135. out.println("地址:"+customer.getAddress()+"<br>");
  136. Stringsex=customer.getSex()=='M'?"男":"女";
  137. out.println("性别:"+sex+"<br>");
  138. StringmarriedStatus=customer.isMarried()?"已婚":"未婚";
  139. out.println("婚姻状况:"+marriedStatus+"<br>");
  140. out.println("生日:"+customer.getBirthday()+"<br>");
  141. out.println("注册时间:"+customer.getRegisteredTime()+"<br>");
  142. out.println("自我介绍:"+customer.getDescription()+"<br>");
  143. out.println("<imgsrc='photo_copy.gif'border=0><p>");
  144. }
  145. publicvoidtest(ServletContextcontext,PrintWriterout)throwsException{
  146. Customercustomer=newCustomer();
  147. customer.setName("Tom");
  148. customer.setEmail("[email protected]");
  149. customer.setPassword("1234");
  150. customer.setPhone(55556666);
  151. customer.setAddress("Shanghai");
  152. customer.setSex('M');
  153. customer.setDescription("Iamveryhonest.");
  154. //设置Customer对象的image属性,它是字节数组,存放photo.gif文件中的二进制数据
  155. //photo.gif文件和BusinessService.class文件位于同一个目录下
  156. InputStreamin=this.getClass().getResourceAsStream("photo.gif");
  157. byte[]buffer=newbyte[in.available()];
  158. in.read(buffer);
  159. customer.setImage(buffer);
  160. //设置Customer对象的birthday属性,它是java.sql.Date类型
  161. customer.setBirthday(Date.valueOf("1980-05-06"));
  162. saveCustomer(customer);
  163. findAllCustomers(context,out);
  164. loadAndUpdateCustomer(customer.getId(),"Beijing");
  165. findAllCustomers(context,out);
  166. deleteCustomer(customer);
  167. }
  168. publicstaticvoidmain(Stringargs[])throwsException{
  169. newBusinessService().test(null,newPrintWriter(System.out,true));
  170. sessionFactory.close();
  171. }
  172. }

  • saveCustomer()方法
该方法调用Session的save()方法,把Customer对象持久化到数据库中。
  1. tx=session.beginTransaction();
  2. session.save(customer);
  3. tx.commit();

当运行session.save()方法时,Hibernate执行以下SQL语句:
  1. insertintoCUSTOMERS(ID,NAME,EMAIL,PASSWORD,PHONE,ADDRESS,SEX,
  2. IS_MARRIED,DESCRIPTION,IMAGE,BIRTHDAY,REGISTERED_TIME)
  3. values(1,'Tom','[email protected]','1234',55556666,'Shanghai','M',0,'Iamveryhonest.',☺,'1980-05-06',null)

在test()方法中并没有设置Customer对象的id属性,Hibernate会根据映射文件的配置,采用increment标识符生成器自动以递增的方式为OID赋值。在Customer.hbm.xml文件中相关的映射代码如下:
  1. <idname="id"column="ID"type="long">
  2. <generatorclass="increment"/>
  3. </id>
  • findAllCustomers()方法
该方法通过Query接口查询所有的Customer对象。
  1. tx=session.beginTransaction();//开始一个事务
  2. Queryquery=session.createQuery("fromCustomerascorderbyc.nameasc");
  3. Listcustomers=query.list();
  4. for(Iteratorit=customers.iterator();it.hasNext();){
  5. printCustomer(context,out,(Customer)it.next());
  6. }
  7. tx.commit();//提交事务

Session的createQuery()方法的参数“from Customer as c order by c.name asc”使用的是Hibernate查询语言。运行Query.list()方法时, Hibernate执行以下SQL语句:
  1. select*fromCUSTOMERSorderbyNAMEasc;
  • loadAndUpdateCustomer ()方法
该方法调用Session的get()方法,加载Customer对象,然后再修改Customer对象的属性。
  1. tx=session.beginTransaction();
  2. Customerc=(Customer)session.get(Customer.class,customer_id);
  3. c.setAddress(address);//修改内存中Customer对象的address属性
  4. tx.commit();
以上代码先调用Session的get()方法,它按照参数指定的OID从数据库中检索出匹配的Customer对象,Hibernate会执行以下SQL语句:
  1. select*fromCUSTOMERSwhereID=1;

loadAndUpdateCustomer()方法接着修改Customer对象的address属性。那么,Hibernate会不会同步更新数据库中相应的CUSTOMERS表的记录呢?答案是肯定的。Hibernate采用脏检查机制,按照内存中的Customer对象的状态的变化,来同步更新数据库中相关的数据,Hibernate会执行以下SQL语句:
  1. updateCUSTOMERSsetNAME="Tom",EMAIL="[email protected]"…ADDRESS="Beijing"
  2. whereID=1;

尽管只有Customer对象的address属性发生了变化,但是Hibernate执行的update语句中会包含所有的字段。

  • deleteCustomer()方法
该方法调用Session的delete()方法,删除特定的Customer对象:
  1. tx=session.beginTransaction();
  2. session.delete(customer);
  3. tx.commit();

运行session.delete()方法时,Hibernate根据Customer对象的OID,执行以下SQL delete语句:
  1. deletefromCUSTOMERSwhereID=1;

八、效果图