JSP应用程序设计 by.XHF

JDBC:

1. 概念:Java DataBase Connectivity  Java 数据库连接, Java语言操作数据库
    * JDBC本质:其实是官方(sun公司)定义的一套操作所有关系型数据库的规则,即接口。各个数据库厂商去实现这套接口,提供数据库驱动jar包。我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类(驱动)2. 快速入门:
    * 代码实现:
          //1. 导入驱动jar包
        //2.注册驱动
        Class.forName("com.mysql.jdbc.Driver");
        
        //private String driver="com.mysql.jdbc.Driver";
        private String url="jdbc:mysql://localhost:3306/cap";
        private String user="root";
        private String password="admin";

        //3.获取数据库连接对象
        Connection conn = DriverManager.getConnection(url,user,password);
        //4.定义sql语句
        String sql = "update account set balance = 500 where id = 1";
        //5.获取执行sql的对象 Statement
        Statement stmt = conn.createStatement();
        //6.执行sql
        int count = stmt.executeUpdate(sql);
        //7.处理结果
        System.out.println(count);
        //8.释放资源
        stmt.close();
        conn.close();

3. 详解各个对象:
    1. DriverManager:驱动管理对象
        * 功能:
            1. 注册驱动:写代码使用:  Class.forName("com.mysql.jdbc.Driver");
                通过查看源码发现:在com.mysql.jdbc.Driver类中存在静态代码块
                 static {
                        try {
                            java.sql.DriverManager.registerDriver(new Driver());
                        } catch (SQLException E) {
                            throw new RuntimeException("Can't register driver!");
                        }
                    }
                注意:mysql5之后的驱动jar包可以省略注册驱动的步骤。
            2. 获取数据库连接:
                * 方法:static Connection getConnection(String url, String user, String password) 
                * 参数:
                    * url:指定连接的路径
                        * 语法:jdbc:mysql://ip地址(域名):端口号/数据库名称
                        * 例子:jdbc:mysql://localhost:3306/cap
                        * 细节:如果连接的是本机mysql服务器,并且默认端口是3306,则url可以简写为:jdbc:mysql:///数据库名称
                    * user:用户名
                    * password:密码 
    2. Connection:数据库连接对象
        1. 功能:
            1. 获取执行sql 的对象
                * Statement createStatement()
                * PreparedStatement prepareStatement(String sql)  
            2. 管理事务:
                * 开启事务:setAutoCommit(boolean autoCommit) :调用该方法设置参数为false,即开启事务
                * 提交事务:commit() 
                * 回滚事务:rollback() 
    3. Statement:执行sql的对象
        1. 执行sql
            1. int executeUpdate(String sql) :执行DML(insert、update、delete)语句、DDL(create、alter、drop)语句
                * 返回值:影响的行数,可以通过这个影响的行数判断DML语句是否执行成功 返回值>0的则执行成功,反之,则失败。
            2. ResultSet executeQuery(String sql)  :执行DQL(select)语句
        2. 练习:
            1. account表 添加一条记录
            2. account表 修改记录
            3. account表 删除一条记录

            
    4. ResultSet:结果集对象,封装查询结果
        * boolean next(): 游标向下移动一行,判断当前行是否是最后一行末尾(是否有数据),如果是,则返回false,如果不是则返回true
        * getXxx(参数):获取数据
            * Xxx:代表数据类型   如: int getInt() ,    String getString()
            * 参数:
                1. int:代表列的编号,1开始   如: getString(1)
                2. String:代表列名称。 如: getDouble("balance")
        
        * 注意:
            * 使用步骤:
                1. 游标向下移动一行
                2. 判断是否有数据
                3. 获取数据

               //循环判断游标是否是最后一行末尾。
                    //6.2 获取数据
                    <%
                        while (resultSet.next()){//获取数据
                    %>
                    <tr>
                        <td><%=resultSet.getInt("id")%></td>
                        <td><%=resultSet.getString("username")%></td>
                        <td><%=resultSet.getString("password")%></td>
                        <td><a href="do_edit.jsp?id=<%=resultSet.getInt("id")%>">Edit</a></td>
                        <td><a href="do_delete.jsp?id=<%=resultSet.getInt("id")%>">Delete</a> </td>
                    </tr>

        * 练习:
            * 定义一个方法,查询emp表的数据将其封装为对象,然后装载集合,返回。
                1. 定义Emp2. 定义方法 public List<Emp> findAll(){}
                3. 实现方法 select * from emp;
                    
    5. PreparedStatement:执行sql的对象
        1. SQL注入问题:在拼接sql时,有一些sql的特殊关键字参与字符串的拼接。会造成安全性问题
            1. 输入用户随便,输入密码:a' or 'a' = 'a
            2. sql:select * from user where username = 'fhdsjkf' and password = 'a' or 'a' = 'a' 

        2. 解决sql注入问题:使用PreparedStatement对象来解决
        3. 预编译的SQL:参数使用?作为占位符
        4. 步骤:
            1. 导入驱动
            2. 注册驱动
            3. 获取数据库连接对象 Connection
            4. 定义sql
                * 注意:sql的参数使用?作为占位符。 如:select * from user where username = ? and password = ?;
            5. 获取执行sql语句的对象 PreparedStatement  Connection.prepareStatement(String sql) 
            6. 给?赋值:
                * 方法: setXxx(参数1,参数2)
                    * 参数1:?的位置编号 从1 开始
                    * 参数2:?的值
                    * preparedStatement.setObject(i+1,params[i]);
            7. 执行sql,接受返回结果,不需要传递sql语句
            8. 处理结果
            9. 释放资源

        5. 注意:后期都会使用PreparedStatement来完成增删改查的所有操作
            1. 可以防止SQL注入
            2. 效率更高
            3. //连接数据库判断是否登录成功
                    Connection conn = null;
                    Statement stmt =  null;
                    ResultSet rs = null;
                    //1.获取连接
                    public ResultSet doQuery(String sql, Object[] params) {
                        ResultSet resultSet=null;
                        getConnection();                        
                        try {
                        conn =  JDBCUtils.getConnection();
                        //2.定义sql
                        String sql = "select * from user where username = ? and password = ?";
                        //3.获取执行sql的对象
                        PreparedStatement preparedStatement=connection.prepareStatement(sql);
                        //4.执行查询
                        for (int i=0;i<params.length;i++){
                        preparedStatement.setObject(i+1,params[i]);
                        }
                        rs = preparedStatemen.executeQuery();
                        //5.判断
                       /* if(rs.next()){//如果有下一行,则返回true
                            return true;
                        }else{
                            return false;
                        }*/
                       return rs.next();//如果有下一行,则返回true
            
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }finally {
                        JDBCUtils.close(rs,stmt,conn);
                    }
            
                    return false;
                }
            }

