为什么使用数据库连接池?
回顾:
加载驱动---
获取连接对象 DriverManager.getConnection(url,username,password)
........
关闭连接。
每次客户连接数据库时都需要创建新的连接对象, 使用完毕后在关闭连接对象。 如果这时有10000请求 需要创建链接对象10000次。 这样数据库服务器受不了。消耗资源。
连接池得介绍
-
概念:
数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏。这项技术能明显提高对数据库操作的性能。
-
常见数据库连接池
-
C3P0:是一个开放源代码的JDBC连接池,它在lib目录中与Hibernate [2] 一起发布,包括了实现jdbc3和jdbc2扩展规范说明的Connection 和Statement 池的DataSources 对象。
-
Proxool:是一个Java SQL Driver驱动程序,提供了对选择的其它类型的驱动程序的连接池封装。可以非常简单的移植到现存的代码中,完全可配置,快速、成熟、健壮。可以透明地为现存的JDBC驱动程序增加连接池功能。
-
Jakarta DBCP:DBCP是一个依赖Jakartacommons-pool对象池机制的数据库连接池。DBCP可以直接的在应用程序中使用。
-
DBPool:是一个高效、易配置的数据库连接池。它除了支持连接池应有的功能之外,还包括了一个对象池,使用户能够开发一个满足自己需求的数据库连接池。
-
Druid(德鲁伊特):
DRUID是阿里巴巴开源平台上一个数据库连接池实现,它结合了C3P0、DBCP、PROXOOL等DB池的优点,同时加入了日志监控,可以很好的监控DB池连接和SQL的执行情况,可以说是针对监控而生的DB连接池(据说是目前最好的连接池)。
Druid不仅是一个数据库连接池,还包含一个ProxyDriver、一系列内置的JDBC组件库、一个SQL Parser。
支持所有JDBC兼容的数据库,包括Oracle、MySql、Derby、Postgresql、SQL Server、H2等。
Druid针对Oracle和MySql做了特别优化,比如:
-
Oracle的PS Cache内存占用优化
-
MySql的ping检测优化
Druid提供了MySql、Oracle、Postgresql、SQL-92的SQL的完整支持,这是一个手写的高性能SQL Parser,支持Visitor模式,使得分析SQL的抽象语法树很方便。
简单SQL语句用时10微秒以内,复杂SQL用时30微秒。
通过Druid提供的SQL Parser可以在JDBC层拦截SQL做相应处理,比如说分库分表、审计等。Druid防御SQL注入攻击的WallFilter,就是通过Druid的SQL Parser分析语义实现的
-
-
如何使用连接池
(1)加入druid得jar包。
(2)修改db.properties
(3) 修改父类BaseDao得代码
2. 过滤器
为什么使用过滤器!
比如我们在每一个请求方法中都需要设置请求编码和响应编码。
比如其他操作时 都需要判断是否登录 如果登录才能进行相应的操作。
过滤器就可以解决上面这些问题!
如何使用过滤器
(1)创建一个Filter类 并实现Filter接口
(2)把自定义的filter类 注册到Tomcat容器。web.xml
(3)定义过滤器的规则
还可以使用注解得方式创建过滤器
-
过滤器的执行流程
客户端发出请求----》过滤器----》放行-----》请求的资源----》响应----》过滤器----》客户端
-
过滤器的生命周期
同servlet生命周期:
init():初始化
doFilter():放行方法
destroy():销毁方法 当服务器正常关闭时,执行。
-
过滤的规则
-
-
具体的资源路径: /index.jsp 只有访问index.jsp资源时,过滤器才会被执行
-
拦截目录:/user/* 访问user目录下的所有资源时,过滤器会被执行
-
后缀名拦截:*.jsp / *.do 访问所有后缀名为.jsp .do时,过滤器会被执行
-
拦截所有资源: /* 访问所有资源时,过滤器都会被执行。
-
-
3. 编码过滤器
package com.ykq.filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter(urlPatterns = "/*")
public class CharacterEncodingFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
servletRequest.setCharacterEncoding("utf-8"); //设置请求得编码
servletResponse.setContentType("text/html;charset=utf-8"); //设置响应的编码
filterChain.doFilter(servletRequest,servletResponse);//放行
}
//修改自己的代码 把原来的编码设置 去除 添加过滤编码设置
@Override
public void destroy() {
}
}
4. 登录过滤器
路径: 如果在servlet中跳转的是其他servlet 使用绝对路径 如果是跳转网页 /
如果在过滤器中 使用绝对路径
package com.ykq.filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@WebFilter(urlPatterns = "/*")
public class LoginFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//把ServletRequest对象和 ServletResponse对象强制为HttpServletRequest和HttpServletResponse对象
HttpServletRequest req= (HttpServletRequest) servletRequest;
//req.getServletContext().getContextPath() java中获取决定路径
HttpServletResponse resp= (HttpServletResponse) servletResponse;
//1.什么时候放行。session中存在用户信息 如果访问得路径为login.jsp登录页面 登录的处理servlet
//1.获取session
HttpSession session = req.getSession();
Object user = session.getAttribute("user"); //获取session中登录者信息
if(user!=null){
filterChain.doFilter(req,resp);
}else{
//获取请求路径是否为login.jsp或者login
String requestURI = req.getRequestURI();
if(requestURI.contains("/login.jsp") || requestURI.contains("/login")){
filterChain.doFilter(req,resp);
}else{
//跳转到登录
resp.sendRedirect("/web04/login.jsp");
}
}
}
@Override
public void destroy() {
}
}