Hibernate学习

hibernate 对象
configuration
sessionFactory
Transaction 事务对象

hibernate持久化类的编写
主键生成策略
持久化类的三种状态
一级缓存

持久化类 就是一个 javabean 这个javabean与表建立了映射关系
可以理解成持久化类就是一个javabean加上一个映射文件

编写规则
1 : 需要提供无参构造 因为要反射
2 : 类的属性要私有 提供getset
3 : 要提供一个唯一标识(OID)的属性与表的主键对应 ,
java里面使用地址区分是否是同一个对象 , 数据库里面是通过主键区分是否是同一条记录
hibernate通过唯一标识区分是否在内存中是同一个对象
3 : 类不要使用final修饰 ,不能延迟加载
4 : 类中得属性尽量使用包装类
5 : 实现序列化接口

主键生成策略
自然主键 : 表的字段本身作为主键
代理主键 : 不是类本省的属性作为主键

increment hibernate底层的自动增长 , 用于int,long,short类型 ,只有当没有其他进程向同一张表插入数据的时候才能使用 , 不能再集群环境下使用 , 适用于代理主键
indentity : 采用的数据库底层是自动增长机制 mysql
sequence : 用数据库的序列生成主键 , 需要数据库支持序列 oracle
native : 根据数据库底层自动选择identity,sequence,hilo三种生成器的一中
uuid : 字符串标识符 32位十六进制字符串
assigned : 由java程序生成 自然主键

hibernate持久化类的三种状态
瞬时态
持久态
托管态

瞬时态: 持久化对象没有持久化标识OID , 而且没有被session管理
持久太 : 有OID ,被Session管理
托管态 : 有OID , 没有被session管理

持久态对象可以自动更新数据库

hibernate的一级缓存
持久态的自动更新数据库就是因为一级缓存
减少对数据库的访问次数

hibernate向一级缓存放入数据时 , 同时复制一份数据放入Hibernate快照中 , 当使用commit()方法提交事物的时候 , 同时会清理session中的一级缓存,这时会使用OID判断一级缓存中的对象和快照中的对象是否一致 , 如果两个对象中的属性发生变化 , 则执行update语句 , 将缓存中的内容同步到数据库 , 并且更新快照 , 如果一致,则不执行update语句
Hibernate的快照的作用就是确保一级缓存中的数据和数据库中的数据一致

hibernate的事物管理
事物是逻辑上的一组操作 , 组成这组操作的各个单元要么全都成功 , 要么全都失败

事物的特性
原子性:不可分割
一致性 : 事物执行前后 ,数据的完整性保持一致
隔离性 : 一个事物执行的过程中不应该受到其他事物的干扰
持久性 , 事物一旦结束 , 数据持久到数据库

hibernate的api
Query接口 支持HQL查询
通过session.createQuery(String hql)获得
hql hibernate查询语言 和sql类似 面向对象的写法

Criteria 支持QBC查询

SQLQuery 支持SQL查询


Hibernate复习
1.1.1.1什么是Hibernate

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

Hibernate六大核心接口,两个主要配置文件,以及他们直接的关系。Hibernate的所有内容都在这了。那我们从上到下简单的认识一下,每个接口进行一句话总结。
1、Configuration接口:负责配置并启动Hibernate
2、SessionFactory接口:负责初始化Hibernate
3、Session接口:负责持久化对象的CRUD操作
4、Transaction接口:负责事务
5、Query接口和Criteria接口:负责执行各种数据库查询
注意:Configuration实例是一个启动期间的对象,一旦SessionFactory创建完成它就被丢弃了。

介绍一下Hibernate的实现原理?   使用Hibernate的一般步骤是:
1.创建配置文件,和实体类,并使用Configuration的对象去生成SessionFactory对象,(默认)加载hibernate.cfg.xml这个核心配置文件,该核心文件里包含了对数据源的连接和一些属性的设置等,当然还包含有映射实体关系配置文件。
2.  生成的SessionFactory,等于是可以获取数据库的连接(能创建session),从而可以操作数据库
  3.  因为核心配置Hibernate.cfg.xml里引入了实体关系映射配置文件,故该文件也会自动被解析——加载对象-关系映射文件:vo类.hbm.xml
