Hibrenate框架
一、Hibrenate
1、是一个持久层框架,实现jdbc的封装。是一个全自动的ORM框架
2、ORM:对象 关系(数据库表) 映射,orm致力于将数据库操作转换成Java程序熟悉的对象操作。
3、ORM主要体现在两个方面
a、java程序通过jdbc与数据库程序交互;类似于 请求—响应
b、orm在请求时,由java程序向数据库传递sql时,通过操作的对象 对于操作表,通过操作的对象属性 对应 操作的表字段
c、orm在响应是,一般就是查询操作,且返回结果,将ResultSet集合中装载的查询组装成对应的实体对象;根据查询时指定的对象,组装成与之对应的对象;根据表字段与对象属性名对应的关系实现数据赋值
二:全自动与半自动
1、 全自动orm:
a) 在请求和响应过程中,都是用orm机制自动进行处理的
2、 半自动orm
a) 在请求过程中,操作对此与对应的表的关系,依然需要使用手动编写的sql实现
b) 在响应过程中,将查询结果自动组成对象
三:hibernate基本使用
1、创建maven程序
2、引入hibernate 和mysql依赖
<dependency>
<groupId>org.hibernategroupId>
<artifactId>hibernate-coreartifactId>
<version>5.1.4.Finalversion>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.29version>
dependency>
3、创建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.jdbc.Driverproperty>
<property name="hibernate.connection.url">jdbc:mysql:///hibernate_day01property>
<property name="hibernate.connection.username">rootproperty>
<property name="hibernate.connection.password">rootproperty>
<property name="hibernate.show_sql">trueproperty>
<property name="hibernate.format_sql">trueproperty>
<property name="hibernate.hbm2ddl.auto">updateproperty>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialectproperty>
<mapping resource="cn/itcast/entity/Car.hbm.xmL"/>
session-factory>
hibernate-configuration>
4、使用框架
4.1、创建实体类
package com.hibernate;
import javax.persistence.criteria.CriteriaBuilder;
import java.io.Serializable;
/**
* @author pgg
* @date 2022/4/6
*/
public class Car implements Serializable {
private Integer cid;
private String cname;
private String color;
public Car() {
}
public Car(Integer cid, String cname, String color) {
this.cid = cid;
this.cname = cname;
this.color = color;
}
public Integer getCid() {
return cid;
}
public void setCid(Integer cid) {
this.cid = cid;
}
public String getCname() {
return cname;
}
public void setCname(String cname) {
this.cname = cname;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
}
4.2、自定义orm配置文件
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.hibernate.Car" table="t_car">
<id name="cid" column="cid">id>
<property name="cname" column="cname"/>
<property name="color" column="color"/>
class>
hibernate-mapping>
4.3、编写dao,使用hibernate实现语句库的交互
4.3.1、hiberante有一个Session对象,该对象提供了CRUD方法
4.3.1.1、每一个session对象内置connection连接
4.3.1.2、session.save/update/delete/get()…
4.3.2、hibernate有一个sessionFactory对象,创建session对象:sessionFactory.openSession()
4.3.3、hibernate有一个Configuration对象,创建sessionFactory对象
第一步 加载hibernate核心配置文件
第二步 创建SessionFactory对象
第三步 使用SessionFactory创建session对象
第四步 开启事务
第五步 写具体逻辑 crud操作
第六步 提交事务
第七步 关闭资源
@Test
public void testAdd() {
// 第一步 加载hibernate核心配置文件
// 到src下面找到名称是hibernate.cfg.xml
//在hibernate里面封装对象
Configuration cfg = new Configuration();
cfg.configure();
// 第二步 创建SessionFactory对象
//读取hibernate核心配置文件内容,创建sessionFactory
//在过程中,根据映射关系,在配置数据库里面把表创建
SessionFactory sessionFactory = cfg.buildSessionFactory();
// 第三步 使用SessionFactory创建session对象
// 类似于连接
Session session = sessionFactory.openSession();
// 第四步 开启事务
Transaction tx = session.beginTransaction();
// 第五步 写具体逻辑 crud操作
//添加功能
User user = new User();
user.setUsername("小王");
user.setPassword("250");
user.setAddress("日本");
//调用session的方法实现添加
session.save(user);
// 第六步 提交事务
tx.commit();
// 第七步 关闭资源
session.close();
sessionFactory.close();
}
四:hibernate操作对象状态
瞬时态:刚刚创建的对象属于瞬时态,在jvm中存在,在数据库和session对象中部存在
持久态:jvm中存在,数据库中存在,session缓存中存在,操作jvm中对象,就会通过session,自动更新数据库中的数据
save()、update() 是将瞬时态对象 转换成持久态
get() 直接获取一个持久态
注意:delete 删除的对象必须是持久态,删除后属于瞬时态
游离态:jvm中存在,数据库中存在,session缓存中不存在
session.close()、session.clear()
五:hibernate的crud
1、hiberante有一个Session对象,该对象提供了CRUD方法,其直接提供的方法只能实现但记录的CRUD
一:session提供的单条记录的查询
package com.hibernate.dao;
import com.hibernate.domain.Car;
import com.hibernate.util.HibernateUtil;
import org.hibernate.Session;
public class CarDao {
public void find1(){
Session session= HibernateUtil.getSession();
Car car=session.get(Car.class,1);
System.out.println(car.getCname());
}
public void find2(){
Session session=HibernateUtil.getSession();
Car car=session.load(Car.class,1);
System.out.println(car);
}
}
六:get和load的特点
懒加载:懒加载不是不加载,只加载id主键,当需要使用数据再通过id去与数据库交互查询
相同点:都是根据主键查找单条记录
不同点:
get方法会从数据库直接获取数据对象,如果没有数据,返回null
load方法会先获得一个代理对象,再需要使用数据时再从数据库中获取数据(懒加载),如果数据不存在,则在获取时抛出异常
load方法查询时,默认是懒加载查询,可以通过设置,关闭懒加载(2中方式)
方式一:在orm文件中通过懒加载属性关闭
<hibernate-mapping>
<class name="com.hibernate.domain.Car" table="t_car" lazy="false">
<id name="cid" column="cid"></id>
<property name="cname" column="cname"/>
<property name="color" column="color"/>
</class>
</hibernate-mapping>
方式二:将实体类Car,使用final关键字修饰
load方法懒加载的体现是先获得代理,然后需要数据时代理再查数据;代理实现有两种方式:1、基于父类 2、实现接口 确保代理对象与目标实体对象有相同的api(方法),final修饰的类不能被继承,即不能产生代理,即关闭懒加载
public final class Car implements Serializable {
private Integer cid;
private String cname;
private String color;
public Car() {
}
}
关闭懒加载后,数据存在,直接获得数据对象,数据不存在,依然会抛出异常
七:hibernate增删改查操作
注意:增删改时需要开启事务,提交事务
1、保存:session.save(对象);
/**
* 保存
*/
public void save1(){
Car car=new Car(1,"bm3","蓝色");
Session session=HibernateUtil.getSession();
session.beginTransaction();//开始事务
session.save(car);
session.getTransaction().commit();//提交事务
}
2、修改:session.update(对象);
扩展:对于持久态对象,修改对象就相当于修改数据,而不需要执行修改方法
/**
*修改的方法
*/
public void update1(){
Car car=new Car(1,"bm2","白色");
Session session=HibernateUtil.getSession();
session.beginTransaction();//开始事务
session.update(car);
session.getTransaction().commit();//提交事务
}
/**
* 扩展修改的方法 只针对持久态对象
*/
public void update(){
Session session=HibernateUtil.getSession();
Car car=session.get(Car.class,1);//持久态
car.setColor("红色");
session.beginTransaction();//开始事务
session.getTransaction().commit();//提交事务
}
3.删除:session.delete(对象);不能通过主键删除
尽管从删除逻辑而言,通过主键数据就可以删除整体记录,但Hibernate对数据库的操作都是一对象的操作体现的,所以删除时也必须删除对象(1、对象可以只包含主键 2、对象必须时持久态才能删除)
/**
* 方式一:删除操作
*/
public void delete1(){
Session session=HibernateUtil.getSession();
Car car=new Car();
car.setCid(1);
session.beginTransaction();//开始事务
session.delete(car);
session.getTransaction().commit();//提交事务
}
/**
* 方式二:删除操作
*/
public void delete2(){
Session session=HibernateUtil.getSession();
Car car=new Car();
car.setCid(1);
session.beginTransaction();//开始事务
session.delete(car);
session.getTransaction().commit();//提交事务
}
/**
* 方式三:删除操作
*/
public void delete3() throws InterruptedException {
Session session=HibernateUtil.getSession();
Car car=new Car(1,"bmw","red");
session.beginTransaction();//开始事务
session.save(car);
session.getTransaction().commit();//提交事务
Thread.sleep(20000);
session.beginTransaction();//开始事务
session.delete(car);
session.getTransaction().commit();//提交事务
}
4、扩展:
保存或修改:session.saveOrUpdate(对象);先根据主键值做查询,数据存在执行修改,数据不存在,执行保存
/**
* 保存或修改
*/
public void saveOrUpdate1(){
Session session=HibernateUtil.getSession();
Car car=new Car(1,"bmw","blue");
session.beginTransaction();//开始事务
session.saveOrUpdate(car);
session.getTransaction().commit();//提交事务
}
5、扩展
保存或修改:session.merge(对象) ;先根据主键值做查询,数据存在执行修改,数据不存在,执行保存
/**
* 保存或修改
*/
public void merge(){
Session session=HibernateUtil.getSession();
Car car=new Car(1,"bmw","blue");
session.beginTransaction();//开始事务
session.merge(car);
session.getTransaction().commit();//提交事务
}
saveOrUpdate和merge区别:
1、区别体现再修改时,
2、无论哪个方法实现修改,都可以将瞬时态对象转换成持久态对象,如果再session缓存中,之前已经存在了一个相同的id的持久态对象,那么saveOrUpdate方法会抛出异常(有两个不同的对象却有相同的id),但是merge方法会修改成功,因为merge会将两个相同的对象数据合并
merge修改的对象并没有变成持久态,而是将对象的数据覆盖到原持久态对象中
扩展:保存时的主键生成机制
只需要在orm配置文件中,使用id的子标签《generator》标签指定生成机制
HIbernate提供了多种主键生成机制,常用的有:
1、uuid varchar主键 32位16进制唯一数
2、identity 一般时mysql等 int类型的主键 自增,需要在建表时也设置主键自增
3、sequence 是oracle int类型的主键,序列自增,因为Oracle的序列是一个独立的数据库对象,拥有自己的名字,所以在设置sequence序列生成机制时需要通过传递指定序列的名,如果没有传递,则默认使用hibernate_sequence名字的 序列
4、foregin 一对一关联时,有关联表外键值充当主键值
5、assigned 默认 手动提供主键值
6、native:使用当前数据库默认支持的主键生成方式,如果是mysql则相当于identity,如果是Oracle,则相当于是sequence
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.hibernate.domain.Book" table="t_book" lazy="false">
<id name="bno" column="bno">
<generator class="uuid">generator>
id>
<property name="bname" column="bname"/>
<property name="author" column="author"/>
class>
hibernate-mapping>
注意:使用主键生成机制时,save方法执行保存后,会以返回值的形式将生成的主键返回