在Java开发中,使用JDBC操作数据库的四个步骤如下:

      ①加载数据库驱动程序(Class.forName("数据库驱动类");)
      ②连接数据库(Connection con  = DriverManager.getConnection();)
      ③操作数据库(PreparedStatement stat = con.prepareStatement(sql);stat.executeQuery();)
      ④关闭数据库,释放连接(con.close();)
  也就是说,所有的用户都需要经过此四步进行操作,但是这四步之中有三步(①加载数据库驱动程序、②连接数据库、④关闭数据库,释放连接)对所有人都是一样的,而所有人只有在操作数据库上是不一样,那么这就造成了性能的损耗。
  那么最好的做法是,准备出一个空间,此空间里专门保存着全部的数据库连接,以后用户用数据库操作的时候不用再重新加载驱动、连接数据库之类的,而直接从此空间中取走连接,关闭的时候直接把连接放回到此空间之中。
  那么此空间就可以称为连接池(保存所有的数据库连接),但是如果要想实现此空间的话,则必须有一个问题要考虑?
      1、 如果没有任何一个用户使用连接,那么那么应该维持一定数量的连接,等待用户使用。
      2、 如果连接已经满了,则必须打开新的连接,供更多用户使用。
      3、 如果一个服务器就只能有100个连接,那么如果有第101个人过来呢?应该等待其他用户释放连接
      4、 如果一个用户等待时间太长了,则应该告诉用户,操作是失败的。
   如果直接用程序实现以上功能,则会比较麻烦,所以在Tomcat 4.1.27之后,在服务器上就直接增加了数据源的配置选项,直接在服务器上配置好数据源连接池即可。在J2EE服务器上保存着一个数据库的多个连接。每一个连接通过DataSource可以找到。DataSource被绑定在了JNDI树上(为每一个DataSource提供一个名字)客户端通过名称找到在JNDI树上绑定的DataSource,再由DataSource找到一个连接。如下图所示:
  
  那么在以后的操作中,除了数据库的连接方式不一样之外,其他的所有操作都一样,只是关闭的时候不是彻底地关闭数据库,而是把数据库的连接放回到连接池中去。
  如果要想使用数据源的配置,则必须配置虚拟目录,因为此配置是在虚拟目录之上起作用的。需要注意的是,如果要想完成以上的功能,在Tomcat服务器上一定要有各个数据库的驱动程序。

JNDI的概念

JNDI是什么: java Naming and Directory Interface, java命名和目录接口// 通过名称将资源与服务进行关联

JNDI的作用和优点: 在应用与java对象或资源之间建立松耦合的逻辑关联,简化应用对于资源的配置以及维护工作//可以在更大的范围,不同应用之间共享资源

问题1

如何实现在Tomcat中发布一条信息供所有Web应用程序使用?

发布信息 :修改 Tomcat/conf/ context.xml文件

<Context>

<Environment name="tjndi"  value="hello JNDI" type="java.lang.String" />

</Context?> 

获取资源:使用lookup()进行查找

//java.naming.Context提供了查找JNDI的接口

//初始化Context对象

Context ctx= new InitialContext();

//java:comp/env/为前缀

//调用lookup方法

String tes =(String)ctx.lookup("java:comp/env/tjndi");

out.print("JNDI:+testjndi");

为什么要使用连接池:

什么是连接池:

连接池是一个等待数据库连接的队列。

连接池的原理:

客户端向服务器端请求连接, 服务器端先看连接池中是否有空的连接,如果有空的连接就让该客户端连接, 如果没有空的连接,那就看现有连接数是否达到连接池限定的个数,如果没有达到就为该客户端创建一个连接,如果达到了那就让该客户端排队,等其他客户端断开连接了,就让该客户端连接。
连接池会设定一个等待时间,超过这个时间就就是连接超时了, 一般服务器性能和网速都会有影响。

Data Source 与连接池

javax.sql.DataSource接口的实现类

以连接池的形式对数据库连接进行管理

