用Hibernate进行对象的持久化(z)
Hibernate作为数据持久化层的一种技术应用很广泛。现在就其中的知识点在读书过程中进行记录和总结。?这里主要考虑的一种数据的解决方案是:通过DAO(Data Accss Object)和ORM(Object Relational Mapping)实现数据的持久化操作。在这种数据持久化实现方案中,通过DAO来实现对Java对象与数据库中数据之间的相互转换,同时他还包括了数据库的连接管理、事务管理以及对象的缓冲管理等功能。 ?这种数据持久化解决方案的实现方法的示意图图下:业务层--->DAO--->ORM--->数据库?首先配置软件开发环境:JDK1.5,Tomcat5.0,MySQL5,Ant1.5,Eclipse3.1相关软件的下载地址见:http://blog.163.com/wyl_jxy/collection/?各种工具的配置和使用请参考相应的资料。?现在先简单介绍一下运用Hibernate进行Web应用开发的过程,为更深层次利用Hibernate工作打下基础。?当然不同的项目可以根据自身情况对设计过程进行适当的剪裁或补充。适合的就是最好的。不必拘泥与某一种方式步骤。?这里采用的开发顺序是先进行系统的建模以及实现系统模型的工作,接下来的工作是完成系统的配置文件和HBM文件(即映射文件),然后进行DAO的开发和测试工作,最后完成整个系统的页面处理部分。?设计、分析和实现持久层对象需要很多步骤来完成,下面一步一步来说明?首先,需要掌握如何确定一个应用程序的业务实体。在分析业务实体的过程中将会创建一系列概念上的模型,用这些模型对象来表示业务实体以及业务实体的属性,这样的模型被称为域模型。然后,使用Java语言实现这个域模型,也就是为每一个实体创建一个持久层的JAVA对象。然后,完成映射文件的定义工作。映射文件的主要作用就是描述这些java持久层对象以及他们的属性和数据库中的表以及表中的字段之间的关系。这样,Hibernate才能自动建立java对象与数据库中数据的关联关系,从而实现他们之间的转换。换言之,映射文件是为了把java对象和数据表以及数据字段关联。配置文件则定义的是如何连接数据库。接下来的步骤是进行DAO的定义和开发工作。通过DAO,可以完成对数据库进行的各种持久化操作以及在开发中所需实现的部分业务逻辑。最后的工作是完成JSP页面,通过对DAO的调用完成整个系统的所有功能。?映射文件的说明: 映射文件顶层是一个hibernate-mapping元素,定义了当前配置文件中映射关系的基本属性,也可以说它所定义的属性是对映射文件中所有子节点发挥作用的。 ?具体细节以后详述?配置文件的说明:Hibernate配置文件主要用来设置Hibernate的行为。他所描述的信息主要包括以下几个方面:?1.? 数据库的连接信息:在Hibernate中可以使用两种方式连接数据库。一种是根据JDBC的参数连接数据库,由Hibernate完成连接的过程和连接的管理。另一种方式是通过JNDI完成数据库的连接,Hibernate之间获取数据库的连接。?使用JDBC进行连接方式,需要对下列参数进行配置:hibernate.dialect指定数据库使用的SQL方言hibernate.connection.driver_class??指定数据库的驱动程序hibernate.connection.url指定数据库的URLhibernate.connection.username指定连接数据库的用户名hibernate.connection.password指定连接数据库的口令hibernate.show_sql如果为true,表示程序在运行时,会在控制台输入SQL语句,这有利于跟踪Hiberante的运行状态,默认为false。在应用开发和测试阶段,可以设这个属性为true,以便跟踪和测试程序,在应用开发阶段,应该把这个属性设为false,以便减少应用的输出信息,提高性能2 .数据库连接池的信息;3 .可选的配置项;4 .HBM(映射文件)列表;?
Hibernate核心接口
===========================================
Configuration:加载配置文件的。
configure()方法实现默认配置文件的加载.
SessionFactory:线程安全的。可以做成员变量使用.多个线程可以共用一个SessionFactory变量。
最好只创建一次。一个数据库对应一个SessionFactory
Session:不同于Connection。open一个session并不代表开启了一个Connection。只有需要用到时才到连接池去获取。Session还关联了缓存。Connection就仅仅是一个连接而已。用的时候绑定了Connection
Session在用完之后必须关闭。属于非线程安全的。(一个业务请求配对一个session,和事务一起操作,完成后session关闭。事务提交或者回滚).其生命周期最好和事务的生命周期一致
JNDI:Tomcat数据库连接池
JDBC:本地事务。只针对一个数据库有效。无语保证跨域数据库操作
JTA(Java 事务 API接口):实现数据库的跨资源操作。(容器,里边有很多连接,并且连接不同的数据库,JTA开启事务,如果执行都没问题,才将事务提交.)EJB默认使用JTA事务。
hibernate可以使用JTA事务,也可以使用JDBC,也可以访问tomcat连接池?使用Hibernate进行数据持久化操作的过程 ??使用Hibernate进行持久化操作主要需要以下步骤:STEP 1:创建Configuration对象。在这一步中主要为了进行配置文件的装载操作,读取所有的配置文件并进行解析 STEP 2: 创建SessionFactory对象。通过创建好的Configuration对象可以创建一个sessionFactory对象的实例,同时是生成Session对象实例的工厂,他在整个应用中应该是唯一的。STEP 3:创建Session对象。?Session对象类似于数据库的连接对象,可以理解为与数据库建立的一个连接,但是他的功能要比JDBC中的Connection对象丰富很多。STEP 4:开始一个事务。在Java中定义一个事务操作的开始,这是使用Hibernate进行持久化操作必不可少的步骤STEP 5:进行持久化操作。在这个步骤中可以读取或者保存Java对象。STEP 6:结束事务。在操作完成之后还要进行显式的结束事务的操作。STEP 7:关闭Session。类似于释放数据库的连接。?下面说最后一项DAO层的实现
DAO层的实现
?在完成了域模型的定义和配置工作之后,接下来要完成的工作就是定义DAO接口,并使用Hibernate来实现所定义的DAO接口。?当然直接使用Hibernate来访问数据库也是完全可以的,但是这种结构的系统会具有更好的灵活性。通过这种使用接口的编程方法,可以在方法的调用者和方法的实现者之间建立一个屏障,即他们之间不存在任何关联,一边的修改不会影响到另外一边的正确运行。例如现在所选择的持久化组件为Hibernate,过一段时间可能会有更好的持久化层组件出现,或者想直接采用JDBC来实现持久化层的操作,那么只需要修改具体的实现方法就可以了,而不需要对调用持久化层的业务处理方法进行任何修改。?DAO接口和DAO实现之间的关系:HibernateDAO,IUerDAO,UserDAO上述的三个*DAO是中(1)HibernteDAO是基础类,它包含了使用Hibernate进行持久化操作的一些基础方法。实现具体业务方法的DAO方法,通过继承这个类,可以在很大程度上简化持久化操作的步骤,减少代码的重复量。(2)IUerDAO是接口,定义了对对象User进行持久化操作的各种方法。只有接口定义,没有实现。具体有什么样的方法,完全取决于对象User。User是前面工作中定义的持久化对象。 注意:一个持久化对象对应一个DAO接口(3)UserDAO? 这个才是真正的DAO实现类。他集成了基础类,实现了DAO接口。一个实现类要实现对应的接口。?下面贴出几段代码可以根据上面的说明自己理解DAO:?提示:在Hibernate软件包的etc目录下,有一个hibernate.properties文件,它提供了连接各种关系数据库的配置代码样例???
??

