Hibernate

概述

JavaEE三层结构

客户端层 JavaApplet,Html,CSS,JS
web层 Servlet,JSP Struts2,SpringMVC,WebWork
业务逻辑层 EJB Spring
持久层 JDBC Hiberate,Mybatis,DBUtils,JdbcTemplate

以上过于底层,故企业中使用SSH(Struts+Spring+Hiberate)、SSM(SpringMVC+Spring+Mybatis)

Hibernate概述

Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用,最具革命意义的是,Hibernate可以在应用EJB的JaveEE架构中取代CMP,完成数据持久化的重任。

Hibernate是一个持久层的ORM框架

什么是ORM

Object Relational Mapping对象关系映射,指的是将java中的对象与关系型数据库中的表建立一种映射关系,对而操作对象就可以操作数据库中的表

入门

开发环境

Hibernate3,Hibernate4.x(兼容性不好),Hibernate5.x

lib目录 Hibernate开发包
required 必须的依赖包
optional 可选的jar包

创建项目,引入jar包

  • 数据库驱动包 mysql
  • Hibernate开发的必须jar包 Hibernater
  • Hibernate引入日志记录包 log4j

创建表

创建实体类

创建映射

通过XML,可任意命名。
Hibernate命名规范:类名.hbm.xml

在xml中增加约束:在org.hibernate的hibernate-mapping.dtd中找到并拷贝过来

//建立映射

<class name=“全路径类” table=“表名“>

//表示主键本地生成

<property name=成员变量” column=“字段”/>

创建Hibernate核心配置文件

hibernate.cfg.xml
在src目录下新建
同样添加约束(在hibernate-configuration.dtd中找)

对应的类名//还有3个 方言类
	<mapping resource="hbm.xml的全路径">//这里全路径用/,不用.
</session-factory>

上述property有4个,driver_class、url、username、password,属性名和类名在hibernate.property中找

编写测试类

1.加载Hibernate的核心配置文件
Configuration configuration = new Configuration().configure();
2.创建一个SessionFactory对象,相当于JDBC中的连接池
SessionFactory sessionFactory = configuration.buildsessionFactory();
3.通过SessionFactory获取到Session对象,相当于JDBC中的Connection
Session session = sessionFactory.openSession();
4.手动开启事务
Transaction transaction = session.beginTransaction();
5.编写代码
Customer = customer = new Customer();
customer.setCust_name(“eee”);
session.save(customer);
6.事务提交
transaction.commit();
7.资源释放
session.close();
sessionFactory.close();

Hibernate常见配置

XML的提示配置

Hibernate映射的配置

class标签的配置:
用来建立类与表的映射关系
属性name:表示类的全路径
table:表示表名(表名与类名一致时,table可以省略)
catalog:数据库名

id标签的配置:
用来建立类中的属性与表中的主键的对应关系
name:类中的属性名
column:表中的字段名(类中的属性名和表中的字段名如果一致,column可以省略)
length:长度
type:类型(可不写,会自动转换)
property标签的配置
用来建立类中的普通属性与表的字段的对应关系
name
column
length
type
not-null
unique

Hibernate的核心配置

必须的配置:
连接数据库的基本参数:驱动类、url路径名、用户名、密码
方言

可选的配置:
显示sql:hibernate.show_sql
格式化sql:hibernate.format_sql
自动建表:hibernate.hbm2ddl.auto
none:不使用hibernate自动建表
create:如果数据库中已有表,删除原有类,重新创建,如果没有则新建表
create-drop:如果数据库中已有表,删除原有表,执行操作,再删除这个表;如果没有,新建表,使用完了删除该表
update:如果数据库中有表,使用原表,如果没有表,创建新表(更新表结构)
validate:如果没有表,不会创建表,只会使用数据库中原有的类(校验映射和表结构是否一致)

映射文件的引入:
引入映射文件的位置

