(转贴)Hibernate 存取及批量更新删除 作者: lian

            Hibernate 存取及批量更新删除

作者:冰莲如水

Hibernate是介于JAVA应用逻辑层与数据库层之间的一类开源的ORM中间件。ORM(即Object-Relation Mapping)从字面意义上讲就是对象-关系映射,ORM模式指的是在单个组件中负责所有实体域对象的持久化。其重点就在于把实体域对象通过一定规则上的映射机制,转化为数据库中所对应的记录,即持久化。为了更好的理解持久化,我们可以回想一下,以前所用到的通过JDBC API来对实体域对象实现的持久化。例如:

    Connetion con = null;

    PreparedStatement stmt = null;

     try{

        con = getConnection();

        con.setAutoCommit(false);

        stmt = con.prepareStatement(“insert into customers (ID, NAME, AGE) values (?,?,?)”);

        stmt.setLong(1, new Long(1));

        stmt.setString(2, new String(“ping”));

        stmt.setInt(3, new Integer(20));

        stmt.execute();

       }catch(SQLException sqlex){

           con.rollback();

         }catch(Exception e){

         …… }

        finally{

           try{

              stmt.close();

              con.close();

           }catch(Exception ex){

             …….

            }

          }

        }

 

相关资源

 

相关评论

标题: Hibernate 存取及批量更新删除  作者: lian  创建时间: 2005-08-30 01:57:52  最近更新: 2005-08-30 01:57:52  编辑  删除 

内容

     在上面的JDBC持久化模式中,业务逻辑层的过程域对象中业务逻辑和数据访问代码是混杂在一起的,并未能完全实现面向对象的编程思路,且程序结构不清晰,当关系数据模型发生变更时,软件的维护难度会大幅增加。而且这种模式中的SQL语句如果存在语法错误,在编译时是不能检查出来的,增加了调试程序时的难度。

    Hibernate的出现,将在业务逻辑层与数据库层之间再次构建出一个持久化层。Hibernate作为ORM中间件,封装了数据访问细节,我们只要通过Hibernate提供的对象-关系映射服务 ,便可在程序中实现域对象到关系数据的保存,或从数据库提取业务数据并转化为实体对象形式。

    对于要被持久化的JAVA对象,它在内存中的生命周期是从new语句创建了这个对象时开始,当不再有任何引用变量引用它时,这个对象的生命中期就将结束,所占用的内存将被JVM的垃圾回收器(GC)回收。 

相关资源 

标题: Hibernate 存取及批量更新删除  作者: lian  创建时间: 2005-08-30 01:58:57  最近更新: 2005-08-30 01:58:57  编辑  删除 

内容

  对于Hibernate所要操作的持久化对象,在它的生命周期中,可处于三种状态:

? 临时状态(transient): 用new语句新建的对象,还没有被持久化,此时它不处于任何的Hibernate 的Session之中。处于临时状态的JAVA对象被称为临时对象。

? 持久化状态(persistent):这类对象已经被持久化,已处于(被加入)Session的缓存中。处于持久化状态的JAVA对象被称为持久华对象。

? 游离状态(detached):已经被持久化,但不再处于Session(被扔出或是Session自行关闭了)的缓存当中。处于游离状态的JAVA对象被称为游离对象。

Session接口是Hibernate向应用程序提供的操作数据库的最主要的接口,它提供了基本的面向对象的保存,更新,删除和查询方法。它由SessionFactory工厂类创建。 

相关资源 

标题: Hibernate 存取及批量更新删除  作者: lian  创建时间: 2005-08-30 01:59:40  最近更新: 2005-08-30 01:59:40  编辑  删除 

内容

* Session 的save()方法:

    save()方法使一个临时对象转变为持久化对象。例如:

         Customer customer = new Customer();

         customer.setId( new Long(9));

         customer.setName(“Tom”);

         Session session = sessionFactory.openSession();

         Transaction tx = session.beginTransaction();

         Session.save(customer);

         tx.commit();

         session.close();

  Session 的save()方法所要注意的问题,1.在实际的对象持久化保存中,新建对象的ID应在此对象的类的映射文件中设置其生成方式,无需在程序中再对ID进行赋值。

例如以上的Customer类的映射文件Customer.hbm.xml中对ID生成方式的设置:

      <id name=”id” column=”ID”>

         <generator class=”increment”/>

      </id>

如果希望由应用程序来为新的对象指定ID,可以调用save()的另一个重载方法:

      save( customer, new Long(1));

   但此种方法在程序中不推荐使用。

2.在应用程序中不应该把持久化对象或游离对象传给save()方法。

 

相关资源 

标题: Hibernate 存取及批量更新删除  作者: lian  创建时间: 2005-08-30 02:00:47  最近更新: 2005-08-30 02:00:47  编辑  删除 

内容

