hibernate 缓存:
1、 缓存就是数据库数据在内存中的临时容器
2、位于数据库与数据库访问层中间
3、ORM在查询数据时首先会根据自身的缓存管理策略,在缓存中查找相关数据,如发现所需的数据,则直接将此数据作为结果加以利用
4、避免了数据库调用性能的开销
5、相对于内存操作而言,数据库调用是一个代价高昂的过程
一级缓存:即在当前事务范围内的数据缓存
就hibernate来讲(一级缓存)事务级缓存是基于session的生命周期实现的,session一旦关闭,一级缓存就清除,一级缓存为hibernate自带的缓存,是必须的。
应用级(二级)缓存:即在某个应用中或应用中某个独立数据库访问子集中的共享缓存,此缓存可以由多个事务共享
在hibernate中,应用级缓存由sessionFactory实现
分布式缓存:即在多个应用实例,多个JVM间共享缓存策略
二级缓存需要使用第三方jar包,在hibernate的 lib目录下,\optional\ehcache,把里面的三个jar包导入《ehcache-2.10.1.jar》《hibernate-ehcache-5.2.1.Final.jar》《slf4j-api-1.7.7.jar》
在hibernate.cfg.xml配置:
<!-- 表示需要使用echcache二级缓存策略 -->
<property name="hibernate.cache.EhcacheProvider">true</property>
<!-- 指明echcache的缓存类 -->
<property name="hibernate.cache.region.factory_class">
org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
<mapping class="com.lovo.bean.MessageBean"/>
<!-- 表示缓存策略为可读,可写,calss表示什么类需要使用二级缓存 -->
<class-cache usage="read-write"class="com.lovo.bean.MessageBean"/>
延迟加载类型:
1、 实体对象的延迟加载(load());
2、 集合的延迟加载(一对多和多对多时,关联集合)
3、 属性的延迟加载(clob大数据类型时)
数据库:
clob:放置的是大文本类型
blob:存放二进制数据的类型
数据库隔离级别:
Read UnCommited没有提交,就能读到,比如发出insert在没有提交时就能更新数据库
存在脏读,一个事务读取一行,另一个事务已经将该记录更新但么有提交
如果一个事务已经写数据,另一个事务则不允许同时进行操作。
Read Commited提交读。提交之后,才可以更新数据库
不存在脏读。存在不可重复读。
如果一个用户读出的是张三。另一个用户将该用户名改为李四,那么第一个用户再读则是李四。
存在虚读,用户查询数据时,两次查询的内容不一致,未提交的写事务将会禁止其他事务访问该行。
Repeatable Read可重复读
读取的事务将禁止写事务,写事务则禁止任何其他事务。
不存在不可重复读,但不能避免虚读
Serializable 可序列号读
事务只能一个接一个执行,不能并发执行
hibernate锁机制:保证数据在某个操作过程中不会被外界修改,这样的机制就是所谓的“锁” ,既给我们选定的目标数据上锁,使其无法被其他程序修改。
hibernate支持的2种锁机制
悲观锁(Pessimistic Locking):
1. 每次存在读取数据的时候,其他用户也会存取同一数据
2. 对数据进行锁定,直到自己操作完成以后
3. 依靠数据库提供的锁机制
❤ 实现依赖于数据库机制,在整个过程中,将数据锁定,其他任何用户不能对其读取和修改,一般适用于短事务,并发行不好
乐观锁 (Optimistic Locking):
1. 为数据增加一个版本表示,增加一个version字段
2. 读取数据时,将版本号一同读出
3. 更新时,版本号加一
4. 将提交数据的版本与数据库表对应记录的当前版本信息进行对比
5. 如果提交的数据版本号大于数据库表当前版本号,则予以更新,否则认为是过期数据
为何使用数据库连接池:
1. 不使用连接池,每一次请求都要建立一次数据库连接
2. 不使用连接池,每一次数据库连接,使用完后都得断开
3. 不使用连接池,不能控制被创建的连接对象
4. 频繁的数据库连接操作势必占用很多系统资源,响应速度必定下降。程序出现异常而未能关闭,将会导致数据库系统中的内存泄漏,最终不得不重启数据库。系统资源被毫无顾及的分配出去,如连接过多,也可能导致内存泄漏,服务器崩溃
连接池工作原理:
为数据库连接建立一次“缓冲池”。预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需要从缓冲池中取出一个,使用完毕之后在放回去。通过设定连接池最大连接数来防止系统无休止的数据库连接。更为重要的是可以通过连接池的管理机制监视数据库的连接数量、使用情况,为系统开发、测试及性能调整提供依据。
连接池的工作流程:
持久层向连接池申请一个连接,连接池返回一个空闲连接。如果没有空闲连接,那么就检查连接池中的连接数量是否到达最大连接数。如果没有到达最大连接数,则建立新的连接对象放入连接池中。如果到达最大连接数,那么用户就需要等待。这是可以设置最大等待时间来控制用户的等待,等待时间内有别的连接对象被释放,那么就分配给等待用户。如果超时,那么返回null。
连接池配置:
<!-- 设置最大连接数 -->
<property name="hibernate.dbcp.ps.maxActive">100</property>
<!-- 设置最小连接数 -->
<property name="hibernate.dbcp.ps.maxIdle">20</property>
<!-- 设置最大等待时间,单位是毫秒 -->
<property name="hibernate.dbcp.ps.maxWait">2000</property>
hibernate常见优化策略:
1. 用高版本的hibernate
2. 制定合理的缓存策略
3. 采用合理的session管理机制
4. 尽量使用延迟加载
5. 如果可能,采用UUID作为主键生成策略
6. 如果可能,选用乐观锁代替悲观锁
7. 在开发中,显示hibernate执行的SQL语句,从而指定更好的实现策略
8. 复杂查询和统计查询可以使用SQL语句完成,甚至可以考虑是哟on个存储过程完成
使用Spring有什么好处
1. Spring能有效的组织你的中间层对象
2. Spring能消除在许多工程中常见的对Singleton的过多使用
3. Spring能消除各种各样自定义格式的属性文件的需要,使配置信息一元化
4. Spring能够帮助我们真正意义上实现针对接口编程
5. 在Spring应用中的大多数业务对象没有依赖于Spring
6. 使用Spring构建的应用程序易于单元测试
7. Spring支持JDBC和O/R Mapping产品(hibernate)
8. MVC Web框架,提供了一种清晰,无侵略性的MVC实现方式
9. JNDI抽象层,便于改变实现细节,可以方便的在远程服务和本地服务间切换
10. 简化访问数据库时的列外处理
11.Spring能使用AOP提供声明性事务管理,可以不直接操作JTA也能够对事务进行管理
12.提供了JavaMail或其他右键系统支持
控制反转:
不创建对象,但是描述创建他们的方式。在代码中不直接与对象和服务器连接,但在配置文件中描述那一个组件需要哪一项服务。容器(在Srping框架中是IOC容器)复杂将这些联系在一起。
IOC组件注入的方式:
1. 接口注入
2. 通过set方法注入(设值注入)
3. 通过构造方法注入
Springbean工厂和ApplicationCaontext联系:
1. ApplicationContext扩展Bean工厂接口
2. ApplicationContext提供附加功能
3. Bean工厂延迟加载所有的Bean,直到getBean被调用
4. ApplicationContext则在初始化自身时检验,为立即加载。这样有利于检查所依赖属性是否注入;所以通常情况下我们选择使用ApplicationContext。
5. Spring容器中的Bean缺省状态下是单态(单例)模式
常用实现:
1. ClassPathXmlApplicationContext Spring配置文件必须放在src目录下
2. FileSystemXmlApplicationContext 配置文件放在工程下(java项目)
3. XmlWebApplicationContext 根据部署路径需找(web项目)
常用的都是第一种
ApplicationContext context = newClassPathXmlApplicationContext("app*.xml"); //创建方式
Bean中 id 和name区别
1. id是唯一表示 bean. 不能用特殊字符X#@,不能用数组开头。在bean引用的时候只能有id指向你需要的bean
2. name可以用特殊字符,并且一个bean可以用多个名称如name=”bean1,bean2,bean3”,用逗号割开。如果没有id,则name的第一个名称默认是id
代理模式:
在目标方法执行前或者执行后,附加非功能性的逻辑。
AOP术语:
切面(Aspect):就是你要实现的交叉的非核心业务功能
连接点(Joinpoint):应用程序执行过程中插入切面的地点,可以是方法调用,异常抛出
通知(Advice):通知切面的实际实现代码
切入点(Pointcut):定义哦体内钙质应用在哪些连接点
目标对象(Target):被通知的对象
代理(Proxy):将通知应用到目标对象后创建的对象
织入(Weaving):将切面应用到目标对象从而创建一个新的代理对象的过程
通知类型:
Around环绕通知:接口org.aopalliance.intercept.MethodInterceptor,目标方法执行前后都调用
Before前置通知:接口org.springframework.aop.MethodBeforeAdvice目标方法调用前被调用
After后置通知:接口org.springframework.aop.AfterReturningAdvice目标方法调用后被调用
Throws抛出异常通知:接口org.springframework.aop.ThrowsAdvice目标方法抛出异常时调用
抛出异常通知不能与其他通知写于一个类中,也不能放入spring组件类的包中@AfterThrowing
ProxyFactoryBean:产生代理对象
@After:为后通知,不管是否有异常都会执行
@AfterReturning:为返回后通知,表示目标方法正常执行后,会执行该方法,如果目标方法有异常抛出则不执行。