两种方式:
1.属性文件的方式
属性文件方式不能引入映射文件(手头编写代码加载)
2.XML文件的方式
hibernate.cfg.xml

核心API

Configuration

Hibernate配置对象,对Hibernate进行配置和启动。
作用:
1.加载核心配置文件
hibernate.properties
Configuration cfg = new Configuration();
hibernate.cfg.xml
Configuration cfg = new Configuration().configure();
手动加载映射
cfg.addResource("");
2.加载映射文件

SessionFactory

负责初始化Hibernate,是数据存储源的代理,负责创建Session对象

内部维护了Hibernate的连接池和二级缓存。线程安全

一个项目只需要创建一个

可抽取工具类

HiberateUtils

Session

负责执行被持久化对象的CRUD操作,与数据库交流,内部维护一级缓存,非线程安全

保存
Serializable save(Object obj);
查询
T get(Class c, Serializable id);
get和load的区别:
get采用的是立即加载,会马上发送SQL语句去查询,查询找不到的对象时返回null
load采用的是延迟加载,当真正使用这个对象的时候才会发送SQL语句,当时返回的是代理对象。javassist.jar利用javassist技术产生的代理,查询找不到的对象,返回ObjectNotFoundException
修改
update(Object obj);
推荐的是先get,再update,确保避免把其他属性覆盖掉
删除
delete(Object obj);
如果是作级联删除,需要先get,再delete
保存或更新
saveOrUpdate()
查询所有
接收HQL:Hibernate Query Language,面向对象查询语言
Query query = session.createQuery(“from Customer”);
List list = query.list();
接收SQL
SQLQuery query = session.createSQLQuery(“select * from customer”);
List<Object[]> list = query.list();

Transaction

Hibernate中管理事务的对象

Commit();
Rollback();

持久化类的编写规则

持久化:将内存中的对象持久化到数据库中的过程

持久化类:java类+映射文件

编写规则:
1.无参数的构造方法
Hibernate底层通过反射生成实例
2.属性需要私有,同时提供public的get和set方法
3.提供一个唯一标识OID与数据库主键对应
4.属性尽量使用包装类类型
5.不要使用final修饰,与延迟加载有关,如果定义为final,load与get就没有区别

主键的生成策略

主键的分类

自然主键
主键的本身就是表中的一个字段(实体中的一个具体属性)
代理主键
不是表中的必须字段

尽量使用代理主键
一旦自然主键参与到业务逻辑中,后期有可能需要修改源代码

生成策略

一般不允许用户手动设置主键,一般将主键交给数据库

increment:hibernate中提供的自动增长机制,适用于short、ing、long类型的主键。在集群中不要使用,在单线程程序中使用
首先先发送一条语句:select max(id) from 表; 然后让id+1作为下一条记录的主键

identity:适用于short、ing、long类型的主键。使用的是数据库底层的自动增长机制,适用于有自动增长机制数据库(MySQL,MSSQL),但Oracle没有自动增长机制

sequenc:适用于short、ing、long类型的主键,采用的是序列的方式。Oracle支持序列,MySQL不支持

uuid:适用字符串类型主键,使用hibernate中的随机方式生成字符串主键

native:本地策略,可以在identity和sequence之间进行自动切换,不用管底层是mysql还是oracle

assigned:hibernate放弃处理的管理,需要通过手动编写程序或用户自己设置

foreign:外部的。一对一的一种 关联映射的情况下使用。

持久化类的三种状态

瞬时态transient
这种对象没有唯一的标识OID,没有被session管理
持久态persistent
这种对象有唯一的标识OID,被session管理
可以自动更新数据库
脱管态detached
这种对象有唯一的标识OID,没有被session管理

状态转换

瞬时态对象
获得: Customer customer = new Customer();
瞬时 到 持久:save() saveOrUpdate()
瞬时 到 脱管:customer.setCust_id(1);