* Session 的update()方法

     update()方法使一个游离对象转变为持久化对象。以下代码在session1中保存一个 Customer 对象,然后在session2中更新这个 Customer对象:

     Customer customer = new Customer();

     customer.setName(“Tom”);

     Session session1 = sessionFactory.openSession();

     Transaction tx1 = session1.beginTransaction();

     session1.save(customer);

     tx1.commit();

     session1.close(); // 此时Customer对象变为游离对象,因为session1已经关闭。

      

     Session session2 = sessionFactory.openSession();

     Transaction tx2 = session2.beginTransaction();

     costomer.setName(“Linda”); //在与session2关联之前修改Customer对象的属性,

                            //这不是必须的一步,你也可以不修改,或修改更多属性。

     session2.update(customer); //在session2中加载 customer游离对象,并使其再次转为

                           //持久化对象。

     customer.setName(“Jack”); //在与session2关联之后再次修改了Customer对象的属性,

     tx2.commit();

     session2.close(); 

相关资源 

标题: Hibernate 存取及批量更新删除  作者: lian  创建时间: 2005-08-30 02:01:52  最近更新: 2005-08-30 02:01:52  编辑  删除 

内容

在上面的例子中,customer先是被session1持久化后,session1关闭,customer变成

游离对象,再次与session2关联后,customer又变成持久对象。其中我们不厌其烦的修改Customer对象的属性,为了要证明当Customer对象与新的session2关联以后,修改了其属性,并不需要再次执行session2.save(customer),Session在清理缓存时,会根据最近一次的更新组装成update语句并执行数据库更新。

* Session的saveOrUpdate()方法

  saveOrUpdate()方法同时包含了save() 和update()方法的功能。如果传入的参数是临时对象,就调用save()方法;如果传入的是游离对象,就调用update()方法;如果传入的参数是持久化对象,就直接返回。以下的示例程序中,customer起初为游离对象, anotherCustomer起初为临时对象,session2的saveOrUpdate()方法分别将它们变为持久化对象:

     ……

Session session2 = sessionFactory.openSession();

Transaction tx2 = session2.beginTransaction();

Customer anotherCustomer = new Customer(); // anotherCustomer为临时对象

anotherCustomer.setName(“Tom”);

session2.saveOrUpdate(customer); //使customer游离对象被session2关联

session2.saveOrUpdate(anotherCustomer); //使anotherCustomer临时对象被session2关联

tx2.commit();

session2.close(); 

相关资源 

标题: Hibernate 存取及批量更新删除  作者: lian  创建时间: 2005-08-30 02:02:34  最近更新: 2005-08-30 02:02:34  编辑  删除 

内容

* Session 的load()和 get()方法

    load()和 get()方法都能根据给定的OID从数据库中加载一个持久化对象,这两个方法的区别在于:当数据库中不存在与对象的OID相同的记录时,load()方法抛出net.sf.hibernate.ObjectNotFoundException异常,而get()方法返回null。示例如下:

    Session session1 = sessionFactory.openSession();

    Transaction tx1 = session1.beginTransaction();

    Customer a = (Customer)session1.load(Customer.class, new Long(1));

    Customer b= (Customer)session1.get(Customer.class. new Long(2));

   

    tx1.commit();

    session1.close();

    当执行了session1.load(Customer.class, new Long(1))这样的代码以后,就把OID为1的Customer对象载到session1的缓存里。我们可以在tx1.commit()执行之前对加载后的Customer对象a进行属性的修改。这些修改并不会马上被执行,而是在Session清理缓存时,会根据持久化对象的属性变化来同步更新数据库。

 

相关资源 

标题: Hibernate 存取及批量更新删除  作者: lian  创建时间: 2005-08-30 02:03:27  最近更新: 2005-08-30 02:03:27  编辑  删除 

内容

*Session 的delete()方法

   delete()方法用于从数据库中删除与Java对象对应的记录。如果传入的参数是持久化对象,Session就计划执行一个delete语句。如果传入的参数是游离对象,先使游离对象被Session关联,使它变为持久化对象,然后计划执行一个delete语句。而真正的删除语句的执行是在Session清理缓存时。示例代码如下,首先加载了一个持久化对象,然后通过delete()方法将它删除。

     Session session1 = sessionFactory.openSession();

     Transaction tx1 = session1.beginTransaction();

     //加载一个持久化对象,因为Session 的get()和load()方法返回的永远是持久化对象。

     Customer customer = (Customer)session1.get(Customer.class, new Long(1));

     session1.delete(customer);

session1.close();

如果customer是游离对象时,下面的代码显示将此游离对象删除:

Session session2 = sessionFactory.openSession();

Transaction tx2 = session2.beginTransaction();

//在删除前,此游离对象customer先与session2关联,成为持久对象,然后将计划

//执行对其删除的SQL语句

session2.delete(customer);

tx2.commit();

session2.close();

 

相关资源 