抽取JDBC工具类 : JDBCUtils

* 目的:简化书写
* 分析:
    1. 注册驱动也抽取
    2. 抽取一个方法获取连接对象
        * 需求:不想传递参数(麻烦),还得保证工具类的通用性。
        * 解决:配置文件
            jdbc.properties
                driverClassName=com.mysql.jdbc.Driver
                url=jdbc:mysql://localhost:3306/cap
                username=root
                password=admin


    3. 抽取一个方法释放资源

* 代码实现:
    public class DBCon {
       private Connection connection;
        /**
         * @return connection
         */
        public Connection getConnection(){
            try{
                Properties properties =new Properties();
                properties.load(DBCon.class.getClassLoader().getResourceAsStream("db.properties"));
                DataSource dataSource =BasicDataSourceFactory.createDataSource(properties);
                connection = dataSource.getConnection();
            }catch (Exception e){
                e.printStackTrace();
            }
            return connection;
        }
    
        public ResultSet doQuery(String sql,Object[] params){
            ResultSet resultSet =null;
            getConnection();
            try {
                PreparedStatement preparedStatement = connection.prepareStatement(sql);
                for (int i = 0; i < params.length; i++) {
                    preparedStatement.setObject(i + 1, params[i]);
                }
                resultSet =preparedStatement.executeQuery();
            }
            catch (SQLException throwables){
                throwables.printStackTrace();
            }
            return resultSet;
        }
    
        public int doUpdate(String sql,Object[] params){
            int result=0;
            getConnection();
            try {
                PreparedStatement preparedStatement=connection.prepareStatement(sql);
                for (int i=0; i < params.length; i++) {
                    preparedStatement.setObject(i+1,params[i]);
                }
                result = preparedStatement.executeUpdate();
            }catch (SQLException throwables){
                throwables.printStackTrace();
            }
            return result;
        }
        public void close(){
            try {
                if (connection!=null)
                    connection.close();
            }catch (SQLException throwables){
                throwables.printStackTrace();
            }
        }
    
    }

            

