----------------------------------------------------------
----------------------------------------------------------
-----------------------------------------------------------
-------------------------------------------------------------
-----------------------------------------------------------------
-------------------------------------------------------------------
-----------------------------------------------------------------
-------------------------------------------------------------------
JSP中一共预先定义了9个这样的对象,分别为:request、response、session、
application、out、pagecontext、config、page、exception
---------------------------------------------------
Http会话的四个过程:
建立连接,发送请求,返回响应,关闭连接。
----------------------------------------------------------------------------------
什么是restful?
Restful就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格,是对http协议的诠释。
资源定位:互联网所有的事物都是资源,要求url中没有动词,只有名词。没有参数
Url格式:http://blog.csdn.net/beat_the_world/article/details/45621673
资源操作:使用put、delete、post、get,使用不同方法对资源进行操作。分别对应添加、删除、修改、查询。
一般使用时还是post和get。Put和Delete几乎不使用。
----------------------------------------------------------------------------------
Rest模式有四种操作,
POST /uri 创建
DELETE /uri/xxx 删除
PUT /uri/xxx 更新或创建
GET /uri/xxx 查看
-------------------------------------------------------------------------------------------------
Http和Https的区别,为什么Https是安全的
https是在http原本的协议上增加了层SSL协议,作用就是将明文的超文本传输协议变成加密的,
使得数据在服务端和客户端之间的传输是以密文的形式进行的——沃通(wosign)专业的数字证书CA机构
-----------------------------------------------------------------------
javaBean的作用:封装数据
---------------------------------------------------
MVC的优缺点
优点
1,。耦合性低
2.重用性高
3.可维护性高
4.有利于软件工程化管理。
缺点
1.增加了系统结构和实现的复杂性
2,。试图和控制器之间过于紧密连接,妨碍了他们的独立风格。
3.试图对模型数据的访问效率低,试图可能需要多次调用才能获得足够的显示数据。
--------------------------------------------------------------------------------------------------
DAO层主要是做数据持久层的工作,负责与数据库进行联络的一些任务都封装在此,
Service层主要负责业务模块的逻辑应用设计。
Controller层负责具体的业务模块流程的控制
----------------------------------------------------------------------------------------------------
servlet是单例吗,多线程下Servlet怎么保证数据安全的,Servlet的生命周期
何时创建:
1.大部分情况下客户端首次请求对应servlet时创建.,filter的init是在tomcat启动时执行
2.在web.xml中设置load-on-startup在启动服务器时创建
servlet是单例的,严格地说是一个ServletMapping对应一个单例实例(如果一个Servlet被映射了两个URL地址,会生成两个实例)
要维护Servlet线程安全有很多办法,通常是使用同步块(或方法)来保护共享数据,其次可以volatile、Lock一些锁机制,
还可以使用ThreadLocal来打通安全通道,另外还有原子操作也是用来保护数据安全,有非常多的选择。
生命周期:
1.创建servlet实例
2.调用init()方法初始化.
3.servlet方法响应doXXX()方法
4.调用servlet的destory方法.
---------------------------------------------------------------
doGet()和doPost()方法
当Http请求中的属性为get时,调用doGet()方法,当method属性为post时调用都Post()方法
get方法主要用来获取服务器的资源信息, 也可以向服务器传数据,但是一般推荐采用post方法来传数据
采用get方法传数据时,一般将数据添加到URL后面,并且二者用?连接,各个变量之间用&连接,而post方法传递数据是通过HTTP请求
的附件进行的,传送的数据量更大一点,一般默认为不受限制的。
由于get方法上传的数据添加在URL中,容易暴露,存在安全隐患,而post不存在
---------------------------------------------------------------------------------------------------------
MyISAM类型不支持事务处理等高级处理,而InnoDB类型支持。MyISAM类型的表强调的是性能,其执行数度比InnoDB类型更快,
但是不提供事务支持,而InnoDB提供事务支持以及外部键等高级数据库功能。
------------------------------------------------------------------
1.所有关键字都出现在叶子结点的链表中(稠密索引),且链表中的关键字恰好是有序的;
2.不可能在非叶子结点命中;
3.非叶子结点相当于是叶子结点的索引(稀疏索引),叶子结点相当于是存储(关键字)数据的数据层;
4.更适合文件索引系统;
-----------------------------------------------------------------------------------
增加索引会增加磁盘占用
建立索引可以提升查询速度,即读速度;但在一定程度上降低写速度
数据库一般使用B*树作为索引
删除数据需要调整索引,所以会降低效率
----------------------------------------------------------
数据库索引类型:
根据数据库的功能,可以在数据库设计器中创建四种索引:唯一索引、非唯一索引、主键索引和聚集索引。
尽管唯一索引有助于定位信息,但为获得最佳性能结果,建议改用主键或唯一约束。
唯一索引:
唯一索引是不允许其中任何两行具有相同索引值的索引。 当现有数据中存在重复的键值时,大多数数据库不允许将新创建的唯一索引与表一起保存。
数据库还可能防止添加将在表中创建重复键值的新数据。例如,如果在 employee 表中职员的姓 (lname) 上创建了唯一索引,则任何两个员工都不能同姓。
非唯一索引:
非唯一索引是相对唯一索引,允许其中任何两行具有相同索引值的索引。 当现有数据中存在重复的键值时,数据库是允许将新创建的索引与表一起保存。
这时数据库不能防止添加将在表中创建重复键值的新数据。
主键索引:
数据库表经常有一列或列组合,其值唯一标识表中的每一行。该列称为表的主键。 在数据库关系图中为表定义主键将自动创建主键索引,
主键索引是唯一索引的特定类型。该索引要求主键中的每个值都唯一。当在查询中使用主键索引时,它还允许对数据的快速访问。
聚集索引(也叫聚簇索引):
在聚集索引中,表中行的物理顺序与键值的逻辑(索引)顺序相同。一个表只能包含一个聚集索引。 如果某索引不是聚集索引,
则表中行的物理顺序与键值的逻辑顺序不匹配。与非聚集索引相比,聚集索引通常提供更快的数据访问速度。
---------------------------------------------------------------------------------------------------------------------
数据库的隔离
大多数的数据库系统的默认事务隔离级别都是:Read committed
而MySQL的默认事务隔离级别是:Repeatable Read
--------------------------------------------------------------------------------
mysql的悲观锁:
其实理解起来非常简单,当数据被外界修改持保守态度,包括自身系统当前的其他事务,以及来自外部系统的事务处理,因此,在整个数据处理过程中,
将数据处于锁定状态。悲观锁的实现,往往依靠数据库提供的锁机制,但是也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,
即使在自身系统中实现了加锁机制,也无法保证外部系统不会修改数据。
来点实际的,当我们使用悲观锁的时候我们首先必须关闭mysql数据库的自动提交属性,因为MySQL默认使用autocommit模式,也就是说,
当你执行一个更新操作后,MySQL会立刻将结果进行提交。
关闭命令为:set autocommit=0;
悲观锁可以使用select…for update实现,在执行的时候会锁定数据,虽然会锁定数据,但是不影响其他事务的普通查询使用。
此处说普通查询就是平时我们用的:select * from table 语句。在我们使用悲观锁的时候事务中的语句例如:
//开始事务
begin;/begin work;/start transaction; (三选一)
//查询信息
select * from order where id=1 for update;
//修改信息
update order set name='names';
//提交事务
commit;/commit work;(二选一)
此处的查询语句for update关键字,在事务中只有SELECT ... FOR UPDATE 或LOCK IN SHARE MODE 同一条数据时会等待其它事务结束后才执行,
一般的SELECT查询则不受影响。
执行事务时关键字select…for update会锁定数据,防止其他事务更改数据。但是锁定数据也是有规则的。
查询条件与锁定范围:
1、具体的主键值为查询条件
比如查询条件为主键ID=1等等,如果此条数据存在,则锁定当前行数据,如果不存在,则不锁定。
2、不具体的主键值为查询条件
比如查询条件为主键ID>1等等,此时会锁定整张数据表。
3、查询条件中无主键
会锁定整张数据表。
4、如果查询条件中使用了索引为查询条件
明确指定索引并且查到,则锁定整条数据。如果找不到指定索引数据,则不加锁。
悲观锁的确保了数据的安全性,在数据***作的时候锁定数据不被访问,但是这样会带来很大的性能问题。因此悲观锁在实际开发中使用是相对比较少的。
mysql的乐观锁:
相对悲观锁而言,乐观锁假设数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会对数据的冲突与否进行检测,如果发现冲突,
则让返回用户错误的信息,让用户决定如何去做。
一般来说,实现乐观锁的方法是在数据表中增加一个version字段,每当数据更新的时候这个字段执行加1操作。这样当数据更改的时候,
另外一个事务访问此条数据进行更改的话就会操作失败,从而避免了并发操作错误。当然,还可以将version字段改为时间戳,不过原理都是一样的。
例如有表student,字段:
id, name, version
1 a 1
当事务一进行更新操作:update student set name='ygz' where id = #{id} and version = #{version};
此时操作完后数据会变为id = 1,name = ygz,version = 2,当另外一个事务二同样执行更新操作的时候,却发现version != 1,此时事务二就会操作失败,
从而保证了数据的正确性。
-----------------------------------------------------------------------------------------
CAS是乐观锁:每次不加锁而是假设没有冲突而去完成某项操作,如果因为冲突失败就重试,直到成功为止。
CAS 操作包含三个操作数 —— 内存位置(V)、预期原值(A)和新值(B)。如果内存位置的值与预期原值相匹配,
那么处理器会自动将该位置值更新为新值。否则,处理器不做任何操作。
----------------------------------------------------------------------------------------------------------------------------------------------
Statement和PreparedStatement
1、相对比较安全,可以防止sql注入
2、有预编译功能,相同操作批量数据效率较高
PreparedStatement 是预编译 ,使用Statement时 sql 中要进行很多的单引号拼接字符串,首先是容易出错也比较麻烦,还有就是存在sql 注入问题这是从安全方面说的。 PreparedStatement 传参数时候用 了占位符 “?”很好的解决了以上Statement的问题。我所体会到得的就是这些。
PreparedStatement是在执行前先输入sql语句,Statement正好相反,是在执行的时候传入sql语句的。
这样的区别在于,PreparedStatement可以在传入sql后,执行语句前,给参数赋值,避免了因普通的拼接sql字符串语句所带来的安全问题,
而且准备sql和执行sql是在两个语句里面完成的,也提高了语句执行的效率。
Statement,就没有以前所说的功能了,我一般很少用
------------------------------------------------------------------------------------
JDBC连接MySQL
1.注册驱动
Class.forname("com.mysql.jdbc.Driver");
2.获取数据库连接
java.sql.Connection conn=java.sql.DriverManager.getConnection();
3.获取表达式
java.sql.Statement stmt=conn.createStatement("jdbc:mysql://localhost/test?useUnicode=true&characterEncoding=GBK","root","null");
4.执行SQL
java.sql.ResultSet rs=stmt.executeQuery("select * from XXX");
5.显示结果集里面的数据
while(rs.next()){
System.out.println(rs.get(i));
}
6.关流
rs.close();
stmt.close();
conn.close();
--------------------------------------------------------------------------------------------------------------
Hibernate 和 JDBC 的优缺点?
Hibernate:优:面向对象的思维,一些简单查询不需要sql语句。比较方便。使用者不必了解sql语句。
缺:面对一些复杂查询的时候不是很灵活,比如要查询多个表的数据作为结果集,用hibernate就要设置这些表的实体对象关联关系。
(虽然hibernate也可以执行sql,但是感觉效率不高)
jdbc:原生sql。需要了解sql语言。优:使用灵活
缺:jdbc需要大量的重复性劳动,比如单表查询,发出sql,根据结果集封装成对象。这种东西往往是类似的。 而hibernate只要一行代码就可以搞定。
---------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------
跨域问题解决方案(HttpClient安全跨域 & jsonp跨域)
-------------------------------------------------------------------------------------
拦截器,在AOP(Aspect-Oriented Programming)中用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作。拦截是AOP的一种实现策略。
过滤器:所谓过滤器顾名思义是用来过滤的,在Java web中,你传入的request,response提前过滤掉一些信息,或者提前设置一些参数,
然后再传入servlet或者struts的action进行业务逻辑,比如过滤掉非法url(不是login.do的地址请求,如果用户没有登陆都过滤掉),
或者在传入servlet或者struts的action前统一设置字符集,或者去除掉一些非法字符(聊天室经常用到的,一些骂人的话)。
filter 流程是线性的, url传来之后,检查之后,可保持原来的流程继续向下执行,被下一个filter, servlet接收等.
***也叫Listener,是Servlet的***,它可以监听客户端的请求、服务端的操作等。通过***,可以自动激发一些操作,比如监听在线的用户的数量。
(1)过滤器(Filter):当你有一堆东西的时候,你只希望选择符合你要求的某一些东西。定义这些要求的工具,就是过滤器。(理解:就是一堆字母中取一个B)
(2)拦截器(Interceptor):在一个流程正在进行的时候,你希望干预它的进展,甚至终止它进行,这是拦截器做的事情。(理解:就是一堆字母中,干预他,通过验证的少点,顺便干点别的东西)。
------------------------------------------------------------------------------------------
struts2工作流程
1.客户端浏览器发出HTTP请求.
2.根据web.xml配置,请求被filterdispatcher接受
3.根据web.xml配置,找到需要调用的action类和方法,并通过IOC方式,将值注入给action.
4.action调用业务逻辑组件处理业务逻辑
5.action执行完毕,根据struts.xml中配置找到对应的返回结果result,并跳转到相应页面.
6.返回http响应到客户端浏览器.
-------------------------------------------------------------------------
1.CommandController(命令控制器)
2 FormController(表单控制器)
3 WizardFormController(向导表单控制器)
----------------------------------------------------------------------------
SpringMVC运行原理
1. 客户端请求提交到DispatcherServlet
2.由DispatcherServlet控制器查询一个或多个HandlerMapping,找到处理请求的Controller
3.DispatcherServlet将请求提交到Controller
4.Controller调用业务逻辑处理后,返回ModelAndView
5. DispatcherServlet查询一个或多个ViewResoler视图解析器,找到ModelAndView指定的视图
6.视图负责将结果显示到客户端
--------------------------------------------------------------------
SpringMVC的controller默认是单例的
------------------------------------------------------------------------------------
Spring MVC 比较 Struts2
1、 springmvc的入口是一个servlet即前端控制器,而struts2入口是一个filter过虑器。
2、 springmvc是基于方法开发(一个url对应一个方法),请求参数传递到方法的形参,可以设计为单例或多例(建议单例),
struts2是基于类开发,传递参数是通过类的属性,只能设计为多例。
3、 Struts采用值栈存储请求和响应的数据,通过OGNL存取数据,springmvc通过参数解析器是将request请求内容解析,并给方法形参赋值,
将数据和视图封装成ModelAndView对象,最后又将ModelAndView中的模型数据通过reques域传输到页面。Jsp视图解析器默认使用jstl。
-----------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------
hibernate工作原理
1.读取并解析配置文件
2.读取并解析映射信息,创建SessionFactory
3.打开session
4.创建事务transaction
5.持久化操作
6.提交事务
7.关闭session
8.关闭sessionfactory
public class PersonTest {
private static SessionFactory sessionFactory;
static{
Configuration configuration = new Configuration();
//加载配置文件
configuration.configure();
//采用了工厂模式创建sessionFactory
sessionFactory = configuration.buildSessionFactory();
}
@Test
public void testSavePerson(){
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Person person = new Person();
//由于在映射文件中已经说明主键的产生方式是hibernate内部产生,所以在程序中不用设置主键
person.setPname("reed");
person.setPsex("male");
session.save(person);
transaction.commit();
session.close();
}
}
---------------------------------------------------------------------------------------------------------------------
hibernate三种状态:瞬时态(transient) 持久态(persistent) 游离态(detached)
----------------------------------------------------------------------------------------------------------------
SessionFactory是线程安全的,可以被多个线程并发访问.
session是由sessionFactory创建的,在任务完成之后被关闭,是非线程安全的
(线程间不能共享session),它表示与数据库进行交互的一个工作单元。
--------------------------------------------------------------------------------------------------
mybatis两种占位符的区别
1. #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。如:order by #user_id#,如果传入的值是111,
那么解析成sql时的值为order by "111", 如果传入的值是id,则解析成的sql为order by "id".
2. $将传入的数据直接显示生成在sql中。如:order by $user_id$,如果传入的值是111,那么解析成sql时的值为order by user_id,
如果传入的值是id,则解析成的sql为order by id.
3. #方式能够很大程度防止sql注入。
4.$方式无法防止Sql注入。
5.$方式一般用于传入数据库对象,例如传入表名.
6.一般能用#的就别用$.
------------------------------------------------------------------------------------------------
MyBatis 延迟加载,一级缓存,二级缓存设置
什么是延迟加载
resultMap中的association和collection标签具有延迟加载的功能。
延迟加载的意思是说,在关联查询时,利用延迟加载,先加载主信息。使用关联信息时再去加载关联信息。
设置延迟加载
需要在SqlMapConfig.xml文件中,在<settings>标签中设置下延迟加载。
lazyLoadingEnabled、aggressiveLazyLoading
<!-- 开启延迟加载 -->
<settings>
<!-- lazyLoadingEnabled:延迟加载启动,默认是false -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- aggressiveLazyLoading:积极的懒加载,false的话按需加载,默认是true -->
<setting name="aggressiveLazyLoading" value="false"/>
<!-- 开启二级缓存,默认是false -->
<setting name="cacheEnabled" value="true"/>
</settings>
Mybatis的一级缓存是指SqlSession。一级缓存的作用域是一个SqlSession。Mybatis默认开启一级缓存。
在同一个SqlSession中,执行相同的查询SQL,第一次会去查询数据库,并写到缓存中;第二次直接从缓存中取。
当执行SQL时两次查询中间发生了增删改操作,则SqlSession的缓存清空。
Mybatis的二级缓存是指mapper映射文件。二级缓存的作用域是同一个namespace下的mapper映射文件内容,多个SqlSession共享。
Mybatis需要手动设置启动二级缓存。在同一个namespace下的mapper文件中,执行相同的查询SQL,第一次会去查询数据库,并写到缓存中;
第二次直接从缓存中取。当执行SQL时两次查询中间发生了增删改操作,则二级缓存清空。
----------------------------------------------------------------------------------------------------
mybatis工作原理
加载sqlmapconfig.xml创建sqlsessionfactory
sqlsessionfactory根据配置文件创建sqlsession
Executor(执行器),是一个接口(基本执行器、缓存执行器)
SqlSession内部通过执行器操作数据库
调用sqlsession.commit提交事务
调用sqlsession.close关闭会话
-----------------------------------------------------------------------------------------------------------------------
mybatis和hibernate的区别
mybatis是半自动的,hibernate是全自动的,就是说mybatis可以配置sql语句,对于sql调优来说是比较好的,hibernate会自动生成所有的sql语句,
调优不方便,hibernate用起来难度要大于mybatis
Hibernate应用场景: 试用需求,变化固定中小型项目
mybatis应用场景: 除了hibernate 的场景,主要应用需求项目较多的场景, 互联网项目; 敏捷开发。
----------------------------------------------------------------------------------------------------
session加载实体对象:首先去一级缓存,然后去二级缓存,然后才会发出sql语句去数据库查询(并存入相应的一级缓存,二级缓存并返回)
--------------------------------------------------------------------------------------------------------------------
N+1问题是什么,应该怎样解决
N+1问题就是执行一次查询获取n条主数据后,由关联引起的执行n次查询从数据,它带来了性能的问题.
一般来说用过懒加载可以部分缓解N+1带来的性能问题.
-------------------------------------------------------------------------------------------------------
什么时候需要使用事务管理机制?
对数据库的数据进行批量或连表操作时,为了保证数据的一致性和正确性,我们需要添加事务管理机制进行管理。
当对数据库的数据进行操作失败时,事务管理可以很好保证所有的数据回滚到原来的数据,如果操作成功,则保证所有需要更新的数据持久化。
-------------------------------------------------------------------------------------------------------------------
事务,也是数据库事务,指的是作为单个逻辑工作单元执行的一系列操作。正常的情况下,操作应该顺利进行,与操作相关的所有数据库信息也成功地更新;
但是,如果在这一系列过程中任何一个环节出了差错,导致操作失败了,数据库中所有信息都必须保持操作前的状态不变。否则,数据库的信息将会一片混乱而不可预测。
一个逻辑工作单元要称为事务,必须满足ACID(原子性,一致性,隔离性和持久性)
A(Atomicity)原子性:数据库中事物执行的是原子操作,即不可再分,要么全部执行,要么全部不执行.
C(consistency)一致性: 只有合法的数据可以被写入数据库,否则事务应该将其回滚到最初状态。
I(Isolation)隔离性 事务的执行是互不干扰的,一个事务不可能看到其他事务运行中的某一刻的状态.
D(Durability)持久性 意味着事务完成以后,该事务对数据库所做的更改便持久的保持在数据库中.
事务的结束只能有两种形式:提交和回滚。操作完全成功则提交,产生永久性的修改;操作不完全成功则回滚,恢复到事务开始前的状态。它们将结束一个事务。
(1)关闭自动提交事务。通过设置连接的自动提交事务属性为false,如下:
Connection conn = DriverManager.getConnection("连接URL","用户名", "密码");
//关闭自动提交事务
conn.setAutoCommit(false);
(2)如果执行顺利,提交事务;一旦发生异常,回滚(rollback)事务,如下:
try{
conn.setAutoCommit(false); //关闭自动提交事务
stmt = conn.createStatement(); //创建会话
stmt.executeUpdate("sql语句");
conn.commit(); //提交事务
}catch(Exception e)
{
e.printStackTrace();
conn.rollback(); //回滚事务
}
(3)关闭连接,如下:
finally{
if(stmt !=null)
stmt.close();
if(conn !=null)
conn.close();
}
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
项目中事务管理
手动编码方式(不常用)
申明式事务管理(ApplicationContext.XML文件配置的方式)
1.5.3.3配置事务管理器
<!-- 事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
1.5.3.4配置事务的通知
<!-- 配置事务的增强 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!--
isolation="DEFAULT" 隔离级别
propagation="REQUIRED" 传播行为
read-only="false" 只读
timeout="-1" 过期时间
rollback-for="" -Exception
no-rollback-for="" +Exception
-->
<tx:method name="transfer" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
申明式事务管理(注解的方式)
<aop:config>
<aop:pointcut expression="execution(* cn.itcast.transaction.demo2.AccountServiceImpl.transfer(..))" id="pointcut1"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut1"/>
</aop:config>
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
开发中主要使用 Spring 的什么技术 ?
①. IOC 容器管理各层的组件
②. 使用 AOP 配置声明式事务
③. 整合其他框架.
----------------------------------------------------------------------------------------------------------
1.在默认情况下,spring创建bean是单例模式
2.如果在Spring配制文件时设置懒加载模式(lazy-init=”true”),在getBean时才会实例化对象。
3.如果scope=”prototype”时,则会变成多例,无论lazy-init的值是什么都只会在使用时才会创建,
<bean id="helloWorld" class="reed1991.scope.HelloWorld" scope="prototype" lazy-init="false"></bean>
当一个bean是多例模式的情况下,lazy-init为false或者default无效
----------------------------------------------------------------------------------------------------------
Spring 如何整合 Hibernate
整合 Hibernate, 即由 IOC 容器生成 SessionFactory 对象, 并使用Spring 的声明式事务
> 利用 LocalSessionFactoryBean 工厂 Bean, 声明一个使用 XML 映射文件的 SessionFactory 实例.
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
</bean>
> 利用 HibernateTransactionManager 配置 Hibernate 的事务管理器
<bean id="transactionmanager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>
-------------------------------------------------------------------------------------------------------------
Spring IOC DI(控制反转,依赖注入)AOP(面向切面编程)
在Spring中,那些组成应用的主体及由Spring IOC容器所管理的对象被称之为Bean。
Spring的IOC容器通过反射的机制实例化Bean并建立Bean之间的依赖关系。
简单地讲,Bean就是由Spring IOC容器初始化、装配及被管理的对象。
获取Bean对象的过程,首先通过Resource加载配置文件并启动IOC容器,然后通过getBean方法获取bean对象,就可以调用他的方法。
spring依赖注入(DI)的三种方式
接口注入、构造器注入、Setter注入
Spring Bean的作用域:
Singleton:Spring IOC容器中只有一个共享的Bean实例,一般都是Singleton作用域。
Prototype:每一个请求,会产生一个新的Bean实例。
Request:每一次http请求会产生一个新的Bean实例。
Spring支持三种依赖注入方式,分别是属性(Setter方法)注入,构造注入和接口注入。
AOP(面向切面编程):将核心关注点和横切关注点分离开来.
核心关注点:业务主要流程
横切关注点:与业务关系不大.
AOP应用到项目中的好处,能够将与业务逻辑不相关的代码(如:日志、权限等)分离出来,减小相关业务类负担,
并能让一些通用需求(如:事务)得到更广泛的复用.
一些概念:
1.切面:日志.安全性框架等,总之和业务逻辑没关系的就可以看做切面.
2.通知:切面中的方法
3.切入点:只有符合切入点才能把通知和目标方法结合在一起.
4.连接点:客户端调用的方法
5.织入:形成代理方法的过程.
AOP中各种通知
前置通知: 在目标方法执行之前
后置通知
* 在目标方法执行之后
* 可以根据returning获取目标方法的返回值
<aop:after-returning method="commit" pointcut-ref="perform" returning="val"/>
public void commit(JoinPoint joinPoint,Object val)
* 如果目标方法遇到异常,该通知不执行
最终通知
* 在目标方法执行之后
* 无论目标方法是否遇到异常,都执行
* 经常做一些关闭资源
异常通知
目的就是为了获取目标方法抛出的异常
环绕通知
能控制目标方法的执行
Spring AOP代理对象的生成 如果目标类实现了接口,则spring容器会采用jdkproxy,如果目标类没有实现接口,则spring容器会采用cglibproxy
JDK动态代理和CGLIB字节码生成的区别?
(1)JDK动态代理只能对实现了接口的类生成代理,而不能针对类
(2)CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法
JDK代理是不需要依赖第三方的库,只要JDK环境就可以进行代理,它有几个要求
* 实现InvocationHandler
* 使用Proxy.newProxyInstance产生代理对象
* 被代理的对象必须要实现接口
使用JDK动态代理,目标类必须实现的某个接口,如果某个类没有实现接口则不能生成代理对象。
CGLib 必须依赖于CGLib的类库,Cglib原理是针对目标类生成一个子类,覆盖其中的所有方法,所以目标类和方法不能声明为final类型。
针对接口编程的环境下推荐使用JDK的代理。从执行效率上看,Cglib动态代理效率较高。
在hibernate中的拦截器其实现考虑到不需要其他接口的条件Hibernate中的相关代理采用的是CGLib来执行。
加载配置文件,启动spring容器
spring容器为bean创建对象
解析aop的配置,会解析切入点表达式
看纳入spring管理的那个类和切入点表达式匹配,如果匹配则会为该类创建代理对象
代理对象的方法体的形成就是目标方法+通知
JDK动态代理和CGLIB字节码生成的区别?
* JDK动态代理只能对实现了接口的类生成代理,而不能针对类
* CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法
Java针对接口的动态代理:
客户端调用--------->代理对象---------->被调用目标对象.
动态代理必须实现InvocationHandler接口,同时使用以下方法.
Object invoke(Objectm代理实例,Method代理实例上调用的接口方法的Method 实例,Object[] 传入代理实例上方法调用的参数值的对象数组);
Proxy.newProxyInstance(类加载器, Class<?>[]接口数组,回调代理对象(一般是this))
public class MyInvocationHandler implements InvocationHandler {
private Object target;
MyInvocationHandler() {
super();
}
MyInvocationHandler(Object target) {
super();
this.target = target;
}
@Override
public Object invoke(Object o, Method method, Object[] args) throws Throwable {
if("getName".equals(method.getName())){
System.out.println("++++++before " + method.getName() + "++++++");
Object result = method.invoke(target, args);
System.out.println("++++++after " + method.getName() + "++++++");
return result;
}else{
Object result = method.invoke(target, args);
return result;
}
}
}
---
public class Main1 {
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
InvocationHandler invocationHandler = new MyInvocationHandler(userService);
UserService userServiceProxy = (UserService)Proxy.newProxyInstance(userService.getClass().getClassLoader(),
userService.getClass().getInterfaces(), invocationHandler);
System.out.println(userServiceProxy.getName(1));
System.out.println(userServiceProxy.getAge(1));
}
}
运行结果
++++++before getName++++++
------getName------
++++++after getName++++++
Tom
------getAge------
10
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
nginx:
Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器
特点:
反向代理 负载均衡 动静分离...
反向代理 :
先来了解正向代理:需要我们用户,手动的设置代理服务器的ip和端口号
反向代理:代理服务器的,用户不需要设置.
负载均衡:
原理就是数据流量分摊到多个服务器上执行,减轻每台服务器的压力,
多台服务器共同完成工作任务,从而提高了数据的吞吐量。
动静分离:
将静态的资源放到反向服务器,节省用户的访问时间.
////////////////////////////////////////////
用nginx在window上搭建一个集群
1.在g盘新建两个目录 tomcat1 tomcat2
2.修改tomcat2的端口 在tomcat1的端口上+10
3.解压nginx
修改nginx的 nginx.conf文件
在locatioin / 下添加了反向代理
proxy_pass 代理服务器
这是只是代理一台服务器
4.代理集群
需要在http节点上添加一个
upstream servlet_yujia{
server 127.0.0.1:8080;
server 127.0.0.1:8090;
}
修改location /下的反向代理
proxy_pass http://servlet_yujia
5.session共享问题
解决方式1:只能在window下好使
web服务器解决(广播机制)
注意:tomcat下性能低
修改两个地方:
1.修改tomcat的server.xml 支持共享
将 引擎标签下的
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
注释去掉
2.修改项目的配置文件 web.xml中添加一个节点
解决方式2:
可以将session的id放入redis中
解决方式3:
保证一个ip地址永远的访问一台web服务器,就不存在session共享问题了,在linux
在nginx的配置文件中
upstream中添加 ip_hash;
////////////////////////////////////////////
在linux搭建集群
1.先将 nginx上传到linux上
2.解压nginx
3.先编译nginx
安装依赖包
yum install gcc-c++
yum install -y pcre pcre-devel
yum install -y zlib zlib-devel
yum install -y openssl openssl-devel
执行编译
先进入 nginx的目录
执行
./configure
4.安装nginx
执行
make
make install
5.启动nginx
cd nginx目录下
配置文件 conf
启动nginx
./nginx
6.将端口号80 放行
/sbin/iptables -I INPUT -p tcp --dport 80 -j ACCEPT
将该设置添加到防火墙的规则中
/etc/rc.d/init.d/iptables save
7.修改conf文件 和window下一样
配置集群
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
redis相比memcached的好处
1.memecached的值均是简单字符串,而redis支持string list set' hash等多种类型
2.redis可以持久化其数据而放在硬盘,而memcached掉电后就没有了
-------------------------------------------------------------------------------------------------------------------
Redis
1. 什么是redis
redis是一个nosql(not only sql不仅仅只有sql)数据库.翻译成中文叫做非关系型型数据库.
关系型数据库:以二维表形式存储数据
非关系型数据库: 以键值对形式存储数据(key, value形式)
是一家意大利的创业公司出的,然后后来这家公司被VMware赞助. redis底层用C语句编写.
redis是将数据存放到内存中,由于内容存取速度快所以redis被广泛应用在互联网项目中,
redis优点:存取速度快,官方称读取速度会达到30万次每秒,写速度在10万次每秒最有,具体限制于硬件.
缺点:对持久化支持不够良好,
所以redis一般不作为数据的主数据库存储,一般配合传统的关系型数据库使用.
2. redis应用领域
分布式缓存
分布式session
保存博客或者论坛的留言回复等.
总之是用在数据量大,并发量高的情况下
3. 怎么用
redis主要就是使用命令来进行操作,java端在代码中可以使用Jedis来操作redis服务器
redis数据类型
1.字符串类型,2.散列类型 3.列表类型 4.集合类型 5.有序集合类型
Redis五种数据类型介绍
4.redis持久化方案:
rdb(Redis DataBase):可以设置间隔多长时间保存一次(Redis不用任何配置默认的持久化方案)
优点:让redis的数据存取速度变快
缺点:服务器断电时会丢失部分数据(数据的完整性得不到保证)
aof:(Append-only file)可以设置实时保存
优点:持久化良好,能包装数据的完整性
缺点:大大降低了redis系统的存取速度
5. 主从复制:
这里使用了心跳检测机制,主从复制必须使用rdb持久化方式
从服务器一般是只读的,保证主服务器和从服务器的数据一致性
6.Redis设置过期时间
- EXPIRE 将key的生存时间设置为ttl秒
- PEXPIRE 将key的生成时间设置为ttl毫秒
- EXPIREAT 将key的过期时间设置为timestamp所代表的的秒数的时间戳
- PEXPIREAT 将key的过期时间设置为timestamp所代表的的毫秒数的时间戳
-------------------------------------------------------------------
-------------------------------------------------------------------
--------------------------------------------------------------------
----------------------------------------------------------------------
--------------------------------------------------------------
-------------------------------------------------------------