基础开源框架—hibernate-02

1.实体类(持久化类)编写规则

1.什么是持久化类

Hibernate是持久层的ORM映射框架,专注于数据的持久化工作。所谓的持久化,就是将内存
中的数据永久存储到关系型数据库中。那么知道了什么是持久化,什么又是持久化类呢?其实所谓的持久化类指的是一个Java类与数据库表建立了映射关系,那么这个类称为是持久化类。其实你可
以简单的理解为持久化类就是一个Java类有了一个映射文件与数据库的表建立了关系。

2.实体类编写规则

(1)类里面有无参数构造

(2)属性是私有的

(3)私有属性提供的公开的get和set方法

(4)要求实体类里面有一个属性和表里面主键对应

(5)建议:实体类写属性类型时候,建议不写基本数据类型,写对应包装类

  • byte short int long float double char boolean
  • int:Integer char:Character ,其他首字母大写 比如 double :Double
    在这里插入图片描述

3.为什么写包装类

(1)使用包装类更准确表示数据值
比如 表示学生分数 int score = 100;
表示学生得了0分:int score = 0;
表示学生没有参数考试:int score = 0;
写包装类Integer score = 0;学生得了0分 Integer score = null;表示学生没有参加考试

2.Hibernate主键生成策略

在讲解Hibernate的主键生成策略之前,先来了解两个概念,即自然主键代理主键,具体如下:

1.主键

**自然主键:**把具有业务含义的字段作为主键,称之为自然主键。例如在customer表中,如
果把name字段作为主键,其前提条件必须是:每-一个客户的姓名不允许为null,不允许客
户重名,并且不允许修改客户姓名。尽管这也是可行的,但是不能满足不断变化的业务需
求,一旦出现了允许客户重名的业务需求,就必须修改数据模型,重新定义表的主键,这
给数据库的维护增加了难度。

**代理主键:**把不具备业务含义的字段作为主键,称之为代理主键。该字段- -般取名为“ID”,
通常为整数类型,因为整数类型比字符串类型要节省更多的数据库空间。在上面例子中,
显然更合理的方式是使用代理主键。
简单理解:
1 自然主键和代理主键
(1)自然主键:表主键字段和业务相关的
- 身份证号码
(2)代理主键(一般使用):表主键字段和业务不相关的

2 .hibernate要求实体类里面有一个属性作为唯一值,对应表主键,主键有不同的生成策略,hibernate主键生成策略有很多的值
在这里插入图片描述

3.在class属性里面有很多值
(1)native: 根据使用数据库自动识别生成策略值,比如使用mysql数据库识别使用inentity

  • 如果表主键是自动增长,字段类型必须是int类型
    (2)uuid:把生成策略写成uuid之后,添加数据时候,自动生成uuid值,添加主键里面
    生成策略是uuid时候,主键类型varchar类型

在这里插入图片描述

3.实体类操作

调用 session的方法
(1)添加:save方法
(2)修改操作:update方法
(3)根据id查询:get方法
(4)删除:delete方法
saveOrUpdate方法:可以保存,可以实现修改

4.实体类对象状态(概念)

1 实体类状态有三种

(0)区别状态方式:

  • 判断实体类对象里面是否有id值
  • 判断实体类对象是否与session对象有关联

(1)瞬时态:对象里面没有id值,和session没有关联
在这里插入图片描述
(2)持久态:对象里面有id值,和session有关联
在这里插入图片描述

(3)托管态:对象里面有id值,和session没有关联

2 演示操作实体类对象的方法

根据实体类对象不同的状态实现不同的操作
(1)saveOrUpdate方法:

  • 如果实体类对象状态是瞬时态,执行添加操作

  • 在这里插入图片描述
    在这里插入图片描述
    如果实体类对象是持久态,执行修改操作
    在这里插入图片描述
    在这里插入图片描述

  • 如果实体类对象是托管态,执行修改
    在这里插入图片描述
    如果使用托管态时候,id值不存在,不是做添加操作,修改操作

3 实体类三种状态转换(看懂)

在这里插入图片描述

(1)瞬时态和持久态之间转换

  • 瞬时态转换持久态:调用session里面save方法或者saveOrUpdate方法实现
    ** 调用save方法之后,与session有关联了,添加数据里面有id值
  • 持久态转换瞬时态:调用session里面delete方法实现

(2)托管态和持久态之间转换

  • 持久态转换托管态:把session关闭
  • 托管态转换持久态:调用update或者saveOrUpdate方法实现

4 持久态自动更新数据库
在这里插入图片描述

5.Hibernate的一级缓存

1.什么是缓存

1 hibernate框架本身提供很多优化机制,一级缓存其中一种优化机制

