栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

JavaWeb学习笔记

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

JavaWeb学习笔记

JDBC 一、什么是JDBC 简介
  • Java连接数据库,可以使用Java语言连接数据库,完成CRUD操作

  • Java中定义了访问数据库的接口,可以为多种关系型数据库提供统一的访问方式,由数据库厂商提供驱动实现类(Driver数据库驱动)

导入JDBC jar包

对着项目名,右键,new,Directory,lib文件夹,复制粘贴,add as library

JDBC API
类型权限定名简介
classjava.sql.DriverManager管理多个数据库驱动类,提供了获取数据库连接的方法
interfacejava.sql.Connection代表一个数据库连接
interfacejava.sql.Statement发送SQL语句到数据库工具
interfacejava.sql.ResultSet发送SQL查询语句的结果数据
classjava.sql.SQLException处理数据库应用程序时所发生的异常
JDBC常见错误
java.lang.ClassNotFoundException找不到类(类名书写错误,没有导入jar包)
java.sql.SQLException与sql语句有关错误,在sqlyog写好,再复制进去,一般就可解决
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:Unknown column列值string类型没有加单引号
Duplicate entry ‘1’ for key ‘PRIMARY’主键值已存在或混乱,更改主键值或清空表
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:Unknown column ‘password’ in可能输入的值的类型不对,确定是否插入的元素时对应的值的类型正确
二、JDBC开发步骤 增删改

int result=statement.executeUpdate(“DELETE FROM t_jobs WHERe job_id=‘H5_Mgr’;”);

插入(验证安装成功)
	package com.tang.JDBC;
	import java.sql.*;
	public class TestJDBC {
    public static void main(String[] args) throws  Exception {
        //1.注册驱动,加载驱动
        Class.forName("com.mysql.jdbc.Driver") ;

        //2.获得数据库连接
        String url="jdbc:mysql://localhost:3306/companydb";  //连接到哪个数据库
        String user="root";
        String password="123456";
        Connection connection=DriverManager.getConnection(url,user,password);

        if(connection!=null){
            System.out.println("连接到数据库了");
        }else{
            System.out.println("连接失败");
        }

        //3.获得执行SQL语句的对象(使用Statement类)
        Statement statement=connection.createStatement();

        //4.编写SQL语句 执行SQL语句
        String sql="INSERT INTO t_jobs(job_id,JOB_TITLE,MIN_SALARY,MAX_SALARY) VALUES ('H4_Mgr','H4_Manager',4000,10000)";
        int result=statement.executeUpdate(sql);
        System.out.println("受影响行数:"+result);   //返回受影响行数

        //5.处理数据库的返回结果
        if(result==1) {
            System.out.println("创建成功");
        }else{
            System.out.println("创建失败");
        }
        //6.关闭资源
        statement.close();
        connection.close();
    }
}
去除警告的验证安装成功
//在原来的数据库名称后面添加  ?useUnicode=true&characterEncoding=utf-8&useSSL=false

package com.tang.JDBC;
import java.sql.*;
public class TestJDBC {
    public static void main(String[] args) throws  Exception {
        //1.注册驱动,加载驱动
        Class.forName("com.mysql.jdbc.Driver") ;

        //2.获得数据库连接
        String url="jdbc:mysql://localhost:3306/companydb?useUnicode=true&characterEncoding=utf-8&useSSL=false";  //连接到哪个数据库
        String user="root";
        String password="123456";
        Connection connection=DriverManager.getConnection(url,user,password);

        if(connection!=null){
            System.out.println("连接到数据库了");
        }else{
            System.out.println("连接失败");
        }

        //3.获得执行SQL语句的对象(使用Statement类)
        Statement statement=connection.createStatement();

        //4.编写SQL语句 执行SQL语句
        String sql="INSERT INTO t_jobs(job_id,JOB_TITLE,MIN_SALARY,MAX_SALARY) VALUES ('H5_Mgr','H5_Manager',4000,10000)";
        int result=statement.executeUpdate(sql);
        System.out.println("受影响行数:"+result);   //返回受影响行数

        //5.处理数据库的返回结果
        if(result==1) {
            System.out.println("创建成功");
        }else{
            System.out.println("创建失败");
        }
        //6.关闭资源
        statement.close();
        connection.close();
    }
}
删除(代码简化了)
package com.tang.JDBC;
import java.sql.*;
public class DeleteJDBC {
    public static void main(String[] args) throws Exception {
        //1.注册驱动,加载驱动
        Class.forName("com.mysql.jdbc.Driver") ;

        //2.获得数据库连接
        Connection connection=DriverManager.getConnection("jdbc:mysql://localhost:3306/companydb","root","123456");

        //3.获得执行SQL语句的对象(使用Statement类)
        Statement statement=connection.createStatement();

        //4.编写SQL语句 执行SQL语句
        int result=statement.executeUpdate("DELETE FROM t_jobs WHERe job_id='H5_Mgr';");


        //5.处理数据库的返回结果
        if(result==1) {
            System.out.println("删除成功");
        }else{
            System.out.println("删除失败");
        }
        //6.关闭资源
        statement.close();
        connection.close();
    }
}

查询(ResultSet)

ResultSet rs=statement.executeQuery(“select * from user”);

package com.tang.JDBC;
import java.sql.*;
public class QueryJDBC {
    public static void main(String[] args) throws Exception {
        //1.注册驱动,加载驱动
        Class.forName("com.mysql.jdbc.Driver") ;

        //2.获得数据库连接
        Connection connection=DriverManager.getConnection("jdbc:mysql://localhost:3306/companydb","root","123456");

        //3.获得执行SQL语句的对象(使用Statement类)
        Statement statement=connection.createStatement();

        //4.编写SQL语句 执行SQL语句
        ResultSet resultSet=statement.executeQuery("select * from t_jobs;");

        //5.处理数据库的返回结果
        while(resultSet.next()) {  //判断下一行是否有数据,get获取列名
            String job_id= resultSet.getString("job_id");
            String job_title= resultSet.getString("job_title");
            String min_salary= resultSet.getString("min_salary");
            String max_salary= resultSet.getString("max_salary");
            System.out.println(job_id+ "t"+ job_title+ "t"+min_salary+ "t"+max_salary);
        }
        //6.关闭资源
        resultSet.close();
        statement.close();
        connection.close();
    }
}
三、SQL注入 综合案例之登陆
#创建用户表users
#插入两条测试语句
CREATE TABLE users(
	id INT PRIMARY KEY AUTO_INCREMENT,
	username VARCHAr(20) UNIQUE NOT NULL,
	pwd VARCHAr(20) NOT NULL,
	phone VARCHAr(11)
)CHARSET=utf8;


INSERT INTO users(username,pwd,phone) VALUES ('zhangsan','1234','4008100100');
INSERT INTO users(username,pwd,phone) VALUES ('lisi','1234','4008120120');
//通过控制台用户输入用户名和密码
//用户输入的用户名和密码作为条件,编写查询SQL语句
//如果该用户存在,提示登陆成功,反之提示登陆失败


package com.tang.JDBC;
import java.sql.*;
import java.util.*;

public class LoginJDBC {
    public static void main(String[] args) throws  Exception{

        Scanner scanner=new Scanner(System.in);
        System.out.println("请输入用户名:");
        String username= scanner.next();;   //改成nextLine 可以接受空格,引起SQL注入
        System.out.println("请输入密码:");
        String password= scanner.next();;

        //1.注册驱动,加载驱动
        Class.forName("com.mysql.jdbc.Driver") ;

        //2.获得数据库连接
        Connection connection=DriverManager.getConnection("jdbc:mysql://localhost:3306/companydb","root","123456");

        //3.获得执行SQL语句的对象(使用Statement类)
        Statement statement=connection.createStatement();

        //4.编写SQL语句 执行SQL语句
        ResultSet resultSet=statement.executeQuery("select * from users where username='"+username+"' and pwd ='"+password+"';");

        //5.处理数据库的返回结果
        if(resultSet.next()) {  //查询到数据
            System.out.println("登陆成功");
        }else {
            System.out.println("登陆失败");
        }
        //6.关闭资源
        resultSet.close();
        statement.close();
        connection.close();
    }
}
SQL注入问题

用户输入的数据中有SQL关键字或语法并且参与了SQL语句的编译,导致SQL语句编译后的条件含义为true,一直得到正确的结果,这种现象称为SQL注入。

#创建用户表users
#插入两条测试语句
CREATE TABLE users(
	id INT PRIMARY KEY AUTO_INCREMENT,
	username VARCHAr(20) UNIQUE NOT NULL,
	pwd VARCHAr(20) NOT NULL,
	phone VARCHAr(11)
)CHARSET=utf8;


INSERT INTO users(username,pwd,phone) VALUES ('zhangsan','1234','4008100100');
INSERT INTO users(username,pwd,phone) VALUES ('lisi','1234','4008120120');
//abc' or 1=1;#

package com.tang.JDBC;
import java.sql.*;
import java.util.*;

public class LoginJDBC {
    public static void main(String[] args) throws  Exception{

        Scanner scanner=new Scanner(System.in);
        System.out.println("请输入用户名:");
        String username= scanner.nextLine(); //abc' or 1=1;#
        System.out.println("请输入密码:");
        String password= scanner.nextLine();  //改成nextLine 可以接受空格

        //1.注册驱动,加载驱动
        Class.forName("com.mysql.jdbc.Driver") ;

        //2.获得数据库连接
        Connection connection=DriverManager.getConnection("jdbc:mysql://localhost:3306/companydb","root","123456");

        //3.获得执行SQL语句的对象(使用Statement类)
        Statement statement=connection.createStatement();

        //4.编写SQL语句 执行SQL语句
        ResultSet resultSet=statement.executeQuery("select * from users where username='"+username+"' and pwd ='"+password+"';");

        //5.处理数据库的返回结果
        if(resultSet.next()) {  //查询到数据
            System.out.println("登陆成功");
        }else {
            System.out.println("登陆失败");
        }
        //6.关闭资源
        resultSet.close();
        statement.close();
        connection.close();
    }
}
PreparedStatement(修复SQL注入)

