一 Hibernate的介绍
1 让我们从JDBC与替代它的框架Hibernate进行一下对比。
1.1 JDBC的缺点
1) 代码结构繁琐。每次书写sql语句操作数据库都得需要很多步;
2) 是面向过程的编程,而非面向对象的;
3) 没有做到数据缓存。这会导致程序与数据库的交互的次数很多;
4) 因为事务是自动开启的,所以存在安全隐患。
1.2 JDBC的优点
1) 因为是底层的数据库操作,所以执行效率很高;
2) sql语句可以自己编写,可以进行优化从而选择效率最高的那些。
1.3 Hibernate的优点
1) 面向对象编程的
2) 代码编程比较简单
3) Hibernate做到了数据缓存
用处: Hibernate用得场合最多的情况是企业中的中小型项目
1.4 Hibernate的缺点
1) 该框架程序员是没有办法干预sql语句的生成的
2) 如果一个项目中,对sql语句的优化的要求比较高,这个时候不能用hibernate来做
3) 表之间的关系很复杂的情况下,不能用hibernate来操作
4) 如果一张表的数据超过了千万级别也不适合用hibernate来做
2 Hibernate的组成
持久化类 —— 是一个JavaBean,对应现实世界中的实体的类。
映射文件 —— 用于建立数据库的表与持久化类之间的联系的文件
说明:
1 对应关系
表结构 对应 持久化类
表数据 对应 持久化类的对象
2 由1可知,数据库中有多少张表(或有多少个持久化类),便至少应该有多少个映射文件。
配置文件 —— 描述hibernate工程配置信息的文件
说明: 一个工程一般只有一个。
小结:
Hibernate就是利用面向对象的思想,以对象为基本单位来操作数据库的一种框架。
二 Hibernate入门案例
1 创建一个Java Project
2 导入jar包
3 创建配置文件
<?xml version=‘1.0‘ encoding=‘utf-8‘?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <!-- 一个session-factory代表一个数据库 --> <session-factory> <!-- 链接数据库的用户名 --> <property name="connection.username">root</property> <!-- 链接数据库的密码 --> <property name="connection.password">sorry</property> <!-- 链接数据库的驱动 --> <property name="connection.driver_class"> com.mysql.jdbc.Driver </property> <!-- 链接数据库的url 最后一个/后面的字符串代表了一个数据库名称。所以,我们书写完配置文件后要创建相应的数据库 --> <property name="connection.url"> jdbc:mysql://localhost:3306/blog_hibernate_01 </property> <!-- 方言 告诉hibernate用什么样的数据库 --> <property name="dialect"> org.hibernate.dialect.MySQLDialect </property> <!-- validate 加载hibernate时,验证数据库的结构 update 加载hibernate时,检查数据库,如果表不存在,则创建,如果存在,则更新 create 每次加载hiberante,都会创建表 create-drop 每次加载hiberante,创建,卸载hiberante时,销毁 --> <property name="hbm2ddl.auto">update</property> <!-- 显示sql语句 --> <property name="show_sql">true</property> <!-- 格式化sql语句 --> <property name="format_sql">true</property> <!-- 加载映射文件 --> <mapping resource="com/hibernate/domain/Student.hbm.xml" /> </session-factory> </hibernate-configuration>
经验:
1 配置文件必须在src目录下
2 名称必须为hibernate.cfg.xml
4 创建持久化类
注:
1 该持久化类最好实现java.io.Serializable接口,以供序列化
2 一定要提供一个无参构造器,以供系统通过反射创建相应持久化类的对象
3 要提供字段的setters和getters
package com.hibernate.domain; import java.io.Serializable; public class Student implements Serializable{ private Long id; private String name; private int age; private String gender; //必须提供一个无参构造器,供系统通过反射生成相关持久化类的对象。 public Student(){ } //生成域的setters和getters public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } }
5 创建映射文件
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <!-- 描述一个持久化类 name属性为持久化类的全名 table 该持久化类对应的表名 默认情况下为类名 --> <class name="com.hibernate.domain.Student" table="student"> <!-- id对应表中的主键 name为持久化类中属性的名称 length 为对应数据库表中相应字段的长度 column 属性的名称对应的表的字段名称 不写则默认和属性的名称一致 --> <id name="id" length="5" type="java.lang.Long" column="id"> <!-- 主键的生成器. --> <generator class="increment"></generator> </id> <property name="name" column="name" type="java.lang.String" length="20"> </property> <property name="age" column="age" length="50"> </property> <property name="gender" column="gender" type="java.lang.String" length="20"></property> </class> </hibernate-mapping>
6 创建Dao包,进行测试
package com.hibernate.crud; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import org.junit.Test; import com.hibernate.domain.Student; public class StudentDao { @Test public void testSaveStudent(){ //1 创建配置对象 Configuration configuration = new Configuration(); //2 加载配置文件 configuration.configure(); //3 获取sessionFactory对象 SessionFactory sessionFactory = configuration.buildSessionFactory(); //4 创建session对象 Session session = sessionFactory.openSession(); //5 开启事务 Transaction transaction = session.beginTransaction(); //6 执行相关操作 —— 保存一个新建的学生对象 Student student = new Student(); //因为在映射文件中设置了主键生成器,所以不用在此设置主键了。后面我们会详细讲解。 student.setName("Leesin"); student.setAge(22); student.setGender("male"); //调用save方法保存 session.save(student); //7 提交事务 transaction.commit(); } }
结果:
三 案例详解
1 Hibernate的流程
说明:
1 crud操作时由session对象完成的
2 Hibernate中,事务需要手动开启,并非自动开启的。
Configuration类
利用该类加载了hibernate的配置文件
sessionFactory类
1、 hibernate配置文件的信息、持久化类的信息、映射文件的信息全部在该类中
2、 sessionFactory对象有且只有一个
3、 生命周期是整个hibernate实例
4、 sessionFactory本身就是线程安全的
5、 二级缓存在sessionFactory中存放
6、 sessionFactory和数据库的链接没有直接的关系
session类
1、 crud操作由session来完成的
2、 一个session代表数据库的一个连接。session类实际上是对connection类的高级封装
内部执行流程
代码结构比较繁琐
面向纯sql语句的编程,面向过程的编程