A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

【石家庄校区】JDBC+数据库连接池+XML+tomcat+serrvlet+cookie+session+JSP

1、JDBC

导入jar包 ----- mysql-connector-java-5.0.8-bin.jar
编写 .properties文件
编写JDBCUtils工具类
读取 .properties文件
Properties p = new Properties();
p.load(new FileInputStream(".properties"));
p.getProperty(“键名”);
注册驱动 Class.forName("com.mysql.jdbc.Driver");
获取连接 Connection conn = DriverManager.getConnection(url,username,password);
编写sql语句 String sql = "“;
预编译sql PreparedStatement ps = conn.prepareStatement(sql);
为占位符赋值 ps.setXXX(索引,值)-----索引是从1开始的
执行sql ResultSet rs = ps.executeQuery();或者ps.exectureUpdate();
有结果集就遍历,没有就算了 whilers.next(){ rs.getXXX("字段名或者别名") }
释放资源 ifrs/ps/conn = null{ rs/ps/conn.close();-------会抛异常,try catch捕获一下 rs/ps/conn = null;--------手动置为null,提早释放资源 }

2、数据库连接
连接池对象应该是一个应用只创建一次就可以了,不用每次使用时都创建。
Druid
导jar包 ----- druid-1.0.9.jar
两种方式配置:
方式一:手动配置
创建DruidDataSource对象DruidDataSource dds = new DruidDataSource();
//用这个对象手动设置数据库连接参数
dds.setDriverClassName("com.mysql.jdbc.Driver");
dds.setUrl("jdbc:mysql://localhost:3306/数据库名");
dds.setUserName("root");dds.setPassword("1234");
//获取连接Connection conn = dds.getConnection();
//编写SQL语句String sql = "";
//用连接对象创建执行对象PreparedStatement ps = conn.prepareStatement(sql);
//如果sql语句中有需要设置的参数就设置ps.setXXX(索引,值);
//执行ResultSet rs = ps.executeQuery();或者int num = ps.executeUpdate();
while(rs.next()){ rs.getXXX();}
//释放资源if(rs/ps/conn != null){ rs/ps/conn.close();------这时候的conn.close()是将连接归还连接池 rs/ps/conn = null;}

方式二:使用 .properties 配置文件从外界读取。
配置文件的名称可以随便定义,但是文件里的内容的键名是指定的。(注意:键名和c3p0的键名有稍微的区别。)
//编写properties配置文件
driverClassName=com.mysql.jdbc.Driverurl=jdbc:mysql://localhost:3306/数据库名username=rootpassword=1234
//编写Utils工具类
//创建properties对象读取配置文件Properties ps = new Properties()ps.load(new FileInputStream("properties文件路径"));
//用DruidDataSourceFactory对象调用createDataSource(Properties ps);方法创建连接池对象
DataSource ds = DruidDataSourceFactory.createDataSource(ps);
//从连接池中获取连接Connection conn = ds.getConnection();
//释放资源
//用连接对象conn获取PreparedStatement ps 执行对象
String sql = "";ps = conn.prepareStatement(sql);
//设置sql参数ps.setXXX();
//执行sql语句ResultSet rs = ps.executequery()或者int num = ps.executeUpdate();
//遍历结果集或者用num进行其他操作while(rs.next()){ rs.getXXX();}
//释放资源

c3p0连接池
导包 ---- c3p0-0.9.1.2.jar
两种设置配置参数的方式:参数的键名和Druid的键名有稍微区别,记得区分。
方式一:手动设置
//创建连接池对象ComboPooledDataSource datasource = new ComboPooledDataSource();
//设置连接配置参数datasource.setDriverClass("com.mysql.jdbc.Driver");datasource.setJdbcUrl("jdbc:mysql://localhost:3306/数据库名");datasource.setUser("root");datasource.setPassword("1234");
//从连接池中获取连接对象Connection conn = datasourcee.getConnection();
//编写sqlString sql = "";
//预编译sql,获取执行sql对象PreparedStatement ps = conn.prepareStatement(sql);
//为sql设置值ps.setXXX(?位置编号,值);
//执行sqlResultSet rs = ps.executeQuery();或者int num = ps.executeUpdate();
//遍历rs或者使用numwhile(rs.next()){ rs.getXXX();}
//释放资源