标题: Hibernate 存取及批量更新删除  作者: lian  创建时间: 2005-08-30 02:04:17  最近更新: 2005-08-30 02:04:17  编辑  删除 

内容

关于Hibernate的批量检索,批量更新和批量删除,所执行的操作并不尽遵循相同的规律。这一点使目前的Hibernate2.0还显得有些不够规格化和强健。但以后的版本中,期望其可以突破这几个屏障。

   首先说明批量查询,我们已经了解到,Session 的load(), get() , find() 方法都可实现对业务数据的查询,其中load()会因所要查询的对象类的映射文件(比如Customer.hbm.xml文件)中设置的检索策略,而实现立即检索或延迟检索。get()方法和find()方法却不受这种控制,它们总是会执行立即检索。那么象load()这样的方法,当其被设置为使用延迟检索时,它会返回什么样的实例呢?当使用延迟检索时返回为这一对象的代理类实例,代理类实例也有一个标志性的OID, 但没有被实例化,其所有属性为默认初始值或为空。关于延迟检索和对象类的映射方式,这里不做多余解释。提到检索,load() 和get()方法都是用指定了OID的方式检索并返回一个与数据库中记录相对应的实例对象。如Customer customer = (Customer)session.get(Customer.class, new Long(1)) 将会返回一个Customer实例对象customer. 而 find()可以实现批量的检索,其返回类型为List的对象集合。例如:

     List customerList = session.find( “from Customer as c”);

注意,其中的”from Customer as c” 为HQL查询语句, Customer 并不是象普通的SQL语句中对表名的引用那样可以对大小写不敏感,这里的查询是基于对象类的,Customer为待查询的对象类,你要写正确你的类名,c是你为这个类在这里所取的别名。Hibernate是通过你对Customer这个对象类的映射文件Customer.hbm.xml中的设置得知此对象类与哪一个表对应。它可能正是对应了CUSTOMERS这个表。那么Hibernate又如何知道你所用的对象类与表的映射,到底是哪一个数据库中的表呢?这个对数据库名的映射是在Hibernate的配置文件hibernate.cfg.xml文件中给出的。相关的一些问题请查阅Hibernate的配置和映射章节。 

相关资源 

标题: Hibernate 存取及批量更新删除  作者: lian  创建时间: 2005-08-30 02:05:00  最近更新: 2005-08-30 02:05:00  编辑  删除 

内容

    以上的session.find( “from Customer as c”)方法,Hibernate最终会执行这样的SQL语句执行数据库的查询(立即检索方式):

    select * from CUSTOMERS ;

或者你也可以按如下的方式进行查询:

    List customerList = session.find(“from Customer as c where c.age > 24”);

最终Hibernate所执行的SQL语句为:

     select * from CUSTOMERS where AGE > 24 ;

如果担心一次检出Customer类对象的量会过大,可以在Customer.hbm.xml文件中设置一次批量检索的检出量batch-size:

    <class name=”mypack.Customer” table=”CUSTOMERS” batch-size=”4”>

对于一对一,一对多的关联也存在着集合(set. list ,bag, map)的延迟检索或立即检索,对于这种关联集合的检索,也存在着批量检索的设置,如在类的映射文件中的一对多的关联集合set中设置延迟检索时的批量检索尺寸:

   <class name=”mypack.customer” table=”CUSTOMERS”>

      ……..

      <set name=”topics” inverse=”true” lazy=”true” batch-size=”3”>

       …..

      </set>

   </class>

对于这类检索本文不做过多解释。有兴趣的读者可参阅Hibernate的关联映射与检索类型。

关于批量删除,可以采用Session 的delete()方法的重载形式,以HQL语句作为参数执行批量的删除:

    session.delete(“from Customer c where c.age > 24”) ;

  但是Hibernate最终并不会为我们构建这样的SQL并执行:

      select * from CUSTOMERS where AGE > 24 ;

  Session 的delete()方法首先通过以下select 语句把所有附合查询条件的Customer对象加载到内存中:select * from CUSTOMERS where AGE > 24 ;

  然后再逐一执行对这些对象的删除工作:

        delect from CUSTOMERS where ID = 1;

        delect from CUSTOMERS where ID = 2;

        delect from CUSTOMERS where ID = 3;

        …….

        delect from CUSTOMERS where ID = 10000; 

相关资源 

标题: Hibernate 存取及批量更新删除  作者: lian  创建时间: 2005-08-30 02:06:15  最近更新: 2005-08-30 02:06:15  编辑  删除 

内容

 这有可能造成对一万条数据的加载和逐一删除。如此将会严重消耗内存,影响系统性能。此时最佳的方案又回到了使用JDBC API执行批量的删除工作。在此我们暂不举其实例。