4、然后是创建session对象,通过SessionFactory创建session。session可以操作数据库
5.  开启事务,也是通过session开启
6.  调用session API,CRUD 对象
 7.  根据Dialect(之前在核心配置文件配置的数据库方言)生成和底层数据库平台相关的sql代码
8.  对JDBC封装,执行sql脚本。     从本质上而言,Hibernate最终还是通过JDBC去操作数据库。只是对JDBC进行了封装。
Hibernate实现原理中使用的技术有什么?
  针对主流的XML文件配置方式,Hibernate实现原理中使用的关键技术主要有两个。一是对XML文档的解析——使用DOM(文档对象模型)/SAX解析,Hibernate使用了常见的开源解析工具——dom4j(使用Java编写,很流行),二是Java的反射技术,比如我可以通过一个Java类的对象,通过反射机制来获取这个对象的类的属性,方法……简单说,就类似我自己照镜子,通过镜子,我可以看清楚我自己身体的各个部位。
  当然了,还有基于注解的方式,那么就还要使用Java的注解技术,本质上大同小异,熟能生巧。

Hibernate的优/缺点:
 
优点:
1、更加对象化
      以对象化的思维操作数据库,我们只需要操作对象就可以了,开发更加对象化。
2、移植性
      因为Hibernate做了持久层的封装,你就不知道数据库,你写的所有的代码都具有可复用性。
3、Hibernate是一个没有侵入性的框架,没有侵入性的框架我们称为轻量级框架。
      对比Struts的Action和ActionForm,都需要继承,离不开Struts。Hibernate不需要继承任何类,不需要实现任何接口。这样的对象叫POJO对象。
4、Hibernate代码测试方便。
5、提高效率,提高生产力。
 
缺点:
1、使用数据库特性的语句,将很难调优
2、对大批量数据更新存在问题
3、系统中存在大量的攻击查询功能

1.1.1.2什么是ORM
ORM:Object Relational Mapping。对象关系映射。开发语言用的是Java,面向对象的(Object)。使用的数据库是关系型数据库(Relational)。就是将对象与数据库中的表建立一种映射关系,操作对象就可以操作这个表。

核心api
加载hibernate核心配置文件
Configuration configure = new Configuration().configure();
创建sessionFactory对象
SessionFactory sessionFactory = configure.buildSessionFactory();
获取session
Session session = sessionFactory.openSession();
开启事物
Transaction transaction = session.beginTransaction();

1.1.1.3Configuration:配置对象
Configuration是一个配置对象,作用主要有两个,一个用来加载核心配置文件。另一个用来加载映射文件。
【加载核心配置文件】
加载hibernate.properties
Configuration cfg = new Configuration();