方式二:编写c3p0-config.xml配置文件
(放在该使用类路径下。文件名必须是这个,文件中的键名也用规定好的)
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jabc:mysql://localhost:3306/数据库名 </property>
<property name="user">root</property>
<property name="password">1234</property>
<!-- 下面的非必须,但是最好设置上-->
<property name="initialPoolSize">5</property>
<property name="minPoolSize">5</property>
<property name="maxPoolSize">20</property>
</default-config>
</c3p0-config>
//创建数据库连接池ComboPooledDataSource datasource = new ComboPooledDataSource(); ----- ( c3p0创建这个对象时会自动去查询该类路径下的c3p0-config.xml配置文件,有的话,就直接配置完成;没有的话,会报错。)
//获取连接Connection conn = datasource.getConnection();
//编写sqlString sql = "";
//预编译sql,获取执行对象PreparedStatement ps = conn.prepareStatement(sql);
//为sql设置值ps.setXXX(?位置编号,值);
//执行sqlResuleSet rs = ps.executeQuery()或者int num = ps.execute();
//遍历结果集,或者使用numwhile(rs.next()){ rs.getXXX();}
//释放资源

DBUtils
对jdbc中的获取连接、预编译sql、释放资源、封装结果集等步骤进行了简单的封装,大大简化了开发步骤,提高了开发效率,还不影响执行效率。
导包 ------ commons-dbutils-1.4.jar
核心类 --- QueryRunner类
构造方法:
QueryRunner(); ------- 无参的
QueryRunner(DataSource ds); ------有参的,传入一个数据库连接池对象。
一般情况下执行CRUD操作
构造:QueryRunner(DataSource da);
方法:int update(String sql , Object...args);
T query(String sql , ResultSetHandler<T> res , Object...args);
如果有事务管理的话,使用另一套CRUD操作
构造:QueryRunner();
方法:int update(Connection conn , String sql , Object...args);
T query(Connection conn , String sql , ResultSetHandler<T> res , Object...args);

ResultSetHandler的常用实现类:
如果查询时sql语句中使用了字段的别名,注意取值和封装是的不同点。

ArrayHandler
  ---- 只查询到一条数据(记录)将其封装到一个 Object[ ]类型的数组中。
public static void demo(){
QueryRunner qr = new QueryRunner(DataSource ds);
String sql = "select * from user where id = ?";
Object[ ] obj = qr.query(sql , new ArrayHandler() , 1); /* 如果使用其中的数据的话,可以进行数据类型的强转。 */ system.out.println(Array.toString(obj));
}
ArrayListHandler
  --- 将查询到多条数据(记录),将每一条数据(记录)封装到一个Object[ ]类型的数组中,再将这些Object[ ]数组装到一个List集合中。
public static void Demo(){
QueryRunner qr = new QueryRunner(DataSource ds);
String sql = "select * from user";
List<Object[]> list = qr.query(sql,new ArrayListHandler());
for(Object obj : list){ /* 如果使用其中的数据的话,可以进行数据类型的强转。 */ system.out.println(Array.toString(obj));
}
}
BeanHandler
  --- 只查询到一条数据(记录)将其封装到一个JavaBean中。
public static void Demo(){
QueryRunner qr = new QueryRunner(DataSource ds);
String sql = "select * from user where id = ?";
User user = qr.query(sql,new BeanHandler<User>(User.class),2); system.out.println(user);
}
BeanListHandler
  --- 将查询到多条数据(记录),将每一条数据(记录)封装成一个JavaBean对象,再将这些JavaBean对象装到一个List集合中。
public static void Demo(){
QueryRunner qr = new QueryRunner(DataSource ds);
String sql = "select * from user";
List<User> list = qr.query(sql,new BeanListHandler<User>(User.class));
for(User user : list){ system.out.println(user);
}
}
MapHandler
  --- 只查询到一条数据(记录),将这一条数据(记录)封装到一个Map集合中,Map的key就是字段名(列名),value就是表中对应的值。
public static void Demo(){
QueryRunner qr = new QueryRunner(DataSource ds);
String sql = "select * from user where id = ?";
//注意Map集合中的泛型,键是String类型的,值是Object类型的。
Map<String,Object> map = qr.query(sql,new MapHandler(),3);
system.out.println(map);
}
MapListHandler
  --- 将查询到多条数据(记录),每一条数据(记录)封装成为一个Map集合,再将这些Map集合装到一个List集合中。
public static void Demo(){
QueryRunner qr = new QueryRuner(DataSource ds);
String sql = "select * from user";
List<Map<String,Object>> list = qr.query(sql,newMapListHand());
for(Map<String,Object> map : list){ system.out.println(map);
}
}
ScalarHandler
  --- 将单个值封装。比如聚合函数查询后的结果。返回的是一个Object 类型的。
