1、Java Web 程序设计与项目实践第十三章 Hibernate配置和会话 Hibernate的配置包括两个重要部分,一个是Hibernate的配置文件Hibernate.cfg.xml,一个是实体类的映射文件,本章将对这两个配置文件进行详细介绍。本章还将一种最新的配置映射关系的方式,使用Annotations配置映射,从而省去繁琐的映射配置文件。本章最后将介绍Hibernate的三种对象状态以及Session的各方法和应用。重点内容:使用XML文件配置Hibernate 配置映射文件 使用Annotations配置映射 Hibernate的三种对象状态 Session的各方法以及其应用Jav
2、a Web 程序设计与项目实践一、配置Hibernate1.使用XML文件配置Hibernate使用XML文件配置Hibernate,是目前最常用的配置方式,同样也是Hibernate官方推荐的配置方式。Hibernate默认的配置文件为hibernate.cfg.xml,不过读者也可以使用其他文件名,到时候再在HibernateSessionFactory类中修改配置文件路径就可以了。在Hibernate配置文件同样有DTD规范,并规范该文件的根节点为,其代码如下所示。Java Web 程序设计与项目实践一、配置Hibernate2.使用资源文件配置Hibernate在Hibernate 3
3、以前开发人员一般使用资源文件配置Hibernate,资源文件的格式是键值对形式的。使用资源文件配置Hibernate时,将属性名称作为key值,属性值作为value值。资源文件的后缀名为.properties,需要将该文件放置于CLASSPATH环境变量指定路径的根目录下,在MyEclipse中可以将其直接放置在src根目录下。hibernate.connection.url=jdbc:mysql:/localhost:3306/javawebhibernate.connection.username=roothibernate.connection.password=adminhiberna
4、te.connection.driver_class=com.mysql.jdbc.Driverhibernate.dialect=org.hibernate.dialect.MySQLDialecthibernate.show_sql=trueJava Web 程序设计与项目实践一、配置Hibernate3.代码动态配置Hibernate前面介绍的两种方式都是在配置文件进行的配置,这类配置在程序运行中是无法修改的。下面再来介绍一种配置Hibernate的方式,那就是在代码中动态配置Hibernate。configuration=new Configuration();configuratio
5、n.setProperty(connection.url,jdbc:mysql:/localhost:3306/javaweb);configuration.setProperty(connection.username,root);configuration.setProperty(connection.password,admin);configuration.setProperty(dialect,org.hibernate.dialect.MySQLDialect);configuration.setProperty(connection.driver_class,com.mysql.
6、jdbc.Driver);configuration.setProperty(show_sql,true);Java Web 程序设计与项目实践二、配置映射文件1.元素映射文件的根节点为,该节点包含一系列可选的属性,如schema和catalog属性。其中schema属性用来指定数据库表所在的schema名称。如果指定了schema属性,表名则会加上所指定的schema的名字扩展为全限定名;如果没有指定该属性,则不会使用全限定名。的所有属性以及属性说明如下表所示。Java Web 程序设计与项目实践二、配置映射文件2.元素元素用来配置一个实体类与一个数据库表的关联,其中name属性用来指定实体
7、类的类名,table属性用来指定数据库表的名称。元素除了常用的name属性和table属性外还有其他一些常用属性如下表所示。Java Web 程序设计与项目实践二、配置映射文件3.元素每一个实体类中都包含一个唯一的标识,元素能够定义该属性和数据库表中的主键字段的映射。元素同样包含许多的属性,其中name属性用来指定标识属性的名称,type属性用来指定标识属性的Hibernate类型,column属性用来指定数据库表中主键字段的名称。元素还有其他一些常用属性如下表所示。Java Web 程序设计与项目实践二、配置映射文件4.元素实体类的标识和数据库表的主键映射完成后,还需要为实体类的其他属性和数
8、据库的其他字段进行映射,这个时候就需要使用到元素。元素的常用属性如下表所示。Java Web 程序设计与项目实践二、配置映射文件5.其他元素元素下除了可以添加元素和元素外,还可以添加其他元素。这些元素同样非常重要,本书将在后面的章节进行重点介绍,这里只做简单概述。元素 元素 元素 元素 元素Java Web 程序设计与项目实践三、使用Annotations配置映射1.使用Entity注释实体类Entity注释用来将一个普通的JavaBean标注为实体类。Entity注释有一个可选的name属性,用来设置实体名,其默认值为JavaBean的类名。并不是所有的JavaBean都能被标注为实体类,必
9、须满足如下三个条件。1JavaBean类的访问权限只能是public。2JavaBean类不能是抽象类。3JavaBean中必须有一个无参的构造方法,而且该构造方法的访问权限只能是public。Java Web 程序设计与项目实践三、使用Annotations配置映射2.使用Table注释实体类Table注释用来对实体类进行进一步注释,用来配置实体类到数据库表映射的更详细的信息。Table注释包含四个属性,分别为catalog、name、schema以及uniqueConstraints。1catalog属性。2name属性。3schema属性。4uniqueConstraints属性。Jav
10、a Web 程序设计与项目实践三、使用Annotations配置映射3.使用Id注释实体类标识Id注释用来对实体类的标识进行配置,一个实体类一般只有一个标识,所有一个实体类只出现一个Id注释。public class Employee Idprivate String employeeID;public String getEmployeeID()return employeeID;Java Web 程序设计与项目实践三、使用Annotations配置映射4.使用GenerateValue注释覆盖标识的默认访问策略使用Id注释实体类标识时将采用Hibernate的默认访问策略,这时可以使用Ge
11、nerateValue注释来覆盖该默认访问策略。GenerateValue注释包含两个属性,分别为generator和strategy。1generator属性,该属性用来指定标识生成器名。标识生成器可以通过SequenceGenerator、TableGenerator和 GenericGenerator来创建,generator属性只需要指定为这些生成器的name属性值即可。2strategy属性,该属性用来用来指定标识生成策略。strategy的属性值为一个枚举类型。Java Web 程序设计与项目实践三、使用Annotations配置映射5.使用GenericGenerator注释生成
12、标识生成器前面介绍了如何使用GenerateValue注释的strategy属性来指定标识生成策略,但是这些生成策略明显不能满足。这时可以使用GenericGenerator注释产生标识生成器,然后通过GenerateValue注释的generator属性来指定该生成器的name属性,这样就可以采用指定的生成器来生成标识。GenericeGenerator注释是在Hibernate中定义的,其注释类在org.hibernate.annotations包下,使用该注释可以使用Hibernate内置的各种生成策略从而生成标识。GenericeGenerator注释包含三个属性,分别为name、pa
13、rameters和strategy。1name属性,该属性用来设置标识生成器名。2parameters属性,该属性用来设置标识生成器所需的参数。3strategy属性,该属性用来设置Hibernate内置的生成策略。Java Web 程序设计与项目实践三、使用Annotations配置映射5.使用GenericGenerator注释生成标识生成器前面介绍了如何使用GenerateValue注释的strategy属性来指定标识生成策略,但是这些生成策略明显不能满足。这时可以使用GenericGenerator注释产生标识生成器,然后通过GenerateValue注释的generator属性来指定
14、该生成器的name属性,这样就可以采用指定的生成器来生成标识。GenericeGenerator注释是在Hibernate中定义的,其注释类在org.hibernate.annotations包下,使用该注释可以使用Hibernate内置的各种生成策略从而生成标识。GenericeGenerator注释包含三个属性,分别为name、parameters和strategy。1name属性,该属性用来设置标识生成器名。2parameters属性,该属性用来设置标识生成器所需的参数。3strategy属性,该属性用来设置Hibernate内置的生成策略。Java Web 程序设计与项目实践三、使用A
15、nnotations配置映射6.使用Column注释实体类非标识属性一个实体类除了有标示,一般还会有许多的其他属性,这时可以使用Column注释这些属性。Column注释最常用的属性为name属性,该属性用来配置数据库表中的字段名。如果不设置该属性值,那么将表示实体类属性名和数据库表字段名一样。Column(name=employeeName)private String employeeName;Column(name=employeeSex)private boolean employeeSex;Column(name=employeeBirth)private Date employee
16、Birth;Column(name=employeePhone)private String employeePhone;Java Web 程序设计与项目实践三、使用Annotations配置映射7.自定义AnnotationSessionFactory类来获得Session对象前面介绍了如何使用Annotations注释来完成实体类到数据库表的映射,这时还有一点需要特别注意。在以前获得SessionFactory对象是通过调用Configuration对象的buildSessionFactory方法来实现,但是这种方式仅仅支持映射文件方式的映射,不支持Annotations注释映射。要支持A
17、nnotations注释映射必须使用AnnotationConfiguration类,通过该类实例对象的buildSessionFactory方法来获得SessionFactory实例对象。Java Web 程序设计与项目实践三、使用Annotations配置映射8.测试Annotations注释是否成功完成映射通过AnnotationSessionFactory可以加载Annotations注释方式的映射,同样可以通过其buildSessionFactory方法获得SessionFactory对象,同时还可以通过其getSession方法获得Session对象。通过调用Session的对象各
18、种方法就可以完成各类数据库操作,如查询记录、添加记录等等。在创建测试类之前,首先同样需要在Hibernate配置文件hibernate.cfg.xml中添加映射信息。同映射文件配置映射不同,这里需要使用在元素中指定其class属性为需要映射的实体类,代码如下所示。完成如上步骤以后,映射信息就已经全部完成了,下面就来创建一个测试类来测试使用Annotations注释是否成功完成映射。Java Web 程序设计与项目实践四、会话(Session)的应用1.Hibernate对象状态一个实体类的实例可能处于三种不同状态中的一种,这三种状态分别是瞬时状态、持久状态、托管状态。下面来看这三种状态的详细说
19、明。各状态转换提交得到其转换图如图所示。Java Web 程序设计与项目实践四、会话(Session)的应用2.使用save方法持久化对象使用new关键字创建的对象并没有保存到数据库当中,这时的对象为瞬时状态,通过Session对象的save方法能够将其转换成持久状态,并同时在数据库表中添加相应记录。save方法两有种重载形式,其代码如下。public Serializable save(Object object)throws Hibernate Exception;public Serializable save(String entityName,Object object)throws
20、 HibernateException;其中Object参数用来设置实体类的实例名,entityName参数用来设置实体类的类名。我们通常只是用第一种重载形式的save方法。Java Web 程序设计与项目实践四、会话(Session)的应用3.使用saveOrUpdate方法持久化对象使用save方法虽然能够完成对象的持久化,但是有时候容易出现问题,比如一个对象已经被持久化了,这时候再次调用save方法将抛出异常。使用saveOrUpdate方法可以很好的解决这一问题,它会自动判断该对象是否已经持久化,如果已经持久化了将执行更新操作,如果没有持久化才进行添加操作。saveOrUpdate方法
21、有两种重载形式,其代码如下。public void saveOrUpdate(Object object)throws HibernateException;public void saveOrUpdate(String entityName,Object object)throws HibernateException;saveOrUpdate方法中的参数含义和save方法是完全一样的。来设置实体类的类名。我们通常只是用第一种重载形式的save方法。Java Web 程序设计与项目实践四、会话(Session)的应用4.使用load方法装载对象如果知道某个对象的持久化标识,就可以使用Sess
22、ion对象的load方法从数据库装载数据,使用load方法装载的对象是持久状态的。load方法有五种重载形式,其代码如下。public Object load(Class theClass,Serializable id)throws HibernateException;public Object load(String entityName,Serializable id)throws HibernateException;public void load(Object object,Serializable id)throws HibernateException;public Obje
23、ct load(String entityName,Serializable id,LockMode lockMode)throws HibernateException;public Object load(Class theClass,Serializable id,LockMode lockMode)throws HibernateException;Java Web 程序设计与项目实践四、会话(Session)的应用5.使用get方法装载对象使用load方法虽然能够装载对象,但是如果装配的对象不存在,load方法仍然会返回一个持久对象该持久对象除了标识属性外,访问器其他属性或者方式时,
24、都将抛出无法恢复的异常。这时可以使用get方法,当装配的对象不存在时将返回一个null值,这样就可以避免异常的出现。get方法有四种重载形式,其代码如下。public Object get(Class clazz,Serializable id)throws HibernateException;public Object get(String entityName,Serializable id)throws HibernateException;public Object get(String entityName,Serializable id,LockMode lockMode)thr
25、ows HibernateException;public Object get(Class clazz,Serializable id,LockMode lockMode)throws HibernateException;Java Web 程序设计与项目实践四、会话(Session)的应用6.使用refresh方法刷新对象使用refresh方法能够根据数据库中的数据来刷新持久对象中的属性值。get方法有两种重载形式,其代码如下。public void refresh(Object object)throws HibernateException;public void refresh(Ob
26、ject object,LockMode lockMode)throws HibernateException;其中object参数用来设置需要刷新的持久对象。Java Web 程序设计与项目实践四、会话(Session)的应用7.使用setFlushMode方法设置更新模式当持久对象的属性值发送变化后,Hibernate会根据情况自动将这些更新的属性值进行持久化。那到底是在什么情况下会进行自动更新呢?可以通过getFlushMode方法来获得当前的更新模式,也可以通过setFlushMode方法来修改默认的更新模式。getFlushMode方法和setFlushMode方法代码如下。publ
27、ic void setFlushMode(FlushMode flushMode);public FlushMode getFlushMode();其中flushMode参数用来设置更新模式,该参数有四个可选值,分别为FlushMode.MANUAL、FlushMode.COMMIT、FlushMode.AUTO、FlushMode.ALWAYS。Java Web 程序设计与项目实践四、会话(Session)的应用8.使用isDirty方法判断数据是否一致有时候我们需要判断当前更新的持久对象和数据库中的数据是否保持一致,这时就可以Session对象的isDirty方法完成该判断。isDirty
28、方法可以判断持久对象中的属性值是否和数据表中相应的字段的值保持一致。如果一致,返回false;否则,返回true。Java Web 程序设计与项目实践四、会话(Session)的应用9.使用delete方法删除记录可以使用Session对象的delete方法来删除数据库中的记录。delete方法有两个重载形式,其代码如下所示。public void delete(Object object)throws HibernateException;public void delete(String entityName,Object object)throws HibernateException;
29、其中object参数用来指定需要删除的持久对象,entityName参数用来设置实体类的类名。Java Web 程序设计与项目实践实训13.1模拟商场VIP系统1模拟商场VIP系统需求描述一个大型的商场为了能够留住客户,会采用一种VIP积分制度,客户购买的东西越多,那么其积分将越多。通过这些积分客户可以用来置换其他商品,或者抵消部分消费。一个商场VIP系统首先需要一个添加功能,从而接纳新的VIP顾客,还需要有一个更新功能,从而对VIP中的信息进行修改,比如用户购物后添加积分,消费积分后减少积分。还需要有一个删除功能,这样可根据需要对VIP信息进行删除。最后还需要有一个查询,可以根据VIP的ID
30、进行查询VIP信息。Java Web 程序设计与项目实践实训13.1模拟商场VIP系统2模块实现我们用如下表的文件,来实现“模拟商场VIP系统”的代码。Java Web 程序设计与项目实践实训13.1模拟商场VIP系统3功能测试运行VIPMain类,在控制台打印输出语句如下。-欢迎进行鸿鹏商城VIP消费信息1.注册VIP2.更新VIP3.删除VIP4.查询VIP-Java Web 程序设计与项目实践实训13.1模拟商场VIP系统3功能测试输出操作序号,比如1,这时表示需要注册VIP,需要输入VIP个各种信息,输入完成后将提交注册VIP记录成功,在控制台打印输出语句如下。请选择操作序号.1请输入VIP姓名:李琴请输入VIP年龄:20请输入VIP职业:小学教师注册VIP记录成功!