缓存
- 就是数据库数据在内存中的临时容器
- 位于数据库与数据库访问层中间
- 避免了数据库调用性能的开销
- 相对于内存而言,数据库调用是一个代价高昂的过程
- orm在查询数据时首先会根据自身的缓存管理策略,在缓存中查找相关数据,如果发现数据,则直接将此数据作为结果加以利用;
- 分类:
- 一级缓存:即在当前事务范围内的数据缓存
- 就hibernate来讲,一级缓存基于session生命周期的,session一旦关闭,一级缓存就清除,为hibernate自带的缓存,是必须的;
- 二级缓存:即在某个应用中或应用中的某个独立数据库访问子集中的共享缓存,此缓存可有多个事务共享,在hibernate中应用级缓存由sessionFatory实现
- 分布式缓存:即在多个应用实例,多个JVM间共享的缓存策略:
延迟加载
- 在有关联的持久类对象中,对一个对象进行查询也会向另外一个对象进行查询
- 所谓的延迟加载就是在真正需要数据的时候,才真正执行数据加载操作
- 实体对象的延迟加载(load())
- 集合的延迟加载(一对多和多对多时,关联集合)
- 属性的延迟加载(clob大数据类型时)
clob
- 存放大文本的类型
blob
- 存放二进制数据的类型
锁
- 多个用户可能同时读取或更新一个数据
- 需要一些机制来保证这些数据在某个操作过程中不会被外界修改,这样的机制,就是锁;
- 悲观锁 pessimistic locking 实现依赖于数据库机制,在整个过程中,将数据库锁定,其他任何用户不能对其读取和修改,一般适合于短事务,并发性不好,性能开销大
- 乐观锁 optimistic locking 依靠数据版本记录机制实现,为数据库增加一个版本标识,增加一个version字段,读取时,将版本号一同读出,
- 更新时,版本号加一,将提交数据的版本与数据库表对应记录的当前版本进行比较,如果提交的数据的版本号大于当前数据库版本号,则更新,否则认为是过期数据
数据库隔离级别
- read uncommitted 没有提交,就能读到,存在脏读
- read commited 提交读,提交之后,才可以更新数据库,不存在脏读
- repeatable read 可重复读
- serializable 可序列化读
连接池
- 使用连接池的原因
- 每一次请求都会建立一个连接
- 每一次数据库连接,使用完后都会断开
- 不能控制创建的连接对象数
- 频繁的数据库连接操作势必会占用很多的系统资源,响应速度必定下降,程序出现异常而未能关闭,将会导致数据库系统中的内存泄漏,最终将不得不重启数据库,系统资源被毫无顾忌的分配出去,如连接过多,也可能导致内存泄漏,服务器奔溃;
- 连接池作用:为数据库建立一个缓冲池,预先往里面放入一定数量的连接,当需要建立连接的时候从里面取出,用完之后再放回去。通过设定最大的连接数量来防止无休止的数据库连接,更重要的是可以通过数据库连接池的管理机制监视数据库的链接数量,使用情况,位系统开发,测试,性能调整提供依据;
- 工作流程:持久层向连接池申请一个连接,连接池返回一个空闲连接。如果没有空弦连接那么久检查连接池中的连接数量是否到达最大连接数。如果没有到达最大连接数,那么就建立新的连接对象,如果到达最大连接数,那么就等待连接被释放。这时可以设置最大等待时间来控制用户的等待状态;等待时间内用别的连接对象被释放,那么就被分配该连接,如果超时,返回空;
hibernate常见的优化策略
- 用高版本的hibernate
- 制定合理的缓存策略
- 采用合理的session管理机制
- 尽量使用延迟加载
- 如有可能,采用uuid作为主键生成策略
- 如有可能选用乐观锁代替悲观锁
-在开发中,显示hibernate执行的sql语句,从而指定更好的实现策略
复杂的查询和统计查询可以使用sql语句完成,甚至可以3考虑使用存储过程完成