持久态对象
获得:get() load() find() iterate()
持久 到 瞬时:delete();
持久 到 脱管:close() clear() evict(obj)

脱管态对象
获得:Customer customer = new Customer();customer.setCust_id(1);
脱管 到 持久:update() saveOrUpdate()
脱管 到 瞬时:customer.setCust_id(null);

Hibernate的一级缓存

一级缓存:称为是session级别的缓存。一级缓存的生命周期与session一致,由session中的一系列java集合构成,是自带的,不可卸载
二级缓存:是sessionfactory级别的缓存,是需要配置的缓存,企业开发中一般不用

一级缓存的结构

快照区

设置事务隔离级别

在核心配置文件中
4

session的事务管理

确保事务中连接对象是同一个
1.向下传递,如DBUtils
2.使用ThreadLocal对象
将这个连接绑定到当前线程中
在DAO的方法中,通过当前线程获得连接对象

Hibernate框架内部已经绑定好了ThreadLocal
在sessionfactory中提供了一个方法getCurrentSession(),但是默认不能用,需要通过一个配置完成
thread

其他API

Query

接收HQL,查询多个对象
// 简单查询
String hql = “from Customer”;
// 条件查询
String hql = “from Customer where cust_name like ?”;
Query query = session.createQuery(hql);
query.setParameter(0, “吴”);
// 设置分页,可进行分布查询
query.setFirstResult(0);
query.setMaxResults(3);
query.list();

Criteria

Query By Criteria

Criteria query = sessioin.createCriteria(Customer.class);
query.list();
// 条件查询
query.add(Restrictions.like(“cust_name”, “吴%”));
query.add(Restrictions.like(“cust_name”, “吴”, MatchMode.END));

SQLQuery

Hibernate的一对多关联映射

数据库表与表的关系

1.一对多关系
一个部门对于多个员工,一个员工只能属于某一个部门
一个客户对应多个联系人,一个联系人只能属于某一个客户

一对多建表原则:
	在多的一方创建外键指向一的一方的主键

2.多对多关系
一个学生可以选择多门课程,一门课程也可以被多个学生选择
一个用户可以选择多个角色,一个角色也可以被多个用户选择

多对多建表原则:
	创建中间表,至少有两个字段,分别作为外键指向多对多双向的主键

3.一对一关系
一个公司只能有一个注册地址,一个注册地址只能被一个公司注册

一对一建表原则:
	1.唯一外键对应
	2.主键对应

2.多对多关系

Hibernate的一对多关系配置

1.创建一个项目,引入相应jar包
2.创建数据库和表
3.创建实体
在一的一方实体,放置多的一方的集合,Hibernate默认使用Set集合
在多的一方实体,放置一的一方的对象
4.创建映射文件
配置多对一的映射
name:一的一方的对象的属性名称
class:一的一方的类的全路径
column:在多的一方的表的外键名称

配置一对多的映射
name:多的一方的对象集合的属性名称
column:多的一方的外键名称
class:多的一方的类的全路径
<set name="">
	<key column=""></key>
	<one-to-many class=""/>
</set>


5.创建核心配置文件
6.引入工具类
7.编写测试类

一对多的级联操作

为了解决session保存时必须对所有对象都显示调用save方法

要操作哪个对象的保存,就在那个对象类的配置文件中进行级联配置

<many-to-one name=“customer” cascade=“save-update”…

级联删除

在没有设置级联删除时,默认情况下,修改外键为null,删除本方对象

需要级联删除,则做以下配置

<many-to-one name=“customer” cascade=“save-update, delete”…

一对多设置了双向关联时,会产生多余的SQL语句

解决多余的SQL语句:
单向维护:使一方放弃外键维护权:一的一方放弃

cascade和inverse,inverse的设置不会影响级联创建,只是影响外键的设置结果

Hibernate的多对多关系映射

两边实体类放置的都是对方的集合

