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; //各属性的setter和getter方法 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(); } } } }