本文主要是从技术操作角度去介绍hibernate,并且简单描述如何快速的上手操作hibernate,用于作为与数据库的连接的持久层。
简单讲述一下hibernate究竟是什么,它有什么作用,在理解它的作用之前,我们先想一想,在一个项目当中,我们需要将项目当中的数据存入数据库,或者从数据库中读取项目当中需要的数据进行操作,我们往常一般使用什么方法呢?首先想到的就是通过JDBC去对数据库进行手动的操作,编写一个连接数据库的模块,通过加载driver并且手动编写增删改查方法联通程序与数据库当中的数据,这种方式很繁琐,并且在对不同的表格操作的时候,还需要手动修改SQL语句,与我们面向对象编程的设计思想不符,于是提出了ORM。
所谓的ORM(Object ralational mapping)是一种为了解决面向对象与关系型数据库存在的互不匹配的现象的技术,简单说:ORM是通过使用描述对象和数据库之间映射的元数据,将Java程序中的对象自动持久化到关系数据中。即将数据库表当中的一行数据,转化到java当中的某个pojo类的实例,本质上就是将数据从一种形式转换到另外一种形式。
从图中的每层之间的关系也可以很直观的看出,本文所介绍的Hibernate主要就是用于做持久层,并且提供ORM的重要组件。
通过Hibernate,我们将对象转换存入数据库,或者反向将数据从数据库提取生成对象就无需再手动编写jdbc的增删改查并且向对象填入字段的代码模块,在建立好orm映射之后,我们只需要操作我们所定义的pojo类,并且使用Hibernate提供的方法即可将pojo对象存入对应的数据库当中,无需关注实现细节,便于简化编程。
在理解什么是orm,并且知道Hibernate在我们编程当中所扮演的角色以及所提供的作用之后,我们开始来了解如何使用Hibernate来实现我们的程序持久层,本文采用的是hibernate 5.1版本对mysql数据进行连接,进行demo演示,首先创建一个java project,并且将hibernate根目录下的 /lib/required 文件夹下的所有jar包引入工程,并且再将 /lib/java8 目录下的jar包引入工程当中,除此之外,因为要与mysql数据库进行连接,还需要提供mysql数据库连接的驱动jar包mysql-connector-java-5.1.26-bin.jar,将这些包都引入并且build the path之后,我们的工程环境就搭建完成。
在通过hibernate去进行ORM的时候,一般的设计流程为Domain Object ->mapping ->DB:
1.需要连接的pojo类对象的设计,这个部分的设计根据所需要实现的程序的功能去进行,比如需要做一个用户信息的统计程序,那么就肯定需要一个名为User的Pojo类,并且该Pojo类里头需要定义用户的属性,如:姓名,性别,年龄等。
2.需要配置的pojo.hbm.xml配置文件,作为类向关系型的映射,即提供pojo类到数据库某张表的对应映射信息。
3.在包外配置hibernate.cfg.xml配置文件,其中Sesson-factory作为连接数据库信息的配置。
如同上述的设计思路流程,首先我们先设计我们的pojo类,就以用户信息为例,代码如下:
package wellhold.hibernate.domain; import java.util.Date; public class User { private int id; private String name; private Date birthday; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } @Override public String toString() { return "User [id=" + id + ", name=" + name + ", birthday=" + birthday + "]"; } }
在这里需要额外提示一下,根据笔者查阅的资料当中,大部分人都表示在hibernate因为反射机制的需求,所定义的pojo类需要有一个空白无参数的构造函数才能对对象进行反射,但是笔者在制作测试demo的时候,将这个空白的构造函数进行去除之后,程序还是没有任何问题,所以这个空白构造函数的必须性还有待商议。
在设计好pojo类之后,我们需要建立对象到数据库的映射关系,即hbm.xml配置文件的建立,如下:
<?xml version="1.0"?> <!-- ~ Hibernate, Relational Persistence for Idiomatic Java ~ ~ License: GNU Lesser General Public License (LGPL), version 2.1 or later. ~ See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. --> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <!-- --> <hibernate-mapping package="wellhold.hibernate.domain"> <class name="User"> <!-- 当类名和表明一样的时候,table="" 这个关键字不需要写 --> <id name="id"> <!-- name指的是属性名,即java类里头的属性 --> <!-- 有一次属性名unsaved-value="-1" 指的是如果ID的值为-1的时候则表示这个对象未保存 --> <generator class="native" /> <!-- 主键产生的方式,其中native是主键生成器 --> </id> <property name="name" /> <property name="birthday" /> </class> </hibernate-mapping>
hibernate会根据我们提供的这个hbm.xml去建立User这个Pojo类与数据库当中User这张表的映射关系。
之后我们需要对全局的hibernate进行配置,通过.cfg.xml对hibernate进行配置,包括提供所需要连接的数据库信息,以及一些功能参数的设定,session-factory的设置,注意在hibernate当中,对数据库的所有操作都是通过SessionFactory进行的,所以SessionFactory是一个很重要的概念,可以理解成是一个对jdbc进行更上一层封装的对象。
<?xml version='1.0' encoding='utf-8'?> <!-- ~ Hibernate, Relational Persistence for Idiomatic Java ~ ~ License: GNU Lesser General Public License (LGPL), version 2.1 or later. ~ See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. --> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="connection.url">jdbc:mysql:///testconnect</property> <property name="connection.username">root</property> <property name="connection.password"></property> <!-- SQL dialect --> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <!-- 使用方言,用于在Sql语句的设计上是存在差异的 --> <property name="hbm2ddl.auto">update</property> <!-- 在不存在表格的情况,自动在数据库生成表格 --> <property name="show_sql">false</property> <!-- 显示Hibernate底层调用的SQL --> <mapping resource="wellhold/hibernate/domain/User.hbm.xml" /> <!-- 在数据库当中自动生成表格 --> </session-factory> </hibernate-configuration>
至此,hibernate的映射环境就已经构建完成,接下来我们通过编写测试用例去进行测试我们所搭建的hibernate是否可以正常工作。
一般在使用Hibernate,我们可以先对原生的Hibernate提供的一些方法进行更高一层的封装,比如Hibernate的SessionFactory所提供的sava方法,update方法,delete方法,get方法,制作一个Hibernate的工具类,代码如下:
package wellhold.hibernate; import java.io.Serializable; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; public final class HibernateUtil { private static SessionFactory sessionFactory; static { Configuration cfg = new Configuration(); cfg.configure("hibernate.cfg.xml"); sessionFactory = cfg.buildSessionFactory(); } public static SessionFactory getSessionFactory() { return sessionFactory; } public static Session getSession() { return sessionFactory.openSession(); } public static void add(Object entity) { Session s = null; Transaction tx = null; try { s = HibernateUtil.getSession(); tx = s.beginTransaction(); s.save(entity); tx.commit(); } finally { if (s != null) s.close(); } } public static void Update(Object entity) { Session s = null; Transaction tx = null; try { s = HibernateUtil.getSession(); tx = s.beginTransaction(); s.update(entity); tx.commit(); } finally { if (s != null) s.close(); } } public static void delete(Object entity) { Session s = null; Transaction tx = null; try { s = HibernateUtil.getSession(); tx = s.beginTransaction(); s.delete(entity); tx.commit(); } finally { if (s != null) s.close(); } } public static Object get(Serializable id) { Session s = null; try { s = HibernateUtil.getSession(); Object obj = s.get(User.class, id); return obj; } finally { if (s != null) s.close(); } } }
在HibernateUtil当中,通过一个static块去加载了hibernate.cfg.xml配置文件,并且获取到sessionfactory实例,之后是对增删改查的封装。这里简单的解释一下为什么使用的都是static的方法生命,因为在使用static的方法的时候,可以无需对HibernateUtil对象进行实例,就可以使用其静态的方法。
最后,我们只需要制作一个程序入口,即main函数,测试HibernateUtil当中的方法即可:
package wellhold.hibernate; import java.util.Date; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.Transaction; import wellhold.hibernate.domain.User; public class maintest { public static void main(String[] args) { // TODO Auto-generated method stub User user = new User(); user.setBirthday(new Date()); user.setName("well"); HibernateUtil.add(user); System.out.println("end"); System.out.println(HibernateUtil.get(1).toString()); } // }
查看效果:
至此,Hibernate快速入门demo完成。