public static void Demo(){
QueryRunner qr = new QueryRunner(DataSource ds);
String sql = "select count(*) from user";
Object obj = qr.query(sql,new ScalarHendler());---可以进行数据类型的强转
system.out.println(obj);
}
ColumnListHendler
  --- 将数据中的某列数据装到一个list集合中。
  有三个构造函数:ColumnListHandler();
               ColumnListHandler(int columnIndex);
               ColumnListHandler(String columnName); --- 常用

public static void Demo(){
QueryRunner qr = new QueryRunner(DataSource ds);
String sql = "select name,password from user";
List<Object> list = qr.query(sql,new ColumnListHandler("name"));
for(Object obj : list){ //可以进行数据强转 system.out.println(obj); }
}
KeyedHandler --- (了解)
  --- 将查询的多条数据(记录),每一条数据(记录)封装成一个Map集合,然后将这些Map集合再装到一个Map集合中,并且外层的这个Map集合可以自定义key。
public static void Demo(){
Query Runner qr = new QueryRunner(DataSource ds);
String sql = "select * from user";
Map<Object,Map<String,Object>> map = qr.query(sql,new KeyedHandler("name"));
for(Object key : map.keySet()){ system.out.println(key+" "+map.get(key));
}
}

QueryRunner类中的其他方法:
int[ ] batch(String sql , Object obj); ------ 普通的批处理 插入、修改、删除 sql 语句
int[ ] batch(Connection conn , String sql ,Object obj);--- 有事务管理的批处理 插入 修改 删除 sql

其他类 --- DbUtils
构造
DbUtils(); ----- 无参构造
常用方法
commitAndCloseQuietly(); --该方法的解释--Commits a Connection then closes it, avoid closing if null and hide any SQLExceptions that occur.
rollbackAndCloseQuietly(); --该方法的解释--Performs a rollback on the Connection then closes it, avoid closing if null and hide any SQLExceptions that occur.

3、XML
XML基础知识
  --- 可扩展标记语言
  --- 现在常用的用途:一、作为应用的配置文件。二、用作不同系统之间的数据传输。
       不常用的用途 :存储数据。  
  --- 没有被预定义的标签,用户可以自己定义标签。
  --- 基本语法:1、必须有闭标签。2、严格区分大小写。3、属性值必须有引号。4、标签与标签之间必须正确的嵌套。
  --- 文档声明:必须在第一行第一列。
      格式:<?xml verson="1.0" encoding="字符集" standalong="?>
          standalong:描述xml文档是否需要依赖其他文件。
  --- xml元素的命名规范:1、可包含字母、数字及其他符号。2、不能数字或者标点符号开始3、名称不能以xml/XML/Xml的任意形式开始。4、名称中不能包含空格。5、名称中不能包含冒号(:)。
  --- CDATA区   <![DATA[..内容:全都当成普通字符串,而不会当成标签内容..]]>
  --- 注释:<!--注释区-->
  --- 特殊字符:< ---- <  > ---- >   & --- &   &apos --- ' " ---- "
XML的解析(重点)
概述:XML解析就是指从XML文档中通过代码获得想要的数据。
共两种解析方式:
  DOM 解析(Document Object Model) 和 SAX 解析(Simple Api for XML)
DOM 和 SAX的区别:
DOM解析:一次性将文档加载到内存,形成DOM树(树形结构),在进行解析。 优点:可以对XML进行增删改的操作。 缺点:如果文档特别大的话,容易导致内存的溢出。 SAX解析:事件驱动的方式一行一行的进行解析。 优点:不能对文档进行增删才的操作。 缺点:即使文档很大,也不会导致内存溢出。
解析步骤及代码:
DOM4J的入门案例步骤:
【步骤一】导入jar包.dom4j-1.6.1.jar
【步骤二】创建解析器
【步骤三】解析文档获得代表文档的Document对象.
【步骤四】获得跟节点.
【步骤五】从跟节点下查找其他的节点.
代码实现:
获得元素的内容:查询的操作.
public void demo1() throws Exception{
// 创建解析器SAXReader reader = new SAXReader();
// 解析XML的文档Document document = reader.read("xml/demo1.xml");
// 获得跟节点Element root = document.getRootElement();
System.out.println(root.getName());
// 查找跟节点下的子节点. element() elements();Element pElement = root.element("person");
// 查找的是第一个person元素// root.elements("person").get(1);
// 查找的是第二个person元素Element nElement = pElement.element("name");
Element aElement = pElement.element("age");
Element sElement = pElement.element("sex");
System.out.println(nElement.getText());
System.out.println(aElement.getText());
System.out.println(sElement.getText());
}
XPath:
dom4j支持XPath的jar包.
jaxen-1.1-beta-6.jar
dom4j的XPath支持的API:
List document.selectNodes(String xPath);
Node document.selectSingleNode(String xPath);
代码:
DOM4J的XPath的写法:
public void demo2() throws Exception{
// 创建解析器: SAXReader reader = new SAXReader();
// 解析XML返回Document对象. Document document = reader.read("xml/demo1.xml");
List<Node> list = document.selectNodes("//name");
for (Node node : list) { Element element = (Element) node;
System.out.println(element.getText());
}
List<Node> list = document.selectNodes("//person['@id']");
for (Node node : list) { Element element = (Element) node; System.out.println(element.attributeValue("id")); }
}
4、tomcat
部署
1.如果要用虚拟路径:
​ tomcat\conf\Catalina\localhost:新建一个xxx.xml ,写 <Context docBase=""/> 访问路径:xxx
2.将项目导出成war包,直接扔到webapps下
协议
请求
1.get/post的区别:
​ get提交的参数显示到地址栏,在请求行中地址后面;post提交的参数在请求体中
​ get有大小的限制,post没有
​ get没有请求体,post有
2.常见的请求头:
​ User-agent:浏览器的类型
​ Referer:防盗链
响应
1.常见的状态码:
​ 302:重定向(结合Location响应头使用)
​ 304:查找本地缓存
​ 404:路径错误,资源真的不存在
​ 500:代码写错了
2.常见的响应头:
​ Location:结合302做重定向
​ Content-Disposition:文件下载的时候用
​ Refresh:定时刷新
5、Servlet
访问规则:
如果要访问一个servlet,这个地址串跟web.xml中配置的url-pattern有关系
生命周期(面试点一)

程序优化的思想:
一次性的资源的加载(耗时的操作)放到服务器启动的时候

url-pattern的配置方式
1.完全路径匹配:以/开头 /aaa
2.目录匹配:以/开头 以*结尾 /aa/ *
3.扩展名匹配:不能以/开头 以*开头 *.do *.action
优先级关系:根本的原因,一次请求只有一次响应
完全路径匹配 > 目录匹配 > 扩展名匹配

ServetContext
如何获得:在有servlet的环境下:this.getServletContext();
范围:整个web应用的范围
域对象存取数据
setAttribute(String name,Object value);
Object getAttribute(String name);
removeAttribute(String name)

读取web项目下的文件
1.有servlet的环境下:
​ InpuptStream getResourceAsStream(String path);
​ String getRealPath(String path);
2.如果没有servlet的环境:
​ 用类加载器去读取文件:
​ InpuptStream is = 当前类的类名.class.getClassLoader().getResourceAsStream(String name);
企业级工具类的一个编写思想

Response
文件下载
把一个文件从服务器读取,写到客户端
文件下载的核心思想:io 读/写的操作
InpuptStream is = new FileInputStream("服务器上的路径");
OutputStream os = response.getOutputStream();
模板代码:
  int len = 0;
  byte[] b = new byte[1024];
  while((len = is.read(b))!= -1){
      os.write(b, 0, len);
  }
  is.close();
Content-Type: getServletContext().getMimiType(String filename);Content-Disposition:"attachment;filename="+filename;

响应乱码
response.getOutputStream():文件下载
下列方式:以后不常用
response.getWriter().print("");这种乱码问题如何解决:response.setContentType("text/html;charset=UTF-8");
Request
获取客户端信息
1.请求方式:request.getMethod();
2.请求ip:request.getRemoteAddr();
3.获取工程名:request.getContextPath();
获取表单参数
String request.getParameter(String name);
String [] request.getParameterValues(String name);
Map<String,String[]> request.getParameterMap();
请求乱码
get:
​ String name = new String(request.getParameter("name").getBytes("ISO-8859-1"),"UTF-8")
post:
​ request.setCharacterEncoding("UTF-8")
作为域对象存取数据
范围:一次请求和响应的范围
setAttribute(String name,Object value);
Object getAttribute(String name);
removeAttribute(String name)
转发和重定向(面试点二)
转发:
​ request.getRequestDispatcher("不带工程名的路径").forward(request,response)
重定向:
​ response.sendRedirect("带工程名称的路径")
区别:
1.地址栏:转发地址栏不变,重定向会变
2.请求响应的次数:转发一次请求一次响应,重定向是两次请求和响应
​ 如果给request域中存放了数据:转发能够获得到数据,重定向不能获得到数据
3.路径的编写:转发不带工程名,重定向带工程名
4.跳转的范围:转发只能在当前工程下跳转,重定向可以跳转至任意网页
6、Cookie
如何获得:Cookie[] cookies = request.getCookies();
如何向客户端写cookie:response.addCookie(Coookie cookie)
如何创建cookie:Cookie cookie = new Cookie(String name,String value);
​ 获得名字:cookie.getName()
​ 获得值:cookie.getValue();
​ 设置路径:cookie.setPath(String path);
​ 设置有效期:cookie.setMaxAge(int age) 单位是:秒
作用范围:默认是一次会话,关闭浏览器就销毁
关于cookie存储中文的问题:
  往回写cookie:
  String value = URLEncoder.encode("老谭", "UTF-8");//"老谭"--fadsf%%33
  Cookie cookie = new Cookie("aa",value);
  response.addCookie(cookie);
  获得:
  Cookie [] cookies = request.getCookies();
  Cookie aa= CookieUtils.findCookie(cookies, "aa");
  if(aa!=null){
      String value = aa.getValue();//fadsf%%33--"老谭"
      String a = URLDecoder.decode(value, "utf-8");
  }
7、Session
如何获得:HttpSession session = request.getSession();
作为域对象存取数据
session.setAttribute(String name,Object value);Object vlaue = session.getAttribute(String name);removeAttribute(String name);
范围:一次会话(根本原因:存SesssionID的cookie默认是会话级别的)
配置sessionion过期时间:web.xml
   <session-config>
       <session-timeout>5</session-timeout> <!--单位是分钟-->
  </session-config>
8、JSP
三大指令:
​ page:
​ 全局错误友好页面的配置
    <error-page>
      <error-code>404</error-code>
      <location>/404.jsp</location>
    </error-page>
    <error-page>
      <error-code>500</error-code>
      <location>/500.jsp</location>
    </error-page>
​ include: <%@ include file="" %> 静态包含
​ taglib:
九大内置对象(面试点三):
              request           HttpServetRequest
              response          HttpServetResponse
              session           HttpSession
              application       ServletContext
              page              Object
              out               JspWriter
              pageContext       PageContext
              config            ServletConfig
              exception         Throwable
技能 拔高点:pageContext:
​ 1.获取其他8个内置对象:getXXX()方法
​ 2.可以向四个域中存取数据:
  pageContext.setAttribute("pname", "pvalue", PageContext.PAGE_SCOPE);
  pageContext.setAttribute("rname", "rvalue", PageContext.REQUEST_SCOPE);
  pageContext.setAttribute("sname", "svalue", PageContext.SESSION_SCOPE);
  pageContext.setAttribute("aname", "avalue", PageContext.APPLICATION_SCOPE);
  <%= pageContext.getAttribute("pname", PageContext.PAGE_SCOPE) %>
  <%= pageContext.getAttribute("rname", PageContext.REQUEST_SCOPE) %>
  <%= pageContext.getAttribute("sname", PageContext.SESSION_SCOPE) %>
  <%= pageContext.getAttribute("aname", PageContext.APPLICATION_SCOPE) %>
  ​
动作标签:
<jsp:forward page=""> :转发
<jsp:include page="">:动态包含
静态包含和动态包含的区别(面试点四)
静态包含:相当于源代码的拷贝,只会翻译成一个Java类,有一个执行结果
动态包含:各自分别去翻译,各自执行,最终包含的是执行的结果
9、EL&JSTL
EL获取数据
以什么名字存到域中,就以什么名字取出来,存进去是什么类型的,取出来就是什么类型
数组,List:[] ----遍历map,java对象:. .属性
EL执行运算
empty:判断是否为空
not empty:判断是否不为空
lt
gt
le
ge
eq
EL操作常用的web对象
${cookie.名字.value}
${pageContext.request.contextPath}
JSTL的中判断
  <c:if test="${}">
      test:如果test返回true,标签内的内容就会被输出
  </c:if>
  if标签没有else,如果想表达else的情况,从条件着手
JSTL中的遍历
  <c:forEach var="" items="" varStatus="status">
      status.index
      status.count
  </c:forEach>
  <c:forEach var="" begin="" end="" step="" varStatus="status">
  </c:forEach>


1 个回复

倒序浏览
我来占层楼啊   
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马