零基础学Struts
上QQ阅读APP看书,第一时间看更新

13.2 Hibernate开发入门

通过使用Hibernate框架,开发者可以使用面向对象的方式来进行数据库访问,从而取代JDBC进行数据库访问。通过使用Hibernate框架,Web应用可以以面向对象的方式来进行数据库的各种访问操作,如插入数据、更新数据、删除数据、查询数据等。

13.2.1 创建Hibernate配置文件

Hibernate从其配置文件中读取和数据库有关的信息。Hibernate的配置文件分为两种:一种是XML格式的配置文件;还有一种是资源文件格式的配置文件。

下面创建XML格式的配置文件,其文件名为“hibernate.cfg.xml”。在该配置文件中可以配置数据库连接URL和数据库连接驱动与数据库用户名以及用户密码。这里还配置一个属性dialect,该属性用来指定数据库产品类型,因为这里使用的是MySQL数据库,所以设置其属性值为org.hibernate.dialect. MySQL Dialect,代码如下所示。

        <! DOCTYPE hibernate-configuration PUBLIC
            "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
            "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
        <hibernate-configuration>
        <session-factory>
            <! -- 数据库连接URL -->
            <property name="connection.url">
                    jdbc:mysql://localhost/mystruts2
            </property>
            <! -- 数据库连接驱动 -->
            <property name="connection.driver_class">
                    com.mysql.jdbc.Driver
            </property>
            <! -- 数据库用户名 -->
            <property name="connection.username">root</property>
            <! -- 数据库用户密码 -->
            <property name="connection.password">root</property>
            <! -- 数据库方言 -->
            <property name="dialect">
                    org.hibernate.dialect.MySQLDialect
            </property>
        </session-factory>
        </hibernate-configuration>

13.2.2 创建持久化类

持久化类是一个POJO类,不用继承和实现任何类或接口。该类中包含3个属性:id、name、price,分别表示产品ID、产品名称以及产品价格。为这3个属性添加setter和getter方法,代码如下所示。

        package net.hncu.hibernate;
        public class Product {
              //产品ID
              private String id;
              //产品名称
              private String name;
              //产品价格
              private double price;
              //各属性的settergetter方法
              public String getId() {
                    return id;
              }
              public void setId(String id) {
                    this.id = id;
              }
              public String getName() {
                    return name;
              }
              public void setName(String name) {
                    this.name = name;
              }
              public double getPrice() {
                    return price;
              }
              public void setPrice(double price) {
                    this.price = price;
              }
        }

13.2.3 创建对象关系映射文件

关系映射文件用来映射持久化类和数据库表,从而将持久化类中的属性和数据库表中的字段关联起来。其中id元素用来定义主键标识,property元素用来定义其他属性。如果不指定数据库表中字段,则默认使用持久化类中的属性作为其数据表表字段名称。

该映射文件的文件名一般采用持久化类名加上“hbm.xml”的形式,代码如下所示。文件保存在持久化类同目录下。

        <? xml version="1.0"? >
        <! DOCTYPE hibernate-mapping PUBLIC
            "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
            "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
        <hibernate-mapping>
              <! -- 每个class对应一个持久化对象 -->
              <class name="net.hncu.hibernate.Product">
                    <! -- id元素用来定义主键标识,并指定主键生成策略 -->
                    <id name="id">
                          <generator class="assigned"></generator>
                    </id>
                    <! -- 定义其他属性 -->
                    <property name="name"></property>
                    <property name="price"></property>
              </class>
        </hibernate-mapping>

要使得映射文件起作用,还必须在Hibernate配置文件中配置该映射文件,代码如下所示。

        <! -- 指定映射文件 -->
        <mapping resource="net/hncu/hibernate/Product.hbm.xml"/>

13.2.4 创建数据库表

以前开发Web应用,都是先创建数据库表,然后再使用JDBC来进行操作。现在将思想转变一下,不创建数据库,而是通过Hibernate来自动创建数据库表,并根据持久化类的属性名来作为数据库表的字段名。

新建一个Java应用程序,通过SchemaExport实例的create()方法来创建数据库表,代码如下所示。

        package net.hncu.hibernate;
        import org.hibernate.cfg.Configuration;
        import org.hibernate.tool.hbm2ddl.SchemaExport;
        public class CreateDB {
              public static void main(String[] args) {
                    //读取配置文件hibernate.cfg.xml
                    Configuration cfg = new Configuration().configure();
                    //创建SchemaExport实例
                    SchemaExport sExport = new SchemaExport(cfg);
                    //创建数据库表
                    sExport.create(true, true);
            }
        }