下面探讨在Hibernate中的批量更新。Hibernate中Session的update()方法的各种重载形式,一次都只能更新一个对象,那么我们可不可以使用Session 的find()方法先检索出要更新的所有的对象,再用轮询的方法逐一对其进更新呢?比如:

     Session session = sessionFactory.openSession();

     Transaction tx = session.beginTransaction();

     Iterator customers = session.find(“from Customer c where c.age >24”) .iterator() ;

     while(customers.hasNext()){

        Customer customer = (Customer)customers.next();

        customer.setAge(customer.getAge() + 1);

        session.flush();

        session.evict(customer);

     }

    tx.commit();

    session.close();

 以上的程序只是实现了批量检索并更新对象的目的,依旧没有注意内存的占用及系统的性能问题。我们还是回到原始却又是最有效的方法,使用JDBC API来实现业务数据的批量更新。幸好Hibernate只是对JDBC进行了轻量的封装,我们在程序中依旧可以引用JDBC API:

    …….

    tx = session.beginTransaction();

    Connection con = session.connection(); //取得当前session使用的数据库连接

    PreparedStatement stmt = con.prepareStatement(“update CUSTOMERS set AGE=AGE + 1 ” + “where AGE >24”);

    stmt.executeUpdate();

    tx.commit(); 

相关资源 

标题: Hibernate 存取及批量更新删除  作者: lian  创建时间: 2005-08-30 02:06:54  最近更新: 2005-08-30 02:06:54  编辑  删除 

内容

如果你使用的底层的数据库(如Oracle)支持存储过程,也可以通过存储过程来执行批量更新。Oracle中的存储过程的设置参考如下:

       create or replace procedure batchUpdateCustomer(p_age in number) as

         begin

            update CUSTOMERS set AGE = AGE + 1 where AGE > p_age ;

         end;

   上面的存储过程中的参数p_age代表一个数值型的传入参数,表示客户的年龄。我想你用它甚至可以查出一个上千年的老妖 :)

    在我们的应用程序中可以对这个存储过程进行如下的调用:

         ……..

tx = session.beginTransaction();

         Connection con = session.connection();

         String procedure = “ {call batchUpdateCustomer(?)}”;

         CallableStatement cstmt = con.prepareCall(procedure);

         cstmt.setInt(1, 24);

         cstmt.executeUpdate();

         tx.commit();

与此类同,Hibernate的批量删除也可以采用程序中调用JDBC API的方式,进行操作。你可以把上面的存储过程改一下,试着去执行它。

总结:Hibernate让我们在面对复杂多变的业务数据时,真正的体验到了面向对象编程的快意高效,但同时它自已也知道自身的不足之处在哪里,给我们留下了充分的空间去选择最适合的开发模式,而Hibernate为我们提供了对这些常规开发模式的支持。也许有一天,国人也能参与到这样经典的大型开源组件的设计当中去,做出我们引领时带的开源品牌,一同努力吧!这的确需要大部分人的努力和奉献。 

Hibernate 存取及批量更新删除

            Hibernate 存取及批量更新删除

作者:冰莲如水

Hibernate是介于JAVA应用逻辑层与数据库层之间的一类开源的ORM中间件。ORM(即Object-Relation Mapping)从字面意义上讲就是对象-关系映射,ORM模式指的是在单个组件中负责所有实体域对象的持久化。其重点就在于把实体域对象通过一定规则上的映射机制,转化为数据库中所对应的记录,即持久化。为了更好的理解持久化,我们可以回想一下,以前所用到的通过JDBC API来对实体域对象实现的持久化。例如:

    Connetion con = null;

    PreparedStatement stmt = null;

     try{

        con = getConnection();

        con.setAutoCommit(false);

        stmt = con.prepareStatement(“insert into customers (ID, NAME, AGE) values (?,?,?)”);

        stmt.setLong(1, new Long(1));

        stmt.setString(2, new String(“ping”));

        stmt.setInt(3, new Integer(20));

        stmt.execute();

       }catch(SQLException sqlex){

           con.rollback();

         }catch(Exception e){

         …… }

        finally{

           try{

              stmt.close();

              con.close();

           }catch(Exception ex){

             …….

            }

          }

        }

the hibernate data access test posted by "lian"

"lian" has posted an article about hibernate data access.

for convenience,I take all these six parts together as below:

目标标题 Eclipse开发环境下Hibernate持久层数据库存取测试(1)  作者: lian  创建时间: 2005-08-12 22:01:37  最近更新: 2005-08-12 22:01:37  我要评论  订阅邮件 

内容

日期:2005年7月29日

作者:binglian

联系方式:binglianrushui@sohu.com

          QQ:284508610

开发环境配置:Eclipse3.0.2, Hibernate2.0, MYSQL数据库。

              打开MYSQL Command Line Client(MYSQL 服务器的客户端交互程序),

              输入ROOT用户登录密码。即你在安装MYSQL服务器时,为ROOT用户设置

              的密码。显示登录成功。创建数据库,此处命名为:learndiary. 输入

              use learndiary,起用此数据库; 注意以分号结尾。创建表:temp.

              表中包括的字段为:

              id bigint, name char(15), value char(30), description text.

              将hibernate.jar, hibernate-tools.jar包考贝到你所要测试的项目的lib

              目录下。如果你想为你的测试程序加入日志追踪,将common-logging.jar

              也考入lib目录下。 