JDBC控制事务:

1. 事务:一个包含多个步骤的业务操作。如果这个业务操作被事务管理,则这多个步骤要么同时成功,要么同时失败。
2. 操作:
    1. 开启事务  2. 提交事务  3. 回滚事务
3. 使用Connection对象来管理事务
    * 开启事务:setAutoCommit(boolean autoCommit) :调用该方法设置参数为false,即开启事务
        * 在执行sql之前开启事务
    * 提交事务:commit() 
        * 当所有sql都执行完提交事务
    * 回滚事务:rollback() 
        *catch中回滚事务

4. 代码:
    public class JDBCTransaction {
public  void trans() {
    Connection connection =(new DBCon()).getConnection();
    try {

        connection.setAutoCommit(false);

        String sql = "insert into admin values(NULL,?,?)";

        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        preparedStatement.setObject(1, "tom");
        preparedStatement.setObject(2, "tom");
        preparedStatement.executeUpdate();
        System.out.println("插入第1条记录");


        preparedStatement.setObject(1, "tom");
        preparedStatement.setObject(2, "tom");
        preparedStatement.executeUpdate();
        System.out.println("插入第2条记录");

        int i = 10 / 0;
        //手动制造问题
        preparedStatement.setObject(1, "tom");
        preparedStatement.setObject(2, "tom");
        preparedStatement.executeUpdate();
        System.out.println("插入第3条记录");
        connection.commit();

    } catch (Exception e) {
        e.printStackTrace();
        try {
            connection.rollback();//事务回滚
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }
}

web相关概念回顾

1. 软件架构
    1. C/S:客户端/服务器端
    2. B/S:浏览器/服务器端

2. 资源分类
    1. 静态资源:所有用户访问后,得到的结果都是一样的,称为静态资源.静态资源可以直接被浏览器解析
        * 如: html,css,JavaScript
    2. 动态资源:每个用户访问相同资源后,得到的结果可能不一样。称为动态资源。动态资源被访问后,需要先转换为静态资源,在返回给浏览器
        * 如:servlet/jsp,php,asp....
        
3. 网络通信三要素
    1. IP:电子设备(计算机)在网络中的唯一标识。
    2. 端口:应用程序在计算机中的唯一标识。 0~65536
    3. 传输协议:规定了数据传输的规则
        1. 基础协议:
            1. tcp:安全协议,三次握手。 速度稍慢
            2. udp:不安全协议。 速度快

web服务器软件:

* 服务器:安装了服务器软件的计算机
* 服务器软件:接收用户的请求,处理请求,做出响应
* web服务器软件:接收用户的请求,处理请求,做出响应。
    * 在web服务器软件中,可以部署web项目,让用户通过浏览器来访问这些项目
    * web容器

* 常见的java相关的web服务器软件:
    * webLogic:oracle公司,大型的JavaEE服务器,支持所有的JavaEE规范,收费的。
    * webSphere:IBM公司,大型的JavaEE服务器,支持所有的JavaEE规范,收费的。
    * JBOSSJBOSS公司的,大型的JavaEE服务器,支持所有的JavaEE规范,收费的。
    * TomcatApache基金组织,中小型的JavaEE服务器,仅仅支持少量的JavaEE规范servlet/jsp。开源的,免费的。

Servlet:server applet

* 概念:运行在服务器端的小程序
    * Servlet就是一个接口,定义了Java类被浏览器访问到(tomcat识别)的规则。
    * 将来我们自定义一个类,实现Servlet接口,复写方法。


* 快速入门:
    1. 创建JavaEE项目
    2. 定义一个类,实现Servlet接口
        * public class ServletDemo1 implements Servlet
    3. 实现接口中的抽象方法
    4. 配置Servlet
         在web.xml中配置:
        <!--配置Servlet -->
        <servlet>
            <servlet-name>demo1</servlet-name>
            <servlet-class>cn.itcast.web.servlet.ServletDemo1</servlet-class>
        </servlet>
    
        <servlet-mapping>
            <servlet-name>demo1</servlet-name>
            <url-pattern>/demo1</url-pattern>
        </servlet-mapping>

* 执行原理:
    1. 当服务器接受到客户端浏览器的请求后,会解析请求URL路径,获取访问的Servlet的资源路径
    2. 查找web.xml文件,是否有对应的<url-pattern>标签体内容。
    3. 如果有,则在找到对应的<servlet-class>全类名
    4. tomcat会将字节码文件加载进内存,并且创建其对象
    5. 调用其方法

* Servlet中的生命周期方法:
    1. 被创建:执行init方法,只执行一次
        * Servlet什么时候被创建?
            * 默认情况下,第一次被访问时,Servlet被创建
            * 可以配置执行Servlet的创建时机。
                *<servlet>标签下配置
                    1. 第一次被访问时,创建
                        * <load-on-startup>的值为负数
                    2. 在服务器启动时,创建
                        * <load-on-startup>的值为0或正整数

        * Servlet的init方法,只执行一次,说明一个Servlet在内存中只存在一个对象,Servlet是单例的
            * 多个用户同时访问时,可能存在线程安全问题。
            * 解决:尽量不要在Servlet中定义成员变量。即使定义了成员变量,也不要对修改值

    2. 提供服务:执行service方法,执行多次
        * 每次访问Servlet时,Service方法都会被调用一次。
    3. 被销毁:执行destroy方法,只执行一次
        * Servlet被销毁时执行。服务器关闭时,Servlet被销毁
        * 只有服务器正常关闭时,才会执行destroy方法。
        * destroy方法在Servlet被销毁之前执行,一般用于释放资源

* Servlet3.0* 好处:
        * 支持注解配置。可以不需要web.xml了
        * 在类上使用@WebServlet注解

Servlet:

* Servlet的体系结构    
    Servlet -- 接口
        |
    GenericServlet -- 抽象类
        |
    HttpServlet  -- 抽象类

    * GenericServlet:将Servlet接口中其他的方法做了默认空实现,只将service()方法作为抽象
        * 将来定义Servlet类时,可以继承GenericServlet,实现service()方法即可

    *最优使用: HttpServlet:对http协议的一种封装,简化操作
        1. 定义类继承HttpServlet
        2. 复写doGet(浏览器访问)/doPost方法(method=“post”)

* Servlet相关配置
    1. urlpartten:Servlet访问路径
        1. 一个Servlet可以定义多个访问路径 : @WebServlet({"/d4","/dd4","/ddd4"})
        2. 路径定义规则:
            1. /xxx:路径匹配
            2. /xxx/xxx:多层路径,目录结构
            3. *.do:扩展名匹配

HTTP:

* 概念:Hyper Text Transfer Protocol 超文本传输协议
    * 传输协议:定义了,客户端和服务器端通信时,发送数据的格式
    * 特点:
        1. 基于TCP/IP的高级协议
        2. 默认端口号:80
        3. 基于请求/响应模型的:一次请求对应一次响应
        4. 无状态的:每次请求之间相互独立,不能交互数据

* 请求消息数据格式
    1. 请求行
        请求方式 请求url 请求协议/版本
        GET /login.html    HTTP/1.1

        * 请求方式:
            * HTTP协议有7中请求方式,常用的有2* GET1. 请求参数在请求行中,在url后。
                    2. 请求的url长度有限制的
                    3. 不太安全
                * POST1. 请求参数在请求体中
                    2. 请求的url长度没有限制的
                    3. 相对安全
    2. 请求头:客户端浏览器告诉服务器一些信息
        请求头名称: 请求头值
        * 常见的请求头:
            1. User-Agent:浏览器告诉服务器,我访问你使用的浏览器版本信息
                * 可以在服务器端获取该头的信息,解决浏览器的兼容性问题

            2. Referer:http://localhost/login.html
                * 告诉服务器,我(当前请求)从哪里来?
                    * 作用:
                        1. 防盗链:
                        2. 统计工作:
    3. 请求空行
        空行,就是用于分割POST请求的请求头,和请求体的。
    4. 请求体(正文)* 封装POST请求消息的请求参数的

    * 字符串格式:
        POST /login.html    HTTP/1.1
        Host: localhost
        User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0
        Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
        Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
        Accept-Encoding: gzip, deflate
        Referer: http://localhost/login.html
        Connection: keep-alive
        Upgrade-Insecure-Requests: 1
        
        username=zhangsan    


* 响应消息数据格式

Request:

1. request对象和response对象的原理
    1. request和response对象是由服务器创建的。我们来使用它们
    2. request对象是来获取请求消息,response对象是来设置响应消息

2. request对象继承体系结构:    
    ServletRequest        -- 接口
        |    继承
    HttpServletRequest    -- 接口
        |    实现
    org.apache.catalina.connector.RequestFacade(tomcat)

3. request功能:
    1. 获取请求消息数据
        1. 获取请求行数据
            * GET /day14/demo1?name=zhangsan HTTP/1.1
            * 方法:
                1. 获取请求方式 :GET
                    * String getMethod()  
                2. (*)获取虚拟目录:/day14
                    * String getContextPath()
                3. 获取Servlet路径: /demo1
                    * String getServletPath()
                4. 获取get方式请求参数:name=zhangsan
                    * String getQueryString()
                5. (*)获取请求URI/day14/demo1
                    * String getRequestURI():
                    * StringBuffer getRequestURL():
                    * URL:统一资源定位符:http://localhost/day14/demo1    中华人民共和国
                    * URI:统一资源标识符:/day14/demo1                   
                6. 获取协议及版本:HTTP/1.1
                    * String getProtocol()
                7. 获取客户机的IP地址:
                    * String getRemoteAddr()
                
        2. 获取请求头数据
            * 方法:
                * (*)String getHeader(String name):通过请求头的名称获取请求头的值 .contains
                * Enumeration<String> getHeaderNames():获取所有的请求头名称
            
        3. 获取请求体数据:
            * 请求体:只有POST请求方式,才有请求体,在请求体中封装了POST请求的请求参数
            * 步骤:
                1. 获取流对象
                    *  BufferedReader getReader():获取字符输入流,只能操作字符数据
                    *  ServletInputStream getInputStream():获取字节输入流,可以操作所有类型数据
                        * 在文件上传知识点后讲解

                2. 再从流对象中拿数据
            
            
    2. 其他功能:
        1. 获取请求参数通用方式:不论get还是post请求方式都可以使用下列方法来获取请求参数
            1. String getParameter(String name):根据参数名称获取参数值    username=zs&password=123
            2. String[] getParameterValues(String name):根据参数名称获取参数值的数组  hobby=xx&hobby=game
            3. Enumeration<String> getParameterNames():获取所有请求的参数名称
            4. Map<String,String[]> getParameterMap():获取所有参数的map集合

            * 中文乱码问题:
                * get方式:tomcat 8 已经将get方式乱码问题解决了
                * post方式:会乱码
                    * 解决:在获取参数前,设置request的编码request.setCharacterEncoding("utf-8");
        
                
        2. 请求转发:一种在服务器内部的资源跳转方式
            1. 步骤:
                1. 通过request对象获取请求转发器对象:RequestDispatcher getRequestDispatcher(String path)
                2. 使用RequestDispatcher对象来进行转发:forward(ServletRequest request, ServletResponse response) 

            2. 特点:
                1. 浏览器地址栏路径不发生变化
                2. 只能转发到当前服务器内部资源中。
                3. 转发是一次请求


        3. 共享数据:
            * 域对象:一个有作用范围的对象,可以在范围内共享数据
            * request域:代表一次请求的范围,一般用于请求转发的多个资源中共享数据
            * 方法:
                1. void setAttribute(String name,Object obj):存储数据
                2. Object getAttitude(String name):通过键获取值
                3. void removeAttribute(String name):通过键移除键值对

        4. 获取ServletContext* ServletContext getServletContext()
        
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JSP程序设计从入门到精通》电子书   第1篇 入门篇 7   第1章 Jsp概述 技术分析 7    1.1 Jsp简介与历史背景 7    1.1.1 日新月异的Web技术 7    1.1.2 什么是JSP 8    1.1.3 JSP技术有以下几个显著的优点 9    1.1.4 JSP和其他类似或相关技术的一个简单比较 10    1.2 JSP环境安装配置 12    1.2.1Tomcat下JSP环境的配置 12    1.2.1建立自己的Jsp工作目录 13    1.3 JSP语法介绍 14    1.3.1 JSP页面中的元素 14    1.3.2 JSP语法概要 15    1.3.3关于模板文本(静态HTML) 16    1.4 运行第一个Jsp程序 16    1. 5本章小结 20   第2章Jsp 基础学习 20    2.1 JSP基本语法 20    2.1.1 JSP 语法之声明 21    2.1.2 JSP 语法之表达式 21    2.1.3 JSP 语法之Scriptlet 21    2.2 JSP的指令 22    2.2.1 page指令(Directive) 22    2.2.2 include指令(Directive) 24    2.3 JSP的动作 25    2.3.1 jsp:include动作 25    2.3.2 jsp:useBean动作 27    2.3.3 jsp:setProperty动作 29    2.3.4 jsp:getProperty动作 30    2.3.5 jsp: forward动作 31    2.3.6 jsp: plugin动作 31    2.3.7注释 31    2.4 JSP 9种基本内置组件 31    2.5 JSP中Session的使用 34    2.6 JSP中forward的使用 36    2.7 JSP运行时错误处理与应该注意的六个常见问题 37    2.8 JSP小实例 38    2.8.1实例1(在JSP中定义函数) 38    2.8.2实例2(获取各种CGI环境变量) 39    2.8.3实例3(JSP里request变量列表) 42    2. 9本章小结 44   第3章JavaBean组件 44    3.1 什么是JavaBeans 45    3.1.1 JavaBeans 简介 45    3.1.2 JavaBeans 属性 45    3.1.3 JavaBeans 的事件 50    3.2 在Jsp中使用JavaBeans 55    3.3 JavaBeans的scope属性 57    3.4 JavaBeans应用实例 59    3.4.1 实例1(HelloWord.java) 59    3.4.2 实例2(People.java) 60    3.4.3实例子3数组应用 (Example2_3.java) 60    3.4.4实例子4运算符、表达式应用 (Example3_1.java) 61    3.5 本章小结 62   第4章Jsp与Servlet 62    4.1 什么是Servlets 63    4.1.1 JavaServlet的解释 63    4.1.2 什么是Jsp 65    4.1.3 得到一个Servlets和JSP的运行环境 66    4.1.4 实现第一个JSP和SERVELT 67    4.2 Servlet规范定义的Servlet 生命周期 70    4.3 JSP/Servlet的重定向技术综述 72    4.3.1 RequestDispatcher.forward() 72    4.3.2 response.sendRedirect() 73    4.4 理解会话 74    4.4.1 会话状态跟踪API 75    4.4.2 在会话对象中保存数据 76    4.4.3实例:显示会话信息 76    4.5 用Java Servlets代替CGI 78    4.6 JSP/Servlet 中的汉字编码问题 80    4.7 图解Eclipse+Tomcat集成开发Servlet 84    4.8 Servlets/JSP开发技术问答 93    4.9 Servlet小实例 97    4.5.1实例1(输出) 98    4.5.2实例2(获取表单参数) 99    4.5.3实例3(获取jsp各种参数) 101    4.1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值