name:对方的集合的属性名称
table:中间表的名称
key的column:当前的对象对应的中间表的外键的名称
class:对方的类的全路径
many-to-mnay的column:对方的对象在中间表的外键的名称


如果多对多建立了双向的关系,必须有一方放弃外键维护,通常是让被动方放弃

需要级联保存时与一对多的级联配置相同

多对多的级联删除(基本用不到)

ThreadLocal管理连接

ThreadLocal tl = new ThreadLocal<>();
conn = tl.get();

Hibernate的查询方式

五种查询方式

OID查询

根据对象的OID(主键)进行检索
使用get和load方法
session.get(Class, oid);
session.load(Class, oid);

对象导航检索

根据一个已经查询到的对象,获得其关联对象的查询方式

HQL检索

简单查询
session.createQuery(“from Customer").list();// Customer实际是类名,只是省略了全路径,不是表名
sql支持*号,hql不支持

"from Customer c"	// 别名查询
"select c from Customer c"  // 别名查询

排序查询
“from Customer order by 属性”
“from Customer order by 属性 desc” // 降序查询 asc:升序

条件查询
1.按位置绑定:根据参数的位置进行绑定
“from Customer where 属性 = ?”)
query.setParameter(0, “”)
2.按名称绑定:给参数变量取名字,如aaa
“from Customer where 属性 = :aaa”
query.setParameter(“aaa”,"")

投影查询
查询对象的某个或某些属性
“select c.属性 from Customer c” // 返回list
“select c.属性1, c.属性2 from Customer c” // 返回list<Object[]>

"select new Customer(属性1, 属性2) from Customer" // 返回list<Customer>

分页查询
query.setFirstResult(0);
query.setMaxResults(3);

分组统计查询
1.聚合函数:count() max() min() avg() sum()
“select count() from Customer" // list.get(0)或uniqueResult()
2.分组统计
"select 属性, count(
) from Customer group by 属性 having count(*) >= 2” // 返回list<Object[]>

QBC检索

简单查询
Criteria criteria = session.createCriteria(Class);
criteria.list();

排序查询
criteria.addOrder(Order.asc(“属性”));

分页查询
criteria.setFirstResult(0);
criteria.setMaxResults(10);

条件查询
criteria.add(Restrictions.eq(“属性”, “”));

Restrictions.gt		Restrictions.ge		Restrictions.lt		Restrictions.le
Restrictions.ne	Restrictions.like		Restrictions.in		Restrictions.and
Restrictions.or

统计查询
// add:where后面的条件
// addOrder:order by
// setProjection:聚合函数和group by having
criteria.setProjection(Projections.rowCount());
criteria.uniqueResult();

离线条件查询
DetachedCriteria对象,可以脱离session使用
DetachedCriteria dc = DetachedCriteria.forClass(Customer.class);
dc.add(Restriptions.eq());

Criteria criteria = DetachedCriteria.getExecutableCriteria(session);
criteria.list();
HQL的多表查询

sql的多表查询:
连接查询:
交叉连接:笛卡尔
select * from 表1,表2;
内连接:inner join inner可以省略,两个表的交集
隐式内连接
select * A,B where A.id = B.aid;
显示内连接
select * from A inner join B on A.id = B.aid;
外连接:outer join outer可以省略
左外连接:左表的所有和两个表的共同
select * from A left outer join B on A.id = B.aid;
右外连接
select * from A right outer join B on A.id = B.aid;

HQL的多表查询
连接查询
交叉连接
内连接
显示内连接
from Customer c inner join c.linkMans // 返回list<Object[]>
隐式内连接
迫切内连接:加了一个fetch,生成sql与普通显示内连接一致,fetch是为了通知Hibernate,将后面表的信息与前面表查询的对象放到一起,增加distinct则是将后面的对象添加到前面对象的属性集合中(相当于去除重复的对象)
from Customer c inner join fetch c.linkMans
select distinct c from Customer c inner join fetch c.linkMans

	外连接
		左外连接
		右外连接
		迫切左外连接