运行该Java应用程序,可以看到在控制台打印出创建数据库表的SQL语句,代码如下所示。

        drop table if exists Product
        create table Product (
              id varchar(255) not null,
              name varchar(255),
              price double precision,
              primary key (id)
        )

在MySQL控制台中输入“desc product; ”命令可以看到该表的字段名称以及其他信息,如图13.4所示。

图13.4 查看表字段

13.2.5 插入数据

下面使用Hibernate来插入一条数据。首先来看完成数据库操作需要哪些步骤。

(1)获得Configuration实例。

(2)通过Configuration实例调用其buildSession-Factory()方法来获得SessionFactory实例。

(3)通过SessionFactory实例调用openSession()方法来获得Session实例。

(4)通过Session实例开启事务。

(5)通过Session实例调用其方法完成面向对象方式的数据库操作。

(6)通过Session实例的getTransaction()获得当前事务并关闭。

(7)关闭Session。

根据上述操作实现新建Java应用程序以实现插入数据的操作,代码如下所示。

          package net.hncu.hibernate;
          import org.hibernate.Session;
          import org.hibernate.SessionFactory;
          import org.hibernate.cfg.Configuration;
          public class InsertProduct {
                public static void main(String[] args) {
                      //读取配置文件hibernate.cfg.xml
                      Configuration cfg = new Configuration().configure();
                      //创建SessionFactory
                      SessionFactory factory = cfg.buildSessionFactory();
                      //创建Session
                      Session session = factory.openSession();
                      //开启事务
                      session.beginTransaction();
                      //实例化一个Product
                      Product product = new Product();
                      product.setId("0511234");
                      product.setName("发电机");
                      product.setPrice(888.88);
                      //保存数据
                      session.save(product);
                      //事务提交
                      session.getTransaction().commit();
                      //关闭session
                      if(session.isOpen()) {
                              session.close();
                      }
                }
          }

运行该Java应用程序。在MySQL控制台中输入“select * from product; ”命令可以看到,数据成功地插入到product表中,如图13.5所示。

图13.5 查看表中数据

13.2.6 更新数据

更新数据操作和插入数据操作非常类似,调用Session对象的update()方法即可将数据更新。新建Java应用程序实现更新数据,用来修改产品的价格,代码如下所示。

          package net.hncu.hibernate;
          import org.hibernate.Session;
          import org.hibernate.SessionFactory;
          import org.hibernate.cfg.Configuration;
          public class UpdateProduct {
                public static void main(String[] args) {
                      //读取配置文件hibernate.cfg.xml
                      Configuration cfg = new Configuration().configure();
                      //创建SessionFactory
                      SessionFactory factory = cfg.buildSessionFactory();
                      //创建Session
                      Session session = factory.openSession();
                      //开启事务
                      session.beginTransaction();
                      //实例化一个Product
                      Product product = new Product();
                      product.setId("0511234");
                      product.setName("发电机");
                      product.setPrice(1888.88);
                      //更新数据
                      session.update(product);
                      //事务提交
                      session.getTransaction().commit();
                      //关闭session
                      if(session.isOpen()) {
                              session.close();
                      }
                }
          }

运行该Java应用程序。在MySQL控制台中输入“select * from product; ”命令可以看到数据成功地更新了,如图13.6所示。

图13.6 查看表中数据

13.2.7 删除数据

删除数据操作和插入数据操作也非常类似,调用Session对象的delete ()方法即可将数据删除。新建Java应用程序实现删除数据的操作,代码如下所示。

          package net.hncu.hibernate;
          import org.hibernate.Session;
          import org.hibernate.SessionFactory;
        import org.hibernate.cfg.Configuration;
        public class deleteProduct {
              public static void main(String[] args) {
                    //读取配置文件hibernate.cfg.xml
                    Configuration cfg = new Configuration().configure();
                    //创建SessionFactory
                    SessionFactory factory = cfg.buildSessionFactory();
                    //创建Session
                    Session session = factory.openSession();
                    //开启事务
                    session.beginTransaction();
                    //实例化一个Product
                    Product product = new Product();
                    product.setId("0511234");
                    product.setName("发电机");
                    product.setPrice(1888.88);
                    //删除数据
                    session.delete(product);
                    //事务提交
                    session.getTransaction().commit();
                    //关闭session
                    if(session.isOpen()) {
                            session.close();
                    }
              }
        }

运行该Java应用程序。在MySQL控制台中输入“select * from product; ”命令可以看到,数据被成功地删除了,如图13.7所示。

图13.7 查看表中数据