由于编写的SQL语句是在用户输入数据,整合后再进行编译,所以为了避免SQL注入的问题,我们要使SQL语句在用户输入数据前就已进行编译成完整的SQL语句,再进行填充数据

作用:

  • 预编译SQL语句,效率高
  • 安全,避免SQL注入
  • 可以动态的填充数据,执行多个同构的SQL语句
#创建用户表users
#插入两条测试语句
CREATE TABLE users(
	id INT PRIMARY KEY AUTO_INCREMENT,
	username VARCHAr(20) UNIQUE NOT NULL,
	pwd VARCHAr(20) NOT NULL,
	phone VARCHAr(11)
)CHARSET=utf8;


INSERT INTO users(username,pwd,phone) VALUES ('zhangsan','1234','4008100100');
INSERT INTO users(username,pwd,phone) VALUES ('lisi','1234','4008120120');
package com.tang.JDBC;

import java.sql.*;
import java.util.*;

public class LoginJDBC2 {

    public static void main(String[] args) throws Exception{
        Scanner scanner=new Scanner(System.in);
        System.out.println("请输入用户名:");
        String username= scanner.nextLine();  //改成nextLine 可以接受空格
        System.out.println("请输入密码:");
        String password= scanner.nextLine();  //abc' or 1=1;#

        //1.注册驱动,加载驱动
        Class.forName("com.mysql.jdbc.Driver") ;

        //2.获得数据库连接
        Connection connection= DriverManager.getConnection("jdbc:mysql://localhost:3306/companydb","root","123456");

        //3.获得PreparedStatement的对象
        PreparedStatement preparedStatement=connection.prepareStatement("select * from users where username=? and pwd=?");


        //4.为?占位符进行赋值
        preparedStatement.setString(1,username); //下标从1开始
        preparedStatement.setString(2,password);

        //5.编写SQL语句 执行SQL语句
        ResultSet resultSet=preparedStatement.executeQuery();

        //6.处理数据库的返回结果
        if(resultSet.next()) {  //查询到数据
            System.out.println("登陆成功");
        }else {
            System.out.println("登陆失败");
        }
        //7.关闭资源
        resultSet.close();
        preparedStatement.close();
        connection.close();
    }
}
四、封装工具类与ORM
在实际JDBC开发中,存在大量重复代码,我们把传统的JDBC代码进行重构,抽取出通用的JDBC工具类,以后连接任何数据库,释放资源都可以使用这个工具类
重用性方案

自己手写,第一第二步,注册驱动获取连接,和最后一步,释放资源,两个方法

配置文件db.properties

IDEA,对着src,右键新建,Resource Bundle,db即可

跨平台方案DBUtils(推荐)
//db.properties   
//IDEA,对着src,右键新建,Resource Bundle,输入db
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/companydb?useUnicode=true&characterEncoding=utf-8&useSSL=false
username=root
password=123456
=========================================================================================
//写工具类DBUtils
package com.tang.JDBC2;
import java.io.*;
import java.sql.*;
import java.util.*;

