Hibernate的概述
什么是Hibernate
Hibernate是一个基于ORM的持久层的框架
这句话有两个概念:ORM和持久层框架
持久层框架:意味着,这个框架就是对数据库进行增删改查的。
ORM:(Object Relational Mapping)对象关系映射。
- 在访问数据库前,将实体类的类和数据库表的表关联起来。通过操作实体类的对象,直接由框架生成操作数据库的SQL操作数据库。这就是ORM的行为。
ORM是一种实现使用实体类对象操作数据库表的设计思想。
框架使用者不用写SQL就可以操作数据库。
配置流程
- HIbernate需要一个总配置文件用于存储连接数据库的信息(hibernate.cfg.xml)
- 总配置文件的信息需要一个读取它类,Configuration
- 配置类可以通过buildSessionFactory()方法获得会话工厂。通过会话工厂管理数据库的连接
- 通过会话工厂可以获得操作对象会话(Session),Session可以操作数据库(增删改查)
- 会话的增删改查必须要依赖映射文件,操作前必须配置一个实体类,然后配置实体类对应的映射文件
配置步骤
根据配置流程图,得出配置步骤如下:
1. 导入包:
- 导入这路径的包`hibernate-release-5.0.7.Final\lib\required`
2. 创建一个hibernate.cfg.xml总配置文件,存储框架的信息
- 四个连接数据库的配置信息
3. 创建一个HibernateUtils获得操作对象(session)
4. 创建实体类
5. 创建一个映射文件,并且在总配置文件加载
- 实体类名和表名各种关联
6. 测试,插入
准备数据库表结构
- 通过SQL脚本创建表
CREATE TABLE `cst_customer` (
`cust_id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '客户编号(主键)',
`cust_name` varchar(32) NOT NULL COMMENT '客户名称(公司名称)',
`cust_source` varchar(32) DEFAULT NULL COMMENT '客户信息来源',
`cust_industry` varchar(32) DEFAULT NULL COMMENT '客户所属行业',
`cust_level` varchar(32) DEFAULT NULL COMMENT '客户级别',
PRIMARY KEY (`cust_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
创建hibernate.cfg.xml总配置文件
注意:配置文件,默认是放在classpath根目录下,放在src目录下,文件名默认必须为hibernate.cfg.xml
任何的框架的配置文件都是有规则的!!!!!!
有格式的xml配置文件都是有规则文件的,dtd或者schema
所以我们需要使用规则文件来生成HIbernate的配置文件!!
- 问题1:Hibernate的规则文件在哪里?
- 答:大部分的框架规则文件都在核心包,Hibernate也是在core 核心包里面找
通过导入的DTD规则文件去生成xml配置文件
*hibernate.cfg.xml*
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "hibernate-configuration-3.0.dtd" >
<!-- 跟标签 -->
<hibernate-configuration>
<!-- 配置一个数据库连接 -->
<session-factory>
<!-- 四要素 -->
<!-- 任何框架的环境参数都可以在代码里面找到对应的代码 -->
<!-- org.hibernate.cfg.AvailableSettings -->
<!-- 驱动 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<!-- 连接字符串 -->
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/crm1</property>
<!-- 用户名 -->
<property name="hibernate.connection.username">root</property>
<!-- 密码 -->
<property name="hibernate.connection.password">123456</property>
<!-- 显示SQL -->
<property name="hibernate.show_sql">true</property>
<!-- 格式化显示的SQL -->
<property name="hibernate.format_sql">true</property>
<!-- 加载映射文件 -->
<mapping resource="com/entity/hbm/Customer.hbm.xml"/>
</session-factory>
</hibernate-configuration>
注意事项:
1. 任何的框架只要提供了XML配置文件,那么必定会提供对应的规则文件:dtd或者schema规则文件 !!!!
2. 必须要学会在Eclipse里面配置规则文件,在Eclipse里面配置规则文件的作用
- 通过规则文件生成xml文件
- 让Eclipse工具有提示标签的功能
3. Hibernate的规则文件都在核心包里面 hibernate-core-5.0.7.Final.jar
4.配置文件最重要的步骤,就是在核心包里面cfg找到对应的属性!!!!!
*HibernateUtils*
- 为什么建议一个项目只有一个连接池呢?
- 答:如果一个项目里面出现多个连接池,有可能导致事务处理不同步。事务同步提交的前提是同一个连接。
/**
* 获得数据库操作对象的帮助类
* @author ranger
*
*/
public class HibernateUtils {
//使用static的关键字,整个项目共享一个对象。
//同一个连接池,获得相同的连接,(线程变量ThreadLoad)
public static SessionFactory sessionFactory=HibernateUtils.createSessionFactory();
//1.获得会话工厂
private static SessionFactory createSessionFactory(){
//1.创建一个Configuration对象
Configuration config=new Configuration();
//2.读取配置文件,获得框架信息,默认读取classpath根目录hibernate.cfg.xml
//也可以写成config.configure("hibernate.cfg.xml");
config.configure();
//3.获得会话工厂,会话工厂是连接数据库,如何要连接数据库必须需要连接数据库的信息(四要素)
//所以,获得会话工厂必须要在读取配置文件之后
SessionFactory sessionFactory = config.buildSessionFactory();
return sessionFactory;
}
//2.获得操作对象
public static Session getSession(){
//每次打开一个新的连接
return sessionFactory.openSession();
}
}
注意
:要理解为什么,一个项目只能有一个连接池。如果出现多个连接池,有可能导致事务处理不同步。
创建一个实体类
public class Customer {
private Long custId;
private String custName;
private String custSource;
private String custIndustry;
private String custLevel;
get/set()...
}
Mapping映射文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "hibernate-mapping-3.0.dtd" >
<hibernate-mapping>
<!-- 1.配置实体类名和表名的关系 -->
<!--
name:字段类的全限制名,就是包含包名的类名
table:指定实体类对应的表名
class标签:作用,用于设置实体类和表的关系
-->
<class name="com.entity.Customer" table="cst_customer">
<!-- 2.实体类的属性名和表的字段名的关系 -->
<!-- 配置ID列 -->
<!-- name:指定实体类对应表的ID字段的属性名 -->
<!-- column:指定属性对应的表的字段名 -->
<id name="custId" column="cust_id">
<!-- ID生成策略
前提:数据库已经配置ID自增长
native:本地的,意思就是ID列的值,使用数据库本身的自增长策略生成
-->
<generator class="native"></generator>
</id>
<!-- 非主键的字段 -->
<!-- name:指定实体类对应表的非主键字段的属性名 -->
<!-- column:指定属性对应的表的字段名 -->
<property name="custName" column="cust_name"></property>
<property name="custSource" column="cust_source"></property>
<property name="custIndustry" column="cust_industry"></property>
<property name="custLevel" column="cust_level"></property>
</class>
</hibernate-mapping>
操作测试
增
@Test
public void save(){
//1.获得操作对象
Session session = HibernateUtils.getSession();
//2.打开事务,操作都需要打开事务(增删改)
Transaction transaction = session.beginTransaction();
//3.操作
Customer c=new Customer();
c.setCustName("腾讯");
session.save(c);
//4.提交事务
transaction.commit();
//5.关闭操作类对象session
session.close();
}
删
/**
* 删除指定ID的记录
*/
@Test
public void delete(){
//1.获得数据库操作对象,session
Session session = HibernateUtils.getSession();
//2. Hibernate框架,操作(增删改)必须先开启事务才能操作
Transaction transaction = session.beginTransaction();
//3.创建一个实体类,并且封装数据
Customer c=new Customer();
//使用delete删除必须要通过OID删除,其他属性不可以删除。
c.setCustId(1L);
//删除
session.delete(c);
//5.提交事务,如果出错自动回滚
transaction.commit();
//6.关闭
session.close();
}
改
@Test
public void update(){
//1.获得数据库操作对象,session
Session session = HibernateUtils.getSession();
//2. Hibernate框架,操作(增删改)必须先开启事务才能操作
Transaction transaction = session.beginTransaction();
//3.创建一个实体类,并且封装数据
Customer c=new Customer();
c.setCustName("网易");
c.setCustId(4L);
//注意,使用update更新必须要有OID
session.update(c);
//5.提交事务,如果出错自动回滚
transaction.commit();
//6.关闭
session.close();
}
查
//需求:通过ID查询指定的客户信息,无延迟
@Test
public void get(){
//1.获得数据库操作对象,session
Session session = HibernateUtils.getSession();
//2.通过OID获得记录
Customer customer = session.get(Customer.class, 4L);
//3.输出获得的对象
System.out.println(customer.getCustName());
//4.关闭
session.close();
}
//需求:通过ID查询指定的客户信息,有延迟
@Test
public void load(){
//1.获得数据库操作对象,session
Session session = HibernateUtils.getSession();
//2.通过OID获得记录
Customer customer = session.load(Customer.class, 4L);
//3.输出获得的对象
System.out.println(customer.getCustName());
//4.关闭
session.close();
}
注意:
- 增删改查都是需要通过ID来进行操作的
- 增删改都是需要启动事务操能进行操作的