一、什么是Mybatis?
Mybatis是一个半自动的ORM持久层框架,内部封装了JDBC。作为开发者只需要关注sql语句本身。
Mybatis是通过xml或注解的方式将需要执行的各种statement配置起来。
通过Java对象和statement中的sql动态参数映射生成最终执行的sql语句,
最终由Mabtais框架执行sql并将结果映射为Java对象并返回。
MyBatis 支持定制化 SQL、存储过程以及高级映射。MyBatis 是可以双向映射的,可以将数据集映射为Java对象,
也可以将Java对象映射为数据库中的记录。
public void test1() throws IOException {
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
//1.SqlSessionFactory会话工厂。
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(is);
//2.会话
SqlSession session = sessionFactory.openSession();
//3.通过会话获取dao接口
UserMapper mapper = session.getMapper(UserMapper.class);
/**
* 默认情况下,一级缓存,就是session级别缓存是开启
* 保存,删除,更新,一级缓存的数据会自动清空,下次查询,会执行sql语句
*/
User user1 = mapper.findUserById(1);
System.out.println("user1:" + user1);
//保存用户
// mapper.save(new User("广东雨神","1",null,"广东"));
User user2 = mapper.findUserById(1);
System.out.println("user2:" + user2);
session.commit();
session.close();
}
mybatis 查询数据库过程
通过Resources加载配置好的mybatis.xml配置文件。
mybatis中xml解析是通过SqlSessionFactoryBuilder.build()方法。
通过SqlSesssionFactory.openSession()方法打开一个SqlSession对象
通过SqlSession.getMapper()根据传入的Mapper对象类型动态代理并返回一个动态代理后的Mapper对象
由SqlSession.select()/update(),MapperProxy对象的invoke()方法执行后再执行execure方法,
再根据情况选择执行select/update
Executor执行Query/queryFromDatabase,在前面经过参数名封装和缓存查询之后(缓存为空),
会调用queryFromDatabase方法去数据库当中查
SimpleExecurot执行doQuery()方法,初始化prepareStatement并且给#{}参数赋值
StatementHandler执行query()方法,执行sql语句
ResuletHandler.handleResultSets()方法封装结果集
6. 什么时候才能命中二级缓存,什么时候才能存到二级缓存里
如果二级缓存想要命中实现,则必须要将上一次sqlSession commit之后才能生效,不然将不会命中,
原因:因为mybatis的缓存会被一个transactioncache类包装住,所有的cache.putObject全部都会被暂时
存到一个map里,等事务提交以后,这个map里的缓存对象才会被真正的cache类执行putObject操作。
这么设计的原因是为了防止事务执行过程中出异常导致回滚,如果get到object后直接put进缓存,
万一发生回滚,就很容易导致mybatis缓存被脏读
多个sqlsession去操作同一个mapper的sql语句,多个sqlsession可以共用二级缓存,
所得到的数据会存在二级缓存区域,二级缓存是跨sqlsession的,二级缓存相比一级缓存的范围更大
(按namespace来划分),多个sqlsession可以共享一个二级缓存
一级缓存
一个SqlSession对象中创建一个本地缓存(local cache),对于每一次查询,都会尝试根据查询的条件
去本地缓存中查找是否在缓存中,如果在缓存中,就直接从缓存中取出,然后返回给用户;
否则,从数据库读取数据,将查询结果存入缓存并返回给用户。
因为所有的增删改都会刷新二级缓存,导致二级缓存失效,所以适合在查询为主的应用中使用,
比如历史交易、历史订单的查询。否则缓存就失去了意义。
一个Tomcat中只有一个Server,一个Server可以包含多个Service,一个Service只有一个Container,但是可以有多个Connectors,
这是因为一个服务可以有多个连接,如同时提供Http和Https链接
(1)Tomcat中只有一个Server,一个Server可以有多个Service,一个Service可以有多个Connector和一个Container;
(2) Server掌管着整个Tomcat的生死大权;
(4)Service 是对外提供服务的;
(5)Connector用于接受请求并将请求封装成Request和Response来具体处理;
(6)Container用于封装和管理Servlet,以及具体处理request请求
Connector
Connector就是使用ProtocolHandler来处理请求的,不同的ProtocolHandler代表不同的连接类型,
比如:Http11Protocol使用的是普通Socket来连接的,Http11NioProtocol使用的是NioSocket来连接的。
其中ProtocolHandler由包含了三个部件:Endpoint、Processor、Adapter。
(1)Endpoint用来处理底层Socket的网络连接,Processor用于将Endpoint接收到的Socket封装成Request,Adapter用于将Request交给Container进行具体的处理。
(2)Endpoint由于是处理底层的Socket网络连接,因此Endpoint是用来实现TCP/IP协议的,而Processor用来实现HTTP协议的,Adapter将请求适配到Servlet容器进行具体的处理。
(3)Endpoint的抽象实现AbstractEndpoint里面定义的Acceptor和AsyncTimeout两个内部类和一个Handler接口。Acceptor用于监听请求,AsyncTimeout用于检查异步Request的超时,Handler用于处理接收到的Socket,在内部调用Processor进行处理。
Container用于封装和管理Servlet,以及具体处理Request请求,在Connector内部包含了4个子容器,结构图如下(图C):
4个子容器的作用分别是:
(1)Engine:引擎,用来管理多个站点,一个Service最多只能有一个Engine;
(2)Host:代表一个站点,也可以叫虚拟主机,通过配置Host就可以添加站点;
(3)Context:代表一个应用程序,对应着平时开发的一套程序,或者一个WEB-INF目录以及下面的web.xml文件;
(4)Wrapper:每一Wrapper封装着一个Servlet
Container处理请求是使用Pipeline-Valve管道来处理的!(Valve是阀门之意)
Pipeline-Valve是责任链模式,责任链模式是指在一个请求处理的过程中有很多处理者依次对请求
进行处理,每个处理者负责做自己相应的处理,处理完之后将处理后的请求返回,再让下一个处理着继续处理。
介绍servlet 定义、实现方式、方法、生命周期
Servlet是使用 Java 语言编写的运行在服务器端的程序。Servlet的作用是处理请求,
服务器会把接收到的请求交给Servlet来处理,在Servlet中通常需要:接收请求,处理请求,完成响应。
实现Servlet的方式
实现Servlet有三种方式:
实例化
Servlet容器负责加载和实例化Servlet。Servlet容器会在Servlet第一次被访问时创建Servlet,
或者是在服务器启动时创建Servlet。
当启动Servlet容器时,容器首先查找配置文件web.xml,这个文件中记录了可以提供服务的Servlet。
Servlet容器会为自动装入的Servlet创建一个实例。所以,每个Servlet类必须有一个公共的无参数
的构造器。
初始化
在Servlet实例化之后,容器将调用Servlet的init()方法初始化这个对象。
初始化的目的是为了让Servlet对象在处理请求前完成一些初始化的工作,
对于每一个Servlet实例,init()方法只被调用一次。
在初始化期间,Servlet实例可以使用容器为它准备的ServletConfig对象从Web应用程序的配置信息
(在web.xml中配置)中获取初始化的参数信息。
请求处理
Servlet容器调用Servlet的service()方法对请求进行处理。在service()方法中,
Servlet实例通过ServletRequest对象得到客户端的相关信息和请求信息,在对请求进行处理后
,
调用ServletResponse对象的方法设置响应信息。 service()方法为Servlet的核心方法,
客户端的业务逻辑应该在该方法内执行。
对于 Servlet 的每一次访问请求,Servlet 容器都会调用一次 Servlet 的 service() 方法,
并且创建新的 ServletRequest 和 ServletResponse 对象,也就是说,service() 方法在 Servlet
的整个生命周期中会被调用多次。
卸载Servlet
当服务器不再需要Servlet实例或重新装入时,会调用destroy方法,使用这个方法,
Servlet可以释放掉所有在init方法申请的资源。一个Servlet实例一旦终止,
就不允许再次被调用,只能等待被卸载。
filter是由servlet规范定义的,是servlet容器支持的。
拦截器是spring容器内的,是spring框架支持的
filter只在servlet前后起作用。而拦截器能够深入到方法前后,异常抛出前后等。拦截器的粒度更小。
拦截器是基于java的反射机制的,而过滤器是基于函数回调。
拦截器可以调用IOC容器中的各种依赖,而过滤器不能
监听器
Servlet的监听器Listener,它是实现了javax.servlet.ServletContextListener接口的服务器端程序,
它也是随web应用的启动而启动,只初始化一次,随web应用的停止而销毁。
主要作用是:做一些初始化的内容添加工作、设置一些基本的内容、比如一些参数或者是
一些固定的对象等等。
在javax.servlet.ServletContextListener接口中定义了2种方法:
void contextInitialized(ServletContextEvent sce) 监听器的初始化
void contextDestroyed(ServletContextEvent sce) 监听器销毁
Servlet中的过滤器Filter是实现了javax.servlet.Filter接口的服务器端程序,
主要的用途是过滤字符编码、做一些业务逻辑判断等。
其工作原理是,只要你在web.xml文件配置好要拦截的客户端请求,它都会帮你拦截到请求,
此时你就可以对请求或响应(Request、Response)统一设置编码,简化操作;同时还可以进行逻辑判断,
如用户是否已经登录、有没有权限访问该页面等等工作,它是随你的web应用启动而启动的,
只初始化一次,以后就可以拦截相关的请求,只有当你的web应用停止或重新部署的时候才能销毁。
在javax.servlet.Filter接口中定义了3个方法:
(1)void init(FilterConfig filterConfig) 用于完成过滤器的初始化
(2)void destroy() 用于过滤器销毁前,完成某些资源的回收
(3)void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) 实现过滤功能,该方法对每个请求增加额外的处理
Nginx几种转发策略【转】
1、轮询(默认)
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。
2、指定权重
指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。
3、IP绑定 ip_hash
每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。
4、fair(第三方)
按后端服务器的响应时间来分配请求,响应时间短的优先分配。
5、url_hash(第三方)
按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。
1、Tomcat可存放jar类库的地方
1)/common/* : Tomcat和所有Web应用都可以访问
2)/server/* : 仅Tomcat可以访问
3)/shared/* : 仅所有Web应用可以访问
4)另外Web应用程序自身的目录:/WEB-INF/*: 仅单个Web应用可以访问
2、各种ClassLoader
1)CommonClassLoader: 加载 /common/*
2)CatalinaClassLoader: 加载 /server/*
3)SharedClassLoader: 加载 /shared/*
4)WebAppClassLoader: 加载Web应用程序目录: /WEB-INF/*
打开server.xml后,在里面找到下图的一段代码,里面的port=“8080”就代表Tomcat的默认端口号,修改8080的值就可以成功改Tomcat的默认端口号。
MVC 模式代表 Model-View-Controller(模型-视图-控制器) 模式。这种模式用于应用程序的分层开发。
Model(模型) - 模型代表一个存取数据的对象。它也可以带有逻辑,在数据变化时更新控制器。
View(视图) - 视图代表模型包含的数据的可视化。
Controller(控制器) - 控制器作用于模型和视图上。它控制数据流向模型对象,并在数据变化时更新视图。
它使视图与模型分离开。
Controller层用来调度View层和Model层,将用户界面和业务逻辑合理的组织在一起,起粘合剂的效果。
所以Controller中的内容能少则少,这样才能提供最大的灵活性。controller相当于路由的作用。
原文:https://www.cnblogs.com/zrzct/p/14394619.html