目标标题 Eclipse开发环境Hibernate持久层数据库存取测试(2)  作者: lian  创建时间: 2005-08-12 22:04:49  最近更新: 2005-08-12 22:04:49  我要评论  订阅邮件 

内容

配置MYSQL驱动程序:将MYSQL驱动的jar包考贝到你所要测试的项目的lib

              目录下,并将其路径设置为系统的环境变量,即设置CLASSPATH值,包含此

              驱动程序的路径,本例中设置如下:

               CLASSPATH值 G:\Eclipse3.1Workspace\LearnDiaryV1.0\web\WEB-INF\lib

              如果你拥有一套JBuilder开发工具,打开它,测试你的MYSQL在开发环境中

              是否可以正确连接。点击JBuilder->tool->DataBase pilot,在窗口中新建

              一个到数据库learndiary的连接。设置驱动程序名和MYSQL服务器链接地址:

              driver name:com.mysql.jdbc.Driver ;

              database url:dbc:mysql://localhost:3306/learndiary

              如果你的MYSQL数据库位于同一域中的另一台机器上,将localhost替换为

              另一台机器的地址,如192.168.1.12, 3306为默认的访问MYSQL服务的端口

              号。接下来设置user name:root, 选中extended properties复选框,点击

              properties栏,在出现的对话框内选择add new , 点击左侧的name,value,

              依次输入:password, 1234, 双击required.保存退出。在DataBase pielot

              对话框内左侧点击MYSQL的+号,出现数据库连接中的动画。稍后数据库连接

              成功,右击MYSQL连接,选择CLOSE,关闭刚才的连接。退出JBuilder. 

目标标题 Eclipse开发环境Hibernate持久层数据库存取测试(3)  作者: lian  创建时间: 2005-08-12 22:05:48  最近更新: 2005-08-12 22:05:48  我要评论  订阅邮件 

内容

以上设置为开发前的预配置。下面为Eclipse开发过程中的类及文件的创建和配置。

首先创建一个新的项目。如果是新建了一个WEB Project, 可以SRC下,设置你所要的包名。此处简化为mypackage.

在这个包名下,创建一个你用以施行持久层测试的测试类,我们把它命名为:ORMService.java ,在此之前,你可

以先创建基于数据库中temp 表的Temp.java类。 Temp.java的代码如下:

/*

 * Created on 2005-7-27

 *本类用以对MYSQL数据库的测试

 *持久层组件为Hibernate

 */

package com.learndiary.website.module.beans;

import java.io.Serializable;

/**

 * @author binglian

 *本类的hbm映射文件为:Temp.hbm

 */

public class Temp implements Serializable{

private Long id;

private String name;

private String value;

private String description;

public Temp(){

}

public Temp( String Vname, String Vvalue, String Vdescription){

this.name = Vname;

this.value =Vvalue;

this.description = Vdescription;

}

/**

* @return Returns the description.

*/

public String getDescription() {

return description;

}

/**

* @param description The description to set.

*/

public void setDescription(String description) {

this.description = description;

}

/**

* @return Returns the id.

*/

public Long getId() {

return id;

}

/**

* @param id The id to set.

*/

public void setId(Long id) {

this.id = id;

}

/**

* @return Returns the name.

*/

public String getName() {

return name;

}

/**

* @param name The name to set.

*/

public void setName(String name) {

this.name = name;

}

/**

* @return Returns the value.

*/

public String getValue() {

return value;

}

/**

* @param value The value to set.

*/

public void setValue(String value) {

this.value = value;

}



目标标题 Eclipse开发环境Hibernate持久层数据库存取测试(4)  作者: lian  创建时间: 2005-08-12 22:06:58  最近更新: 2005-08-12 22:06:58  我要评论  订阅邮件 

内容

再为Temp.java到数据库中的temp表做映射,映射文件名为Temp.hbm.xml,请注意书写正确的映射文件名,

Temp.hbm.xml如下:

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping

PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping>

  <class name="com.learndiary.website.module.beans.Temp" table="TEMP" >

    <cache usage="read-write"/>

    <id name="id" type="long" column="ID">

      <generator class="increment" />

    </id>

    <property name="name" type="string" >

      <column name="NAME" length="15"/>

    </property>

    <property name="value" type="string" >

      <column name="VALUE" length="30" />

    </property>

    <property name="description" type="string" >

      <column name="DESCRIPTION" />

    </property>

  </class>

</hibernate-mapping>

   其中:<id name="id" type="long" column="ID">

      <generator class="increment" />

    </id>