2 什么是缓存
(1)之前存储数据存到数据库里面,比如mysql数据库里面,数据库本身是文件系统
操作数据库相当于操作文件,使用流方式操作文件,文件里面有很多内容,使用流方式做读写操作,很慢
(2)缓存:数据本身不是存储到文件里面,存到系统内存里面,获取数据效率很高

2.Hibernate缓存

1 hibernate框架中提供很多优化方式,hibernate的缓存就是一个优化方式

2 hibernate缓存有两种
第一种 一级缓存
(1)hibernate中一级缓存默认存在的,可以使用
(2)一级缓存使用范围:session对象范围的缓存,session创建到session关闭范围
(3)一级缓存中缓存 持久态 数据
(4)一级缓存使用集合结构

第二种 二级缓存(替代技术redis)
(1)默认不是打开的,需要配置使用
(2)二级缓存使用依赖于其他组件使用
(3)二级缓存范围不是session范围的,是sessionFactory范围

3.验证一级缓存存在

1 验证方式
使用同样的id值查询两次
(1)首先根据id=8a7e8411593de1d501593de1d7d70000值查询
(2)再根据这个id=8a7e8411593de1d501593de1d7d70000值查询
在这里插入图片描述
(1)第一次调用get方法发送sql语句查询数据库
(2)第二个调用get方法没有发送sql语句,数据从hibernate的一级缓存中获取

2.一级缓存执行过程

在这里插入图片描述

3.一级缓存特性

1 持久态自动更新数据库
在这里插入图片描述

做修改时候,根据id调用get方法查询,向返回对象里面设置值,最后不需要调用update方法实现修改

2 执行过程(了解)
一级缓存快照区(副本)
文字描述:
(1)一级缓存范围是session范围,创建session之后,创建一级缓存,除了一级缓存,一级缓存还会有一个对应一块区域,称为一级缓存对应的快照区
(2)调用get方法,首先到一级缓存找是否有相同数据,如果没有查询数据库,返回user持久态对象,把返回user对象放到一级缓存中,除了放到一级缓存中,还会放到一级缓存对应快照区
(3)修改user对象里面值时候,修改持久态对象里面值,同时会去修改一级缓存中内容,但是不会修改快照区内容
(4)最终提交事务,提交时候,做事情:比较一级缓存和快照区内容是否一样,如果不一样把一级缓存中更新到数据库里面,如果一样不会更新

在这里插入图片描述

6.Hibernate事务操作

1.事务相关概念

1 什么是事务
(1)逻辑上一组操作,要么都成功,如果有一个失败都失败
(2)转账例子

2 事务特性
(1)四个特性:原子性、一致性、隔离性、持久性
(2)隔离性:多个事务操作之间不会产生影响

3 不考虑隔离性产生问题
(1)脏读:一个事务读到另一个事务没有提交数据
(2)不可重复读:一个事务读到另一个事务提交update数据
(3)虚(幻)读:一个事务读到另一个事务提交insert数据

4 设置事务隔离级别
(1)mysql默认隔离级别:repeatable read

7.Hibernate绑定session

1 session类似于jdbc的connection,之前web阶段学过 ThreadLocal
(0)与线程绑定,把数据库连接与线程绑定
(1)保证session肯定不能被公用,把session与本地线程绑定

2与本地线程绑定session

3 获取与本地线程session
(1)在hibernate核心配置文件中配置
在这里插入图片描述
thread

(2)这个值到hibernate.properties里面没有

(2)调用sessionFactory里面的方法得到
在这里插入图片描述

4 获取与本地线程绑定session时候,关闭session报错,不需要手动关闭了
在这里插入图片描述

5 hibernate配置事务隔离级别

(1)配置在hibernate核心配置文件中,使用级别对应数字配置
在这里插入图片描述
6.事务添加到Service层
在这里插入图片描述

8.Hibernate的api使用

1 在hibernate第一天时候,调用session对象里面的方法实现crud操作,做查询操作时候,只是做了根据id查询

2 下面的这几个对象,实现查询操作
(1)查询表所有记录
(2)条件查询

  • 包含模糊查询
    (3)分页查询
    (4)排序查询
    (5)投影查询
  • 不是查询所有字段值,查询部分字段值
    (6)聚集函数使用
    (7)多表查询
    (8)hibernate操作不能实现复杂查询操作,使用普通sql

1.Query对象

1 作用:
(1)使用query对象实现查询操作,写到语句实现,不是sql语句,是hibernate提供一种查询语句
(2)hql:hibernate query language,hibernate查询语言
(3)sql语句和hql语句区别:
sql语句:操作数据库表和表里面字段
hql语句:操作不是表和字段,是实体类和实体类里面属性