public class DBUtils {
    private static final Properties PROPERTIES=new Properties(); //存储配置文件的map
    static {
        InputStream is=DBUtils.class.getResourceAsStream("/db.properties");
        try{
            PROPERTIES.load(is); //通过流,将配置文件内容加载到properties集合里
            Class.forName(PROPERTIES.getProperty("driver"));
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public static Connection getConnection() {
        Connection connection = null;
        try {
            connection = DriverManager.getConnection(PROPERTIES.getProperty("url"), PROPERTIES.getProperty("username"), PROPERTIES.getProperty("password"));
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return  connection;
    }

    public static void closeALl(Connection connection,Statement statement,ResultSet resultSet) {
        try{
            if (resultSet!=null){
                resultSet.close();
            }
            if (statement!=null){
                statement.close();
            }
            if (connection!=null){
                connection.close();
            }
        }catch (SQLException e){
            e.printStackTrace();
        }
    }
}
========================================================================================
   //测试类,主函数
    package com.tang.JDBC2;

import java.sql.*;

public class TestDBUtils {
    public static void main(String[] args) {
        Connection connection=DBUtils.getConnection();
        System.out.println(connection);
    }
}
ORM

ORM,从数据库查询到的结果集(ResultSet)在进行遍历时,逐行遍历。取出的都是零散的数据,在实际应用开发中,我们需要将零散的数据进行封装整理

实体类:是零散数据的载体

  • 一行数据中,多个零散的数据进行整理
  • 通过entity的规则对表中的数据进行对象的封装
  • 表名=类名,列名=属性名,提供各个属性的get set方法
  • 提供无参构造方法,视情况添加有参构造
package com.tang.JDBC2;

import java.io.*;
import java.sql.*;
import java.util.*;

public class DBUtils {
    private static final Properties PROPERTIES=new Properties(); //存储配置文件的map
    static {
        InputStream is=DBUtils.class.getResourceAsStream("/db.properties");
        try{
            PROPERTIES.load(is); //通过流,将配置文件内容加载到properties集合里
            Class.forName(PROPERTIES.getProperty("driver"));
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public static Connection getConnection() {
        Connection connection = null;
        try {
            connection = DriverManager.getConnection(PROPERTIES.getProperty("url"), PROPERTIES.getProperty("username"), PROPERTIES.getProperty("password"));
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return  connection;
    }

    public static void closeALl(Connection connection,Statement statement,ResultSet resultSet) {
        try{
            if (resultSet!=null){
                resultSet.close();
            }
            if (statement!=null){
                statement.close();
            }
            if (connection!=null){
                connection.close();
            }
        }catch (SQLException e){
            e.printStackTrace();
        }
    }
}
=======================================================================================
    //entity类
    package com.tang.JDBC2;

public class T_Jobs {

    private String job_id;
    private String job_title;
    private String min_salary;
    private String max_salary;

    public T_Jobs() {
    }

    public T_Jobs(String job_id, String job_title, String min_salary, String max_salary) {
        this.job_id = job_id;
        this.job_title = job_title;
        this.min_salary = min_salary;
        this.max_salary = max_salary;
    }

    public String getJob_id() {
        return job_id;
    }

    public void setJob_id(String job_id) {
        this.job_id = job_id;
    }

    public String getJob_title() {
        return job_title;
    }

    public void setJob_title(String job_title) {
        this.job_title = job_title;
    }

    public String getMin_salary() {
        return min_salary;
    }

    public void setMin_salary(String min_salary) {
        this.min_salary = min_salary;
    }

    public String getMax_salary() {
        return max_salary;
    }

    public void setMax_salary(String max_salary) {
        this.max_salary = max_salary;
    }

    @Override
    public String toString() {
        return "T_Jobs{" +
                "job_id='" + job_id + ''' +
                ", job_title='" + job_title + ''' +
                ", min_salary='" + min_salary + ''' +
                ", max_salary='" + max_salary + ''' +
                '}';
    }
}
=========================================================================================
    package com.tang.JDBC2;

import java.sql.*;
import java.util.*;


public class TestORM {
    public static void main(String[] args) {
        Connection connection=null;
        PreparedStatement preparedStatement=null;
        ResultSet resultSet=null;
        List t_jobsList=new ArrayList<>();

        try {

            connection=DBUtils.getConnection();
            preparedStatement=connection.prepareStatement("select * from t_jobs");
            resultSet=preparedStatement.executeQuery();

            while (resultSet.next()){
                String job_id=resultSet.getString("job_id");
                String job_title=resultSet.getString("job_title");
                String min_salary=resultSet.getString("min_salary");
                String max_salary=resultSet.getString("max_salary");

                //创建对象,封装查询到的零散数据
                T_Jobs t_jobs=new T_Jobs();
                t_jobs.setJob_id(job_id);
                t_jobs.setJob_title(job_title);
                t_jobs.setMin_salary(min_salary);
                t_jobs.setMax_salary(max_salary);
                t_jobsList.add(t_jobs);  //每遍历一次得到对象,存放在集合里,方便后续的使用

            }
            //遍历集合
            for (T_Jobs t:t_jobsList) {
                System.out.println(t);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DBUtils.closeALl(connection,preparedStatement,resultSet);
        }
    }
}
五、DAO层

DAO实现了业务逻辑和数据库访问相分离,即用户名密码和class.forName开始相分离

  • 对同一张表的所有操作封装在XXXDaoImpl对象中
  • 根据增删改查的不同功能实现具体的方法
  • 对数据库一张表的访问操作,做复用
增删改查
  • 下面的代码,都在person包里
CREATE TABLE Person(
	id INT PRIMARY KEY AUTO_INCREMENT,
	NAME VARCHAr(20) UNIQUE NOT NULL,
	age INT NOT NULL,
	bornDate DATE,
	email VARCHAr(20),
	address VARCHAr(20)
)CHARSET=utf8;
//db.properties   
//IDEA,对着src,右键新建,不是class,是Resource Bundle
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/companydb?useUnicode=true&characterEncoding=utf-8&useSSL=false
username=root
password=123456
package person;

import java.io.*;
import java.sql.*;
import java.util.*;

public class DBUtils {
    private static final Properties PROPERTIES=new Properties(); //存储配置文件的map
    static {
        InputStream is= DBUtils.class.getResourceAsStream("/db.properties");
        try{
            PROPERTIES.load(is); //通过流,将配置文件内容加载到properties集合里
            Class.forName(PROPERTIES.getProperty("driver"));
        }catch (IOException e){
            e.printStackTrace();
        }catch (ClassNotFoundException e){
            e.printStackTrace();
        }
    }

    public static Connection getConnection() {
        Connection connection = null;
        try {
            connection = DriverManager.getConnection(PROPERTIES.getProperty("url"), PROPERTIES.getProperty("username"), PROPERTIES.getProperty("password"));
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return  connection;
    }

    public static void closeALl(Connection connection,Statement statement,ResultSet resultSet) {
        try{
            if (resultSet!=null){
                resultSet.close();
            }
            if (statement!=null){
                statement.close();
            }
            if (connection!=null){
                connection.close();
            }
        }catch (SQLException e){
            e.printStackTrace();
        }
    }
}
//entity类
package person;

import java.util.*;

public class Person {
    private int id;
    private  String name;
    private int age;
    private Date bornDate;
    private String email;
    private String address;

    public Person() {
    }

    public Person(String name, int age, Date bornDate, String email, String address) {
        this.name = name;
        this.age = age;
        this.bornDate = bornDate;
        this.email = email;
        this.address = address;
    }

    public Person(int id, String name, int age, Date bornDate, String email, String address) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.bornDate = bornDate;
        this.email = email;
        this.address = address;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Date getBornDate() {
        return bornDate;
    }

    public void setBornDate(Date bornDate) {
        this.bornDate = bornDate;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", name='" + name + ''' +
                ", age=" + age +
                ", bornDate=" + bornDate +
                ", email='" + email + ''' +
                ", address='" + address + ''' +
                '}';
    }
}
//增删改查所有方法
package person;

import java.sql.*;
import java.util.*;
import java.util.Date;

public class PersonDaoImpl {
        //新增
        public int insert(Person person){
            Connection connection=null;
            PreparedStatement preparedStatement=null;
            String sql="insert into person(name,age,borndate,email,address) values (?,?,?,?,?);";

            try {
                connection=DBUtils.getConnection();
                preparedStatement= connection.prepareStatement(sql);
                preparedStatement.setString(1, person.getName());
                preparedStatement.setInt(2, person.getAge());
                preparedStatement.setDate(3,DateUtils.utilToSql(person.getBornDate()));
                preparedStatement.setString(4, person.getEmail());
                preparedStatement.setString(5, person.getAddress());
                int result= preparedStatement.executeUpdate();
                return  result;
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                DBUtils.closeALl(connection,preparedStatement,null);
            }
            return 0;
        }

        //修改
        public int update(Person person){
            Connection connection=null;
            PreparedStatement preparedStatement=null;
            String sql="update person set name=?,age=?,borndate=?,email=?,address=? where id=?";

            try {
                connection=DBUtils.getConnection();
                preparedStatement= connection.prepareStatement(sql);
                preparedStatement.setString(1, person.getName());
                preparedStatement.setInt(2, person.getAge());
                preparedStatement.setDate(3,DateUtils.utilToSql(person.getBornDate()));
                preparedStatement.setString(4, person.getEmail());
                preparedStatement.setString(5, person.getAddress());
                preparedStatement.setInt(6, person.getId());
                int result= preparedStatement.executeUpdate();
                return  result;
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                DBUtils.closeALl(connection,preparedStatement,null);
            }
            return 0;
        }

        //删除
        public int delete(int id){
            Connection connection=null;
            PreparedStatement preparedStatement=null;
            String sql="delete from person where id=?";

            try {
                connection=DBUtils.getConnection();
                preparedStatement= connection.prepareStatement(sql);
                preparedStatement.setInt(1, id);
                int result= preparedStatement.executeUpdate();
                return  result;
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                DBUtils.closeALl(connection,preparedStatement,null);
            }
            return 0;
        }

        //查单个
        public Person select(int id){
            Connection connection=null;
            PreparedStatement preparedStatement=null;
            ResultSet resultSet=null;
            String sql="select * from person where id=?;";
            Person person=null;
            try {
                connection=DBUtils.getConnection();
                preparedStatement= connection.prepareStatement(sql);
                preparedStatement.setInt(1,id);
                resultSet= preparedStatement.executeQuery();
                if (resultSet.next()){
                    person=new Person();
                    int pid=resultSet.getInt("id");
                    String name=resultSet.getString("name");
                    int age=resultSet.getInt("age");
                    Date bornDate=resultSet.getDate("borndate");
                    String email=resultSet.getString("email");
                    String address= resultSet.getString("address");
                    person.setId(pid);
                    person.setName(name);
                    person.setAge(age);
                    person.setBornDate(bornDate);
                    person.setEmail(email);
                    person.setAddress(address);

                }
                return person;
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                DBUtils.closeALl(connection,preparedStatement,resultSet);
            }
            return null;
        }

        //查所有
        public List selectAll(){
            Connection connection=null;
            PreparedStatement preparedStatement=null;
            ResultSet resultSet=null;
            Person person=null;
            List personList=new ArrayList<>();

            try {
                connection=DBUtils.getConnection();
                String sql="select * from person";
                preparedStatement= connection.prepareStatement(sql);
                resultSet= preparedStatement.executeQuery();
                while (resultSet.next()){

                    int pid=resultSet.getInt("id");
                    String name=resultSet.getString("name");
                    int age=resultSet.getInt("age");
                    Date bornDate=resultSet.getDate("borndate");
                    String email=resultSet.getString("email");
                    String address= resultSet.getString("address");
                    person=new Person(pid,name,age,bornDate,email,address);
                    personList.add(person);
                }
                return personList;
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                DBUtils.closeALl(connection,preparedStatement,resultSet);
            }
            return null;
        }
}

//测试增删改查
//主程序

public static void main(String[] args) {
       
        //测试新增
        PersonDaoImpl personDao=new PersonDaoImpl();
        Person person=new Person("Marry",28,DateUtils.strToUtil("1998-06-01"),"Marry@163.com","北京市海淀区");

        int result=personDao.insert(person);
        if (result==1){
            System.out.println("新增成功");
        }else{
            System.out.println("新增失败");
        }


    
    }
===================================================================================
    //测试删除
    public static void main(String[] args) {
        PersonDaoImpl personDao=new PersonDaoImpl();
        int result=personDao.delete( 1);
        if (result==1){
            System.out.println("删除成功");
        }else {
            System.out.println("删除失败");
        }
    }
=========================================================================================
    //测试修改
    public static void main(String[] args) {
        PersonDaoImpl personDao=new PersonDaoImpl();
        Person person=new Person(1,"Aaron",20,DateUtils.strToUtil("2000-03-08"),"Aaron@vip.com","北京市昌平区");
        int result=personDao.update(person);
        if (result==1){
            System.out.println("修改成功");
        }else{
            System.out.println("修改失败");
        }
    }
=======================================================================================
    //测试查询单个
    public static void main(String[] args) {
        PersonDaoImpl personDao=new PersonDaoImpl();
        Person person=personDao.select(1);
        if (person!=null){
            System.out.println(person);
        }else {
            System.out.println("没有查到该用户");
        }
    }
=====================================================================================
    //测试查询所有
    public static void main(String[] args) {

        PersonDaoImpl personDao=new PersonDaoImpl();
       List personList= personDao.selectAll();
        for(Person p:personList){
            System.out.println(p);
        }

    }
util.Date和sql.Date的转换(直接用工具类)

数据库存储类型是java.sql.Date,Java应用层存储日期类型为java.util.Date,当我们用Java应用程序插入带有日期的数据到数据库中时,需要进行转换

package person;

import java.text.SimpleDateFormat;

public class TestTimes {

    public static void main(String[] args) throws Exception {
        //字符串:自定义日期
        String str="1999-09-09";
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
        
        //parse方法将字符串转换为util.date
        java.util.Date date=sdf.parse(str);
        System.out.println(date);
        
        //sql.Date不支持字符串转换,只支持毫秒值创建
        //通过util.Date拿到指定日期的毫秒值,转换为sql.Date
        java.sql.Date sqlDate=new java.sql.Date(date.getTime());
        System.out.println(sqlDate);

        //formate方法转换为string类型
        String dates= sdf.format(new java.util.Date());
        System.out.println(dates);
    }
}
DateUtils工具类封装
package person;

import java.text.SimpleDateFormat;

public class DateUtils {
    private static  SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
    //1字符串转换为util.Date
    public static java.util.Date strToUtil(String str){
        try {
            java.util.Date date=sdf.parse(str);
            return date;
        } catch (Exception e) {
            e.printStackTrace();
        } 
        return null;
    }
    //2util.Date转换为sql.Date
    public static java.sql.Date UtilToSql(java.util.Date date){
        return new java.sql.Date(date.getTime());
    }
    //3util.Date转换为字符串形式
    public static String UtilToStr(java.util.Date date){
        return sdf.format(date);
    }
}

六、Service业务逻辑层
//这边还是用的第五大类,,DAO的person类,小应用,感受一下service业务逻辑层

//写一个注册的Service业务功能
package person;
public class PersonServiceImpl {
    //注册
    public void register(Person person){
        //一个业务功能由多个DAO的访问操作组成
        PersonDaoImpl personDao=new PersonDaoImpl();
        //1先查询用户是否存在
        Person persons=personDao.select(person.getName());
        //2不存在,新增
        if (persons==null){
            personDao.insert(person);
            System.out.println("注册成功");
        }else {
            //3存在,就返回已注册
            System.out.println("该用户已注册");
        }
    }
}
=======================================================================================
  //测试注册功能
    package person;
	public class TestRegister {
    public static void main(String[] args) {
        PersonServiceImpl personService=new PersonServiceImpl();
        Person person=new Person("Coco",12,DateUtils.strToUtil("1997-07-07"),"Marry@123.com","北京市");
        personService.register(person);
    }
}
=======================================================================================
    //在PersonDaoImpl文件里,重载查询单个,原来参数是int,现在是string
     public Person select(String name){
        Connection connection=null;
        PreparedStatement preparedStatement=null;
        ResultSet resultSet=null;
        String sql="select * from person where name=?;";
        Person person=null;
        try {
            connection=DBUtils.getConnection();
            preparedStatement= connection.prepareStatement(sql);
            preparedStatement.setString(1,name);
            resultSet= preparedStatement.executeQuery();
            if (resultSet.next()){
                person=new Person();
                int pid=resultSet.getInt("id");
                String pname=resultSet.getString("name");
                int age=resultSet.getInt("age");
                Date bornDate=resultSet.getDate("borndate");
                String email=resultSet.getString("email");
                String address= resultSet.getString("address");
                person.setId(pid);
                person.setName(pname);
                person.setAge(age);
                person.setBornDate(bornDate);
                person.setEmail(email);
                person.setAddress(address);

            }
            return person;
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            DBUtils.closeALl(connection,preparedStatement,resultSet);
        }
        return null;
    }

Account转账案例 没有事务
//entity类
package account;

public class Account {
    private String cardNo;
    private String password;
    private String name;
    private double balance;

    public Account() {
    }

    public Account(String cardNo, String password, String name, double balance) {
        this.cardNo = cardNo;
        this.password = password;
        this.name = name;
        this.balance = balance;
    }

    public String getCardNo() {
        return cardNo;
    }

    public void setCardNo(String cardNo) {
        this.cardNo = cardNo;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getBalance() {
        return balance;
    }

    public void setBalance(double balance) {
        this.balance = balance;
    }

    @Override
    public String toString() {
        return "Account{" +
                "cardNo='" + cardNo + ''' +
                ", password='" + password + ''' +
                ", name='" + name + ''' +
                ", balance=" + balance +
                '}';
    }
}
====================================================================================
//DBUtils类
package account;

import java.io.*;
import java.sql.*;
import java.util.*;

public class DBUtils {
    private static final Properties PROPERTIES=new Properties(); //存储配置文件的map
    static {
        InputStream is= person.DBUtils.class.getResourceAsStream("/db.properties");
        try{
            PROPERTIES.load(is); //通过流,将配置文件内容加载到properties集合里
            Class.forName(PROPERTIES.getProperty("driver"));
        }catch (IOException e){
            e.printStackTrace();
        }catch (ClassNotFoundException e){
            e.printStackTrace();
        }
    }

    public static Connection getConnection() {
        Connection connection = null;
        try {
            connection = DriverManager.getConnection(PROPERTIES.getProperty("url"), PROPERTIES.getProperty("username"), PROPERTIES.getProperty("password"));
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return  connection;
    }

    public static void closeALl(Connection connection,Statement statement,ResultSet resultSet) {
        try{
            if (resultSet!=null){
                resultSet.close();
            }
            if (statement!=null){
                statement.close();
            }
            if (connection!=null){
                connection.close();
            }
        }catch (SQLException e){
            e.printStackTrace();
        }
    }
}
======================================================================================
   //DAO层
    package account;

import java.sql.*;

public class AccountDaoImpl {

    public int insert(Account account){return 0;}

    public int delete(String cardNo){return 0;}
    //修改
    public int update(Account account){
        Connection connection=null;
        PreparedStatement preparedStatement=null;
        String sql="update account set password=?,name=?,balance=? where cardNo=?";

        try {
            connection=DBUtils.getConnection();
            preparedStatement=connection.prepareStatement(sql);
            preparedStatement.setString(1, account.getPassword());
            preparedStatement.setString(2, account.getName());
            preparedStatement.setDouble(3, account.getBalance());
            preparedStatement.setString(4, account.getCardNo());
            int result= preparedStatement.executeUpdate();
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            DBUtils.closeALl(connection,preparedStatement,null);
        }
        return 0;
    }

    //查询单个
    public Account select(String cardNo){
        Connection connection=null;
        PreparedStatement preparedStatement=null;
        ResultSet resultSet=null;
        Account account=null;
        String sql="select * from account where CardNo=?;";
        try {
            connection=DBUtils.getConnection();
            preparedStatement= connection.prepareStatement(sql);
            preparedStatement.setString(1,cardNo);
            resultSet= preparedStatement.executeQuery();
            if (resultSet.next()){
                String cardNos= resultSet.getString("cardNo");
                String password= resultSet.getString("password");
                String name= resultSet.getString("name");
                Double balance=resultSet.getDouble("balance");
                account=new Account(cardNos,password,name,balance);

            }
            return account;
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            DBUtils.closeALl(connection,preparedStatement,resultSet);
        }
        return null;
    }
}
=======================================================================================
    //service
    package account;

public class AccountServiceImpl {

    public void transfer(String fromNo,String pwd,String toNo,double money){
        try {
            AccountDaoImpl accountDao=new AccountDaoImpl();
            //1验证fromNo是否存在
            Account account= accountDao.select(fromNo);
            if (account==null){
                throw new RuntimeException("卡号不存在");
            }
            //2验证fromNo密码是否正确
            if (!account.getPassword().equals(pwd)){
                throw new RuntimeException("密码错误");
            }
            //3验证余额是否充足
            if (account.getBalance() 
ThreadLocal控制事务 

线程共享同一个ThreadLocal

事务的封装

将事务的开启,提交,回滚都封装在工具类中,业务层调用即可

package account;

import java.io.*;
import java.sql.*;
import java.util.*;

public class DBUtils {
    private static final Properties PROPERTIES=new Properties(); //存储配置文件的map
    private static ThreadLocal threadLocal=new ThreadLocal<>();
    static {
        InputStream is= person.DBUtils.class.getResourceAsStream("/db.properties");
        try{
            PROPERTIES.load(is); //通过流,将配置文件内容加载到properties集合里
            Class.forName(PROPERTIES.getProperty("driver"));
        }catch (IOException e){
            e.printStackTrace();
        }catch (ClassNotFoundException e){
            e.printStackTrace();
        }
    }

    public static Connection getConnection() {
        Connection connection = threadLocal.get();//将当前线程中绑定的connection对象赋值给connection
        try {
            if (connection==null){
                connection = DriverManager.getConnection(PROPERTIES.getProperty("url"), PROPERTIES.getProperty("username"), PROPERTIES.getProperty("password"));
                threadLocal.set(connection);//把连接存在当前线程共享中
            }
              } catch (SQLException e) {
            e.printStackTrace();
        }
        return  connection;
    }

    //开启事务
    public static void begin(){
        try {
            Connection connection=getConnection();
            connection.setAutoCommit(false);
        }catch (SQLException e){
            e.printStackTrace();
        }
    }

    //提交事务
    public static void commit(){
        Connection connection=null;
        try {
            connection=getConnection();
            connection.commit();
        }catch (SQLException e){
            e.printStackTrace();
        }finally {
            closeALl(connection,null,null);
        }

    }

    //回滚事务
    public static void rollback(){
        Connection connection=null;
        try {
            connection=getConnection();
            connection.rollback();
        }catch (SQLException e){
            e.printStackTrace();
        }finally {
            closeALl(connection,null,null);
        }

    }
    public static void closeALl(Connection connection,Statement statement,ResultSet resultSet) {
        try{
            if (resultSet!=null){
                resultSet.close();
            }
            if (statement!=null){
                statement.close();
            }
            if (connection!=null){
                connection.close();
                threadLocal.remove();//关闭连接后,移除已关闭connection对象
            }
        }catch (SQLException e){
            e.printStackTrace();
        }
    }
}
七、三层架构 概念
1.表示层
命名:XXXView
职责:收集用户的数据和需求、展示数据

2.业务逻辑层
命名:XXXServiceImpl
职责:数据加工处理、调用DAO完成业务实现、控制事务

3.数据访问层
命名:XXXDaoImpl
职责:向业务层提供数据,将业务层加工后的数据同步到数据库


utils存放工具类(DBUtils)
entity存放实体类(Person)
dao存放DAO接口(PersonDao)
   impl存放DAO接口实现类(PersonDaoImpl)
service存放service接口(PersonService)
	impl存放service接口实现类(PersonServiceImpl)
view存放程序启动类(main)

以后实际开发,直接写DAO接口,Service接口,不要写类了,方便版本更新,便于未来更换实现类

======================================================================================

DaoUtils工具类封装增删改查通用方法(这个是自己封装,后面有Apache封装)

新建包名,com.tang.person

CREATE TABLE Person(
	id INT PRIMARY KEY AUTO_INCREMENT,
	NAME VARCHAr(20) UNIQUE NOT NULL,
	age INT NOT NULL,
	bornDate DATE,
	email VARCHAr(20),
	address VARCHAr(20)
)CHARSET=utf8;
//db.properties   
//IDEA,对着src,右键新建,不是class,是Resource Bundle
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/companydb?useUnicode=true&characterEncoding=utf-8&useSSL=false
username=root
password=123456
新建包名,advanced
//impl包下,PersonRowMapper的class文件

package com.tang.person.advanced.impl;

import com.tang.person.advanced.RowMapper;
import com.tang.person.entity.Person;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;

public class PersonRowMapper implements RowMapper {

    @Override
    public Person getRow(ResultSet resultSet) {
        Person person=null;
        try{
            int pid=resultSet.getInt("id");
            String name=resultSet.getString("name");
            int age=resultSet.getInt("age");
            Date bornDate=resultSet.getDate("borndate");
            String email=resultSet.getString("email");
            String address= resultSet.getString("address");
            person=new Person(pid,name,age,bornDate,email,address);
            return person;
        }catch (SQLException e){
            e.printStackTrace();
        }

        return null;
    }
}
===================================================================================
  //  RowMapper接口
    package com.tang.person.advanced;

import java.sql.ResultSet;
//约束封装对象的ORM
public interface RowMapper {
    public T getRow(ResultSet resultSet);

}

新建包名,dao
//impl包下,PersonDaoImpl的class文件

package com.tang.person.dao.impl;
import com.tang.person.advanced.impl.PersonRowMapper;
import com.tang.person.dao.PersonDao;
import com.tang.person.entity.Person;
import com.tang.person.utils.*;


import java.sql.*;
import java.util.*;
import java.util.Date;
public class PersonDaoImpl implements PersonDao {
    private DaoUtils daoUtils=new DaoUtils();
    //新增
    public int insert(Person person){

        String sql="insert into person(name,age,borndate,email,address) values (?,?,?,?,?);";
        Object[] args={person.getName(),person.getAge(),DateUtils.UtilToSql((person.getBornDate())),person.getEmail(),person.getAddress()};
        return daoUtils.commonsUpdate(sql,args);

    }

    //修改
    public int update(Person person){
        String sql="update person set name=?,age=?,borndate=?,email=?,address=? where id=?;";
        Object[] args={person.getName(),person.getAge(),DateUtils.UtilToSql((person.getBornDate())),person.getEmail(),person.getAddress(),person.getId()};
        return daoUtils.commonsUpdate(sql,args);

    }

    //删除
    public int delete(int id){

        String sql="delete from person where id=?";
        return daoUtils.commonsUpdate(sql,id);
    }

    //查单个
    public Person select(int id){
        String sql="select * from person where id=?;";
      List list=daoUtils.commonsSelect(sql,new PersonRowMapper(),id);
      if (!list.isEmpty()){
          return list.get(0);
      }
      return null;
    }

    //查所有
    public List selectAll(){
        String sql="select * from person;";
        List list=daoUtils.commonsSelect(sql,new PersonRowMapper(),null);
        return list;
    }
}

===================================================================================
  //  PersonDao接口
    package com.tang.person.dao;

import com.tang.person.entity.Person;

import java.util.List;

public interface PersonDao {
    public int insert(Person person);

    public int update(Person person);

    public int delete(int id);

    public Person select(int id);

    public List selectAll();
}

新建包名,entity
//存放person的class文件

package com.tang.person.entity;
import java.util.*;
public class Person {
    private int id;
    private  String name;
    private int age;
    private Date bornDate;
    private String email;
    private String address;
    public Person() {
    }

    public Person(String name, int age, Date bornDate, String email, String address) {
        this.name = name;
        this.age = age;
        this.bornDate = bornDate;
        this.email = email;
        this.address = address;
    }

    public Person(int id, String name, int age, Date bornDate, String email, String address) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.bornDate = bornDate;
        this.email = email;
        this.address = address;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Date getBornDate() {
        return bornDate;
    }

    public void setBornDate(Date bornDate) {
        this.bornDate = bornDate;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", name='" + name + ''' +
                ", age=" + age +
                ", bornDate=" + bornDate +
                ", email='" + email + ''' +
                ", address='" + address + ''' +
                '}';
    }
}

新建包名,service
//impl包下,PersonServiceImpl的class文件

package com.tang.person.service.impl;

public class PersonServiceImpl {
}

===================================================================================
  //  PersonService接口
    package com.tang.person.service;

public interface PersonService {
}

新建包名,utils
//DaoUtils
package com.tang.person.utils;
import com.tang.person.advanced.RowMapper;
import java.sql.*;
import java.util.*;
//复用增删改查方法
public class DaoUtils {
    public int commonsUpdate(String sql,Object...args){
        Connection connection=null;
        PreparedStatement preparedStatement=null;
        connection=DBUtils.getConnection();
        try {
            preparedStatement=connection.prepareStatement(sql);
            for (int i=0;i commonsSelect(String sql, RowMapper rowMapper, Object...args){
        Connection connection=null;
        PreparedStatement preparedStatement=null;
        ResultSet resultSet=null;
        List list=new ArrayList<>();

        connection=DBUtils.getConnection();
        try{

            preparedStatement=connection.prepareStatement(sql);
            if (args!=null){
                for (int i=0;i THREAD_LOCAL=new ThreadLocal<>();
    static {
        InputStream is= DBUtils.class.getResourceAsStream("/db.properties");
        try{
            PROPERTIES.load(is); //通过流,将配置文件内容加载到properties集合里
            Class.forName(PROPERTIES.getProperty("driver"));
        }catch (IOException e){
            e.printStackTrace();
        }catch (ClassNotFoundException e){
            e.printStackTrace();
        }
    }

    public static Connection getConnection() {
        Connection connection = THREAD_LOCAL.get();//将当前线程中绑定的connection对象赋值给connection
        try {
            if (connection==null){
                connection = DriverManager.getConnection(PROPERTIES.getProperty("url"), PROPERTIES.getProperty("username"), PROPERTIES.getProperty("password"));
                THREAD_LOCAL.set(connection);//把连接存在当前线程共享中
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return  connection;
    }

    //开启事务
    public static void begin(){
        try {
            Connection connection=getConnection();
            connection.setAutoCommit(false);
        }catch (SQLException e){
            e.printStackTrace();
        }
    }

    //提交事务
    public static void commit(){
        Connection connection=null;
        try {
            connection=getConnection();
            connection.commit();
        }catch (SQLException e){
            e.printStackTrace();
        }finally {
            closeALl(connection,null,null);
        }

    }

    //回滚事务
    public static void rollback(){
        Connection connection=null;
        try {
            connection=getConnection();
            connection.rollback();
        }catch (SQLException e){
            e.printStackTrace();
        }finally {
            closeALl(connection,null,null);
        }

    }
    public static void closeALl(Connection connection,Statement statement,ResultSet resultSet) {
        try{
            if (resultSet!=null){
                resultSet.close();
            }
            if (statement!=null){
                statement.close();
            }
            if (connection!=null){
                connection.close();
                THREAD_LOCAL.remove();//关闭连接后,移除已关闭connection对象
            }
        }catch (SQLException e){
            e.printStackTrace();
        }
    }
}

新建包名,view
//TestPerson的class文件
package com.tang.person.view;
import com.tang.person.dao.*;
import com.tang.person.dao.impl.PersonDaoImpl;
import com.tang.person.entity.Person;
import com.tang.person.utils.DateUtils;
public class TestPerson {
    public static void main(String[] args) {
        PersonDao personDao=new PersonDaoImpl();
 //       Person person=new Person("Gavin",19, DateUtils.strToUtil("1998-09-09"),"Gavin@163.com","北京市昌平区");
 //       int result=personDao.insert(person);
  //      System.out.println(result);           //测试添加功能
        Person person =personDao.select(4);
        System.out.println(person);             //测试查询功能
    }
}
八、Druid连接池

在程序初始化时,预先创建指定数量的数据库连接对象存储在池中。当需要连接数据库时,从连接池中取出现有链接,使用完毕后,也不会进行关闭,而是放回池中,实现复用,节省资源

使用步骤 引入druid jar包 创建database.properties配置文件
//database.properties   
//IDEA,对着src,右键新建,Resource Bundle,输入database
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/companydb?useUnicode=true&characterEncoding=utf-8&useSSL=false
username=root
password=123456

initialSize = 10
maxActive = 30
minIdle = 5
maxWait = 3000
连接池的简单使用
//DBUtils
package com.tang.jdbcpool.utils;

import com.alibaba.druid.pool.*;

import javax.activation.DataSource;
import java.io.*;
import java.sql.*;
import java.util.*;

public class DBUtils {
    //声明一个连接池对象
    private static DruidDataSource ds;
    static {
        Properties properties=new Properties();
        InputStream is= DBUtils.class.getResourceAsStream("/database.properties");
        try{
            properties.load(is);
            //创建连接池
            ds=(DruidDataSource)DruidDataSourceFactory.createDataSource(properties);
        }catch (IOException e){
            e.printStackTrace();
        }catch (Exception e){
            e.printStackTrace();
        }

    }
    public static Connection getConnection(){
        try {
            return ds.getConnection();   //通过连接池获得连接对象
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }
    public static DataSource getDataSource(){
        return (DataSource) ds;
    }
}

=======================================================================================
    
    //测试连接池
 package com.tang.jdbcpool.test;

import com.tang.jdbcpool.utils.DBUtils;

import java.sql.Connection;

public class TestPool {
    public static void main(String[] args) throws Exception {
        for(int i=1;i<=20;i++){
            Connection connection= DBUtils.getConnection();
            System.out.println(connection);
           // connection.close();//放回池里
        }
    }
}
九、Apache的DBUtils使用

使用步骤

1.mysql连接驱动jar包

2.druid jar包

3.database.properties配置文件

4.commons-dbutils-1.7.jar

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/companydb?useUnicode=true&characterEncoding=utf-8&useSSL=false
username=root
password=123456

initialSize = 10
maxActive = 30
minIdle = 5
maxWait = 3000
CREATE TABLE users(
	userId INT PRIMARY KEY AUTO_INCREMENT,
	username VARCHAr(20) UNIQUE NOT NULL,
	address VARCHAr(20),
	PASSWORD VARCHAr(20) NOT NULL,
	phone VARCHAr(11)
)CHARSET=utf8;


INSERT INTO users(username,PASSWORD,address,phone) VALUES ('张三','123','北京昌平沙河','13812345678');
INSERT INTO users(username,PASSWORD,address,phone) VALUES ('王五','5678','北京海淀','13812345141');
INSERT INTO users(username,PASSWORD,address,phone) VALUES ('赵六','123','北京朝阳','13812340987');
INSERT INTO users(username,PASSWORD,address,phone) VALUES ('田七','123','北京大兴','13812345687');

=====================================================================================

大包名:com.tang.jdbcpool

dao包
//新建包Impl, UserDaoImpl的class文件
package com.tang.jdbcpool.dao.Impl;

import com.tang.jdbcpool.dao.UserDao;
import com.tang.jdbcpool.entity.User;
import com.tang.jdbcpool.utils.DBUtils;
import org.apache.commons.dbutils.*;
import org.apache.commons.dbutils.handlers.*;


import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.List;

public class UserDaoImpl implements UserDao {
    private QueryRunner queryRunner=new QueryRunner(DBUtils.getDataSource());
    @Override
    public int insert(User user) {
        Object[] params={user.getUserId(),user.getUsername(),user.getPassword(),user.getAddress(),user.getPhone()};
       try{
           int result=queryRunner.update("insert into users(userid,username,password,address,phone) values (?,?,?,?,?)",params);
           return result;
       }catch (SQLException e){
           e.printStackTrace();

       }
        return 0;
    }

    @Override
    public int update(User user) {
        Object[] params={user.getUsername(),user.getPassword(),user.getAddress(),user.getPhone(),user.getUserId()};
        try{
            int result= queryRunner.update("update users set username=?,password=?,address=?,phone=? where userid=?",params);
            return result;
        }catch (SQLException e){
            e.printStackTrace();
        }
        return 0;
    }

    @Override
    public int delete(int id) {

        try{
            int result= queryRunner.update("delete from users where userid=?",id);
            return result;
        }catch (SQLException e){
            e.printStackTrace();
        }
        return 0;
    }

    @Override
    public User select(int id) {
       try{
           User user=queryRunner.query("select * from users where userid=?;",new BeanHandler(User.class),id);
            return user;
       }catch (SQLException e){
           e.printStackTrace();
       }
        return null;
    }

    @Override
    public List selectAll() {
        try{
            List userList=queryRunner.query("select * from users ;",new BeanListHandler(User.class));
            return userList;
        }catch (SQLException e){
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public long selectUserNums() {
       try {
           long count=queryRunner.query("select count(*) from users;",new ScalarHandler<>());
           return count;
       }catch (SQLException e){
           e.printStackTrace();
       }
        return 0;
    }
}
====================================================================================
    //userDao接口文件
    
    package com.tang.jdbcpool.dao;

import com.tang.jdbcpool.entity.User;

import java.util.List;

public interface UserDao {
    public int insert(User user);
    public int update(User user);
    public int delete(int id);
    public User select(int id);
    public List selectAll();
    public long selectUserNums();
}

entity包
//创建User的class文件
package com.tang.jdbcpool.entity;

public class User {
    private int userId;
    private String username;
    private String password;
    private String address;
    private String phone;

    public User() {
    }

    public User(int userId, String username, String password, String address, String phone) {
        this.userId = userId;
        this.username = username;
        this.password = password;
        this.address = address;
        this.phone = phone;
    }

    public int getUserId() {
        return userId;
    }

    public void setUserId(int userId) {
        this.userId = userId;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    @Override
    public String toString() {
        return "User{" +
                "userId=" + userId +
                ", username='" + username + ''' +
                ", password='" + password + ''' +
                ", address='" + address + ''' +
                ", phone='" + phone + ''' +
                '}';
    }
}

test包
//创建TestDbutils的class文件
package com.tang.jdbcpool.test;

import com.tang.jdbcpool.dao.Impl.UserDaoImpl;
import com.tang.jdbcpool.dao.UserDao;
import com.tang.jdbcpool.entity.User;

import java.util.List;

public class TestDbutils {
    public static void main(String[] args) {
        UserDao userDao=new UserDaoImpl();
        User user=new User(5,"Aaron","1234","北京市延庆区","1234567");
  //      int result=userDao.insert(user);
  //      System.out.println(result);//测试新增功能

  //      int result=userDao.update(user);
  //        System.out.println(result);//测试修改功能

  //      int result=userDao.delete(5);
   //     System.out.println(result);//测试删除功能

  //      User users=userDao.select(1);
 //       System.out.println(users);         //测试查找单个功能

 //     List userList=userDao.selectAll();
//    userList.forEach(System.out::println);    //测试查找多个功能


        long count=userDao.selectUserNums();
        System.out.println("一共有:"+count);    //打印用户数量
    }
}
utils包
创建Dbutils的class文件
package com.tang.jdbcpool.utils;

import com.alibaba.druid.pool.*;

import javax.sql.DataSource;
import java.io.*;
import java.sql.*;
import java.util.*;

public class DBUtils {
    //声明一个连接池对象
    private static DruidDataSource ds;
    static {
        Properties properties=new Properties();
        InputStream is= DBUtils.class.getResourceAsStream("/database.properties");
        try{
            properties.load(is);
            //创建连接池
            ds=(DruidDataSource)DruidDataSourceFactory.createDataSource(properties);
        }catch (IOException e){
            e.printStackTrace();
        }catch (Exception e){
            e.printStackTrace();
        }

    }
    public static Connection getConnection(){
        try {
            return ds.getConnection();   //通过连接池获得连接对象
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }
    public static DataSource getDataSource(){
        return ds;
    }
}

Servlet 一、C/S和B/S架构区别

C/S架构(客户端/服务器)

  • 特点:必须在客户端安装特定软件
  • 优点:图形效果显示较好
  • 缺点:服务器的软件和功能进行升级,客户端也必须升级,不利于维护
  • 常见的C/S架构:QQ 微信

B/S架构(浏览器/服务器)

  • 特点:无需安装客户端,任何浏览器都可直接访问
  • 优点:涉及到功能的升级,只需要升级服务器端
  • 缺点:图形显示效果不如C/S架构
  • 需要通过HTTP协议访问
二、软件配置 (1)Tomcat 1.1 验证Tomcat安装成功
  1. 进入Tomcat安装目录bin下,双击startup.bat启动程序,最后一行出现xx毫秒即可
  2. 打开浏览器,输入localhost:8080,看到Tomcat页面
  3. 安装目录bin下,双击shutdown.bat关闭Tomcat程序
2.1 项目部署及访问静态资源

Tomcat是Web服务器,我们的项目应用是部署在webapps下,然后通过特定的URL访问

2.1 创建项目
  1. 在Tomcat安装目录webapps中建立文件夹,比如:myweb

  2. 在myweb文件夹里面,创建WEB-INF文件夹,用于存放项目的核心内容

  • 创建classes文件夹,用于存放.class文件
  • 创建lib文件夹,用于存放jar文件
  • 创建web.xml,项目配置文件(到ROOT项目下的WEB-INF复制即可)
  1. 把网页hello.html复制到myweb文件夹中,与WEB-INF在同级目录
2.2 URL访问资源

启动Tomcat,输入localhost:8080/myweb/hello.html

(2)Servlet 2.1 Servlet作用
  • 接收客户端请求,完成操作
  • 动态生成网页(页面数据可变)
  • 将包含操作结果的动态网页响应给客户端
2.2 Servlet开发步骤 2.2.1 搭建开发环境

将Servlet相关jar包,tomcat路径下的,(libservlet-api.jar)配置到classpath中,

此电脑-高级系统设置-环境变量-classpath-添加D:Tomcatapache-tomcat-9.0.20libservlet-api.jar

2.2.2 编写Servlet
  • 实现javax.servlet.Servlet
  • 重写五个主要方法
  • 在核心的service()方法中编写输出语句,打印访问结果
//命名为MyServlet.java文件
import java.io.IOException;
import javax.servlet.*;
public class MyServlet implements Servlet {
    public void init(ServletConfig servletConfig) throws ServletException {
    }
    public void service(ServletRequest request,ServletResponse response) throws ServletException,IOException{
		System.out.println("My First Servlet");	
    }
	public void destroy(){	 
    }
	public ServletConfig getServletConfig(){	
		return null;
	}
	public String getServletInfo(){
		return null;
    }
}
2.2.3 部署Servlet

cmd命令:javac MyServlet.java,,将生成的class文件放在WEB-INF/classes文件

2.2.4 配置Servlet

编写WEB-INF下项目配置文件web.xml





 

	
	my
	
	MyServlet

		


	
	my
	
	/myservlet





2.2.5 运行测试

启动Tomcat,在浏览器地址输入localhost:8080/myweb/myservlet进行访问,在cmd中打印My First Servlet表示成功

(3)IDEA创建web项目 3.1 创建web项目

先创建普通的Java项目,再对着项目名右键-Add frameWork Support-选择Web Application,勾选create web xml java ee 7

3.2 IDEA开发Servlet

对着WEB-INF右键新建DIRECTORY,lib文件夹,随后导入servlet-api.jar包,复制到lib文件夹,右键add as library

3.3 编写Servlet

对着src,创建package,com.tang.servlet,新建名字为MyServlet的class文件,添加以下代码

package com.tang.servlet;

import javax.servlet.*;
import java.io.IOException;

public class MyServlet implements Servlet {

    @Override
    public void init(ServletConfig servletConfig) throws ServletException {

    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("My First Web Project");
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {

    }
}

3.4 配置web.xml
添加以下代码
    
    
        
        my
        
        com.tang.servlet.MyServlet
    

    
    
        
        my
        
        /myservlet
    

3.5 IDEA集成Tomcat

IDEA,左上角File-Settings-左侧Build Execution Deployment 找到Application Servers,点击加号,添加Tomcat Server,选择tomcat的目录,点击OK,点击Apply,点击OK

右上角Add configuration,点击加号,找到tomcat server,点击local,找到Deployment,点击加号,Arifact。点击OK,启动tomcat

浏览器输入localhost:8080/MyServlet_war_exploded/myservlet IDEA控制台输出My First Web Project 成功!

3.6 如何导出war包(项目完成后再做)

IDEA左上角File-Project Setting-左侧Artifact ,点击加号,Web Application Archive-选择For WebProject war exploded 出现一个没有exploded的,点击apply,点击ok

IDEA上方,build-Build Artifact-选择war包,点击build,然后在idea out里面,artifacts找到war包,复制到tomcat-webapps 文件夹下粘贴

然后启动tomcat的bat文件,浏览器输入http://localhost:8080/WebProject_war/myservlet,会在cmd看到输出内容,说明成功

三、Servlet详解 3.1 三种创建方式 3.1.1 实现接口

五个方法

package com.tang.servlet;

import javax.servlet.*;
import java.io.IOException;

public class MyServlet implements Servlet {

    @Override
    public void init(ServletConfig servletConfig) throws ServletException {

    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("My First Web Project");
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {

    }
}
3.1.2 GenericServlet,无http协议

只需重写抽象service方法即可

package com.tang.servlet;

import javax.servlet.*;
import java.io.IOException;

public class GenServlet extends GenericServlet{
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("嘿嘿嘿");
    }
}
 
    
        
        gs
        
        com.tang.servlet.GenServlet
    

    
    
        
        gs
        
        /gs
    
3.1.3 HttpServlet(推荐)

继承GenericServlet的基础上进一步扩展,必须重写一个方法。doGet doPost doPut doDelete

package com.tang.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class HttpsServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("这是get请求过来的");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("这是post请求过来的");
    }
}

  
    
        
        hs
        
        com.tang.servlet.HttpsServlet
    

    
    
        
        hs
        
        /hs
    
3.2 两种配置方式 3.2.1 web.xml(servlet2.5之前,通用方法)
精确匹配/具体的名称只有url路径是具体名称才会触发servlet
后缀匹配*.xxx只要是以xxx接的就会触发servlet
通配符匹配/*匹配所有请求,包含服务器的所有资源
通配符匹配/匹配所有请求,包含服务器的所有资源,不包含jsp

load-on-startup 表示加载顺序,从0开始,数值越小越先被加载,如果没有设置,则访问时,被加载

3.2.2 使用注解(servlet3.0之后,推荐)
nameservlet名字,可选
value配置url路径,可以配置多个
urlPatterns配置url路径,和value作用一样,不能同时使用
loadOnstartup配置servlet创建的时机,数值越小,优先级越高
package com.tang.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(value ={"/bs","/bss"},loadonStartup = 0)
public class BasicServlet extends HttpsServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("这是get");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("这是post");
    }
}

四、request对象 4.1 get和post区别
get请求post请求
get提交的数据会放在url之后,以?分隔url和传输数据,参数之间以&相连post方法是把提交的数据放在http包的body中
get方式明文传递,数据量小,不安全密文传递数据,数据量大,安全
效率高,浏览器默认请求方式为get请求效率相对没有get高
对应的Servlet方法是doGet对应的Servlet方法是doPost
4.2 get和post应用(发送数据,解决编码)
//java project 项目名是 MyServlet
//对着web,右键新建html file,register.html




    
    注册页面


用户名:
密码:
//src包下,新建class文件,RegisterServlet.class
package com.tang.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet(value = "/rs")
public class RegisterServlet extends HttpsServlet{

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       String username=req.getParameter("username");
       String password=req.getParameter("password");
        System.out.println("提交的数据:"+username+"t"+password);

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //对request请求对象设置统一的编码
        req.setCharacterEncoding("utf-8");
        //获取用户请求发送的数据
        String username=req.getParameter("username");
        String password=req.getParameter("password");
        System.out.println("提交的数据:"+username+"t"+password);

      
        resp.setCharacterEncoding("utf-8"); // 指定输出到客户端的是编码格式,电脑用一行的会显示??
        resp.setContentType("text/html;charset=UTF-8");
        PrintWriter printWriter= resp.getWriter();
        printWriter.println("注册成功!");
    }
}
//http://localhost:8080/MyServlet_war_exploded/register.html  测试
4.3 转发和重定向 4.3.1 转发的页面跳转req.getRequestDispatcher

服务器内部跳转,url地址不改变,只能将请求转发给同一个web应用中的组件

当业务逻辑和显示结果分离后,需要跳转到显示结果的Servlet,需要页面跳转

req.getRequestDispatcher("/b").forward(req,resp); 在a里跳转到b

4.3.2 转发的数据传递req.setAttribute

业务逻辑得到的数据结果如何传递给显示结果的Servlet,配合页面跳转

在a里,req.setAttribute(“username”,“gavin”); 存数据

req.getRequestDispatcher("/b").forward(req,resp); 转发给b

在b里,String s=(String)req.getAttribute(“username”); 取数据

4.3.3 重定向的页面跳转resp.sendRedirect

可以指向其他站点的资源

resp.sendRedirect("/MyServlet_war_exploded/b")

跳转时,地址栏改变,说明发送两次请求,response没有作用域,两次request请求中的数据无法共享

4.3.4 重定向的数据传递(只能传string类型,明文传递而且要拼接)

resp.sendRedirect("/MyServlet_war_exploded/b?username=tom") ; 传递数据

String username=req.getParameter(“username”); 取数据

4.3 生命周期和线程安全 4.3.1 四个阶段
实例化load-on-startup设置数字 执行一次
初始化init()执行一次
服务service()执行多次
销毁destroy()执行一次
4.3.2 线程安全

synchronized 不推荐,加锁效率低

实现singlethreadmodel接口,已过时

在doget dopost里面 尽可能使用局部变量(推荐)

五、状态管理
现有问题http协议,不能保存每次提交的信息,如果用户发来一个新的请求,服务器无法知道他是否与上次的请求有联系,对于 那些需要多次提交数据才能完成的web操作,比如登陆,就成问题了
状态管理就将浏览器与web服务器之间多次交互当作一个整体来处理,并且将多次交互所涉及的数据保存下来
客户端状态管理技术将状态保存到客户端,代表性的是cookie技术
服务器状态管理技术将状态保存到服务器端,代表性的是Session技术
5.1 cookie

主要由标识该信息的名称(name)和值(value)组成,键值对

查看cookie:360浏览器,设置-高级设置-网页内容高级设置-所有cookie和网站数据-输入localhost

5.1.1 设置cookie访问路径和有效期
 //1.服务端创建cookie对象
cookie cookie=new cookie("username","gavin");
cookie cookie2=new cookie("password","123456");
 //1.1设置cookie的访问路径
cookie.setPath("MyServlet_war_exploded/get");
cookie.setPath("MyServlet_war_exploded");
//1.2设置cookie生命周期,取值有三种,>0,有效期单位秒,=0浏览器关闭,<0浏览器内存临时存储
cookie.setMaxAge(60*60);
cookie2.setMaxAge(60*60);
//2.将cookie响应给客户端
resp.addcookie(cookie);
resp.addcookie(cookie2);
5.1.2 循环遍历,获取cookie
 //1通过request对象获取所有的cookie
cookie[] cookies=req.getcookies();
//2 通过循环遍历cookie
 if (cookies!=null){
     for (cookie cookie:cookies) {
        System.out.println(cookie.getName()+":"+cookie.getValue());
     }
   }
5.1.3 cookie的修改

只需要保证cookie的名字和路径一致即可修改,原理是替换原cookie

//新建一个cookie类,路径名字与之前一致,会自动替换掉之前的cookie
cookie cookie=new cookie("username","gavin");
cookie.setPath("MyServlet_war_exploded/get");  
5.1.4 cookie编码与解码

cookie默认不支持中文,所以需要编码

import java.net.*;
//编码  在创建对象时候,直接这么创建
cookie cookie=new cookie(URLEncoder.encode("姓名","UTF-8"),URLEncoder.encode("张三","UTF-8"));
//解码,在循环遍历,获取cookie里面,foreach改成输出这个就行
System.out.println(URLDecoder.decode(cookie.getName(),"UTF-8")+":"+URLDecoder.decode(cookie.getValue(),"UTF-8"));
           
5.2 Session

Session用于记录用户的状态。Session指的是在一段时间内,单个客户端与Web服务器的一连串相关的交互过程

session由服务端创建,服务器会为每一次会话分配一个session对象,首次使用到Session时,服务器会自动创建Session,并创建cookie存储Session id发送回客户端

5.2.1 基本操作
  //1 通过request对象获取Session对象
HttpSession session= req.getSession();
System.out.println(session.getId());

//2.session保存数据
session.setAttribute("key",value);  //以键值对形式存储在session作用域中

//3.session获取数据
session.getAttribute("key");  //通过String类型的key访问Object类型的value

//4.session移除数据
session.removeAttribute("key");  //通过键移除session作用域中的值

//5.生命周期
//5.1浏览器关闭,则结束
//5.2设置session生命周期10秒,session超时则结束
 session.setMaxInactiveInterval(10);
//5.3手工销毁,则结束
 session.invalidate();
5.2.2 浏览器禁用cookie(不推荐,后期用EL表达式做)

服务器在默认情况下,会使用cookie的方式将session id发送给浏览器,如果用户禁止cookie,则session id不会被浏览器保存,此时服务器可以使用如URL重写这样的方式来发送Session id,即后面加上session id

//先拼接session id,再页面跳转,来保证页面两次跳转,还是同一个session会话
String newUrl= resp.encodeRedirectURL("/MyServlet_war_exploded/gets");
resp.sendRedirect(newUrl);
5.3 ServletContext
  • 全局对象,也有作用域,对应一个Tomcat中的Web应用
  • 当web服务器启动时,会为每一个web应用程序创建一块共享的存储区域
  • ServletContext在web服务器启动时创建,关闭时销毁
5.3.1 获得 ServletContext对象
  		 //1 通过this.getServletContext()
        ServletContext servletContext1=this.getServletContext();
        //2 通过request对象获取
        ServletContext servletContext2=req.getServletContext();
        //3 通过session对象获取
        HttpSession session= req.getSession();
        ServletContext servletContext3=session.getServletContext();
5.3.2 ServletContext作用
 //获取当前项目在服务器发布的真实路径
 System.out.println(servletContext1.getRealPath("/"));
 
 //获取项目的上下文路径,两句一样
  System.out.println(servletContext2.getContextPath());
	System.out.println(req.getContextPath()); //两句一样,输出/MyServlet_war_exploded

	//全局容器
	servletContext1.setAttribute("name",value);  //存储数据
        servletContext1.getAttribute("name");   //获取数据
        servletContext1.removeAttribute("name");   //移除数据
5.3.3 作用域总结
  • HttpServletRequest:一次请求,请求响应之前有效
  • HttpSession:一次会话开始,浏览器不关闭或不超时之前有效
  • ServletContext:服务器启动开始,服务器停止之前有效
六、过滤器

​ 过滤器执行地位在Servlet之前,客户端发送请求时,会先经过Filter,再到达目标Servlet中;响应时,会根据执行流程再次反向执行Filter。

​ Servlet API中提供了一个Filter接口,开发人员编写一个Java类实现了这个接口即可,这个类称之为过滤器

​ 导入包: import javax.servlet.*;

6.1 过滤器基本实现
//过滤器
package com.tang.servlet;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter(value = "/t")
public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("---MyFilter---");
        filterChain.doFilter(servletRequest,servletResponse);
        System.out.println("---End---");
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}
======================================================================================
   //目标Servlet
    package com.tang.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet(value = "/t")
public class TargetServlet extends HttpsServlet{
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("---target---");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }
}
=====================================================================================
   输出的执行结果,可以看出执行顺序,客户端到filter到Servlet,再返回filter,再返回客户端
---MyFilter---
---target---
---End---

6.2 两种配置方式 6.2.1 注解配置

@WebFilter(value = “/过滤目标资源”)

6.2.2 xml配置

    xml
    
            com.tang.servlet.XmlFilter
    
  
  
    xml
    /t
  

6.3 过滤器优先级

在一个Web应用中,可以开发编写多个Filter,这些Filter组合起来称之为一个FIlter链

优先级:

  1. 如果为注解的话,是按照字母的排序顺序
  2. 如果web.xml,是按照从上往下顺序
  3. web.xml配置高于注解方式
  4. 如果注解和web.xml同时配置,会创建多个过滤器对象,造成过滤多次
6.4 配置拦截路径

精确拦截匹配:/index.jsp

后缀拦截匹配:*.jpg

通配符拦截匹配:/*

6.5 过滤器典型应用 乱码处理



    
    登录页面


    
用户名:
密码:
//编写Servlet
package com.tang.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(value = "/login")
public class LoginServlet extends HttpsServlet{
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username= req.getParameter("username");
        String password= req.getParameter("password");
        System.out.println(username+"t"+password);
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }
}

//过滤器
package com.tang.servlet;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter(value = "/login")
public class EncodingFilter 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() {

    }
}

JSP

作用是替换显示页面部分的Servlet

一、JSP开发 1.1 创建JSP
  1. 先创建普通的Java项目,名字Web_JSP,再对着项目名右键-Add frameWork Support-选择Web Application,勾选create web xml
  2. 对着WEB-INF右键新建DIRECTORY,lib文件夹,随后导入servlet-api.jar包,复制到lib文件夹,右键add as library
  3. (可省)IDEA集成Tomcat,左上角File-Settings-左侧Build Execution Deployment 找到Application Servers,点击加号,添加Tomcat Server,选择tomcat的目录,点击OK,点击Apply,点击OK
  4. 右上角Add configuration,点击加号,找到tomcat server,点击local,找到Deployment,点击加号,Arifact。点击OK,
  5. 网页url,context两个改成web_jsp,,
  6. 热部署,on update action=redeploy,,,on frame deactivation=update classes and resources
  7. 对着web右键新建jsp文件,然后写以下代码,网页直接刷新即可,访问http://localhost:8080/web_jsp/first.jsp
  8. 以下代码打印系统当前时间
<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


    Now:<%=new java.util.Date() %>



1.2 实现原理

Tomcat把.jsp转换成Java代码,进而编译成.class文件运行,最终将运行结果通过response响应给客户端

二、JSP与HTML集成开发 2.1 脚本

脚本可以编写Java语句、变量、方法或表达式

2.1.1 普通脚本

语法: <% Java代码 %>

普通脚本可以使用所以java语法,除了定义函数

脚本与脚本之间不可嵌套,脚本与HTML标签不可嵌套


<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    脚本的使用


    <%
        int a=10;
        System.out.println(a); //输出在控制台
        out.println(a);//输出在页面
    %>



2.1.2 声明脚本

语法: <%! 定义变量、函数 %>

声明脚本声明的变量是全局变量

声明脚本的内容必须在普通脚本<% %>中调用

如果声明脚本中的函数具有返回值,使用输出脚本调用<%=%>

2.1.2 输出脚本

语法: <%= Java表达式 %>

输出脚本可以输出带有返回值的函数

输出脚本不能加;分号

2.2 JSP注释

主要功能:为脚本代码注释和为html内容注释

语法描述
<%-- JSP注释 --%>JSP注释内容,注释内容不会被发送至浏览器甚至不会被编译
HTML注释,通过浏览器查看网页源代码时可以看见注释内容
2.3 JSP指令

JSP指令用来设置与整个JSP页面相关的属性

指令描述
<%@ page %>定义页面的依赖属性
<%@ include %>包含其他文件
<%@ taglib %>引入标签库的定义,可以是自定义标签
2.3.1 Page指令

Page指令为容器提供当前页面的使用说明。一个JSP页面可以包含多个page指令

属性描述
errorPage指定当jsp页面发生异常时需要转向的错误处理页面
isErrorPage指定当前页面是否可以作为另一个jsp页面的错误处理页面
pageEncoding指定jsp页面的解码格式
2.3.2 include指令

通过这个指令,包含其他jsp页面

可能会有重名的冲突问题,不建议使用

2.3.3 taglib指令

引入jsp的标准标签库

2.4 动作标签

动作标签指的是jsp页面在运行期间的命令

2.4.1 include(推荐)

include指令,是将外部文件的输出代码复制到了当前jsp文件中,而这里的jsp:include动作不同,是将外部文件的输出结果引入到了当前jsp文件中

2.4.2 useBean setProperty getProperty(JavaBean)
	
	用来加载一个将在JSP页面中使用的JavaBean
    
	进行属性赋值
    
	提取指定Bean属性的值,转换成字符串,然后输出到页面
2.4.3 forward param(页面跳转)

把请求转到另外的页面
param获取参数
2.5 内置对象 2.5.1 四大域对象

JSP有四大作用域对象,存储数据和获取数据的方式一样,不同的是取值的范围有差别

  • pageContext:当前JSP页面范围
  • request:一次请求有效
  • session:一次会话有效,关闭浏览器失效
  • application:整个web应用有效,服务器重启或关闭失效
 <%
        pageContext.setAttribute("name",value);//当前页面作用域有效
    %>
2.5.2 pageContext获取其他内置对象
 <%
        pageContext.getRequest();//返回Request内置对象
        pageContext.getResponse();//返回Response内置对象
        pageContext.getSession();//返回Session内置对象
        pageContext.getServletContext();
        pageContext.getOut();
        pageContext.getException();
        pageContext.getPage();
        pageContext.getServletConfig();
    %>
2.5.3 pageContext操作其他内置对象的作用域
<%
    pageContext.setAttribute("page","123");//当前jsp有效
    pageContext.setAttribute("req","aaa",PageContext.REQUEST_SCOPE);
    pageContext.setAttribute("sess","bbb",PageContext.SESSION_SCOPE);
    pageContext.setAttribute("app","ccc",PageContext.APPLICATION_SCOPE);

    String req=(String) request.getAttribute("req");
    String sess=(String) session.getAttribute("sess");
    String app=(String) application.getAttribute("app");

%>
   request:<%=req%>
    session:<%=sess%>
    application:<%=app%>
三、EL表达式

EL使JSP写起来更简单,主要用于获取作用域中的数据,用于替换作用域对象.getAttribute(“name”)

3.1 作用域基本操作

EL和脚本的区别,就是EL返回空,脚本返回null

<%
   request.setAttribute("key1","value1");//当前jsp有效
    session.setAttribute("key2","value2");
    application.setAttribute("key3","value3");
%>

    通过作用域对象获取:
<%--通过作用域对象获取数据--%>                      //EL和脚本的区别,就是EL返回空,脚本返回null
   <%=request.getAttribute("key1")%>
    <%=request.getAttribute("key1")%>
    <%=request.getAttribute("key1")%>
    
<%--通过EL表达式获取数据,有以下2种--%> 通过EL表达式获取: ${requestScope.key1} ${sessionScope.key2} ${applicationScope.key3}
${key1} ${key2} ${key3} <%--这个简写,需要区分key不同的情况下,如果key相同对应的value不同,就不适合了--%>
3.2 操作普通对象
${user.username}
${user.password}
3.3 操作数组,集合对象
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    EL操作数组,集合元素


<%
    int[] array=new int[]{1,2,3,4,5};
    request.setAttribute("array",array);

    List nums=new ArrayList<>();
    nums.add("A");
    nums.add("B");
    nums.add("C");
    request.setAttribute("nums",nums);

    Map maps=new HashMap<>();
    maps.put("CN","中国");
    maps.put("US","美国");
    maps.put("IT","意大利");
    request.setAttribute("maps",maps);
%>

${array[1]}
${array[2]}
${array[3]}

${nums[0]}
${nums[1]}
${nums.get(2)}

${maps["CN"]}
${maps.IT}






3.4 EL内置对象
${pageContext.request.contextPath}  获得应用上下文
${cookie.username.value}   获得username
${cookie.password.value}   获得password
四、JSTL标准标签库

是JSP标签集合,可以对EL获取到的数据进行逻辑操作,与EL合作完成数据的展示

4.1 JSTL的准备工作
  1. 把standard.jar和jstl.jar拷贝到/WEB-INF/lib下
  2. 在JSP页面引入标签库<%@ taglib uri=“http://java.sun.com/jsp/jstl/core” prefix=“c” %>
4.2 核心标签 4.2.1 if条件判断
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib  uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>


    Title


  <%
    request.setAttribute("username","tom");
  %>


  欢迎你,${username} 


  
    请你重新登陆 
  



4.2.2 choose多条件判断

相当于if else结构

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib  uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>


    Title


  <%
    request.setAttribute("age",38);
  %>


   少年 
   青年 
   中年 
  老年





4.2.3 迭代foreach标签
<%@ page import="java.util.*" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib  uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>


    Title


  <%
    List list=new ArrayList<>();
    list.add("A");
    list.add("B");
    list.add("C");
    list.add("D");
    request.setAttribute("list",list);
  %>


  ${s}







4.2.4 重写URL

在cookie禁用的情况下,通过重写URL拼接session id来传递id值,便于下一次访问时仍可查找到上一次的Session对象,所有涉及到页面跳转或者重定向跳转,都应该使用URL重写

<%@ page import="java.util.*" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib  uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>


    Title


    
  
  
  ">跳转




五、MVC框架 5.1 概念

MVC又称为编程模式,是一种软件设计思想,将数据操作、页面展示、业务逻辑分为三个模块,独立完成,互相调用。

视图,view,这是用户看到并与之交互的界面,比如html

控制器,controller,是控制请求的处理逻辑,接收view发送来的信息,对请求进行处理,负责流程跳转

模型层,Model,是service+dao+entity

5.2 优点

低耦合性:模块与模块直接的关联性不强,不与某一种具体实现产生密不可分的关联性

高维护性:基于低耦合性,可做到不同层级的功能模块灵活更换

高重用性:相同的数据库操作,可以服务于不同的业务处理,将数据作为独立模块,提高重用性

5.3 三层架构与MVC

三层架构:view service dao

MVC是框架,架构是框架之下的

MVC强调的是视图和业务的分离,view只负责数据展示,而数据封装到model里,controller负责在V和M之间传递。

三层架构指的是代码之间的解耦,方便维护和复用

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/270430.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号