   这一段中的 <generator class="increment" />指定temp表的 id的设置,不由应用程序设置,由MYSQL数据库

   中的内置序列号增长器控制生成序列号。即数据库将根据每次插入的记录,自动为其生成序列号。我们在执行

   Hibernate的持久层操作,对新建的Temp类对象进行持久化保存时,也不要为这个新的对象设置其id 值。 

目标标题 Eclipse开发环境Hibernate持久层数据库存取测试(5)  作者: lian  创建时间: 2005-08-12 22:07:50  最近更新: 2005-08-12 22:07:50  我要评论  订阅邮件 

内容

回到我们刚才提到的ORMService类,我们将在这个类中调用Hibernate的持久化操作,将一个新的Temp类对象

存入数据库中。这一切都是由Hibernate经由我们为temp配置的映射文件,调用其session.save(temp)操作,

在后台执行的数据库插入动作,并不由我们费力的创建显示的connection链接并书写insert语名。

ORMService类的代码如下:

package com.learndiary.website.services;

import javax.servlet.ServletContext;

import net.sf.hibernate.*;

import net.sf.hibernate.cfg.Configuration;

import net.sf.hibernate.SessionFactory;

import net.sf.hibernate.Session;

import net.sf.hibernate.Transaction;

import java.sql.Connection;

import java.io.File;

public class ORMService {

ServletContext context = null;

private static SessionFactory sessionFactory =null;

//用以测试MYSQL数据库连接的方法

public void initSessionFactory(){

try{

File file = new File("g:\\Eclipse3.1Workspace\\LearnDiaryV1.0\\web\\WEB-INF\\src\\hibernate.cfg.xml");

Configuration cfg = new Configuration().configure(file);

SessionFactory factory = cfg.buildSessionFactory();

sessionFactory = factory;

if(sessionFactory ==null){

System.out.println("sessionFactory is null!");

}

}catch(Exception ex){

ex.printStackTrace();

}

}

public boolean saveTempData(){

boolean success = false;

String name = "binglian";

String value = "coding girl";

String description ="programer";

Session session =null;

Transaction tr =null;

try{

Temp temp = new Temp(name, value, description);

if(sessionFactory !=null){

session = sessionFactory.openSession();

tr = session.beginTransaction();

Connection con = session.connection();

if(con !=null){

session.save(temp);

session.flush();

}else{

System.out.println("the connection is null!");

}

tr.commit();

success = true;

}else{

System.out.println("the sessionFactory is null");

}

}catch(Exception eg){

try{

if(tr !=null) {tr.rollback();}

}catch(Exception eh){

eh.printStackTrace();

}

eg.printStackTrace();

System.out.println("session save failed!");

}finally{

try{

session.close();

}catch(Exception em){

em.printStackTrace();

}

}

return success;

}

        public static void main(String args[]){

ORMService ser = new ORMService();

ser.initSessionFactory();

boolean saved = ser.saveTempData();

System.out.println("data has " + saved + " saved!");

}

           

目标标题 Eclipse开发环境Hibernate持久层数据库存取测试(6)  作者: lian  创建时间: 2005-08-12 22:08:33  最近更新: 2005-08-12 22:08:33  我要评论  订阅邮件 

内容

当你看过这一段代码后,我们再回过头来讲解一下:

  File file = new File("g:\\Eclipse3.1Workspace\\LearnDiaryV1.0\\web\\WEB-INF\\src\\hibernate.cfg.xml");

  Configuration cfg = new Configuration().configure(file);

Configuration类负责管理Hibernate的配置信息,当调用new Configuration().configure()时,默认的Hibernate会在

当前的CLASSPATH中搜寻hibernate.cfg.xml并将其加载至内存中,作为后继操作的基础配置。我们也可以替换使用

hibernate.properties这个文件,但此文件在配置条目上,不及hibernate.cfg.xml丰富灵活,此处我们选用hibernate.cfg.xml

作为配置文件。在LearnDiaryV1.0\web\WEB-INF\src目录下创建这个hibernate.cfg.xml文件,当然你也可以把它放在mypackage包

下或其它你想要找到它的地方,重要的是你要把它的绝对路径放在上面所示的FILE类下:

    new File("g:\\Eclipse3.1Workspace\\LearnDiaryV1.0\\web\\WEB-INF\\src\\hibernate.cfg.xml");

请注意正确的路径书写样式,采用"\\"表示下一级路径。

调试运行你的程序,选中窗口内的ORMService,点击工具栏中的运行图标,以Java application程序运行,注意下方的

Consle控制台输入信息,显示:

  Hibernate: insert into TEMP (NAME, VALUE, DESCRIPTION, ID) values (?, ?, ?, ?)

data has true saved!

以上英文信息很粗劣,你可以添加更正为你的正确的输出信息。本例省略了log日志创建代码。

关于Hibernate的持久化组件实现细节的解释,请详见Learndiary开发方案及相关的Hibernate教程。

初你的工作顺利,成功!