如何获取DataSource的实例

访问数据源:

Context的配置文件

属性

分成模式

使用Jsp的弊端: 页面展示和逻辑掺杂在一起阅读起来不清晰。不利于代码的维护和更新

三层架构

表示层:最外层,使用户直接能够访问,用于显示数据和接收用户输入的数据,为用户提供一种交互式操作界面
业务逻辑层:业务逻辑层的主要功能就是提供对业务逻辑处理的封装,在业务逻辑层中,通常会定义一些接口,表示层通过调用业务逻辑层的接口来实现各种操作
数据访问层:数据访问层就是实现对数据的保存和读取操作,数据访问,可以访问关系数据库,文本文件或XML文档等
层与层之间的关系
表示层依赖业务逻辑层,业务逻辑依赖于数据访问层各层之间的数据传递方向为请求与响应两个方向

使用三层开发的原则
1.上层依赖下层,依赖关系不跨层
2.下一层不能调用上一层
3.下一层不依赖上一层
4.在上一层不能出现下一层的概念
使用三层开发的优势和特点
1.下层不知道上层的存在
2.每一层仅仅知道它下一层的存在,而不知道另外的下层

使用分层架构的优点如下
1.职责划分清晰
2.无损替换
3.复用代码
4.降低了系统内部的依赖程度

连接池(DBCP与C3p0) 1): 之前的连接操作 拿到一个连接--->执行sql进行数据操作--->关闭连接 ps: 这样的话存在一些缺点的,比如每拿到一个连接用完后则就把这个连接关闭了,这很浪费,毕竟拿到一个连接等是需要时间的 这样也不能很好的对连接数进行控制 ,如果连接数过多的话,则可能会有内存泄漏服务器崩溃 2): 连接池 连接池则在创建一个数据库连接的缓冲池,在这个缓冲池创建时则可以在里边初始化一定的连接数,如需要获取连接时,则只需要到这个缓冲池中获取就行, 且用完后并不会把连接销毁,而是放回到缓冲池中,我们也可以设置同时的最大连接数等等,可以很好的避免之前连接操作的缺点 3): DataSource接口 对于数据库连接操作,有给我们提供了一个DataSource接口让我们来实现, 而这个接口一般会由一些开源组织或者服务器来实现 常用的有DBCP连接池与C3P0连接池, DataSource一般也叫数据源,也习惯把DataSource叫做连接池 2: DBCP连接池 1): DBCP连接池使用前提 需要导入两个jar包commons-dbcp.jar, commons-pool.jar 2): 数据源对象 数据源对象与数据库连接对象不同,它是产生(获取 )数据库连接对象的工厂 3: C3P0连接池 1): 使用前提需要导入c3p0的jar包 2): 使用

连接池的配置

