目录
第一章:hibernate概念
1.1 hibernate概述
Hibernate框架是当今主流的持久层框架之一,是一个开源的ORM框架,它对JDBC进行了轻量级的封装,可以自动生成SQL语句,自动执行,允许开发人员使用面向对象的思想操作数据库。
1.2 ORM概述
ORM(Ogbject Relationship Mapping)意思是对象关系映射。该框架思想是建立对象模型和基于SQL的关系型数据库模型的映射关系,通过操作对象的属性和方法,即可对持久层数据进行增删改查操作。
1.3 hibernate优势
- 对JDBC进行了轻量级封装,开发减少重复代码;
- 是ORM框架思想,开发可以减少DAO层操作,避免复杂冗余的SQL语句编写;
- 灵活性很高,支持多种关系型数据库,从一对一到多对多的复杂关系;
- 可扩展性强。
第二章:hibernate案例入门
2.1 搭建hibernate开发环境
2.1.1 jar包拷贝
导入数据库驱动包:
Hibernate/lib/required/*.jar:
日志记录包:
2.1.2 创建数据库和实体类
hibernate使用功能普通java对象(Plain Old Java Object)进行持久化操作,即POJO的编程模式进行持久化。POJO类中包含于数据库表对应的各个属性,这些属性通过getter和setter方法进行获取,对外部隐藏。以下创建持久化类Customer。在src目录下创建cn.itcast.domain包,在包中创建实体类Customer(对应数据库表cst_customer),Customer类包含和数据库表对应的属性,和属性对应的getXXX(),setXXX()方法。
/*创建客户表*/
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 '客户级别',
`cust_address` varchar(32) default null comment '客户联系地址',
`cust_phone` varchar(32) default null comment '客户联系电话',
primary key (`cust_id`)
) engine=InnoDB auto_increment=1 default charset=utf8;
/**
*创建客户实体类
*/
public class Customer implements Serializable{
private Long custId;
private String custName;
private String custSource;
private String custIndustry;
private String custAddress;
private String custLevel;
private String custPhone;
/*
*创建各个属性的get,set方法
*/
public Long getCustId(){
return custId;
}
public void setCustId(Long custId){
this.custId = custId;
}
//......等等
}
2.1.3 编写映射配置文件(xml)
将实体类进行持久化操作,hibernate需要知道实体类和数据库表的映射表关系,即映射配置文件。我们在Customer所在包内创建一个Customer.hbm.xml映射文件。
<?xml version="1.0" encoding="UTF-8"?>
<!-- 导入约束:dtd约束
位置:在Hibernate的核心jar包中名称为hibernate-mapping-3.0.dtd
明确该文件中的内容:
实体类和表的对应关系
实体类中属性和表的字段的对应关系
-->
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package='cn.itcast.domain'><!--package属性指定包名,接下来该配置文件中凡是用到此包中的对象都可以省略包名-->
<!--class标签用于指定映射关系范围,哪个实体类和哪个数据库表存在映射
name属性:实体类
table属性:数据库表
-->
<class name='Customer' table='cst_customer'>
<!--id标签专用于主键映射
name属性:实体类属性,get/set方法后面的部分,首字母转小写
column属性:数据库表的字段名称
-->
<id name='custId' column='cust_id'>
<!--generator标签:用于指定主键生成策略
class属性:指定生成策略
取值:native 使用本地数据库的自动增长能力
identity:用于MySql数据库。特点:递增。注:对于MySql数据库使用递增序列时需要在建表时对主键指定为auto_increment属性。
sequence:用于Oracle数据库
等等(共7中取值)
-->
<generator class='native'></generator>
</id>
<!--property标签:类似id标签,指定普通属性和字段的映射-->
<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>
<property name='custAddress' column='cust_address'></property>
<property name='custPhone' column='cust_phone'></property>
</class>
</hibernate-mapping>
generator标签中class属性取值(主键生成策略),详细如下
2.1.4 编写主配置文件
hibernate主配置文件用于配置数据库连接和hibernate运行所需的各个属性。在src下创建hibernate.cfg.xm文件。
<?xml version="1.0" encoding="UTF-8"?>
<!-- 导入dtd约束:
位置:在核心jar包中的名称为hibernate-configuration-3.0.dtd中
-->
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<!--配置SessionFactory
SessionFactory就是一个工厂,用于生产Session对象的。
Session就是我们使用hibernate操作数据库的核心对象了。
明确:
它和我们Web阶段的HttpSession没一点关系。
此配置文件中的内容不需要背,很多配置都是可以在开发包中找到的。
但是要求必须知道:
创建SessionFactory由三部分组成,缺一不可。要知道是哪三部分
1.链接数据库的基本信息
2.hibernate基本配置
3.映射文件位置
-->
<session-factory>
<!--1、数据库连接基本信息-->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/CustomerManageSystem</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">1234</property>
<!--2、hibernate基本配置-->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property><!--配置数据库方言-->
<property name="hibernate.show_sql"></property><!--是否显示SQL语句-->
<property name="hibernate.format_sql"></property><!--是否格式化SQL语句-->
<!-- 是否让hibernate根据表结构的变化来生成DDL语句
DDL:数据定义语言
hibernate可以根据映射文件来为我们生成数据库的表结构。但是他不能生成数据库。
hbm2ddl.auto的取值
* none:不用Hibernate自动生成表.
* create:每次都会创建一个新的表.(测试)
* create-drop:每次都会创建一个新的表,执行程序结束后删除这个表.(测试)
* update:如果数据库中有表,使用原来的表,如果没有表,创建一个新表.可以更新表结构。
* validate:只会使用原有的表.对映射关系进行校验.
-->
<property name="hibernate.hbm2ddl.auto">update</property>
<!--3、配置文件位置-->
<mapping resource="cn/itcast/domain/Customer.hbm.xml"/>
</session-factory>
</hibernate-configuration>
2.2 抽取HibernateUtil工具类
一般情况下,在实际项目使用中,通常会抽取出一个HibernateUtils的工具类,用来提供Session对象。
/**
*hibernate工具类:用于生产一个session对象
*/
public class HibernateUtil{
private static SessionFactory factory;
static{
try{
Configuration cfg = new Configuration();
cfg.configure();
factory = cfg.buildSessionFactory();
}catch(Exception e){
throw new ExceptionInInitializerError("初始化SessionFactory失败");
}
}
/*
*使用工程生产一个Session对象,
*每次都是一个新的(此时Session还不符合自己的使用原则,调整在后续章节)
*/
public static Session openSession(){
return factory.openSession();
}
}
2.3 使用hibernate对数据库进行增删改查操作
操作步骤:
- 加载主配置文件
- 根据主配置文件配置构建SessionFactory工厂方法
- 使用工厂生产一个Session对象
- 对Session对象开启事务
- 执行持久化操作
- 提交事务
- 释放资源
2.3.1 保存操作
/**
*hibernate保存实例对象
*/
public class HibernateDemo1{
/*保存*/
public void add(){
Customer c = new Customer();
c.setCustName("test");
c.setCustLevel("VIP客户");
c.setCustSource("网络");
c.setCustIndustry("IT");
c.setCustAddress("北京");
c.setCustPhone("123456");
//使用工具获得一个session
Session session = HibernateUtil.openSession();
//开启事务
Transaction tx = session.beginTransaction();
//保存客户
session.save(c);
//提交事务
tx.commit();
//释放资源
session.colse();
}
2.3.2 查询一个实体
查询有两种方法,分别是get和load方法。
/**
*get方法:
* 根据id查询一个实体
* @param entityType 指的是要查询的实体类字节码对象
* @param id 查询的条件,即主键的值。
* @return 返回的是实体类对象
*
<T> T get(Class<T> entityType, Serializable id);
*/
/*查询*/
public void query(){
//使用工具获得一个session
Session session = HibernateUtil.openSession();
//开启事务
Transaction tx = session.beginTransaction();
//根据id查询客户
session.get(Customer.class,1);
//提交事务
tx.commit();
//释放资源
session.colse();
}
/**load方法:
*
* 根据id查询一个实体
* @param theClass 指的是要查询的实体类字节码
* @param id查询的条件,即主键的值。
* @return 返回的是实体类对象或者是实体类对象的代理对象
<T> T load(Class<T> theClass, Serializable id);
*/
//load方法的代码演示:
/**
* 需求: 使用load方法查询id为1的客户
*/
@Test
public void test2(){
Session s = HibernateUtil.getCurrentSession();
Transaction tx = s.beginTransaction();
Customer c = s.load(Customer.class, 1L);
System.out.println(c.toString());
tx.commit();
}
get和load的区别:
1、查询的时机不一样
get方法任何时候都是立即加载,即只要一调用get马上发起数据库查询
load方法默认情况下是延迟加载,即真正用到对象的非OID字段数据才发起查询
load方法可以通过配置的方式改为立即加载。
配置的方式:
由于load方法是hibernate的方法所以只有XML的方式:
<class name="Customer" table="cst_customer" lazy="false">
2、返回的结果不一样
get方法永远返回查询的实体类对象。
load方法当是延迟加载时,返回的是实体类的代理对象。
2.3.3 修改操作
/**
* 修改一个实体
*/
@Test
public void testUpdate(){
//1.使用工具类获取一个Session
Session session = HibernateUtil.openSession();
//2.开启事务
Transaction tx = session.beginTransaction();
//3.根据id查询
Customer c = session.get(Customer.class, 1L);
c.setCustName("TBD云集中心");
//修改实体
session.update(c);
//4.提交事务
tx.commit();
//5.释放资源
session.close();
}
2.3.4 删除操作
/**
* 删除一个实体
*/
@Test
public void testDelete(){
//1.使用工具类获取一个Session
Session session = HibernateUtil.openSession();
//2.开启事务
Transaction tx = session.beginTransaction();
//3.根据id查询
Customer c = session.get(Customer.class, 1L);
//删除实体
session.delete(c);//delete from cst_customer where cust_id = ?
//4.提交事务
tx.commit();
//5.释放资源
session.close();
}
}
2.4 入门案例执行过程
第三章:hibernate API介绍
3.1 Configuration对象
3.1.1 Configuration的作用
在使用hibernate时,首先要创建Configuration实例。该对象主要用于启动,加载,管理hibernate的配置文件信息。在启动hibernate过程中,Configuration对象首先确定hibernate配置文件位置,然后读取配置信息,最后创建唯一的SessionFactory实例。
Configuration实例只存在于hibernate初始化阶段,SessionFactory创建完毕,即销毁。
hibernate通常使用
Configuration cfg = new Configuration().configure();
的方式创建实例,该方式默认从src下读取hibernate.cfg.xml文件。若想从其他位置读取,需要向实例提供位置信息。例如从src下的config包里读取配置文件,
Configuration cfg = new Configuration().configure("/config/hibernate.cfg.xml");
如果使用properties文件作为核心配置文件,则主配置文件不能指定映射关系文件,可以使用
Configuration cfg = new Configuration().configure("/config/hibernate.cfg.xml");
//可以利用Configuration对象加载映射关系配置文件
configuration.addResource("cn/itcats/domain/Customer.hbm.xml");
3.1.2 Configuration的常用方法
默认构造函数:
它只能加载类的根路径下,名称为hibernate.properties的配置文件。不能加载xml。
configure():
它御用加载类根路径下,名称为hibernate.cfg.xml的配置文件。可以通过对该方法传入位置信息的方式,加载其他位置的配置文件。
buildSessionFactory():
根据配置文件,创建工厂对象。
addResource(String url):
指定映射文件位置。
addClass(Class clazz):
指定实体类的字节码。
3.2 SessionFactory对象
3.2.1 SessionFactory的作用
SessionFactory接口负责对hibernate进行初始化,创建Session对象,并起到缓冲区作用。
SessionFactory实例通过Configuration对象获取,方法如下:
SessionFactory sessionFactory = cfg.buildSessionFactory();
3.2.2 SessionFactory的常用方法
openSession():每次生成一个新的Session
其他(在第二天)
3.2.3 SessionFactory的注意细节
该对象既然可以充当缓冲区,便说明其维护了很多信息:
- 连接数据库的信息
- hibernate基本配置信息
- 映射文件位置信息,映射文件配置信息
- 一些预定义的SQL语句(这些语句都是通用的) 比如:全字段保存,根据id的全字段更新,根据id的全字段查询,根据id的删除等等。
- hibernate的二级缓存
该对象是线程安全的,非轻量化对象,不应该反复创建销毁。一般情况下,一个应用一个SessionFactory,当存在多个数据源时,每个数据源一个SessionFactory。
3.2.4 在hibernate中使用数据源(连接池)
SessionFactory内部还维护了一个连接池,如果我们需要使用第三方的连接池如C3P0,那么需要我们自己手动进行配置
配置C3P0步骤如下:
1、导入连接池的jar包
2、在hibernate主配置文件中配置
<!-- 配置数据源的提供商 -->
<property name="hibernate.connection.provider_class">
org.hibernate.connection.C3P0ConnectionProvider
</property>
3.3 Session对象
3.3.1 Session的作用
获取Session实例的方式有两种,一种是openSession()方法,另一种是getCurrentSession()方法。
//采用openSession方法创建session
Session session = sessionFactory.openSession();
//采用getCurrentSession()方法创建session
Session session = sessionFactory.getCurrentSession();
两种方式的区别:
openSession():
1.该方法创建每次创建一个新的Session
2.使用完成后需要调用close()方法手动关闭
getCurrentSession():
1.获得当前线程的Session,在没有配置把Session绑定到当前线程之前,该方法无法使用
2.线程绑定之后,它在提交或回滚操作时会自动关闭
3.3.2 Session的常用方法
save(Object entity);//保存一个实体到数据库
update(Object entity);//更新一个实体
delete(Object entity);//删除一个实体
get(Class clazz,Serializable id);//查询一个实体
beginTransaction();//开启事务
3.3.3 Session的注意细节
- Session维护内容少,为轻量化对象
- 非线程安全
- 维护hibernate一级缓存
- 反复创建销毁不会消耗太多资源
3.4 Transaction对象
3.4.1 Transaction的作用
Transaction transaction = session.beginTransaction();
3.4.2Transaction的常用方法
commit():提交事务
rollback():回滚事务
Session执行完数据库操作后,要使用Transaction接口的commit()方法进行事务提交,才能真正的将数据操作同步到数据库中。发生异常时,需要使用rollback()方法进行事务回滚,以避免数据发生错误。因此,在持久化操作后,必须调用Transaction接口的commit()方法和rollback()方法。如果没有开启事务,那么每个Session的操作,都相当于一个独立的操作。