                                    冰莲如水。 

Eclipse开发环境Hibernate持久层数据库存取测试(6

当你看过这一段代码后,我们再回过头来讲解一下:

  File file = new File("g:\\Eclipse3.1Workspace\\LearnDiaryV1.0\\web\\WEB-INF\\src\\hibernate.cfg.xml");

  Configuration cfg = new Configuration().configure(file);

Configuration类负责管理Hibernate的配置信息,当调用new Configuration().configure()时,默认的Hibernate会在

当前的CLASSPATH中搜寻hibernate.cfg.xml并将其加载至内存中,作为后继操作的基础配置。我们也可以替换使用

hibernate.properties这个文件,但此文件在配置条目上,不及hibernate.cfg.xml丰富灵活,此处我们选用hibernate.cfg.xml

作为配置文件。在LearnDiaryV1.0\web\WEB-INF\src目录下创建这个hibernate.cfg.xml文件,当然你也可以把它放在mypackage包

下或其它你想要找到它的地方,重要的是你要把它的绝对路径放在上面所示的FILE类下:

    new File("g:\\Eclipse3.1Workspace\\LearnDiaryV1.0\\web\\WEB-INF\\src\\hibernate.cfg.xml");

请注意正确的路径书写样式,采用"\\"表示下一级路径。

调试运行你的程序,选中窗口内的ORMService,点击工具栏中的运行图标,以Java application程序运行,注意下方的

Consle控制台输入信息,显示:

  Hibernate: insert into TEMP (NAME, VALUE, DESCRIPTION, ID) values (?, ?, ?, ?)

data has true saved!

以上英文信息很粗劣,你可以添加更正为你的正确的输出信息。本例省略了log日志创建代码。

关于Hibernate的持久化组件实现细节的解释,请详见Learndiary开发方案及相关的Hibernate教程。

初你的工作顺利,成功!

                                    冰莲如水。

Eclipse开发环境Hibernate持久层数据库存取测试(5

回到我们刚才提到的ORMService类,我们将在这个类中调用Hibernate的持久化操作,将一个新的Temp类对象

存入数据库中。这一切都是由Hibernate经由我们为temp配置的映射文件,调用其session.save(temp)操作,

在后台执行的数据库插入动作,并不由我们费力的创建显示的connection链接并书写insert语名。

ORMService类的代码如下:

package com.learndiary.website.services;

import javax.servlet.ServletContext;

import net.sf.hibernate.*;

import net.sf.hibernate.cfg.Configuration;

import net.sf.hibernate.SessionFactory;

import net.sf.hibernate.Session;

import net.sf.hibernate.Transaction;

import java.sql.Connection;

import java.io.File;

public class ORMService {

ServletContext context = null;

private static SessionFactory sessionFactory =null;

//用以测试MYSQL数据库连接的方法

public void initSessionFactory(){

try{

    File file = new File("g:\\Eclipse3.1Workspace\\LearnDiaryV1.0\\web\\WEB-INF\\src\\hibernate.cfg.xml");

Configuration cfg = new Configuration().configure(file);

SessionFactory factory = cfg.buildSessionFactory();

sessionFactory = factory;

if(sessionFactory ==null){

System.out.println("sessionFactory is null!");

}

}catch(Exception ex){

ex.printStackTrace();

}

}

public boolean saveTempData(){

boolean success = false;

String name = "binglian";

String value = "coding girl";

String description ="programer";

Session session =null;

Transaction tr =null;

try{

Temp temp = new Temp(name, value, description);

if(sessionFactory !=null){

session = sessionFactory.openSession();

tr  = session.beginTransaction();

Connection con = session.connection();

if(con !=null){

session.save(temp);

session.flush();

}else{

System.out.println("the connection is null!");

}

tr.commit();

success = true;

}else{

System.out.println("the sessionFactory is null");

}

}catch(Exception eg){

try{

if(tr !=null) {tr.rollback();}

}catch(Exception eh){

eh.printStackTrace();

}

eg.printStackTrace();

System.out.println("session save failed!");

}finally{

try{

session.close();

}catch(Exception em){

em.printStackTrace();

}

}

return success;

}

   

       public static void main(String args[]){

ORMService ser = new ORMService();

ser.initSessionFactory();

boolean saved = ser.saveTempData();

System.out.println("data has " + saved + " saved!");

}        

           

Eclipse开发环境Hibernate持久层数据库存取测试(4

再为Temp.java到数据库中的temp表做映射,映射文件名为Temp.hbm.xml,请注意书写正确的映射文件名,

Temp.hbm.xml如下:

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping

PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping>

  <class name="com.learndiary.website.module.beans.Temp" table="TEMP" >

    <cache usage="read-write"/>

    <id name="id" type="long" column="ID">

      <generator class="increment" />

    </id>

    <property name="name" type="string" >

      <column name="NAME" length="15"/>

    </property>

    <property name="value" type="string" >

      <column name="VALUE" length="30" />

    </property>

    <property name="description" type="string" >

      <column name="DESCRIPTION"  />

    </property>

  </class>

</hibernate-mapping>

   其中:<id name="id" type="long" column="ID">

      <generator class="increment" />

    </id>

   这一段中的  <generator class="increment" />指定temp表的 id的设置,不由应用程序设置,由MYSQL数据库

   中的内置序列号增长器控制生成序列号。即数据库将根据每次插入的记录,自动为其生成序列号。我们在执行

   Hibernate的持久层操作,对新建的Temp类对象进行持久化保存时,也不要为这个新的对象设置其id 值。

Eclipse开发环境Hibernate持久层数据库存取测试(3

以上设置为开发前的预配置。下面为Eclipse开发过程中的类及文件的创建和配置。

首先创建一个新的项目。如果是新建了一个WEB Project, 可以SRC下,设置你所要的包名。此处简化为mypackage.

在这个包名下,创建一个你用以施行持久层测试的测试类,我们把它命名为:ORMService.java ,在此之前,你可

以先创建基于数据库中temp 表的Temp.java类。 Temp.java的代码如下:

/*

 * Created on 2005-7-27

 *本类用以对MYSQL数据库的测试

 *持久层组件为Hibernate

 */

package com.learndiary.website.module.beans;

import java.io.Serializable;

/**

 * @author binglian

 *本类的hbm映射文件为:Temp.hbm

 */

public class Temp implements Serializable{

private Long id;

private String name;

private String value;

private String description;

public Temp(){

}

public Temp( String Vname, String Vvalue, String Vdescription){

this.name = Vname;

this.value =Vvalue;

this.description = Vdescription;

}

/**

* @return Returns the description.

*/

public String getDescription() {

return description;

}

/**

* @param description The description to set.

*/

public void setDescription(String description) {

this.description = description;

}

/**

* @return Returns the id.

*/

public Long getId() {

return id;

}

/**

* @param id The id to set.

*/

public void setId(Long id) {

this.id = id;

}

/**

* @return Returns the name.

*/

public String getName() {

return name;

}

/**

* @param name The name to set.

*/

public void setName(String name) {

this.name = name;

}

/**

* @return Returns the value.

*/

public String getValue() {

return value;

}

/**

* @param value The value to set.

*/

public void setValue(String value) {

this.value = value;

}

}

Eclipse开发环境Hibernate持久层数据库存取测试(2

配置MYSQL驱动程序:将MYSQL驱动的jar包考贝到你所要测试的项目的lib

              目录下,并将其路径设置为系统的环境变量,即设置CLASSPATH值,包含此

              驱动程序的路径,本例中设置如下:

               CLASSPATH值 G:\Eclipse3.1Workspace\LearnDiaryV1.0\web\WEB-INF\lib

              如果你拥有一套JBuilder开发工具,打开它,测试你的MYSQL在开发环境中

              是否可以正确连接。点击JBuilder->tool->DataBase pilot,在窗口中新建

              一个到数据库learndiary的连接。设置驱动程序名和MYSQL服务器链接地址:

              driver name:com.mysql.jdbc.Driver ;    

              database url:dbc:mysql://localhost:3306/learndiary

              如果你的MYSQL数据库位于同一域中的另一台机器上,将localhost替换为

              另一台机器的地址,如192.168.1.12, 3306为默认的访问MYSQL服务的端口

              号。接下来设置user name:root,  选中extended properties复选框,点击

              properties栏,在出现的对话框内选择add new , 点击左侧的name,value,

              依次输入:password, 1234, 双击required.保存退出。在DataBase pielot

              对话框内左侧点击MYSQL的+号,出现数据库连接中的动画。稍后数据库连接

              成功,右击MYSQL连接,选择CLOSE,关闭刚才的连接。退出JBuilder.

Eclipse开发环境下Hibernate持久层数据库存取测�

日期:2005年7月29日

作者:binglian

联系方式:binglianrushui@sohu.com

          QQ:284508610

开发环境配置:Eclipse3.0.2, Hibernate2.0, MYSQL数据库。

              打开MYSQL Command Line Client(MYSQL 服务器的客户端交互程序),

              输入ROOT用户登录密码。即你在安装MYSQL服务器时,为ROOT用户设置

              的密码。显示登录成功。创建数据库,此处命名为:learndiary. 输入

              use learndiary,起用此数据库; 注意以分号结尾。创建表:temp.

              表中包括的字段为:

              id bigint, name char(15), value char(30), description text.

              将hibernate.jar, hibernate-tools.jar包考贝到你所要测试的项目的lib

              目录下。如果你想为你的测试程序加入日志追踪,将common-logging.jar

              也考入lib目录下。