1.1. 映射文件配置
映射配置文件它的名称是”类名”.hbm.xml,它一般放置在实体类所在的包下。
这个配置文件的主要作用是建立表与类的映射关系。
1. 统一声明包名,这样在<class>中就不需要写类的全名.
2. 关于<class>标签配置
name属性:类的全名称
table 表的名称,可以省略,这时表的名称就与类名一致
catalog属性:数据库名称 可以省略.如果省略,则自动参考核心配置文件hibernate.cfg.xml中url路径中的数据库名称
3. 关于<id>标签
首先它必须存在。<id>是用于建立类中的属性与表中的主键映射。
name 类中的属性名称
column 表中的主键名称 column它也可以省略,这时列名就与类中属性名称一致
length 字段长度
type属性 指定类型
<generator>它主要是描述主键生成策略.
4. 关于<property>标签
它是描述类中属性与表中非主键的映射关系
5.关于hibernate的映射文件中类型问题
对于type属性它的取值,可以有三种:
1. java中的数据类型
2. hibernate中的数据类型
3. SQL的数据类型
默认是hibernate中数据类型
1. Hibernate常用API介绍
1.1. Configuration
1.它主要是用于加载hibernate配置.
Configuration config=new Configuration().config ure(); 主要加载src下的hibernate.cfg.xml
Configuration config=new Configuration();主要加载的src下的hibernate.properties
Configuration config=new Configuration().config ure ure不知道该不该加自己百度(核心配置文件名称);加载指定的名称的配置文件
修改hibernate.cfg.xml名称为my.xml,单元测试的时候发现报错,修改Configuration加载即可
1.1. sessionFactory
1.首先SessionFactory它的获取是通过Configuration得到。
SessionFactory接口负责初始化Hibernate。它充当数据存储源的代理,并负责创建Session对象。这里用到了工厂模式。需要注意的是SessionFactory并不是轻量级的,因为一般情况下,一个项目通常只需要一个SessionFactory就够,当需要操作多个数据库时,可以为每个数据库指定一个SessionFactory。
2.通过SessionFactory可以得到Session.
是从连接池中获取一个连接。
获取一个与线程绑定的Session.
SessionFactory它不是轻量级的,不要频繁创建关闭它。在一个项目中有一个SessionFactory就可以,通过SessionFactory来获取Session进行操作。
SQLQuery
要想执行本地sql
SQLQuery sqlQuery=session.createSqlQuery(String sql);
使用addEntity方法来将结果封装到指定的对象中,如果不封装,得到的是List<Object[]>
如果sql中有参数,我们使用setParameter方法完成参数传递。
如果结果就是一个可以使用uniqueResult()来得到一个单独对象。
1. 查询全部数据
2. 条件查询
1.1. Criteria
Criteria接口与Query接口非常类似,允许创建并执行面向对象的标准化查询。值得注意的是Criteria接口也是轻量级的,它不能在Session之外使用。
首先我想使用Criteria,必须得到Criteria
Criteria criteria=Session.createCriteria()
查询所有操作
Session.createCriteria(实体类.class)得到一个Criteria对象,调用list查询所有
分页操作与query的方法一样
setFirstResult() setMaxResults()
条件查询
criteria.add(Restrictions.eq(“name”,”xxxx”));
criteria.add(Restrictions.or(Restricitons.eq(),Restrictions.list()…..))
我们使用Criteria可以更加面向对象去操作,它非常适合进行多条件组合查询。
Hibernate持久化类与主键生成策略
Hibernate持久化类
什么是持久化类?
Persistent Object (PO)
PO=POJO+hbm映射配置
对于hibernate中的PO编写规则:
1. 必须提供一个无参数的public构造方法
2. 所有属性要private ,对外提供public 的get/set方法
3. 在PO类必须提供一个标识属性,让它与数据库中的主键对应,我们管这个属性叫OID
4. PO类中的属性尽量使用基本数据类型的包装类.
Int-àInteger double--àDouble float-àFloat
5. PO类它不能使用final修饰符
OID作用:
OID指的是与数据库中表的主键对应的属性。
Hibernate框架它是通过OID来区分不同的PO对象,如果在内存中有两个相同的OID对象,那么hibernate认为它们是同一个对象。
为什么PO类属性它要使用包装类型?
使用基本数据类型是没有办法去描述不存在概念,如果使用包装类型,它就是一个对象,对于对象它的默认值是null.
PO类不可以使用final修饰?(hibernate中的get/load方法的区别)
Get/load方法它们都是根据id去查询对象。
1. get直接得到了一个持久化类型对象,它就是立即查询操作
load它得到的是持久化类开的代理类型对象(子类对象)。它采用了一种延迟策略来查询数据。
2. get方法在查询时,如果不存在返回null
load方法在查询时,如果 不存在,会产生异常
ObjectNotFoundException.
Hibernate主键生成策略
Hibernate中定义的主键类型包括:自然主键和代理主键:
自然主键:具有业务含义 字段 作为主键,比如:学号、身份证号
代理主键:不具有业务含义 字段作为主键(例如 自增id),比如:mysql自增主键,oracle序列生成的主键、uuid()方法生成的唯一序列串
建议:企业开发中使用代理主键!
判断持久化类对象三种状态:
1. 是否有OID
2. 判断是否与session关联
1. 瞬时态(new 出来的)
瞬时------à持久 save saveOrUpdate
瞬时-----à脱管(游离) 手动设置oid
2. .持久态 它是由session管理
持久-------à瞬时 delete() 被删除后持久化对象不在建议使用
持久-----à脱管 注意:session它的缓存就是所说的一级缓存
evict(清除一级缓存 中指定的一个对象)
clear(清空一级缓存)
close(关闭,也是清空一级缓存)
3. .脱管态 (它是无法直接获取)
脱管-----à瞬时 直接将oid删除
脱管----à持久 update saveOrUpdate lock(过时)
Hibernate常用API-Session补充
Update
udpate操作它主要是针对于脱管对象,持久对象具有自动更新能力。
问题1:如果我们直接操作的对象是一个脱管对象,执行update会出现什么情况?
Update操作时,如果对象是一个脱管对象,可以操作,它会将脱管对象转换成持久对象在操作
如果在session中出现相同的oid两个对象,会产生异常
问题2脱管对象的oid如果在数据表中不存在,会报异常?
所以:在操作中,建议我们通过持久化对象来直接修改其操作。
示例:在单元测试类HibernateTest中创建单元测试方法test6测试update操作
saveOrUpdate
如果对象是一个瞬时对象 --------执行save操作
如果对象是一个脱管对象---------执行update
如果是一个持久对象-------直接返回
delete
删除一个脱管对象,与session关联,在删除
注意:如果执行delete操作,先删除一级缓存,在删除数据库中的数据。
Hibernate关联映射--一对多(多对一)
我们以客户(Customer)与订单(Order)为例
1.实体类创建
创建项目Hibernate-demo3,进行相关的配置
1.1.订单
创建Order类,并实现字段的set和get方法
1.2.客户
创建Customer类,实现字段的set和get方法
2.Hbm映射文件编写
2.1.Order.hbm.xml
2.2.Customer.hbm.xml
3.测试保存
创建一个单元测试类OneToManyTest,创建单元测试方法test1
上面操作是一种双向关联
问题:我们可不可以只保存订单或只保存客户完成保存操作?
4.测试单向关联保存
4.1.在单元测试类OneToManyTest中创建test2单元测试方法
org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: cn.itheima.oneToMany.Customer
…………..
这个异常代表提一个持久化对象关联了一个瞬时对象。
4.2.我们可以使用级联操作来解决上述的问题.
4.2.1.我们现在要做的是保存订单时保存客户,需要在订单的hbm配置文件中修改
设置cascade=save-update 那么在保存订单时就可以自动将客户保存。
4.2.2.如果我们要完成保存客户时,保存订单
4.2.2.1.在单元测试类OneToManyTest中创建test3单元测试方法
4.2.2.2.Customer.hbm.xml
5.双向关联维护
我们在开发中要配置双向关联配置。---------可以通过任意一方来操作对方
在操作代码,尽量来要进行单向关联。------可以尽量资源浪费。
在双向关联中,会存在多余的update语句。
我们可以使用inverse属性来设置,双向关联时由哪一方来维护表与表之间的关系。
Customer.hbm.xml
Inverse它的值如果为true代表,由对方来维护外键。
Inverse它的值如果为false代表,由本方来维护外键。
关于inverse的取值:
外键在哪一个表中,我们就让哪一方来维护外键。
cascade总结
使用cascade可以完成级联操作
它可常用取值:
none这是一个默认值
save-update,当我们配置它时,底层使用save update或save-update完成操作,级联保存临时对象,如果是游离对象,会执行update.
delete 级联删除
delete-ophan 删除与当前对象解除关系的对象。 删除孤儿
all 它包含了save-update delete操作
all-delete-orphan 它包含了delete-orphan与all操作
hibername常见笔试题:cascade与inverse有什么区别?
cascade它是完成级联操作
Inverse它只有在双向关联情况下有作用,它来指定由哪一方维护外键。
转载自:https://blog.csdn.net/weixin_39592397/article/details/80857737