今天开始学习Hibernate框架,在学习之前先了解下什么是ORM?
ORM,全称为Object Relational Mapping,利用面向对象编程思想都是为了把对象的信息存进关系型数据库中,所以要写很多底层SQL语句,但是不同的数据库SQL语句又有不同,所以为了解决面向对象与关系数据库不匹配的问题提出了ORM技术,使用ORM技术可以完全摒弃SQL语句,充分利用面向对象进行编程。
Hibernate是一个关系型映射框架,对JDBC进行了非常轻量级的封装,其实底层还是使用JDBC来进行与数据库交互,Hibernate可以自动的生成SQL语句,并自动的执行,因此Hibernate是作为MVC模式中的数据持久层,并且Hibernate还开放源代码,把软件开发人员从数据持久层的工作中解放出来,避免了重复编写繁琐的SQL语句。
1、将对数据库的操作转换为对Java对象的操作,从而简化开发。通过修改一个“持久化”对象的属性从而修改数据库表中对应的记录数据。
2、提供线程和进程两个级别的缓存提升应用程序性能。
3、有丰富的映射方式将Java对象之间的关系转换为数据库表之间的关系。
4、屏蔽不同数据库实现之间的差异。在Hibernate中只需要通过“方言”的形式指定当前使用的数据库,就可以根据底层数据库的实际情况生成适合的SQL语句。
5、非侵入式:Hibernate不要求持久化类实现任何接口或继承任何类,POJO即可。
1、引入jar包,或者在创建Hibernate工程的时候勾选下载,jar包可以去官网上下载,引入lib目录下required中的所有包,注意要引入数据库驱动包。