SQL检索

sqlQuery.addEntity(Customer.class); // 之后调用sqlQuery.list()可以返回list<Customer>

Hibernate的检索策略

优化手段

延迟加载

lazy懒加载
执行到该代码时,不会发送语句去查询,直到真正使用这个对角的属性时才会发送SQL语句进行查询

类级别的延迟加载

通过load方法查询某个对象时,是否采用延迟
session.load(Customer.class, 1);

配置:在中增加属性lazy=“true”

让lazy失效:
1.将lazy置为false
2.将持久化类使用final修饰
3.Hibernate.initialize();

关联级别的延迟加载

指的是在查询到某个对象时,查询其关联对象时,是否采用延迟加载
session.get(Customer.class, 1);
customer.getLinkMans(); // 通过客户获得联系人时,联系人对象是否采用了延迟加载,称为关联级别的延迟

配置:在或中增加属性lazy=“true”

抓取策略往往会和关联级别的延迟加载一起使用,优化语句

抓取策略

通过一个对象抓取到关联对象需要发送SQL语句,如何发送,发送成什么样格式,通过策略进行配置

通过或进行设置,fetch属性

fetch和lazy共同设置来优化发送的SQL语句

上的fetch和lazy

fetch:抓取策略,控制SQL语句格式
select:默认值,发送普通的select,查询关联对象
join:发送一条迫切左外连接查询关联对象(lazy不起作用,不需要设置)
subselect:发送一条子查询查询其关联对象
lazy:延迟加载,控制查询关联对象时是否采用延迟
true:默认值,查询关联对易用时采用延迟加载
false:查询关联对象时,不采用延迟加载
extra:极其懒惰

上的fech和lazy

fetch:抓取策略,控制SQL语句格式
select:默认值,发送普通的select,查询关联对象
join:发送一条迫切左外连接查询关联对象(lazy不起作用,不需要设置)
lazy:延迟加载,控制查询关联对象时是否采用延迟
proxy:默认值,具体的取值取决于另一端上的lazy的值
false:查询关联对象时,不采用延迟加载
no-proxy:(不会使用)

批量抓取

一批关联对象一起抓取 batch-size
在或上设置 batch-size=“4”

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你好!关于学习Hibernate,我可以为你提供一些指导。Hibernate是一个Java持久化框架,用于将Java对象映射到关系数据库中。它简化了与数据库的交互,提供了ORM(对象关系映射)的功能。 如果你想学习Hibernate,以下是一些建议的步骤: 1. 了解基本概念:开始之前,建议你先了解一些Hibernate的基本概念,例如持久化、实体类、会话(Session)等。这将帮助你更好地理解Hibernate的工作原理。 2. 学习Hibernate配置:Hibernate使用一个配置文件来连接数据库和定义映射关系。你可以学习如何配置Hibernate以适应你的项目需求。这包括数据库连接配置、实体类映射等。 3. 学习Hibernate实体映射:Hibernate通过注解或XML文件将Java实体类映射到关系数据库表中。你可以学习如何使用注解或XML文件来定义实体类的映射。 4. 学习Hibernate查询语言(HQL):HQL是一种类似于SQL的查询语言,用于对数据库进行查询操作。学习如何使用HQL进行查询和操作数据库是很重要的。 5. 学习Hibernate事务管理:事务管理是在处理数据库操作时非常重要的一部分。学习如何使用Hibernate进行事务管理,包括开启事务、提交事务、回滚事务等。 6. 实践项目:最好的学习方法是通过实际项目来应用所学的知识。尝试在一个小型项目中使用Hibernate来进行数据库操作,这将帮助你更好地理解和掌握Hibernate的使用。 除了上述步骤,还有很多其他方面的内容可以学习,例如缓存管理、性能优化等。希望这些步骤能够帮助你入门Hibernate!如果你有任何进一步的问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值