https://study.163.com/course/courseMain.htm?courseId=1004377001
对网易云课堂hibernate课程的文字总结:
一、实体类编写规则
1、实体类里面的属性要是私有的
2、私有属性使用公开的set和get方法进行操作
3、要求实体类有属性作为唯一值(一般使用id值)
4、实体类属性建议不使用基本数据类型,使用基本数据类型对应的包装类
(1)八个基本数据类型对应的包装类
int---Integer
char--Character
其他的都是首字母大写,比如:double--Double
(2)为什么用包装类而不用基本数据类型
比如,表示学生的分数,假如:int score;
比如学生得了0分,int score=0;
若表示学生没有参加考试,int score=0;,则不代表学生没有参加表示,不能准确的表示学生是否参加考试。
解决:使用包装类可以了,Integer score=0,表示学生得了0分
表示学生没有参加考试,Integer score = null;
二、hibernate主键生成策略
1、hibernate要求实体类里面有一个属性作为唯一值,对应表主键,主键可以不同生成策略
2、hibernate主键生成策略有很多的值
oracle不支持自动增长,即不能使用identity值
mysql不支持序列,即sequence不能使用sequence值
问题就来了,首先得识别使用的数据库,自动帮助选可以使用的值!由native来实现。
(1)native :根据使用的数据库,帮选择那个值
(2)uuid:之前web阶段写代码生成uuid值,hibernate帮我们自动生成uuid值
3、演示生成策略值uuid
(1)使用uuid生成策略,实体类id属性类型,必须字符串类型,不能是int类型
(2)配置部分写成uuid值
测试效果:
uuid是随机和唯一的
三、实体类操作
1、crud操作
(1)添加操作
调用session里面的save方法实现
(2)根据id查询
(2.1)调用session里面的 get方法实现
(3)修改操作
(3.1)首先进行查询,再修改里面的值
先根据id查询,返回对象
或者session.saveOrupdate
设置Uid不起作用,对于数据库表的自动增长字段。
实验前:
实验后:
存在的问题:
session.update存在的问题:
实验前:
实验后:
所以不建议这么写!
(4)删除操作
(4.1)调用session里面的delete方法可以实现
(4.2)第二种方法
2、实体类对象状态(概念)
(1)实体类的状态有三种
(1.1)瞬时态
对象里面没有id值,对象与session没有关联
瞬时态一般做添加的操作
(1.2)持久态(重要)
对象里面有id值,对象与session也有关联
该user是通过session查出来的,并且该user也有id值
(1.3)托管态
对象里面有id值,对象与session没有关联
(2)演示操作实体类对象的方法
(2.1)saveOrUpdate方法:既能实现添加,也能实现修改。
其是根据不同实体类状态做不同操作
四、hibernate的一级缓存
什么是缓存?
1、数据库本身是个文件系统;数据存到数据库里面。
使用流方式操作文件效率并不是很高,
(1.1)把数据存到内存里面,不需要使用流的方式就可以直接读取内存中的数据。
(1.2)把数据放到内存中,提高读取效率
hibernate缓存?
1、hibernate框架中提供了很多优化方式,hibernate中的缓存,就是一种优化方式。
2、hibernate缓存特点:
第一类hibernate的一级缓存
(1)hibernate的一级缓存默认就是打开的
(2)hibernate的一级缓存使用范围,是session范围,为从session创建到session关闭范围。
(3)hibernate的一级缓存中,存储的数据必须持久态数据
第二类hibernate的二级缓存
(1)目前已经不使用了。替代技术有:redis,用Redis替代二级缓存。
(2)二级缓存默认不是打开的,需要配置
(3)二级缓存使用范围,是SessionFactory范围
3、演示一级缓存存在操作:
(1)验证方式
首先根据uid=1进行查询,返回对象(查数据库)
其次再根据uid=1再进行查询,返回对象(查一级缓存中的内容)
代码:
第一次执行get方法之后,会发送SQL语句查询数据库
第二个执行get方法后,没有哦发送SQL语句,查询一级缓存内容
4、hibernate一级缓存的执行过程
5、hibernate一级缓存中特性
(1)持久态自动更新数据库,不需要调用session的update方法
(2)执行过程(了解)
如果一级缓存内容和对应的快照去内容相同,就不会更新到数据库中。
(3)演示
如果一级缓存内容和对应的快照去内容不相同,就会更新到数据库中。
如果一级缓存内容和对应的快照去内容相同,就不会更新到数据库中。
五、hibernate的是事务操作
1、事务相关概念:
(1)什么是事务?
事务是操作中最基本单元,所有操作要么都成功,有一个失败就全部都失败。
(2)事务的特性
原子性,一致性,隔离性,持久性
(3)不考虑隔离性产生问题
脏读:一个事务读取到另一个事务未提交的数据。
不可重复读:一个事务读到了另一个事务已经提交的update的数据,导致在同一个事务中的多次查询结果不一致。
虚读/幻读:一个事务读到了另一个事务已经提交的insert的数据,导致在同一个事务中的多次查询结果不一致。
(4)解决问题(3)的方法:设置事务隔离级别
mysql默认的隔离级别:repeatable read
2、事务代码规则写法
事务中有提交有回滚,有异常时要回滚。
(1)代码结构:
try{
开启事务
提交事务
}catch(){
回滚事务
}finally{
关闭
}
//事务规范代码
@Test
public void testTx() {
SessionFactory sessionFactory=null;
Session session=null;
Transaction tx=null;
try {
sessionFactory=HibernateUtils.getSessionFactory();
session=sessionFactory.openSession();
//开启事务
tx=session.beginTransaction();
//添加
User user=new User();
user.setUsername("小马");
user.setPassword("250");
user.setAddress("美国");
session.save(user);
int i=10/0;
//提交事务
tx.commit();
}catch(Exception e) {
e.printStackTrace();
//回滚事务
tx.rollback();
}finally {
//关闭操作
session.close();
sessionFactory.close();
}
}
3、hibernate绑定session
Session对象是单线程对象,即只能自己用不能与别人共用
怎么保证Session为单线程对象?
1.Session类似jdbc的connection,之前web阶段学过threadLocal,即绑定Session底层就是threadLocal。
2.帮我们实现了与本地线程绑定Session。
3.获取与本地线程绑定的Session
(1)在hibernate核心配置文件中配置
(2)调用SessionFactory里的方法得到
(3)测试
(4)获取与本地线程绑定session时候,关闭session报错。
因为session与本地线程绑定在一起了,操作结束,线程就结束了。本地线程结束,session已经关闭了。即本地线程结束,session会自动关闭。
注意:当你获取与本地线程session的时候,不需要手动关闭了。否则会报异常。
六、hibernate其他的api(查询)
1、Query对象查询所有记录
(1)使用query对象,不需要写SQL语句,但是写hql语句
hql:hibernate query language,hibernate提供查询语言,这个hql语句和普通SQL语句很相似
(2)hql和sql语句区别:
使用sql操作表和表字段
使用hql操作实体类和实体类中的属性
(3)查询所有的hql语句:
from 实体类名称
(4)Query对象的使用
创建Query对象
调用Query 对象里面的方法得到结果
2、Criteria对象查询所有记录
(1)使用这个对象查询操作,但是使用这个对象时候,不需要写语句,直接调用方法实现
(2)实现过程
创建criteria对象
调用对象里面的的方法得到结果
3、SQLQuery对象查询所有记录
(1)使用hibernate时候,调用底层SQL实现
(2)实现过程
创建对象
调用对象的方法得到结果
返回list集合每部分是数组
返回list中每部分是对象形式