1.hibernate概述
hibernate是一款基于ORM的全自动化开源框架,可以通过原生SQL,自定义的HQL以及CriteriaAPI操作数据库,基于JDBC
2.hibernate与mybatis的区别
2.1orm的区别
*hibernate的对象关系型映射:POJO对应数据库的表,POJO的对象对应数据库表的记录,POJO属性对应表的字段
*mybatis的对象关系型映射:基于输入映射和输出映射
输入映射:把POJO与输入参数绑定,与表字段映射
输出映射:把sql执行返回的结果集与POJO中的属性进行映射
2.2自动化的区别
*hibernate是全自动ORM框架
hibernate封装了大量的API在Criteria对象中用来操作数据库,以及独有的HQL语句,这些功能无非一个目的,那就是与原生SQL进行解耦,与数据库进行解耦,以达到可移植的目的
*mybatis是半自动ORM框架
mybatis是直接编写SQL语句来操作数据库的,这个特性导致了它的可移植性差的特点,但是灵活性却大大提高
2.3缓存的区别
*一级缓存都是基于session内
*mybatis二级缓存是基于mapper级别,hibernate二级缓存是基于session之间,所有session可以共享
3.hibernate的工作原理
3.1应用启动Configuration,并加载核心配置文件hibernate.cfg.xml,同时引入映射文件*.hbm.xml
Configuration config = new Configuration().configure();
3.2构建与数据源绑定的SessionFactory
SessionFactory sessionFactory = config.buildSessionFactory();
3.3通过SessionFactory可以构建不同的session
Session session = sessionFactory.openSession();
Session session = sessionFactory.getCurrentSession(); //与本地线程绑定的Session副本,线程安全
3.4开启一个事务
Transaction transaction = session.beginTransaction();
3.5执行逻辑操作DB,session操作数据库API
3.6如果失败则rollback,如果成功则commit
transaction.rollback();
transaction.commit();
3.7关闭session
session.close();
4.hibernate核心API
4.1Configuration
Configuration configure(String resource) 该方法如果不传参数则默认取classpath下加载hibernate.cfg.xml
SessionFactory buildSessionFactory()来构建一个SessionFactory
Configuration setProperties(Properties properties)可以用来加载properties中的配置文件
4.2SessionFactory
该对象线程安全,所有数据源相关的配置都会注入到该对象中,用于构建session的工厂类
4.3Session
Transaction beginTransaction() 开启事务
void saveOrUpdate(Object object) 添加或修改对象
void delete(Object object) 删除对象
void flush() 刷新缓存
void clear() 清空缓存
Connection close() 关闭session连接
Criteria createCriteria(Class pojoClass) 构建离线查询对象
Query createQuery(String hql) 根据HQL语句构建Query
SQLQuery createSQLQuery(String sql) 根据原生sql语句构建SQLQuery
5.hibernate一二级缓存
*一级缓存是session级别的缓存,session关闭,缓存也清空,默认开启,spring整合后会失效
*二级缓存是应用级别的缓存,SessionFactory来维护二级缓存的开启和关闭
*hibernate没有提供二级缓存的默认组件,通常是引入第三方二级缓存组件,例如EHcache
配置步骤:
5.1注入EHcache到SessionFactory
<!-- 在当前SessionFactory中维护一个二级缓存 -->
<property name="hibernate.cache.use_second_level_cache">true</property>
<!-- 配置一个第三方缓存组件 -->
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
5.2引入二级缓存的相关配置,例如:ehcache.xml
5.3开启二级缓存,在需要开启的hbm.xml中的class标签下
<!-- read-only 一般都设置为只读 -->
<cache usage="read-only"/>
6.get和load的区别
get会立即发送查询sql,load只在访问非ID属性时才发送查询sql
get返回的是POJO,load返回的是pojo的一个代理对象
7.save、saveOrUpdate、persist、lock的区别
save 添加
saveOrUpdate 添加和修改
persist 在事务范围外不能添加,必须在事务范围内才等价于save
lock 把一个没有改变过的游离态对象变成持久态对象
8.hibernate中POJO的三个状态
transient瞬时态未与session开启连接
persistent持久态与session连接中
detached游离态与session断开连接
9.hibernate批处理
*凡是涉及到批量数据插入数据库的操作,请用jdbc的批处理方式替代,效率是最高的
*hibernate的批处理方式:
9.1首先在SessionFactory中配置批处理的属性hibernate.jdbc.batch_size,通常10-100之间
<property name="hibernate.jdbc.batch_size" value="50" />
9.2在代码中每隔50个刷新和清空session缓存
//开启事务
for循环{
session.save(pojo);
if( i % 50 == 0 ) {
session.flush();
session.clear();
}
}
//提交事务
session.close();
10.hibernate中inverse的作用
*inverse用于多对多关系对中间表的维护,默认值false,表示维护中间表
*只能由一方来维护中间表,根据业务来定。
*如果双方同时维护中间表(双方inverse=false),则中间表会插入重复数据
*如果双方同时不维护中间表(双方inverse=true),则中间表不会被插入数据
11.hibernate的延迟加载
*延迟加载机制的优势是,当使用到关联POJO的时候才去加载数据,这样对性能有一定的提升,默认lazy=true延迟加载
*在JSP应用中,使用EL表达式,延迟加载报错的解决方式是,在web.xml中配置一个过滤器OpenSessionInViewFilter即可
12.hibernate中SqlQuery查询结果集转POJO的方式
第一种:
SQLQuery addEntity(String 表的别名,Class arg0)
第二种:
SqlQuery setResultTransformer(ResultTransformer transformer)
ResultTransformer Transformers.aliasToBean(Pojo.class)
两种的区别是:
第二种在oracle中有bug,oracle中使用第二种,
需要setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP)先转成Map再把Map转成一个POJO
13.Hibernate拦截器
hibernate的拦截器可以实现Interceptor,或继承EmptyInterceptor类,会被hibernate自动调用
核心API:
void postFlush() 事务提交后被调用(常用) 可以应用于记录日志
void onDelete() 在一个对象删除前被调用
boolean onSave() 在一个对象保存前被调用
void preFlush() 在一个对象修改后被调用,如果有onSave方法在其后被调用
boolean onFlushDirty() 在当 Hibernate 探测到一个对象在一次 flush(例如,更新操作)中是脏的(例如,被修改)时被调用
14.hibernate中sorted collection和ordered collection
当Pojo.hbm.xml中的属性包含set或map集合时,需要配置排序字段就会使用到,sorted和order-by属性
sorted:是在内存中进行排序
order-by:是在数据库中排序
15.hibernate获取线程安全的session
*getCurrentSession()方法会获取一个与本地线程绑定的session来保证线程安全,具体实现逻辑如下
*TransactionSynchronizationManager的getResource方法会获取一个ThreadLocal<Map<Object, Object>>类型的resource实例
*resource中包含一个对应的SessionHolder实例
*SessionHolder实例中持有一个final类型的session实例
该resource是ThreadLocal类型的,与当前线程是绑定的,因此各个Http线程对应的resource也是不同的,所以session也是不同的,因此解决了session的线程安全问题
16.hibernate注解
@Entity 声明当前类为一个POJO
@Table(name = ‘tableName’) 声明该POJO跟表的映射关系
@Id 声明主键
@GeneratedValue(strategy = GenerationType.IDENTITY) 声明主键的生成策略
GenerationType.SEQUENCE 采用数据库的序列方式自增长,前提示只适用于支持序列的数据库 例如:Oracle
GenerationType.IDENTITY 主键自增长,适用数据库,例如:mysql,sqlserver,db2
GenerationType.AUTO 主键由程序控制生成
GenerationType.TABLE 使用一个特定的数据库表格来保存主键
采用UUID主键生成策略方式:
@GenericGenerator(name="uuidGenerator",strategy="uuid")
@GeneratedValue(generator="uuidGenerator")
@Column(name="字段名称",length=30)声明属性对应表的字段名称
@OneToMany(mappedBy="department",cascade=CascadeType.REMOVE,fetch=FetchType.LAZY)一对多
mappedBy 当前POJO的类名称首字母小写
cascade 级联效应
CascadeType.REMOVE 声明为级联删除
CascadeType.PERSIST 声明为级联新增
CascadeType.REFRESH 声明为级联刷新
CascadeType.MERGE声明为级联更新
CascadeType.ALL 以上4个属性全部有效
fetch 加载机制
FetchType.EAGER 默认同时加载
FetchType.LAZY延迟加载
@ManyToOne(cascade=CascadeType.PERSIST,fetch=FetchType.LAZY)多对一
多对多声明维护多对多关系的一方
@ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
@JoinTable(
name="sboot1_user_role",
joinColumns={@JoinColumn(name="userid",referencedColumnName="id")}, inverseJoinColumns={@JoinColumn(name="roleid",referencedColumnName="id")}
)
private List<Role> roles;
id 表示当前POJO对应表的主键ID
userid表示当前POJO对应中间表中的外键ID
roleid 表示多对多另一方POJO对应中间表中的外键ID
多对多声明另一方
@ManyToMany(mappedBy="roles")
mappedBy声明另一方对当前POJO的集合引用名称
private List<User> users;