??user.setPassword( "def" );
??// user仍然处于游离态??Session session = sessionFactory.openSession();
??Transaction tx = session.beginTransaction();
??// 此时user对象仍然是Transient状态
??session.save( user );
??// 此时,user对象已经被纳入了Hibernate的实体管理容器中,并转变为Persistent状态
??System.out.println( "User 1:" + user );
??// 此时的id已经有值了。
??get( user.getId() );
??// 但并未真正的执行数据库的操作,所以无法得到对象的值
??tx.commit();
??// 事务被提交后,将向数据库的用户表中插入一条记录
??System.out.println( "Transaction 1 commit!" );
??get( user.getId() );
??// 这时可以由数据库中得到刚才插入的user对象了。
??
??Transaction tx2 = session.beginTransaction();
??user.setPassword( "mmmmmmmmmmmmm" );
??tx2.commit();
??// 虽然这个事务中并没有调用Session的save()方法来保存user对象
??// 但由于user对象处于Persistent状态,所以对user对象所做的任何修改都将被持久化到数据库中
??// 那么数据库中的用户密码也应该变为了def。
??System.out.println( "Transaction 2 commit!" );
??session.close();??get( user.getId() );
??// 此时密码已经变为新的值了
?}
?
?public static User get( String id )
?{
??Session session = sessionFactory.openSession();
??Transaction tx = session.beginTransaction();
??
??User user = (User)session.get( User.class, id );
??// Hibernate在返回User对象之间会将其纳入到Hibernate的实体管理容器中
??// 所以,这时的user对象是Persistent状态的
??display( user );
??
??tx.commit();
??session.close();
??
??return user;
?}
?
?public static void display( Object obj )
?{
??System.out.println( obj );
?}
}
???(1)C3P0。这是Hiberante自身提供的。其文档地址见:www.mchange.com/projects/c3p0/index.html;有关Hibernte中配置c3p0的文档参考:www.hibernate.org/214.html?(2)DBCP:它是Apache软件基金组织的一个开源项目。由于在Hibernte3中不再提供DBCConnectionProvider类来直接使用DBCP建立数据库的连接池,在这里提供两种方法解决这个问题。一种是仿照Hibernate2中的DBCPConnectionProvider类自己实现一个使用DBCP并实现了ConnetcitonProvider接口的连接池类。另一种是让应用服务器通过JNDI的方式来提供数据库的连接,Hibernate通过JNDI得到数据库的连接。DBCP的详细信息见:http://jakarta.apache.org/commons/dbcp/。关于自己实现ConnectionProvider接口的方法见http://wiki.apache.org/jakarta-commons/DBCP/Hibernate
(3)Proxool:也是开放源代码的提供数据库连接池的组件。其官方网站为:http://proxool.sourceforge.net。有关配置的详细参数见官方网站