加载hibernate.cfg.xml
Configuration cfg = new Configuration().configure();
【加载映射文件】
// 手动加载映射文件
// configuration.addResource(“com/itheima/hibernate/domain/Customer.hbm.xml”);
// configuration.addClass(Customer.class);
1.1.1.4SessionFactory:Session工厂
SessionFactory负责管理Session,管理连接池,管理Hibernate二级缓存。采用了工厂模式,不是一个轻量级的对象。通常情况下一个项目只对应一个SessionFactory就够了。是线程安全的对象。
【抽取Hibernate的工具类】
public class HibernateUtils {

private static final Configuration configuration;
private static final SessionFactory sessionFactory;

static{
    configuration = new Configuration().configure();
    sessionFactory = configuration.buildSessionFactory();
}

public static Session openSession(){
    return sessionFactory.openSession();
}

}
1.1.1.5Session:相当于Connection
Session是Hibernate程序与数据库之间的桥梁。完成CRUD的操作。Session是一个单线程的对象,内部维护了Hibernate的一级缓存。
Save
查询:get&load
get方法和load方法的区别?
* * get方法采用的是立即加载,执行到该行代码的时候,马上发送SQL语句进行查询。查询之后返回的是真实对象本身。
* 查询一个找不到的对象返回null.
* * load方法采用的是延迟加载(lazy),执行到改行的代码的时候,不会马上发送SQL语句,
* 只有真正使用这个对象的时候(使用这个对象的普通属性的时候)才会发送SQL语句。
* load方法返回的是代理对象。(产生的是Customer的子类对象)
* 查询一个找不到的对象抛出异常:ObjectNotFoundException
Get方法会立即查询,查询不到会抛出异常,load方法,懒加载,要用的时候才去查询,用load方法是认为数据库一定有这个数据,所以可以放心的到要用的时候去加载

不管是修改还是删除,new一个对象 
这个对象必须指定id;
不推荐new一个对象 , 会把其他的属性置位null

Commit的时候:
  比较一级缓存的数据和快照的数据是否一致,如果不一致
就将一级缓存的数据更新到快照区并发送sql语句到数据库
所以并不需要update就能完成修改

从数据库查询数据的时候,

1.1.2持久化类的三种状态
1.1.2.1瞬时态
瞬时态:持久化对象没有持久化标识OID,对象没有被Session管理。
1.1.2.2持久态(*
持久态:持久化对象有持久化标识OID,对象被Session管理。
可以自动更新数据库,查询过后直接设置修改,自动更新 不用调用update
1.1.2.3脱管态
脱管态:持久化对象有持久化标识OID,对象没有被Session管理。

1.1.3Hibernate的一级缓存 重点!!!
1.1.3.1什么是一级缓存
,增删改查操作都会进入一级缓存,只有oid查询会从一级缓存获取,其他查询不会,根据id查询
一级缓存称为是Session级别的缓存,一级缓存的生命周期与Session是一致的。一级缓存其实由Session中的一组集合构成的。

一级缓存和快照区:
所有的查询操作都会进去一级缓存和快照区;
因为快照区的存在,才能自动更新数据库;
事物提交的时候 , 比较缓存区和快照区的数据是否一致
如果不一致,更新数据库,所以一般都是先查询在操作

1.1.4Hibernate的事务管理
1.1.4.1什么是事务

事务是逻辑上的一组操作,组成这组操作的各个单元要么全都成功,要么全都失败!
1.1.4.2事务的特性
原子性:不可分割。
一致性:事务执行前后,数据的完整性保持一致。
隔离性:一个事务执行的过程中不应该受到其他事务的干扰。
持久性:事务一旦结束,数据持久到数据库。
1.1.4.3如果不考虑隔离性,引发哪些问题?
脏读:一个事务读到另一个事务未提交的数据。
不可重复读:一个事务读到另一个事务已经提交的update数据,导致多次查询结果不一致。
虚读:一个事务读到另一个事务已经提交的insert数据,导致多次查询结果不一致。
1.1.4.4避免读问题:
设置隔离级别:

1.1.4.5Hibernate中设置事务隔离级别

4
1.1.4.6与线程绑定的Session的使用
业务层是添加事物最好的地方,
必须保证开始事物的连接和dao中使用相同的连接才可以
1: 传递 . 不是特别到 dao 的方法就有依赖性了
2: 绑定到当前线程中 ThrealLocal.(key值是线程id,value是对象)

在hibernate配置文件中

thread

1.1.5Hibernate的其他的API
1.1.5.1Query:支持HQL查询
查的对象 里面写 from 类名 不支持的写法 count()可以)
分页查询 : query.setFirstResult(3)
      query.setMaxResult(3)
