Hibernate框架概述
1.简介
- Hibernate是一个开放源代码的对象关系映射框架
- 它对JDBC进行了非常轻量级的对象封装
- 它将POJO与数据库表建立映射关系,是一个全自动的orm框架
- hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。
- Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用
- 持久层的ORM框架
ORM:Object Relational Mapping(对象关系映射)。
指的是将一个Java中的对象与关系型数据库中的表建立一种映射关系,从而操作对象就可以操作数据库中的表。
2.优点
- 对JDBC访问数据库的代码进行了轻量级封装,简化了数据访问层繁琐重复性的代码,减少了内存消耗,加快了运行效率
- 是一个基本JDBC的主流持久化框架,很大程度上简化了DAO层的编码工作
- 性能非常好, 映射灵活性比较好,支持多关系数据库,一对一,一对多,多对多的各种复杂关系
- 可扩展性强,源代码及API开放,当本身功能不够用时,可以自行编码进行扩展
Hibernate的基本使用
1.导入jar包
再导入jar前我们先来了解一下hibernate的目录结构
- documentation Hibernate开发的文档
- lib Hibernate开发的jar包
-required
Hibernate开发的必须的依赖包
-optional
Hibernate开发的可选的jar包 - project
Hibernate提供的参考项目
除了上述hibernate中必须导入的jar包外我们还需要导入数据库的驱动包,连接池jar包。
2.配置文件
- 要使用hibernate我们首先需要配置一下核心配置文件hibernate.cfg.xml
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- 连接数据库的基本参数 -->
<property name="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql:///hibernate?useSSL=false&serverTimezone=UTC</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">123456</property>
<!-- 配置Hibernate的方言 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL8Dialect</property>
<!-- 打印SQL -->
<property name="hibernate.show_sql">true</property>
<!-- 格式化SQL -->
<property name="hibernate.format_sql">true</property>
<!-- 自动创建表 -->
<property name="hibernate.hbm2ddl.auto">update</property>
<!--加载映射文件-->
<mapping resource="com/thinmoon/domain/Customer.hbm.xml"/>
</session-factory>
</hibernate-configuration>
对hibernate.hbm2ddl.auto各种操作的一个解析
属性 | 含义 |
---|---|
none | 不使用hibernate的自动建表 |
create | 如果数据库中已经有表,删除原有表,重新创建,如果没有表,新建表 |
create-drop | 如果数据库中已经有表,删除原有表,执行操作,删除这个表。如果没有表,新建一个,使用完了删除该表。最后数据库中一个表没有,为了做测试用。把sessionFactory也close掉时才有效果 |
update | 如果数据库中有表,使用原有表,如果没有表,创建新表 更新表结构,如果column没有时会创建新的一列 |
validate | 如果没有表,不会创建表。只会使用数据库中原有的表 校验映射和表结构是否一致,不一致就会报错 |
-
创建映射关系配置文件,我们知道hibernate可以让我们使用面向对象的方法操纵数据库,所以我们必须得建立类与表之间的映射关系才能让hibernate正确的去操纵,其中配置文件命名格式我们一般是类名.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"> <hibernate-mapping> <!--建立类与表的映射关系--> <class name="com.thinmoon.domain.Customer" table="customer"> <!--建立主键映射关系--> <id name="cust_id" column="cust_id"> <!--设置主键增长方式--> <generator class="native"/> </id> <!--建立属性之间的映射关系--> <property name="cust_name" column="cust_name" /> <property name="cust_source" column="cust_source"/> <property name="cust_industry" column="cust_industry"/> <property name="cust_level" column="cust_level"/> <property name="cust_phone" column="cust_phone"/> <property name="cust_mobile" column="cust_mobile"/> </class> </hibernate-mapping>
Customer类:
@Setter @Getter public class Customer { long cust_id; String cust_name; String cust_source; String cust_industry; String cust_level; String cust_phone; String cust_mobile; }
3.操纵数据库
先来看一个小demo:
public class HibernateTest {
@Test
public void testM(){
//1.加载配置文件 hibernate.cfg.xml
Configuration configure = new Configuration().configure();
//2.创建sessionFactory 相当于jdbc的连接池
SessionFactory sessionFactory = configure.buildSessionFactory();
//3.获取session连接对象 相当于jdbc中的连接对象
Session session = sessionFactory.openSession();
Customer customer = new Customer();
customer.setCust_name("thinmoon");
customer.setCust_level("2");
session.save(customer);
session.close();
sessionFactory.close();
}
}
接下来我们对上面对象分别做一个解释:
Configuration
Configuration是Hibernate的配置对象,作用是对Hibernate 进行配置,以及对它进行启动。在Hibernate 的启动过程中,Configuration 类的实例首先定位映射文档的位置,读取这些配置,然后创建一个SessionFactory对象。虽然Configuration 类在整个Hibernate 项目中只扮演着一个很小的角色,但它是启动hibernate 时所遇到的第一个对象。通过这个对象去加载它里面的配置,把里面的数据内容或得到,才能进行后面的工作。
作用:
-
加载核心配置文件,其中核心配置文件可以是xml形式,也可以是properties形式
- 核心配置文件是属性文件名称为:hibernate.properties
configuration cfg = new configuration()
- 核心配置文件是一个xml名称为:hibernate.cfg.xml
configuration cfg = new configuration(); cfg.config()
-
加载映射文件
属性文件是没有办法加载映射,可以通过config加载映射文件
configuration.addResource("映射文件的全路径");
xml可以直接在配置文件中配置即可。
SessionFactory
SessionFactory接口负责初始化Hibernate,并负责创建Session对象。需要注意的是SessionFactory并不是轻量级的,因为一般情况下,一个项目通常只需要一个SessionFactory就足够。当需要操作多个数据库时,可以为每个数据库指定一个SessionFactory。SessionFactory
内部维护了Hibernate的连接池和Hibernate的二级缓存,一个项目只需要创建一个就行了,因为里面有连接池,通常连接池创建一个就可以。
hiberante5.0后内部自带有连接池如果我们想用第三方的连接池需要额外配置,下面是配置c3p0的例子(应为hibernate对c3p0支持比较好)。首先我们需要导入jar包在hibernate的lib目录中的optional中有c3p0的jar包。接着在hibernate.cfg.xml中进行配置。
<!--配置c3p0-->
<property name="connection.provider_class">org.hibernate.c3p0.internal.C3P0ConnectionProvider</property>
<!--在连接池中可用的数据库连接的最少数目 -->
<property name="c3p0.min_size">5</property>
<!--在连接池中所有数据库连接的最大数目 -->
<property name="c3p0.max_size">20</property>
<!--设定数据库连接的过期时间,以秒为单位,
如果连接池中的某个数据库连接处于空闲状态的时间超过了timeout时间,就会从连接池中清除 -->
<property name="c3p0.timeout">120</property>
<!--每3000秒检查所有连接池中的空闲连接 以秒为单位-->
<property name="c3p0.idle_test_period">3000</property>
既然我们上面说了一个项目一般只要一个SessionFactory所以我们就有必要专门为它抽取出一个工具类出来:
public class HibernateUtil {
public static final SessionFactory sessionFactory;
static {
//1.加载配置文件 hibernate.cfg.xml
Configuration configure = new Configuration().configure();
//2.创建sessionFactory 相当于jdbc的连接池
sessionFactory = configure.buildSessionFactory();
}
public static Session openSession(){
//3.获取session连接对象 相当于jdbc中的连接对象
Session session = sessionFactory.openSession();
return session;
}
}
Session
session代表的是hibernate与数据库的连接对象,与数据库交互的桥梁,通过它来完成与数据库的增删改查的工作
使用session进行增删改查很简单:
方法 | 代码 | 解释 |
---|---|---|
保存方法 | save(Object obj) | |
查询方法 | get(T.class,id) load(T.class,id) |
get(T.class,id) 2.查询之后,返回的是真实对象本身 3.没有查询到指定的id,返回的是一个空值 load(T.class,id) 1.查询之后返回的是一个代理对象,使用的是第三方的代理机制,javassist.jar 2.没有查询到结果直接报一个异常 |
修改 | void update(Object obj) | 直接创建对象修改,如果没有指定其它的字段,会把其它的字段设置为null。 建议先把要修改的记录查询出来之后再修改相应的对象 |
删除 | void delete(Object obj) | 直接创建对象删除,不支持级联删除 建议查询之后再删除,支持级联删除 |
保存或更新 | void saveOrUpdate(Object obj) | 没有设置id,是保存的操作 设置了id是修改的操作,如果设置的id没有,就会报错 |
查询所有 | Query query = session.createQuery("from Customer"); List |
使用HQL的方式 HQL:Hibernate Query Language 面向对象的查询语言 |
demo:
public class HibernateTest {
@Test
public void testSave(){
Session session = HibernateUtil.openSession();
Transaction transaction = session.beginTransaction();
Customer customer = new Customer();
customer.setCust_name("thinmoon111");
customer.setCust_level("3");
session.save(customer);
transaction.commit();
session.close();
}
@Test
public void testDelete(){
Session session = HibernateUtil.openSession();
Transaction transaction = session.beginTransaction();
Customer customer = session.get(Customer.class, 1L);
System.out.println(customer);
session.delete(customer);
transaction.commit();
session.close();
}
@Test
public void testUpdate(){
Session session = HibernateUtil.openSession();
Transaction transaction = session.beginTransaction();
Customer customer = session.get(Customer.class, 2L);
System.out.println(customer);
customer.setCust_level("10");
session.update(customer);
transaction.commit();
session.close();
}
@Test
public void testHQL(){
Session session = HibernateUtil.openSession();
Transaction transaction = session.beginTransaction();
Query query = session.createQuery("from com.thinmoon.domain.Customer");
List<Customer> list = query.list();
for (Customer c: list) {
System.out.println(c);
}
transaction.commit();
session.close();
}
}
归纳
配置文件hibernate.cfg.xml
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- 连接数据库的基本参数 -->
<property name="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql:///hibernate?useSSL=false&serverTimezone=UTC</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">15160673718wen</property>
<!-- 配置Hibernate的方言 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL8Dialect</property>
<!-- 打印SQL -->
<property name="hibernate.show_sql">true</property>
<!-- 格式化SQL -->
<property name="hibernate.format_sql">true</property>
<!-- 自动创建表 -->
<property name="hibernate.hbm2ddl.auto">update</property>
<!--配置c3p0-->
<property name="connection.provider_class">org.hibernate.c3p0.internal.C3P0ConnectionProvider</property>
<!--在连接池中可用的数据库连接的最少数目 -->
<property name="c3p0.min_size">5</property>
<!--在连接池中所有数据库连接的最大数目 -->
<property name="c3p0.max_size">20</property>
<!--设定数据库连接的过期时间,以秒为单位,
如果连接池中的某个数据库连接处于空闲状态的时间超过了timeout时间,就会从连接池中清除 -->
<property name="c3p0.timeout">120</property>
<!--每3000秒检查所有连接池中的空闲连接 以秒为单位-->
<property name="c3p0.idle_test_period">3000</property>
<!--添加映射文件-->
<mapping resource="com/thinmoon/domain/Customer.hbm.xml"/>
</session-factory>
</hibernate-configuration>