文件上传
客户端提交表单,将文件传给服务器,就是文件上传.
表单标签 必须为 method="post"
enctype="multipart/form-data" <h3>客户,请上传的头像</h3>
<form action="upload.jsp" method="post" enctype="multipart/form-data">
文件: <input type="file" name="userfile"><br><br>
<input type="submit" value="提交">
</form> 上传文件的基本要求:
上传文件的格式类型
上传文件的大小
上传文件的路径
上传文件的命名机制 java实现文件上传
、jspsmartupload 文件上传组件 ,早些时间使用的多,简单 SmartUpload su = new SmartUpload();
su.initialize(pageContext);
su.upload(); //接表单值,如果有乱码,最好下载支持utf-8组件
out.print(su.getRequest().getParameter("username")); String path = request.getServletContext().getRealPath("upload");
File f = new File(path);
if(!f.exists()){
f.mkdirs();
}
//上传文件
su.save(path); //指定上传文件的目标路径 在服务器当前项目根目录下的upload目录
String path = request.getServletContext().getRealPath("upload");
File f = new File(path);
if(!f.exists()){
f.mkdirs();
} //控制文件上传类型
su.setAllowedFilesList("jpg,png"); //控制上传文件的大小
su.setMaxFileSize(*); 100KB <%@ page import="com.jspsmart.upload.SmartUpload" %>
<%@ page import="java.io.File" %>
<%@ page import="com.jspsmart.upload.Files" %>
<%@ page import="java.util.UUID" %>
<%@ page import="java.text.SimpleDateFormat" %>
<%@ page import="java.util.Random" %>
<%@ page import="java.util.Date" %>
<%@ page contentType="text/html;charset=utf-8" language="java" %>
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8">
<title>webrx-</title>
</head>
<body>
<%
SmartUpload su = new SmartUpload();
su.initialize(pageContext);
su.setAllowedFilesList("jpg,png");
su.setMaxFileSize(*);
try {
su.upload(); //接表单值,如果有乱码,最好下载支持utf-8组件
out.print(su.getRequest().getParameter("username")); //指定上传文件的目标路径 在服务器当前项目根目录下的upload目录
String path = request.getServletContext().getRealPath("upload");
File f = new File(path);
if (!f.exists()) {
f.mkdirs();
} //上传文件
//su.save(path); 将文件全部指上传到指定目录下,文件使用原来名子,如果有重复覆盖 //从0开始
int c = su.getFiles().getCount(); //out.print(su.getFiles().getFile(0).getFileName());
Files fs = su.getFiles();
for(int n=;n<c;n++){
com.jspsmart.upload.File fff = fs.getFile(n);
//String name = fff.getFileName();//原文件名 //使用uuid命名
String ext = fff.getFileExt();
//String name = UUID.randomUUID().toString()+"."+ext; //使用年月日信息命名
//SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssS");
//Random r = new Random();
//int nn = r.nextInt(9999999);
//String name = sdf.format(new Date())+"_"+String.format("%07d",nn)+"."+ext; //使用命名编号
String fname = fff.getFileName();
String basename = fname.substring(,fname.lastIndexOf("."));
String name = path+"/"+fname;
File nf = new File(name);
int num = ;
while(nf.exists()){
fname = basename+"("+ ++num + ")."+ext;
name = path+"/"+fname;
nf = new File(name);
} fff.saveAs("./upload/"+fname,SmartUpload.SAVE_VIRTUAL); //fff.saveAs("./upload/"+name,SmartUpload.SAVE_VIRTUAL);
}
}catch (Exception e){
out.print(e.getMessage());
}
%>
</body>
</html> 、Commons FileUpload apache文件上传组件 目前使用是最多的 使用2个jar包文件
commons-fileupload-1.3..jar
commons-io-2.5.jar @WebServlet("/UpFile.action")
public class UpFile extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//使用apache commons fileupload 上传 boolean isMultipart = ServletFileUpload.isMultipartContent(req);
String path = this.getServletContext().getRealPath("upload/"); //上传文件 if(isMultipart){
DiskFileItemFactory f = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(f);
try {
List<FileItem> items = upload.parseRequest(req);
for(FileItem ft : items){
if(ft.isFormField()){
//取得上传的表单字符串,
System.out.println(ft.getFieldName()+"="+ft.getString("utf-8"));
}else{
//如果没有选文件
//System.out.println(ft.getSize()); //0
//System.out.println(ft.getFieldName());//userfile 表单名
//System.out.println(ft.getName());//'' 空字符串
//System.out.println(ft.getContentType());//application/octet-stream //97289
//userfile
//66ba2e6152f638cba76a99f77d0f74c31e86204c238d0-qIKBWz_fw658.jpg
//image/jpeg //取得上传的文件名称
String filename = ft.getName(); //实现将文件写入到服务器指定的目录中
if(!"".equals(filename)) {
ft.write(new File(path, filename));
} }
} } catch (FileUploadException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} } }
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
boolean isMultipart = ServletFileUpload.isMultipartContent(req);
String path = this.getServletContext().getRealPath("upload/");
if(isMultipart){
DiskFileItemFactory f = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(f);
try {
Map<String,List<FileItem>> maps = upload.parseParameterMap(req);
//直接接表单username 字符串值
String username = maps.get("username").get().getString("utf-8"); //直接接userface单文件
FileItem ft1 = maps.get("userface").get();
if(!ft1.getName().equals("")){
ft1.write(new File(path,ft1.getName()));
} //直接接checkbox 多选表单
List<FileItem> itemss = maps.get("love");
for(FileItem ftc : itemss){
System.out.println(ftc.getString("utf-8"));
} //直接接userfile 文件数目不定
List<FileItem> items = maps.get("userfile");
for(FileItem ft : items){
if(!ft.getName().equals("")){
ft.write(new File(path,ft.getName()));
}
} } catch (FileUploadException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} }
} 、cos 文件上传组件 性能最好, 最快, 是国外一家出版社编写的 、sun在servlet3. 时候 内置 直接实现文件上传 headers
content-disposition
content-type upfile.jsp
<h3>servlet3 客户,请上传的头像</h3>
<form action="upload.action" method="post" enctype="multipart/form-data">
姓名:<input type="text" name="username"><br><br>
文件1: <input type="file" name="userfile1" multiple><br><br>
文件2: <input type="file" name="userfile2" ><br><br>
文件3: <input type="file" name="userfile3" ><br><br>
<input type="submit" value="提交">
</form> upload.action
package com.fz.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.File;
import java.io.IOException;
import java.util.Collection; /**
* Created by webrx on 2017-05-06.
*/
@WebServlet("/upload.action") @MultipartConfig
public class Upload extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("utf-8");
//接表单值
String name = req.getParameter("username");
System.out.println(name); //接单个文件文件
//Part uf = req.getPart("userfile");
//if(!uf.getSubmittedFileName().equals("")){
// uf.write(getServletContext().getRealPath("upload/")+uf.getSubmittedFileName());
//} //接批量文件上传
Collection<Part> uf = req.getParts();
for(Part p : uf){
if(p.getHeader("content-type")==null) continue;
if(!p.getSubmittedFileName().equals("")){
p.write(getServletContext().getRealPath("upload/")+p.getSubmittedFileName());
}
} //Part part = req.getPart("username");
/*
System.out.println(req.getParameter("username"));
Collection<Part> ps = req.getParts();
for(Part p : ps){
String name = p.getName();//表单名
//System.out.println(p.getHeader("content-disposition"));
//System.out.println(p.getHeader("content-type")); //如果为null 就是普通字符串表单
//System.out.println(p.getSubmittedFileName());
// p.getSubmittedFileName() 如果是null 则是普通表单 if(p.getHeader("content-type")==null){
//普通表单 }else{
//可能是文件,也可以是空文件
//form-data; name="userfile"; filename=""
//application/octet-stream //实现文件上传到 c:/目录下
if(!p.getSubmittedFileName().equals("")) {
p.write("c:/"+p.getSubmittedFileName());
}
}
}

JSP使用分层实现业务处理的更多相关文章

  1. JSP/Servlet开发——第五章 使用分层实现业务处理

    1.JNDI(Java Naming and Directory Interface)Java命名和目录接口: ●JNDI:是一个有关应用序设计的 API 为开发人员提供了查找和访问各种命名和目录服务 ...

  2. Javaweb学习笔记--分层设计

    在早期的JavaWeb应用中,JSP文件负责处理业务逻辑,控制网页流程并创建HTML页面,JSP文件是一个独立的,能自主完成所有任务的模块, 这带来了一系列问题:HTML代码和Java程序代码强耦合在 ...

  3. java web学习总结(二十七) -------------------JSP标签介绍

    一.JSP标签介绍 JSP标签也称之为Jsp Action(JSP动作)元素,它用于在Jsp页面中提供业务逻辑功能,避免在JSP页面中直接编写java代码,造成jsp页面难以维护. 二.JSP常用标签 ...

  4. JSP页面以及JSP九大隐式对象

    €JSP全称是Java Server Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术. €JSP这门技术的最大的特点在于,写jsp就像在写html,但它相比 ...

  5. 11 JSP/EL表达式/EL函数

    JSP      * 概述: JSP(Java Server Pages)与Java Servlet一样,是在服务器端执行的不同的是先由服务器编译部署成Servlet执行      * JSP的运行原 ...

  6. JavaWeb---总结(十)JSP标签

    一.JSP标签介绍 JSP标签也称之为Jsp Action(JSP动作)元素,它用于在Jsp页面中提供业务逻辑功能,避免在JSP页面中直接编写java代码,造成jsp页面难以维护. 二.JSP常用标签 ...

  7. jsp机制基础

    JSP 和Servlet技术一样,JSP也是SUN公司定义的一种开发动态web资源的技术,属于JavaEE技术之一.JSP实际上就是Servlet,它们在一起又称JSP/Servlet规范. Serv ...

  8. jsp的标签

    一.JSP标签介绍 JSP标签也称之为Jsp Action(JSP动作)元素,它用于在Jsp页面中提供业务逻辑功能,避免在JSP页面中直接编写java代码,造成jsp页面难以维护. 二.JSP常用标签 ...

  9. Jsp技术总结

    这节我们总结一下Jsp的相关技术. 1. 什么是JSP JSP即Java Server Pages,它和servlet技术一样,都是sun公司定义的一种用于开发动态web资源的技术.该技术的最大特点在 ...

随机推荐

  1. SpringCloud-分布式配置中心【加密-非对称加密】

    案例代码:https://github.com/q279583842q/springcloud-e-book 非对称加密 一.什么是非对称加密(Asymmetric encryption) 二.Jav ...

  2. 向HashMap中添加1000个元素,设置new HashMap()值为多少合适?

    在已知元素容量的情况下,为了尽量减少碰撞增加查询效率,应该尽量选择较大数的同时避免资源浪费. HashMap底层通过hash值来计算索引位置的源码: 1.重新计算hash值 static final ...

  3. 办公利器-一行代码搞定http服务

    平时给内网的同事分享个文件,直接用python启动一个http服务,方便又简洁: python3: python -m http.server [port] 默认端口为8000 python2: py ...

  4. Ubuntu --- Virtualbox 和 宿主机文件夹共享

    1.在设置里面共享文件夹 2.在Ubuntu中配置 sudo mount -t vboxsf share /var/www/html/ 无需重启即可生效 3.实现系统重启后也自动挂载 在文件 /etc ...

  5. 03、MySQL—数据表操作

    1.创建数据表 基本语法:create table 表名(字段名 字段类型 [字段属性], 字段名 字段类型 [字段属性],…) [表选项] 范例:创建数据表 以上错误说明:表必须放到对应的数据库下: ...

  6. 由django请求生命周期延伸出的知识点大总结

    django项目搭建见: https://www.cnblogs.com/dongxixi/p/10981577.html django请求生命周期图: 由浏览器发起请求开始 知识点1: 浏览器与服务 ...

  7. vi的替换使用、如何让linux有回收站功能、系统重要文件、目录数据

      1 vi的替换使用方法 vi使用的原理 (编辑文件会生成一个隐藏临时文件) 1.1 替换文件内容方法:vi (1)%s#oldboy#oldgirl#g --- 将oldboy全部替换为oldgi ...

  8. git的基本指令

    更多详情请看廖雪峰官方网站 http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000 1.删 ...

  9. java代码书写易犯错误

    java代码书写易犯错误: 常见报错: 控制台报错: 找不到或无法加载主类 HelloWorld 原因: java.lang.NoClassDefFoundError: cn/itcast/day01 ...

  10. 如何让apache支持.htaccess 解决Internal Server Error The server …错误

    如何让apache支持.htaccess 解决Internal Server Error The server …错误 文章来源:小灰博客| 时间:2013-12-25 12:17:08| 作者:Le ...