q
获得Query接口可以通过session.createQuery(String hql);获得。
HQL:Hibernate Query Language。Hibernate查询语言。语法与SQL是类似的。HQL中查询的是对象。
Session session = HibernateUtils.openSession();
Query query = session.createQuery(“from Customer where cust_name=?”);
query.setString(0, “张”);

1.1.5.2Criteria:支持QBC查询
session.createCriteria();处理一些复杂的查询,完全的对象操作,
主要是条件查询
获得Criteria接口可以通过session.createCriteria();获得。
QBC:Query By Criteria。条件查询。一种更加面向对象的方式。
public void demo4(){
Session session = HibernateUtils.openSession();
Criteria criteria = session.createCriteria(Customer.class);
criteria.add(Restrictions.eq(“cust_name”,”李四”));
List list = criteria.list();
for (Object o : list) {
System.out.println(o);
}
}

1.1.5.3SQLQuery:支持SQL查询

获得SQLQuery接口可以通过session.createSQLQuery();获得。
SQLQuery:通过SQL语句进行查询。

1.1.6Hibernate的一对多的关联关系映射











1.1.7Hibernate的一对多的级联操作
1.1.7.1级联保存或更新
级联操作:操作一个对象的时候,同时操作其关联的对象。
级联保存:
* * 保存客户同时级联保存联系人。
* * 保存的主体对象是客户对象,那么就需要在Customer.hbm.xml文件中配置。
* * 在标签上配置cascade=”save-update”
级联删除:
* * 删除客户同时级联删除联系人。
* * 在Customer.hbm.xml中的上配置cascade=”delete”

Hibernate关联关系:多对多








1.1.8Hibernate的多对多的级联操作
*
* 保存用户同时级联角色
* 在User.hbm.xml中的上配置cascade=”save-update”
保存角色同时级联用户
* 在Role.hbm.xml中的上配置cascade=”save-update”
1.1.8.1级联删除(了解)
【删除用户级联删除角色】
@Test
/**
* 删除用户同时级联删除角色
* 在User.hbm.xml中配置cascade=”delete
1.1.9Hibernate多对多的其他的操作:
1.1.9.1为某个用户添加角色
@Test
/**
* 给1号用户添加2号角色
*/
public void demo6(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
// 查询一号用户
User user = session.get(User.class, 1l);
// 查询二号角色
Role role = session.get(Role.class, 2l);
user.getRoles().add(role);

    tx.commit();
}

1.1.9.2为用户删除某个角色
@Test
/**
* 给1号用户添加1号角色
*/
public void demo7(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
// 查询一号用户
User user = session.get(User.class, 1l);
// 查询一号角色
Role role = session.get(Role.class, 1l);
user.getRoles().remove(role);

    tx.commit();
}

1.1.9.3为用户改选角色
@Test
/**
* 给2号用户将2号角色改为3号角色
*/
public void demo8(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();

    User user = session.get(User.class, 2l);

    Role role2 = session.get(Role.class, 2l);
    Role role3 = session.get(Role.class, 3l);
    user.getRoles().remove(role2);
    user.getRoles().add(role3);

    tx.commit();
}

Hibernate的查询的方式
1.1.10Hibernate的五种查询的方式
对象图导航查询:通过某个对象获得到其关联对象。
Customer c = session.get(Customer.class,1l);
Set linkMans = c.getLinkMans();
OID检索:根据对象的ID查询
get/load();
HQL检索:通过传入的HQL进行查询。
HQL:Hibernate Query Language.语法与SQL类似。面向对象的查询方式。
QBC检索:通过传入Criteria对象进行查询。
QBC:Query By Criteria.更加面向对象的方式查询。
SQL检索:通过SQL查询。
SQL:通过SQL语句进行查询的方式

/ 设置排序:
//criteria.addOrder(Order.asc(“cust_id”));// 升序
criteria.addOrder(Order.desc(“cust_id”));// 降序
// criteria.add(Restrictions.like(“cust_name”, “%强%”));
criteria.add(Restrictions.like(“cust_name”, “强”, MatchMode.ANYWHERE));

