Hibernate是一个开放源代码的对象关系映射框架,它将 POJO与数据库表建立映射关系,Hibernate 可以自动生成SQL语句,自动执行,完成数据持久化的任务,使得我们方便的使用对象编程思维来操纵数据库。
一、Hibernate 概述
Hibernate 的API一共有6个接口,分别为:Session、SessionFactory、Transaction、Query、Criteria和Configuration。通过这些接口,可以对持久化对象进行存取、事务控制。
- Session:Session接口负责执行被持久化对象的CRUD操作。但需要注意的是Session对象是非线程安全的。
- SessionFactory:SessionFactory接口负责初始化Hibernate,并负责创建Session对象。这里用到了工厂模式。SessionFactory并不是轻量级的,所以在一般情况下,一个项目通常只需要一个SessionFactory对象。
- Transaction:Transaction 接口是对实际事务实现的一个抽象,这些实现包括JDBC的事务、JTA 中的UserTransaction、甚至可以是CORBA 事务。
- Query:Query接口可以实现对数据库及持久对象进行查询,它可以有两种表达方式:HQL语言或本地数据库的SQL语句。
- Criteria:Criteria接口与Query接口非常类似,允许创建并执行面向对象的标准化查询。
- Configuration:Configuration 类的作用是对Hibernate 进行配置,以及对它进行启动。在Hibernate 的启动过程中,Configuration 类的实例首先定位映射文档的位置,读取这些配置,然后创建一个SessionFactory对象。
二、创建第一个 Hibernate 项目
2.1、导入 Jar 包
一个简单的 Hibernate 工程共需要两类 Jar 包,一种是 Hibernate 所必须使用的 Jar 包,另外一种是数据库驱动 Jar 包。所需的 Jar 包名称如下:
- Hibernate 必备的 Jar 包
antlr-2.7.7.jar
dom4j-1.6.1.jar
geronimo-jta_1.1_spec-1.1.1.jar
hibernate-commons-annotations-5.0.1.Final.jar
hibernate-core-5.0.7.Final.jar
hibernate-jpa-2.1-api-1.0.0.Final.jar
jandex-2.0.0.Final.jar
javassist-3.18.1-GA.jar
jboss-logging-3.3.0.Final.jar
- 数据库驱动 Jar 包
mysql-connector-java-5.1.47.jar
c3p0-0.9.2.1.jar
hibernate-c3p0-5.0.7.Final.jar
mchange-commons-java-0.2.3.4.jar
2.2、编写实体类
创建用户(User) 实体类,其中包含用户名、密码、昵称、出生日期等基本信息。
package com.hibernate.domain;
import java.util.Date;
public class User {
private Integer uid;
private String username;
private String password;
private String nickname;
private Date birthday;
private String realname;
public Integer getUid() {
return uid;
}
public void setUid(Integer uid) {
this.uid = uid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getRealname() {
return realname;
}
public void setRealname(String realname) {
this.realname = realname;
}
@Override
public String toString() {
return "User [uid=" + uid + ", username=" + username + ", password=" + password + ", nickname=" + nickname
+ ", birthday=" + birthday + ", realname=" + realname + "]";
}
}
2.3、编写Hibernate和实体类配置文件
2.3.1、编写 Hibernate 配置文件 —— hibernate.cfg.xml
Hibernate 的配置文件默认编写位置是在工程项目的 src
下,在配置文件中,主要配置 session-factory
,用于创建 Session
对象,以便对 POJO 进行增删改查的操作。
在 session-factory
中,主要配置数据库的配置信息、连接池供应商以及实体类映射文件的位置。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<!-- 配置 SessionFactory 用于创建 Session 对象 -->
<session-factory>
<!-- 数据库的配置信息 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql:///hibernate</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">admin</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 可选配置 -->
<property name="hibernate.show_sql">true</property>
<!-- <property name="hibernate.format_sql">true</property> -->
<!-- 配置 Hibernate 以何种方式生成DDL语句 update:表示检测实体类的映射配置和数据库表结构是否一致,不一致则自动更新
auto: -->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- 配置 Session 绑定本地线程 -->
<property name="hibernate.current_session_context_class">thread</property>
<!-- 设置连接池供应商 -->
<property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
<!-- 配置实体类的映射文件位置 -->
<mapping resource="com/one_to_many/domain/User.hbm.xml" />
</session-factory>
</hibernate-configuration>
2.3.2、编写实体类配置文件 —— User.hbm.xml
实体类映射文件则是编写在与实体类相同的包下面,命名通常以 实体类名称.hbm.xml
为命名规则。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- package:配置实体类所在的包名称 -->
<hibernate-mapping package="com.hibernate.domain">
<!--
class标签,对应实体类
name:实体类的名称,如果配有配置package属性,需要写类的绝对路径
table:对应数据库中的表名称
-->
<class name="User" table="tb_user">
<!--
id:数据库表中的主键
id,property
name:实体类的属性名称
column:实体类属性对应数据库表中的列名称
-->
<id name="uid" column="user_id">
<!-- generator:表主键的生成策略 -->
<generator class="native"></generator>
</id>
<property name="username" column="username"></property>
<property name="password" column="password"></property>
<property name="nickname" column="nickname"></property>
<property name="birthday" column="birthday"></property>
<property name="realname" column="realname"></property>
</class>
</hibernate-mapping>
2.3.3、编写 Hibernate 工具类,获取 Session 对象
package com.hibernate.utils;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
// 使用静态代码块来创建 SessionFactory 对象,保证单例
private static SessionFactory sessionFactory;
static {
// 创建 Configuration 对象
Configuration cfg = new Configuration();
// 加载 Hibernate 默认配置文件,如果配置文件不在 src 目录下,则需要填写配置文件地址
cfg.configure();
// 根据配置文件,创建 SessionFactory 对象
sessionFactory = cfg.buildSessionFactory();
}
public static Session openSession() {
// 获取 session 对象
return sessionFactory.openSession();
}
public static Session getCurrentSession() {
// 获取与当前线程绑定的 session 对象
return sessionFactory.getCurrentSession();
}
}
2.3.4、测试工具类
package com.hibernate.test;
import org.hibernate.Session;
import org.junit.Test;
import com.hibernate.utils.HibernateUtil;
public class TestHibernateUtil {
@Test
public void test() {
Session session = HibernateUtil.openSession();
}
}
如果测试类运行成功,则在 Hibernate 配置中所连接的数据库中就会出现 tb_user
表。
三、简单的增删改查操作
3.1、保存操作
使用 Hibernate 保存数据,只需要调用 session 的 save() 方法,即可将 POJO 保存到数据库中。
package com.hibernate.test;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import com.hibernate.domain.User;
import com.hibernate.utils.HibernateUtil;
public class TestHibernate {
@Test
public void testSave() {
// 获取 session 对象
Session session = HibernateUtil.openSession();
// 获取 Transaction 对象
Transaction tx = session.beginTransaction();
// 开启事务
tx.begin();
try {
User user = new User();
user.setUsername("martin_depp@126.com");
user.setPassword("martin0319");
user.setNickname("奔跑的小蚂蚁");
user.setBirthday(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("1991-03-19 11:55:00"));
user.setRealname("孟祥杰");
// 调用 session 对象的 save() 实现数据的持久化操作
session.save(user);
} catch (ParseException e) {
e.printStackTrace();
} finally {
// 提交事务
tx.commit();
// 关闭 session
session.close();
}
}
}
3.2、查找操作
使用 Hibernate 进行查找,只需要调用 session 的get(Class<T> arg0, Serializable arg1)
方法,其中 arg0 表示对应实体类名称,arg1表示主键值,如:查询主键为1的 User 实体对象。
package com.hibernate.test;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import com.hibernate.domain.User;
import com.hibernate.utils.HibernateUtil;
public class TestHibernate {
@Test
public void testGet() {
// 获取 session 对象
Session session = HibernateUtil.openSession();
// 获取 Transaction 对象
Transaction tx = session.beginTransaction();
// 开启事务
tx.begin();
// 此时需要注意所查询实体类主键的类型,如果是Long类型,最好为1L
User user = session.get(User.class, 1);
// 输出结果:
// User [uid=1, username=martin_depp@126.com, password=martin0319, nickname=奔跑的小蚂蚁, birthday=1991-03-19 11:55:00.0, realname=孟祥杰]
System.out.println(user);
// 提交事务
tx.commit();
// 关闭 session
session.close();
}
}
3.3、更新操作
使用 Hibernate 更新数据,只需要调用 session 的 update() 方法,即可将 POJO 数据更新到数据库中。
package com.hibernate.test;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import com.hibernate.domain.User;
import com.hibernate.utils.HibernateUtil;
public class TestHibernate {
@Test
public void testUpdate() {
// 获取 session 对象
Session session = HibernateUtil.openSession();
// 获取 Transaction 对象
Transaction tx = session.beginTransaction();
// 开启事务
tx.begin();
User user = session.get(User.class, 1);
user.setUsername("mengxiangjie2005@126.com");
session.update(user);
// 提交事务
tx.commit();
// 关闭 session
session.close();
}
}
3.4、删除操作
使用 Hibernate 保存数据,只需要调用 session 的 delete() 方法,即可将 POJO 从数据库中删除。
package com.hibernate.test;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import com.hibernate.domain.User;
import com.hibernate.utils.HibernateUtil;
public class TestHibernate {
@Test
public void testDelete() {
// 获取 session 对象
Session session = HibernateUtil.openSession();
// 获取 Transaction 对象
Transaction tx = session.beginTransaction();
// 开启事务
tx.begin();
User user = session.get(User.class, 1);
session.delete(user);
// 提交事务
tx.commit();
// 关闭 session
session.close();
}
}
}