/1 使用query查询所有记录

@Test

public void testQueryFindALL() {

SessionFactory sessionFactory = null;

Session session = null;

Transaction tx = null;

try {

//获取sessionFactory对象

sessionFactory = HibernateUtils.getSessionFactory();

//获取session

session = sessionFactory.openSession();

//开启事务

tx = session.beginTransaction();


//1 创建query对象

// createQuery里面写hql语句

//查询所有

String hql = "from User";

Query query = session.createQuery(hql);


//2 调用query的方法得到结果

List<User> list = query.list();


for (User user : list) {

System.out.println(user);

}

//提交

tx.commit();

}catch(Exception e) {

//回滚

tx.rollback();

}finally {

//关闭

session.close();

sessionFactory.close();

}

}

4 条件查询操作
条件查询hql语句: from 实体类名称 where 属性名称=? and ….
(1)根据username查询
第一个参数是 int类型,?位置,从0开始的
第二个参数是 条件值

2 使用query条件查询

@Test

public void testQueryCondition() {

SessionFactory sessionFactory = null;

Session session = null;

Transaction tx = null;

try {

//获取sessionFactory对象

sessionFactory = HibernateUtils.getSessionFactory();

//获取session

session = sessionFactory.openSession();

//开启事务

tx = session.beginTransaction();


//1 创建query对象

//根据username查询

String hql = "from User where username=?";

Query query = session.createQuery(hql);


//2 设置条件值

//第一个参数是 int类型,?位置,从0开始的

//第二个参数是 条件值

query.setParameter(0, "岳不群");	


List<User> list = query.list();


for (User user : list) {

System.out.println(user);

}

//提交

tx.commit();

}catch(Exception e) {

//回滚

tx.rollback();

}finally {

//关闭

session.close();

sessionFactory.close();

}

}

2.Criteria对象

(1)qbc查询,query by criteria,使用qbc时候特点:不需要写hql语句,使用封装的方法实现

/3 使用criteria查询所有

@Test

public void testQBCFindall() {

SessionFactory sessionFactory = null;

Session session = null;

Transaction tx = null;

try {

//获取sessionFactory对象

sessionFactory = HibernateUtils.getSessionFactory();

//获取session

session = sessionFactory.openSession();

//开启事务

tx = session.beginTransaction();


//1 创建criteria对象

//createCriteria参数是实体类class

Criteria criteria = session.createCriteria(User.class);


//2 调用方法得到结果

List<User> list = criteria.list();


for (User user : list) {

System.out.println(user);

}

//提交

tx.commit();

}catch(Exception e) {

//回滚

tx.rollback();

}finally {

//关闭

session.close();

sessionFactory.close();

}

}

3.SQLQuery对象

1 作用
(1) hibernate操作很难实现复杂查询操作,使用普通sql,SQLQuery对象用来在hibernate里面调用普通sql语句实现功能

/4 使用SQLQuery查询所有

@Test

public void testSQLQueryFindAll() {

SessionFactory sessionFactory = null;

Session session = null;

Transaction tx = null;

try {

//获取sessionFactory对象

sessionFactory = HibernateUtils.getSessionFactory();

//获取session

session = sessionFactory.openSession();

//开启事务

tx = session.beginTransaction();


//1 创建sqlquery对象

String sql = "select * from t_user";

SQLQuery sqlQuery = session.createSQLQuery(sql);


//2 调用方法得到结果

List<Object[]> list = sqlQuery.list();


for (Object[] objects : list) {

System.out.println(Arrays.toString(objects));

}


//提交

tx.commit();

}catch(Exception e) {

e.printStackTrace();

//回滚

tx.rollback();

}finally {

//关闭

session.close();

sessionFactory.close();

}

}3)让返回list集合中每部分是对象结构

//4 使用SQLQuery查询所有

@Test

public void testSQLQueryFindAllDemo() {

SessionFactory sessionFactory = null;

Session session = null;

Transaction tx = null;

try {

//获取sessionFactory对象

sessionFactory = HibernateUtils.getSessionFactory();

//获取session

session = sessionFactory.openSession();

//开启事务

tx = session.beginTransaction();


//1 创建sqlquery对象

String sql = "select * from t_user";

SQLQuery sqlQuery = session.createSQLQuery(sql);


//2 设置返回list集合中每部分结构

sqlQuery.addEntity(User.class);


//2 调用方法得到结果

List<User> list = sqlQuery.list();


for (User user : list) {

System.out.println(user);

}

//提交

tx.commit();

}catch(Exception e) {

e.printStackTrace();

//回滚

tx.rollback();

}finally {

//关闭

session.close();

sessionFactory.close();

}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值