学习Hibernate框架笔记-第2天
持久化类的编写规则
一、持久化类的概述
1、什么是持久化类
持久化:将内存中的一个对象持久化到数据库中的过程。
Hibernate框架就是用来进行持久化的框架。
持久化类:一个Java对象与数据库中的表建立了映射关系,那么这个类在Hibernate中就被称为是持久化类。
持久化类 = Java类 + 映射文件。
二、编写规则
1、持久化类的编写规则
对持久化类提供一个无参的构造方法 : Hibernate底层需要使用反射生成实例。
属性需要私有,对私有属性提供public的get和set方法 : Hibernate中获取,设置对象的值。
对持久化类提供一个唯一标识符OID与数据库主键对应 : Java中通过对象确定是否是同一个对象,数据库中通过主键确定是否是同一个记录,在Hibernate中通过持久化类的OID的属性区分是否是同一个对象。
持久化类中的属性尽量使用包装类类型(Integer,Long,Double等):因为基本数据类型默认是0,那么0就会有很多歧义。而包装类类型默认值是null。
持久化类不要使用final进行修饰 :延迟加载本身是Hibernate的一个优化手段,返回的是一个代理对象(javassist可以对没有实现接口的类产生代理——使用了非常底层的字节码增强技术,继承这个类进行代理)。如果使用final之后,则不能被继承,就不能产生代理对象,延迟加载也就失效了;此时,load方法与get方法一致。
主键生成策略
一、主键的分类
1、自然主键
自然主键 : 主键的本身就是表中的一个字段(实体中的一个具体的属性)。
创建一个人员表,每个人员都会有一个身份证号(唯一的不可重复的),并且使用了身份证号作为主键,这种主键被称为是自然主键。
2、代理主键
代理主键 : 主键的本身不是表中必须的一个字段(不是实体中的某个具体的属性)。
创建一个人员表,没有使用人员表中的身份证号作为主键,而是用了一个与这个表不相关的字段ID(如PNO)作为主键。这种主键被称为是代理主键。
在实际开发中,要尽量使用代理主键。
因为一旦自然主键参与到业务逻辑中,后期就有可能需要修改源代码。
一个好的程序设计需要满足OCP原则 : 对程序的扩展是open的,对修改源码是close的。
二、主键生成策略
1、Hibernate的主键生成策略
在实际开发过程中一般是不允许用户进行手动设置主键的,一般是将主键交给数据库、手动编写程序进行设置的。在Hibernate中为了减少程序的编写,提供了多种主键生成策略。
increament : hibernate中提供了自动增长机制,适用于short、int、long类型的主键,并且只能在单线程程序中使用。
首先先发送一条语句:select max(id)from 表;然后让id+1作为下一条记录的主键,这个时候在多线程下就容易引发进程问题。
identity:适用于short、int、long类型的主键,它使用的是数据库底层的自动增长机制。注意:仅适用于有自动增长机制的数据库(如:MySQL、MSSQL),Oracle没有自动增长机制,故不适用。
sequence:适用于short、int、long类型的主键,采用的是序列的方式。Oracle支持序列,但是像MySQL就不能使用sequence。
uuid:适用于字符串类型的主键,它使用的是hibernate中的随机方式生成字符串主键,类似java中的uuid。
native: 本地策略,可以认为它是在identity和sequence之间进行自动切换。就是说如果你把这个本地策略配置成MySQL,此时native就相当于identity;如果你把本地策略配置成Oracle,那么此时的native就当于是sequence。
assigned:hibernate放弃外键的管理,需要通过手动编写程序或者用户自己设置。
foreign:外部的,只有在一对一的一种关联映射的情况下使用。有一种情况就是,主键对应的情况,即我的主键也是你的主键,这个时候可以用,否则都不能用这个。
持久化类的三种状态
一、持久化类的三种状态
Hibernate是持久层框架,通过持久化类完成ORM操作。Hibernate为了更好的管理持久化类,将持久化类分成三种状态。
1、 瞬时态:transient
这种对象没有唯一的标识OID,没有被session管理,称为瞬时态对象。
2、 持久态:persistent
这种对象有唯一标识OID,被session管理,称为持久态。
持久化类的持久态对象,可以自动更细你数据库。
3、 脱管态(游离态):detached
这种对象有唯一标识OID,但是没有被session管理,称为脱管态对象。
4、区分三种状态对象:
@Test
// 区分三种状态对象
public void demo1() {Session session = HibernateUtils.openSession();Transaction transaction = session.beginTransaction();Customer customer = new Customer(); // 瞬时态对象:没有唯一标识OID,没有被session管理customer.setCust_name("小明");// 可以获取保存的这条数据的idSerializable id = session.save(customer); // 持久态对象: 有唯一标识OID,被session管理,即有session操作session.get(Customer.class, id);transaction.commit();session.close();System.out.println("客户名:"+customer.getCust_name()); // 脱管态对象,有位移标识OID,但是没有被session管理
}
二、持久化类的状态转换(了解)
1、三种状态转换图
2、瞬时态对象
瞬时态对象
获得:直接创建即可,new一个
- Customer customer = new Customer();
状态转换:
瞬时–>持久:调用session的save、saveOrUpdate方法
- save(Object obj)、saveOrUpdate(Object obj);
瞬时–>脱管:给创建的对象设置一个id
- customer.setCust_id(1l);
3、持久态对象
持久态对象
获得:调用session的get、load、find、iterate方法即可
- get()、load()、find()、iterate()
- Customer customer = session.get(Customer.class,1l);
状态转换
持久–>瞬时:调用session的delete方法
- delete();
持久–>脱管:调用session的close、clear、evict方法
- close()、clear()(清空所有)、evict(Obeject obj)(清空某一个);
4、托管态对象
脱管态对象
获得:没有直接获得的办法,但可以创建完之后设置一个id
- Customer customer = new Customer();
- customer.setCust_id(1l);
状态转换
脱管–>持久:调用session的update、saveOrUpdate方法
- update(Object obj)、saveOrUpdate(Object obj);
脱管–>瞬时:将id设置为null即可
- customer.setCust_id(null);
三、持久态对象特性
1、持久化类持久态对象自动更新数据库
@Test
// 持久态对象自动更新数据库
public void demo2() {Session session = HibernateUtils.openSession();Transaction transaction = session.beginTransaction();// 获得持久态对象Customer customer = session.get(Customer.class, 1l); // 持久态对象,有自动更新数据库的功能customer.setCust_name("李小宝");// session.update(customer);transaction.commit();session.close();
}
当设置的名字和原来的一样的时候,只进行查询,不进行更新,很智能。
原理:依赖了hibernate的一级缓存。
Hibernate的一级缓存
一、缓存的概述
1、什么是缓存
缓存:是一种优化的方式,将数据存入到内存中,使用的时候直接从缓存中获取,不用通过存储源。
二、Hibernate的缓存
1、Hibernate的一级缓存
Hibernate框架中提供了多种多样的优化手段:缓存、抓取策略。
Hiernate中提供了两种缓存机制:
一级缓存
Hibernate的一级缓存称为是Session级别的缓存,以及缓存生命周期与session一致。即如果session创建了,则以及缓存也就存在了,session如果被销毁,那么一级缓存也就没有了,因为一级缓存是由session中的一系列Java集合构成的。
一级缓存是自带的不可卸载的。
二级缓存
Hibernate二级缓存是SessionFactory级别的缓存,需要配置的缓存,也就是说,二级缓存默认是不开启的,如果要使用二级缓存,则需要你自己去进行配置。
现在企业中一般很少用二级缓存,基本上不用,替代的是redis。
2、证明一级缓存的存在
@Test
// 证明一级缓存的存在
public void demo1() {Session session = HibernateUtils.openSession();Transaction transaction = session.beginTransaction();/*Customer customer1 = session.get(Customer.class, 1l); // 发送sql语句System.out.println(customer1);Customer customer2 = session.get(Customer.class, 1l); // 不发送sql语句,是从缓存里获取,不去数据库查询System.out.println(customer2);System.out.println(customer1 == customer2);*/Customer customer = new Customer();customer.setCust_name("王峰");Serializable id = session.save(customer);Customer customer2 = session.get(Customer.class, id); // 不发送sql语句System.out.println(customer2);transaction.commit();session.close();
}
三、Hibernate的一级缓存的内部结构
1、一级缓存中的特殊区域:快照区
@Test
// 一级缓存的快照区
public void demo2() {Session session = HibernateUtils.openSession();Transaction transaction = session.beginTransaction();Customer customer = session.get(Customer.class, 1l); // 发送SQL语句,同时放到一级缓存中去customer.setCust_name("王大锤");transaction.commit();session.close();
}
Hibernate的事务管理
一、事务的回顾
1、什么是事务
事务:事务指的是逻辑上的一组操作,组成这组操作的各个逻辑单元要么全部成功,要么全部失败。
2、事务特性
原子性:代表事务不可分割;
一致性:代表事务执行的前后,数据的完整性保持一致;
隔离性:代表一个事务执行的过程中,不应该受到其他事务的干扰;
持久性:代表事务执行完成后,数据就持久到数据库中。
3、如果不考虑隔离性,则会引发安全性问题
读问题
脏读:一个事务读到另一个事务未提交的数据;
不可重复读:一个事务读到另一个事务已经提交的update数据,导致在前一个事务多次查询结果不一致;
虚读:一个事务读到另一个事务已经提交的insert数据,导致在前一个事务多次查询结果不一致。
写问题(了解)
引发两类丢失更新
4、读问题的解决
设置事务的隔离级别
Read uncommitted : 以上读问题都会发生;
Read committed : 解决脏读,但是不可重复读和虚读有可能发生;(Oracle采用)
Repeatable read : 解决脏读和不可重复读,但是虚读有可能发生;(MySQL采用)
Serializable : 解决所有读问题,不能有事务的并发。(效率最低,安全性最高,故基本不用)
二、Hibernate中设置事务隔离级别
1、Hibernate中设置事务的隔离级别
1 --Read uncommitted : 以上读问题都会发生;
2 --Read committed : 解决脏读,但是不可重复读和虚读有可能发生;(Oracle采用)
4 --Repeatable read : 解决脏读和不可重复读,但是虚读有可能发生;(MySQL采用)
8 --Serializable : 解决所有读问题。(效率最高,安全性最低,故基本不用)
三、Service层事务
1、Hibernate解决Service的事务管理
改写工具类
public class HibernateUtils {// 定义session创建所需要的Configuration,SessionFactory,都定义成静态的public static final Configuration cfg;public static final SessionFactory sf;// 对上面的两个对象进行赋值,静态代码块static{cfg = new Configuration().configure();sf = cfg.buildSessionFactory();}// 对外提供一个方法,返回openSession()public static Session openSession(){return sf.openSession();}public static Session getCurrentSession() {return sf.getCurrentSession();}}
配置完成
Hibernate的其他API
一、Hibernate的其他API
1、Query
Query借口给用户接受HQL,查询多个对象;
HQL: Hibernate Query Language Hibernate查询语言,这种语言与SQL的语法极其类似,是面向对象的查询语言。
@Test// Querypublic void demo1() {Session session = HibernateUtils.getCurrentSession();Transaction transaction = session.beginTransaction();// 通过Session获得Query接口// 查询所有数据// String hql="from Customer";// 条件查询,如:查询所有姓王的// String hql = "from Customer where cust_name like ?";//分页查询String hql = "from Customer";Query query = session.createQuery(hql);// 设置条件// query.setParameter(0, "王%");// 设置分页query.setFirstResult(3);query.setMaxResults(3);List<Customer> list = query.list();for (Customer customer : list) {System.out.println(customer);}transaction.commit();}
2、Criteria
Creteria : QBC(Query By Criteria)
更加面向对象的一种查询方式。
@Test// Criteriapublic void demo2() {Session session = HibernateUtils.getCurrentSession();Transaction transaction = session.beginTransaction();// 通过session获得Criteria的对象/*Criteria criteria = session.createCriteria(Customer.class);List<Customer> list = criteria.list();*/// 条件查询/*Criteria criteria = session.createCriteria(Customer.class);criteria.add(Restrictions.like("cust_name", "李%"));*/// 还有一种写法,like后面是三个参数,最后一个是%,END是在后面,START是在前面,ANYWHERE是恰后都有//criteria.add(Restrictions.like("cust_name", "李", MatchMode.ANYWHERE));// 分页查询Criteria criteria = session.createCriteria(Customer.class);criteria.setFirstResult(3);criteria.setMaxResults(4);List<Customer> list = criteria.list();for (Customer customer : list) {System.out.println(customer);}transaction.commit();}
3、SQLQuery
SQLQuery用于接收SQL。在sql语句特别复杂的时候使用SQLQuery,否则一般情况下使用前两种方法就可以了。
学习Hibernate框架笔记-第2天相关推荐
- 深入浅出学习Hibernate框架(一):从实例入手初识Hibernate框架
这篇博客是hibernate学习的第一篇,主要简单介绍hibernate框架,之后简单说一下hibernate的目录结构,最后写一个简单的hibernate实例.通过这三步来简单的认识一下hibern ...
- 深入浅出学习Hibernate框架(二):JDBC基础操作
上篇博客<深入浅出学习Hibernate框架(一):从实例入手初识Hibernate框架>简单介绍了一下Hibernate框架,并且举了一个实例来了解Hibernate.这篇博客将介绍JD ...
- Hibernate框架基础——Hibernate入门
Hibernate入门 Hibernate介绍 Hibernate是一个基于jdbc的开源的持久化框架,是一个优秀的ORM实现,它很大程度的简化了dao层编码工作.Hibernate对JDBC访问数据 ...
- Hibernate框架--学习笔记(上):hibernate项目的搭建和常用接口方法、对象的使用
一.什么是Hibernate框架: 1.Hibernate是一个操作数据库的框架,实现了对JDBC的封装: 2.Hibernate是一个ORM(对象关系映射)框架,我们在写程序时 ,用的是面向对象的方 ...
- hibernate框架学习笔记2:配置文件详解
实体类: package domain;public class Customer {private Long cust_id;private String cust_name;private Str ...
- AI学习笔记(九)从零开始训练神经网络、深度学习开源框架
AI学习笔记之从零开始训练神经网络.深度学习开源框架 从零开始训练神经网络 构建网络的基本框架 启动训练网络并测试数据 深度学习开源框架 深度学习框架 组件--张量 组件--基于张量的各种操作 组件- ...
- 吴恩达老师深度学习视频课笔记:超参数调试、Batch正则化和程序框架
Tuning process(调试处理):神经网络的调整会涉及到许多不同超参数的设置.需要调试的重要超参数一般包括:学习率.momentum.mini-batch size.隐藏单元( ...
- Java常用框架笔记(1)
Linux操作系统 重点在于使用,理论可以几乎忽略 学习原因: 我们一般是在Windows上开发,Linux上去做部署 市面上的常见的操作系统 Windows系列,unix系统,Linux系统,mac ...
- Hibernate课堂笔记
Hibernate课堂笔记 Hibernate第一天 一:hibernate的基础知识 Hibernate的整体思想就是"操作对象的过程,就是操作数据库表的过程".如图: 1:Hi ...
最新文章
- gbdt 算法比随机森林容易_用Python实现随机森林算法
- 微信公众平台帐号通过昵称无法搜索到怎么办
- 微信小程序02【配置详解、生命周期-app对象使用、页面跳转详解】
- ubuntu下安装openfetion
- C/C++之函数返回值为指针或者是引用时常见错误总结
- 谷歌guava_Google Guava MultiMaps
- 装饰器3--装饰器作用原理
- 查看mysql数据用户权限_查看MYSQL数据库中所有用户及拥有权限
- python读usb_使用Python来操作Microchip安全芯片
- 《矩阵分析与应用》(第2版)———知识+Matlab2018a——2nd
- 单片机课设中期报告_毕业设计中期报告
- 电脑硬盘怎么分区?C盘/D盘/E盘......快来创建自己的DIY磁盘吧!
- Python绘制圆锥曲线动画
- 微商怎么引流学生粉?如何把学生粉变现成精准粉?
- win10驱动开发19——IRP同步
- 骁龙768g和765g的差距大不大
- 批量转换中文名称为英文名称(注:一般为转换格式拼音)
- 绿联扩展坞拆解_拆解报告:绿联USB-C多功能拓展坞2A1C
- 大学物理 质点运动学
- SPA,什么是单页面应用,为什么要使用单页面应用,单页面应用有啥好处
热门文章
- C++项目实战-先把项目跑起来看看
- matlab 元编程,北航有限元编程大作业(Matlab)
- 推荐21款最佳 HTML 5 网页游戏
- sa提开放系统下的虚拟新贵Virtualbox权技巧之xp_regwrite替换sethc.exe
- Android 快速修复功能,安卓系统修复工具(ReiBoot for Android)v2.1.0免费版
- 2.7.0 gitk 打不开 Error in startup script: unknown color name lime
- QT之鼠标点击事件学习
- php 红包算法教程,php仿微信红包分配算法的实现方法
- 毕业生做了这个考研论坛系统,使用的是SSM框架和JSP技术
- TC气象数据下载包括NCEP的FNL(python脚本)、STI的Best_track、NOAA的SST