2、创建一个数据库,不用创建表
3、创建一个持久化的Student类
package com.demo.model;
public class Student {
private int id;
private String username;
private String password;
private int age;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
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 int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
4、创建Hibernate配置文件,在src目录下
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.url">jdbc:mysql://localhost:3306/hibernate1</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.username">root</property>
<property name="connection.password">ForMe=520</property>
<!-- 指定在控制台打印生成的Sql语句 -->
<property name="show_sql">true</property>
<!-- 指定使用mysql数据库中的SQL语句格式-->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<!-- 指定是否自动生成数据库表 -->
<property name="hbm2ddl.auto">update</property>
<!-- 表示为每个线程生成一个session 必须要加上这一句否则会出错-->
<property name="current_session_context_class">thread</property>
<!-- 引入对象-关系映射文件 -->
<mapping resource="com/demo/model/student.hbm.xml"/>
</session-factory>
</hibernate-configuration>
注意:Hibernate配置文件的创建是由固定格式的,如上所示,每个property代表着不同的含义。
5、创建对象--关系映射文件,要和持久化的类在同一包下。
<?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 package="com.demo.model" >
<!--类名、表名-->
<class name="com.demo.model.Student" table="stu">
<id name="id" type="int">
<!--column表示列名-->
<column name="id"/>
<generator class="identity"/>
</id>
<property name="username" type="java.lang.String">
<column name="username"/>
</property>
<property name="password" type="java.lang.String">
<column name="password"/>
</property>
<property name="age" type="int">
<column name="age"/>
</property>
</class>
</hibernate-mapping>
对映射文件的各个属性进行分析
id:定义了该属性到数据库表主键字段的映射。
type:指定该标识属性的数据类型,该类型可以是
Hibernate的内建类型,也可以是java类型,如果是java类型则需要使用全限定类名(带包名)。该属性可选,如果没有指定类型, 则hibernate自行判断该标识属性数据类型。通常建议设定。
name="userId":标识属性的名字;
column="userId":表主键字段的名字,如果不填写与
name一样;
对generator进行解释:
class的取值可以有下面几种
1、increment
increment: 对 long , short 或 int 的数据列生成自动增长主键。 主键按数值顺序递增,存在并发问题
2、identity
对如 SQL server , MySQL 等支持自动增长列的数据库。
3、seqhilo
对如 Oracle , DB2 等支持 Sequence 的数据库,
oracle自增长是序列化的形式。
4、uuid:
对字符串列的数据采用 128-位 uuid 算法生成唯一的字符串主键。
5、native
自增长,会根据底层数据库自增长的方式选择identity或
sequence
如果是mysql数据库, 采用的自增长方式是identity
如果是oracle数据库, 使用sequence序列的方式实现自增长
6、assigned
主键由外部程序负责生成,无需Hibernate参与
7、foreign
使用外部表的字段作为主键。
<property>:为类定义一个持久化的javaBean风格的属性。
name="name":标识属性的名字,以小写字母开头;
column="name":表主键字段的名字,如果不填写与name一样;
update="true"/insert="true":默认为true,表示可以被更新或插入;
access="property/field":指定Hibernate访问持久化类属性的方式。默认property。property表示使用setter/getter方式。field表示运用java反射机制直接访问类的属性。
6、创建HibernateUtils工具类
package com.demo.utils;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.Nullable;
public class HibernateUtils {
private static SessionFactory sessionFactory = null;
static{
Configuration configuration = new Configuration().configure();
sessionFactory = configuration.buildSessionFactory();
}
@Nullable
public static Session getSession(){
return (sessionFactory != null)?sessionFactory.openSession():null;
}
@Contract(pure = true)
public static SessionFactory getSessionFactory(){
return sessionFactory;
}
public static void closeSession(Session sess){
if(sess != null)
if(sess.isOpen())
sess.close();
}
}
7、利用HibernateUtils工具类进行CRUD
package com.demo.tests;
import com.demo.model.Student;
import com.demo.utils.HibernateUtils;
import org.hibernate.Session;
public class HibernateTest1 {
public static void main(String[] args) {
// createTest();
// updateTest();
// retrieveTest();
// deleteTest();
}
public static void createTest(){
Session session = HibernateUtils.getSession();
session.beginTransaction();
Student student = new Student();
student.setId(11);
student.setUsername("李四");
student.setPassword("798233");
student.setAge(17);
session.save(student);
session.getTransaction().commit();
HibernateUtils.closeSession(session);
}
public static void updateTest(){
Session session = HibernateUtils.getSession();
session.beginTransaction();
Student student = session.load(Student.class,2);
student.setAge(19);
student.setPassword("412435");
session.getTransaction().commit();
HibernateUtils.closeSession(session);
}
public static void retrieveTest(){
Session session = HibernateUtils.getSession();
session.beginTransaction();
Student student = session.load(Student.class,new Integer(1));
System.out.println("年龄:" + student.getAge() + " 姓名:" + student.getUsername()
+ " 密码:" + student.getPassword());
session.getTransaction().commit();
}
public static void deleteTest(){
Session session = HibernateUtils.getSession();
session.beginTransaction();
Student student = session.load(Student.class,new Integer(4));
session.delete(student);
session.getTransaction().commit();
}
}
1、先看下HibernateUtils中的类Configuration类,是Hibernate的入口,操作的是主配置文件(hibernate.cfg.xml或者是hibernate.properties)。
2、Configuration类的configure()方法:
configure()方法用于加载配置文件
加载主配置文件的方法有两种
如果指定参数,那么加载参数的路径配置文件
如果不指定参数,默认加载src/目录下的
hibernate.cfg.xml
3、SessionFactory
SessionFactory用到了工厂模式,用户程序从工厂类SessionFactory中取得Session的实例,是重量级的,在一个项目中最好只存在一个SessionFactory,可以在整个应用程序中共享,SessionFactory在Hibernate中实际上起到了一个缓冲区的作用 他缓冲了HIbernate自动生成SQL语句和其他的映射数据 还缓冲了一些将来有可能重复利用的数据。
4、buildSessionFactory()方法
用于创建session工厂
5、SessionFactory.openSession()方法
用于创建session对象
6、Session
上面介绍了这么多关于session的类和方法,那么什么是
session呢?它的功能又是什么呢?
Session的主要功能是为映射的实体类的实例提供增删改查操作。
● 保存对象到数据库 session.save(Object obj);
● 保存对象到数据库 session.persist(Object obj);
● 数据更新,session.update(Object obj);
● 更新或者保存,session.saveOrUpdate(Object user);
本方法当有主键的时候,执行更新,没有设置主键的时候执行的是保存。
● 主键查询
//两者都可用于主键查询
//Student student = session.get(Student.class,2);
Student student = session.load(Student.class,2);
beginTransaction()方法,开启事务
最后总结一下Hibernate的执行流程如下图

Hibernate实体对象的三种状态
Hibernate是基于实体对象的操作,也就是说把实体对象与数据库表一一对应起来,通过操作实体对象来进行改变数据库中的数据。而是对对象在Hibernate中有三种存在状态,分别为:瞬时状态、持久化状态和游离状态。
通过new创建出来的对象,与Hibernate没有关系,不在Hibernate的缓存中,此时的状态为瞬时状态,此时如果对象不再被其他对象调用,将会被垃圾处理机制回收。
对象与session关联,此对象就处在持久化状态,处于持久化状态的对象拥有数据库标识(也就是主键)。对象与
session相互关联的方式有两种:
第一种就是调用get或者load方法从数据库加载对象;第二种就是瞬时状态的对象调用save方法或者
SaveOrUpdate方法时,对象处于持久化的状态Hibernate会选择时机将变更固化到数据库中。
当Session进行了close()、clear()、evict()或flush()后,实体对象从持久态变成游离态。
画一个草图简单理解