/**
* 分页查询
*/
public void demo4(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();

    Criteria criteria = session.createCriteria(LinkMan.class);
    criteria.setFirstResult(10);
    criteria.setMaxResults(10);
    List<LinkMan> list = criteria.list();

*
* 统计查询
*/
public void demo5(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();

    Criteria criteria = session.createCriteria(Customer.class);
    criteria.setProjection(Projections.rowCount());
    Long count = (Long) criteria.uniqueResult();
    System.out.println(count);
    tx.commit();

1.1.10.1离线条件查询:DetachedCriteria.
DetachedCriteria对象可以脱离session使用。使用离线条件查询对象的优点:
*
* 离线条件查询
*/
public void demo6(){
DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Customer.class);
detachedCriteria.add(Restrictions.like(“cust_name”, “%强%”));

    Session session = HibernateUtils.getCurrentSession();
    Transaction tx = session.beginTransaction();

    Criteria criteria = detachedCriteria.getExecutableCriteria(session);
    List<Customer> list = criteria.list();

1.1.11Hibernate的多表查询
1.1.11.1SQL中多表查询
【交叉连接】
select * from A,B;
【内连接】
显示内连接:inner join(inner 可以省略)
Select * from A inner join B on 条件;
隐式内连接:
Select * from A,B where 条件;
【外连接】
左外连接:left outer join
Select * from A left outer join B on 条件;
右外连接:right outer join
Select * from A right outer join B on 条件;
Hibernate的抓取策略
1.1.12延迟加载
1.1.12.1延迟加载的概述
lazy延迟加载:什么时候使用什么时候再去查询。
1.1.12.2延迟加载的分类
【类级别延迟】
使用延迟加载的方法查询某个类的时候是否采用的延迟称为是类级别的延迟。默认值是true。
Customer customer = session.load(Customer.class,1l);// 默认就会采用延迟加载,这种称为是类级别的延迟。

类级别延迟加载失效:
* final修饰这个类,不能产生代理类,延迟加载就会失效。
* 在上配置lazy=”false”
【关联级别的延迟】
查询到某个对象以后,获得其关联的对象。查询其关联对象的时候是否采用的延迟。称为是关联级别的延迟。
Customer c = session.get(Customer.class,1l);
c.getLinkMans(); // 查询关联对象的时候,是否采用延迟加载。
关联级别的延迟往往会与抓取策略一起使用,优化程序。(关联级别的延迟在或者是标签上的延迟加载)
1.1.13抓取策略
抓取策略指的是查找到某个对象后,抓取其关联的对象的时候采用的策略。抓取策略就是在关联对象的配置上(和)配置fetch属性。
1.1.13.1set上的fetch和lazy
fetch:抓取策略,控制SQL语句的发送的格式。
* select :默认值。发送一条select语句查询关联对象。
* join :发送一条迫切左外连接查询关联对象。
* subselect :发送一条子查询查询关联对象。

lazy:延迟加载,控制SQL语句的发送的时候。
* true :默认值。采用延迟加载。
* false :不采用延迟加载。
* extra :及其懒惰。

1.1.13.2many-to-one上的fetch和lazy
fetch:抓取策略,控制SQL语句的发送的格式。
* select :默认值.发送一条select语句查询关联对象。
* join :发送一条迫切左外连接查询关联对象。
lazy:延迟加载,控制SQL的发送的时机。
* proxy :默认值。是否采用延迟,需要由另一方类上的延迟加载来决定。
* false :不采用延迟加载。
* no-proxy:不用研究
1.1.14批量抓取
批量抓取:查询了多个客户的时候,查询多个客户下的所有联系人。
1.1.14.1查询客户批量抓取联系人
在Customer.hbm.xml中上配置batch-size
1.1.14.2查询联系人批量抓取客户
在Customer.hbm.xml中上配置batch-size

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值