同样可以使用HQL查询语句来实现按ID删除,代码如下所示。

        package net.hncu.hibernate;
        import org.hibernate.Query;
        import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.cfg.Configuration;
    public class deleteProductByid
          public static void main(String[] args) {
                //读取配置文件hibernate.cfg.xml
                Configuration cfg = new Configuration().configure();
                //创建SessionFactory
                SessionFactory factory = cfg.buildSessionFactory();
                //创建Session
                Session session = factory.openSession();
                //开启事务
                session.beginTransaction();
                // 使用HQL查询
                String hql = "DELETE Product WHERE id=? ";
                Query q = session.createQuery(hql);
                q.setString(0, "0511234");
                q.executeUpdate();
                //事务提交
                session.getTransaction().commit();
                //关闭session
                if(session.isOpen()) {
                    session.close();
                }
          }
    }

13.2.8 查询数据

同样可以使用HQL查询语句来实现查询所有数据,代码如下所示。

    package net.hncu.hibernate;
    import java.util.Iterator;
    import java.util.List;
    import org.hibernate.Query;
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.cfg.Configuration;
    public class QueryAllProduct {
          public static void main(String[] args) {
                // 读取配置文件hibernate.cfg.xml
                Configuration cfg = new Configuration().configure();
                // 创建SessionFactory
                      SessionFactory factory = cfg.buildSessionFactory();
                      // 创建Session
                      Session session = factory.openSession();
                      Product p = null;
                      // 使用HQL查询
                      String hql = "FROM Product as pro";
                      // 通过Query方法查询
                      Query q = session.createQuery(hql);
                      //查询结果保存到list
                      List list = q.list();
                      //遍历是否存在该id的产品,如果存在则进行输出
                      Iterator iter = list.iterator();
                      while(iter.hasNext()) {
                          p = (Product) iter.next();
                          System.out.println("id:" + p.getId() + " name:" + p.getName() + "  price:" + p.getPrice());
                      }
                      // 关闭session
                      if(session.isOpen()) {
                              session.close();
                      }
              }
          }

为了能够查询到数据,首先应插入多条数据。运行该Java应用程序,在控制台打印输出了所有的产品信息,代码如下所示。

        id:0511234 name:发电机   price:888.88
        id:0511235 name:电视机   price:988.0
        id:0511236 name:冰箱   price:1250.0

同样可以使用HQL查询语句来实现按ID查询数据,代码如下所示。

        package net.hncu.hibernate;
        import java.util.Iterator;
        import java.util.List;
        import org.hibernate.Query;
        import org.hibernate.Session;
        import org.hibernate.SessionFactory;
        import org.hibernate.cfg.Configuration;
        public class QueryProductByid {
              public static void main(String[] args) {
                    // 读取配置文件hibernate.cfg.xml
                    Configuration cfg = new Configuration().configure();
                    // 创建SessionFactory
                    SessionFactory factory = cfg.buildSessionFactory();
                    // 创建Session
                    Session session = factory.openSession();
                    // 使用HQL查询
                    String hql = "FROM Product as pro WHERE pro.id=? ";
                    // 通过Query方法查询
                    Query q = session.createQuery(hql);
                    q.setString(0, "0511234");
                    //查询结果保存到list
                    List list = q.list();
                    //遍历是否存在该id的产品,如果存在则进行输出
                    Iterator iter = list.iterator();
                    if(iter.hasNext()) {
                          Product p = (Product) iter.next();
                          System.out.println("id:" + p.getId() + " name:" + p.getName() + "  price:" + p.getPrice());
                    }
                    // 关闭session
                    if(session.isOpen()) {
                            session.close();
                    }
              }
        }

运行该Java应用程序,在控制台打印输出了该ID的产品信息,代码如下所示。

        id:0511234 name:发电机   price:888.88

13.2.9 使用Hibernate工具类

在前面的应用中,每次都是通过获得Configuration实例,并通过Configuration实例调用其buildSessionFactory()方法来获得SessionFactory实例。然后再通过SessionFactory实例调用openSession()方法来获得Session实例。可以编写一个Hibernate工具类HibernateUtil来封装这些操作,这时如果要获得Session对象,只需调用HibernateUtil类的getSession()即可,代码如下所示。

        package net.hncu.util;
        import org.hibernate.Session;
        import org.hibernate.SessionFactory;
        import org.hibernate.cfg.Configuration;
        public class HibernateUtil {
              private static SessionFactory factory;
              static{
                      //读取配置文件hibernate.cfg.xml
                      Configuration cfg = new Configuration().configure();
                      //创建SessionFactory
                      factory = cfg.buildSessionFactory();
                }
                //获得SessionFactory实例
                public static SessionFactory getSessionFactory(){
                      return factory;
                }
                //获得Session实例
                public static Session getSession() {
                      return factory.openSession();
                }
                //关闭指定Session
                public static void closeSession(Session session) {
                      if(session ! = null) {
                              if(session.isOpen()) {
                                      session.close();
                              }
                      }
                }
          }