JavaWeb

MySQL数据库

1、DDL数据定义语言

00)常用约束&数据类型
主键约束primary key
主键自动增长auto_increment
非空约束not null
唯一性约束unique
默认值default
主外键约束foreign key

数值类型

tinyint(m)1个字节 范围(-128~127)
smallint(m)2个字节 范围(-32768~32767)
mediumint(m)3个字节 范围(-8388608~8388607)
int(m)4个字节 范围(-2147483648~2147483647)
bigint(m)8个字节 范围(±9.22*10的18次方)

浮点型(float和double)

float(m,d)单精度浮点型 8位精度(4字节) m总个数,d小数位
double(m,d)双精度浮点型 16位精度(8字节) m总个数,d小数位

字符类型

char(n)固定长度,最多255个字符
varchar(n)固定长度,最多65535个字符
tinytext可变长度,最多255个字符
text可变长度,最多65535个字符
mediumtext可变长度,最多2的24次方-1个字符
longtext可变长度,最多2的32次方-1个字符

日期时间类型

date日期 ‘2008-12-2’
time时间 ‘12:25:36’
datetime日期时间 ‘2008-12-2 22:06:44’
timestamp自动存储记录修改时间
01)创建数据库并且设置字符集
create database 数据库名 character set 字符集;
02)创建表
create table 表名( 字段名 字段类型 字段约束,字段名 字段类型 字段约束);

绑定主外键:
语法:fore
示例:ign key (外建字段名) references 主键表名(主键字段名)
示例:create table toursInfo(
  		id int primary key auto_increment,
  		introduce varchar(500),
  		pubTime date,
 		price decimal(6,2),
  		cityId int,
  		foreign key (cityId) references city(cityId)
);
03)显示所有数据库
show databases;
04)查看当前数据库中所有表名称
show tables;
05)切换数据库
use 数据库名;
07)修改列类型
alter table 表名 modify 列名 列类型;
08)增加列
alter table 表名 add 列名 列类型;
09)删除列
alter table 表名 drop 列名;
10)列改名
alter table 表名 change 旧列名 新列名 列类型;
11)更改表名
alter table 表名 rename 新表名;
12)查看表结构
desc 表名;
13)删除表
drop table 表名;
14)删除数据库
drop databases 数据库名;

2、DML 数据操纵语言

01)插入单行数据
insert into 表名(字段列表) values(列表值);
02)插入多行数据
insert into 表名(字段1,字段2) values(字段值1,字段值2);
03)更新数据
update 表名 set1 = 新值1 ,2 = 新值2    where 条件;
04)可以根据条件删除,可以回滚数
delete from 表名 [where 条件]
05)永久删除,无法回滚
truncate table 表名;

3、DQL数据查询语言数据

单表查询
00)关键字
A)and:表示连接多个条件,表示并且关系。
B)or:表示连接多个条件,表示或者的关系。
C)in(): 包含哪些值
D)not in():不包含哪些值
E)sql中null的写法 是空的:is null 不是空的:is not null
F)between … and : 表示范围内的记录, 表示闭区间。
G)<>:表示:不等于
H)模糊查询
01)基础查询的语法
select 字段名 from 表名  where 条件
02)字段控制查询

注:distinct字段: 去除字段的重复记录

select distinct 字段名 from 表名  where 条件;

IFNULL(字段,0):函数表示:如果字段是空的,用0代替

select 字段1+IFNULL(字段2,0),字段名 from 表名;

concat()函数:连接字段,形成字符串

select concat(字段名,'的工资是',字段1+IFNULL(字段2,0),'美元' )from 表名;

order by:
字段 asc : 升序排序,默认升序:如果不写,默认升序。
字段 desc: 降序排序,desc必须写。如果有多个排序条件:order by 字段1 desc,字段2 asc,…

order by:排序
03)求年龄
select timestampdiff (year, 字段名, CURDATE())as 年龄 from 表名;
04)聚合函数

count()函数:

统计有多少条记录

语法:select count(*)/count(1)  from 表名;

统计某个字段不为空的记录

语法:select count(字段) from from 表名;

sum()函数:统计某个字段的总和

语法:select sum(字段) from 表名;

avg()函数:统计某个字段的平均值

语法:select avg(字段) from 表名;

max()函数:统计某个字段的大值

语法:select max(字段) from 表名;

min()函数:统计某个字段的小值

语法:select min(字段) from 表名;
05)分组查询

语法:group by 要分组的字段

select * from 表名
where 条件 
group by 分组 
having 对聚合函数进行过滤 
order by 排序 
limit 分页

having和where的区别?:

01)having:对聚合进行过滤,写在group by 后面,千万不能写where中!!

02)where:对普通字段进行过滤

06)模糊查询

关键字:like

查询不包含某个字符

select * from student  where  列名 not like'王%'

查询包含某个字符

select * from student  where  列名 like'王%'
07)分页查询

limit:查询指定的记录

语法:limit 起始行-1,行数

select * from 表名 limit  起始行-1,查询几行记录;

公式:

查询前5条  每一页显示5行  pageSize=5

currentPage:显示第几页  
pageSize:每页显示几行

select * from 表名 limit (currentPage-1)*pageSize,pageSize
多表查询
01)合并结果集

union 去除重复记录

union all 不去除重复记录

select 字段名 from 表名1     
union     
select 字段名 from 表名2  
02)内连接
select * from  主表  ,  子表   where  主表主键字段  =  子表外键字段;
03)等值连接
select  字段名    from   左表名  inner  join  右表  on 左表主键 = 从表外键;
04)左外连接

做外链接把左表作为主表

select  字段名    from   左表名  left  join  右表  on 左表主键 = 从表外键;
05)右外连接
select  字段名    from   左表名  right  join  右表  on 左表主键 = 从表外键;
06)全连接
select  字段名    from   左表名  left  join  右表  on 左表主键 = 从表外键;      
union       
select  字段名    from   左表名  right  join  右表  on 左表主键 = 从表外键;

4、DCL数据控制语言用户权限

01)创建新的mysql账户

注:localhost代表只有本机可以登录,远程不可以,也可以省掉
[ @‘localhost’ ]

create user '用户名'@'localhost' identified by '密码';
02)给这个用户授所有权限

注:这是把所有的权限授权给这个用户并允许这个用户给其他用户授权,[
with grant option ] 代表此用户可以给其他用户授权

grant all on *.* to '用户名'@'localhost' with grant option;
03)刷新权限列表
FLUSH PRIVILEGES;
04)收回用户权限
revoke all on *.* from 用户名 cascade;

5、MySQL数据库备份与还原

01)生成SQL脚本

在控制台使用mysqldump命令可以用来生成指定数据库的脚本文本,但要注意,脚本文本中只包含数据库的内容,而不会存在创建数据库的语句!所以在恢复数据时,还需要自已手动创建一个数据库之后再去恢复数据。

未完待续…

JDBC封装源码

JDBC的API组成

01)DriverManager类:加在数据库驱动得到数据库的连接对象

02)Connection接口:表示连接对象,创建这个对象成功,表示数据库连接成功

03)Statement接口:sql语句执行器 增删改:executeUpdate(sql) 查:executeQuery(sql)

04)ResultSet接口:表示一个结果及对象

05)PreparedStatement子接口: 继承自Statement,预编译对象,使用占位符

ResultSetMetaData rsmd= rs.getMetaData();
得到rs这个结果集列的信息

6)CallableStatement 是PreparedStatement子接口,子程序【存储过程,函数】,调用或执行数据库存储过程

{?= call <function-name>[(<arg1>,<arg2>, ...)]}
 {call <procedure-name>[(<arg1>,<arg2>, ...)]}

连接池

javax.sql.* DataSource连接池的一个标准 c3p0 实现了DataSource这个接口

ComboPooledDataSource  ds=new  ComboPooledDataSource();
自动到src下找c3p0-config.xml,读取这个文件中的连接信息
ds.getConnection();
1)连接数据库

使用JDBC连接数据库进行查询的步骤:

1) 导入驱动程序jar包 :mysql-connector-java-5.1.7-bin.jar

2) 加载驱动程序 Class.forName(“com.mysql.jdbc.Driver”);

3) 获取数据库连接对象:Connection

4) 获取发送SQL语句的对象:Statement

5) 创建sql语句

6) 把SQL语句发送到数据库执行

7) 返回结果集对象:ResultSet

8) 遍历结果集对象,获取数据9)关闭连接,释放资源图示:

#连接数据库
import com.mysql.jdbc.Driver;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class JdbcConn {

    public static void main(String[] args) throws SQLException, ClassNotFoundException {
        //2.加载驱动程序
        //mysql的驱动对象
        //Driver driver = new Driver();
        //DriverManager:jav提供的管理驱动的类,调用registerDriver来注册驱动程序
        //问题:
        // 1)重复注册
        //2)有硬编码
        //DriverManager.registerDriver(driver);

        //解决问题:使用类加载的方式来加载驱动程序
        Class.forName("com.mysql.jdbc.Driver");
        //3.创建连接数据库的对象:Connection
        /*
        * 参数1: url : 连接到数据库的url
        *    jdbc:mysql://IP地址:3306/数据库名?charsetEncoding=utf8
        *    charsetEncoding=utf8:指定连接数据库的编码格式
        * 参数2:数据库用户名
        * 参数3:数据库密码
        * */
        //java.sql包下面
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/employee5?charsetEncoding=utf8",
                "root","sa123");
        if(conn!=null){
            System.out.println("数据库连接成功!");
        }else{
            System.out.println("数据库连接失败!");
        }
    }
}

向数据库插入数据

public void add() throws ClassNotFoundException, SQLException {
        //1.加载驱动程序
        Class.forName("com.mysql.jdbc.Driver");
        //2.获取数据库连接对象
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/employee5?charsetEncoding=utf8",
                "root","sa123");
        //3.获取发送sql语句的对象:statement
        Statement stmt = conn.createStatement();
        //4.创建sql语句
         //注意:这里写的SQL语句跟在mysql中语法完全一样!
        String sql = "insert into dept values (null,'抖音部','777777')";
        //5,把SQL语句发送到数据库执行
        //executeUpdate: 执行增/删/改的操作
        //i: 表示增/删/改影响的行数
        int i = stmt.executeUpdate(sql);
        if(i>0){
            System.out.println("成功插入["+i+"]条记录!");
        }else{
            System.out.println("插入失败!");
        }
        //6.关闭连接,释放资源
        stmt.close();
        conn.close();
    }
2)向数据库修改数据:

注:增、删、改都一样,只需要修改sql语句

//向数据库修改数据
    @Test
    public void delete() throws ClassNotFoundException, SQLException {
        //1.加载驱动程序
        Class.forName("com.mysql.jdbc.Driver");
        //2.获取数据库连接对象
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/employee5?charsetEncoding=utf8",
                "root","sa123");
        //3.获取发送sql语句的对象:statement
        Statement stmt = conn.createStatement();
        //4.创建sql语句
        //注意:这里写的SQL语句跟在mysql中语法完全一样!
        String sql = " delete from dept where did=7 ";
        //5,把SQL语句发送到数据库执行
        //executeUpdate: 执行增/删/改的操作
        //i: 表示增/删/改影响的行数
        int i = stmt.executeUpdate(sql);
        if(i>0){
            System.out.println("成功删除["+i+"]条记录!");
        }else{
            System.out.println("删除失败!");
        }
        //6.关闭连接,释放资源
        stmt.close();
        conn.close();
    }
3)从数据库查询数据
  1. 导入驱动程序jar包 :mysql-connector-java-5.1.7-bin.jar

2) 加载驱动程序 Class.forName(“com.mysql.jdbc.Driver”);

3) 获取数据库连接对象:Connection

4) 获取发送SQL语句的对象:Statement

5) 创建sql语句

6) 把SQL语句发送到数据库执行

7) 返回结果集对象:ResultSet

8) 遍历结果集对象,获取数据

9)关闭连接,释放资源图示:

//从数据库查询数据
    //使用JDBCUtils工具类
    @Test
    public void select2() throws ClassNotFoundException, SQLException {
        Connection conn = JDBCUtils.getConn();
        //3.获取发送sql语句的对象:statement
        Statement stmt = conn.createStatement();
        //4.创建sql语句
        //注意:这里写的SQL语句跟在mysql中语法完全一样!
        String sql = " select * from dept ";
        //5.把SQL语句发送到数据库执行
        //executeQuery:表示查询操作
        //6.返回结果集对象:ResultSet
        //ResultSet:结果集对象
        ResultSet rs = stmt.executeQuery(sql);
        //next():当调用next()的时候,游标会向下移动一行
        //返回boolean类型,如果没有下一行了,返回false
        while (rs.next()){
            /*
             * 获取数据的方式:
             * 1)通过 get数据类型(行下标);
             * 2)通过 get数据类型("列的名字");
             *
             *
             * 数据库的类型       java类型
             * int                getInt()
             * char/varchar       getString()
             * date               getDate()
             * time               getTime()
             * timestamp          getTimestamp()
             * float              getFloat()
             * double             getDouble()
             *
             * */
            System.out.println(rs.getInt(1)+","+
                    rs.getString("dname")+","+rs.getString(3));
        }
        //7.关闭连接,释放资源
        JDBCUtils.closeAll(conn,stmt,rs);
    }

JDBC代码简单优化

方案1:Class反射机制连接

使用工具类来封装JDBC

创建类:JDBCUtils.java

封装加载驱动和获取数据库连接

1) 创建类:JDBCUtils.java 来封装

2) 使用 .properties配置文件来存放jdbc的连接信息案例演示:

db.properties

预编译对象:PreparedStatement , 继承自Statement

#配置文件,用来配置数据库连接信息
#mysql
className=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/students?characterEncoding=utf8
username=root
password=ROOT

连接数据库的工具类

import java.io.FileReader;
import java.io.IOException;
import java.sql.*;
import java.util.Properties;

/**
 * @ClassName JDBCUtils
 * @Description TODO 连接数据库的工具类
 * @Author zhaojing
 * @Date 2020/3/12 17:15
 * @Version 1.0
 */
public class JDBCUtils {

    //创建全局属性
    private static String className;
    private static String url;
    private static String username;
    private static String password;

    static {
        //加载配置文件,获取连接信息
        Properties pro = new Properties();
        try {
            //写法1:读取配置文件,获取信息
            //pro.load(new FileReader("db.properties"));
            //写法2:从当前运行的文件根目录去找文件也就是JDBCPackaging的根目录src
            pro.load(JDBCPackaging.class.getResourceAsStream("/db.properties"));
            //根据key获取value
            className = pro.getProperty("className");
            url = pro.getProperty("url");
            username = pro.getProperty("username");
            password = pro.getProperty("password");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    static {
        //加载驱动程序
        try {
            Class.forName(className);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    //获取数据库连接对象
    public static Connection getConn(){
        try {
            return DriverManager.getConnection(url,username,password);
        } catch (SQLException e) {
            e.printStackTrace();
            throw new RuntimeException("数据库连接错误!");
        }
    }

    //关闭连接,释放资源
    public static void closeAll(Connection conn, Statement stmt, ResultSet rs){
        if(rs!=null){
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(stmt!=null){
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(conn!=null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    //方法的重载
    public void closeAll(Connection conn, Statement stmt){
        if(stmt!=null){
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(conn!=null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    public void closeAll(Connection conn){
        if(conn!=null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

方案2:线程池技术连接

1.通过线程池方式建立连接

2.提取重复代码封装,子类继承封装后的父类

3.切记一定要导入相关jar包,和配置xml文件

4.命名规范实体类的名+DAO

DAO封装==父类
package day14.exercise.dao;

import day14.exercise.utils.ConnectionPrepared;

import java.sql.*;

/**
 * 父类==封装重复的代码
 */
public class BaseDao {
    /**
     *
     * @param sql 要执行的sql语句
     * @param params  这个sql中的?所需要参数
     */
    protected void executeUpdate(String sql,Object[] params){
        //1.得到连接==线程池
        Connection conn = ConnectionPrepared.getConnection();

        PreparedStatement pstmt = null;
        //2.得到预编译对象
        try {
            pstmt = conn.prepareStatement(sql);
            //如果有参数表示sql有占位符
            if (pstmt != null){
                for (int i = 0; i < params.length; i++) {
                    pstmt.setObject(i+1,params[i]);
                }
            }
            pstmt.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            close(pstmt,conn);
        }
    }

    /**
     * 线程池归还连接      两个方法重载
     * @param stmt
     * @param conn
     */
    protected void close(Statement stmt,Connection conn){

            try {
                if (stmt != null){
                stmt.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                if (conn != null){
                    conn.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }

    }

    protected void close(ResultSet rs,Statement stmt,Connection conn){
        try {
            if (rs != null){
                stmt.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            if (stmt != null){
                stmt.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            if (conn != null){
                conn.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

DAO封装==子类

继承了父类封装的方法

优点:

1.优化了占位符

package day14.exercise.dao;

import day14.exercise.utils.ConnectionPrepared;

import day14.exercise.entity.Student;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;


public class StudentDao extends BaseDao{
    /**
     * 实现修改属性
     * @param id
     */
    public void delete(int id){
        String sql = "delete from student where stuid=?";
        Object[] params = {id};
        executeUpdate(sql,params);
    }

    /**
     * 实现增加记录
     * insert into student values(null,?,?,?,?)
     */
    public void insert(Student stu){
        String sql = "insert into student values(?,?,?,?,?)";
        Object[] params = {stu.getStuid(),stu.getName(),stu.getSex(),stu.getBirthday(),stu.getSclass()};
        executeUpdate(sql,params);
    }

    /**
     *更新一条记录
     */
    public void update(Student stu){
        String sql = "update student set name=?,sex=?  where id=?";
        Object[]params = {stu.getName(),stu.getSex(),stu.getStuid()};
        executeUpdate(sql,params);
    }

    /**
     * 查询表记录
     */
    public List<Student>findAll(){
        String sql = "select * from student";
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        List<Student>list = new ArrayList<>();
        Student stu = null;
        Connection conn = null;


        try {
            conn = ConnectionPrepared.getConnection();
            pstmt = conn.prepareStatement(sql);
            rs = pstmt.executeQuery();
            while (rs.next()){
                int id = rs.getInt("id");
                String name = rs.getString("name");
                String sex = rs.getString("sex");
                String birthday = rs.getString("birthday");
                String sclass = rs.getString("sclass");
                stu = new Student(id,name,sex,birthday,sclass);
                list.add(stu);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            close(rs,pstmt,conn);
        }
        return list;

    }
    public Student findById(int id){
        //1.定义sql
        String sql = "select * from student where id = ?";
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        Student stu = null;
        Connection conn = null;

        try {
            conn = ConnectionPrepared.getConnection();
            pstmt = conn.prepareStatement(sql);
            pstmt.setInt(1,id);
            rs = pstmt.executeQuery();
            if (rs.next()){//true表示有一条记录
                int sid = rs.getInt("id");
                String name = rs.getString("name");
                String sex = rs.getString("sex");
                String birthday = rs.getString("birthday");
                String aClass = rs.getString("class");
                stu = new Student(sid,name,sex,birthday,aClass);
                return stu;
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            close(rs,pstmt,conn);
        }
        return stu;
    }
}
实体类==实例化存储表对象
package day14.exercise.entity;

public class Student {
    private Integer stuid;
    private String name;
    private String sex;
    private String birthday;
    private String sclass;

    public Student() {
    }

    public Student(Integer stuid, String name, String sex, String birthday, String sclass) {
        this.stuid = stuid;
        this.name = name;
        this.sex = sex;
        this.birthday = birthday;
        this.sclass = sclass;
    }

    public Integer getStuid() {
        return stuid;
    }

    public void setStuid(Integer stuid) {
        this.stuid = stuid;
    }

    public String getName() {
        return name;
    }

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

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getBirthday() {
        return birthday;
    }

    public void setBirthday(String birthday) {
        this.birthday = birthday;
    }

    public String getSclass() {
        return sclass;
    }

    public void setSclass(String sclass) {
        this.sclass = sclass;
    }

    @Override
    public String toString() {
        return "Student{" +
                "stuid=" + stuid +
                ", name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", birthday='" + birthday + '\'' +
                ", sclass='" + sclass + '\'' +
                '}';
    }
}
工具类==创建线程池
package day14.exercise.utils;

import com.mchange.v2.c3p0.ComboPooledDataSource;


import java.sql.Connection;
import java.sql.SQLException;

public class ConnectionPrepared {
    private static ComboPooledDataSource dataSource;

    public ConnectionPrepared() {
    }

    static {
        dataSource = new ComboPooledDataSource();
    }

    public static Connection getConnection(){
        try {
            return dataSource.getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }
}
模拟用户登录
//模拟用户登录操作
    @Test
    public void login() throws SQLException {
        /*
        * 1、如果用户登录成功,提示登录成功
        * 2、如果登录失败,提示登录失败
        * */
        Scanner input = new Scanner(System.in);
        System.out.println("请输入用户名:");
        String username =  input.nextLine();
        System.out.println("请输入密码:");
        String userpwd =  input.nextLine();
        //根据输入的用户名和密码去数据库查询
        Connection conn = JDBCUtils.getConn();
        Statement stmt = conn.createStatement();
        String sql = "select * from users where username = '"+username+"'  and  userpwd = '"+userpwd+"'";
        System.out.println("sql:"+sql);
        ResultSet rs = stmt.executeQuery(sql);
        /*
        * SQL注入问题:
        * 输入: 123' or '1'='1
        *
        * 为什么会产生问题:
        * 1)statement是通过拼接字符串来创建SQL语句的,所以就可以改变SQL语句的结构
        *      正常:select * from users where username='admin' and userpwd = 'admin';
        *      改造后:select * from users where username = 'root'  and  userpwd = '123' or '1'='1'
        * 2)statment是创建完SQL语句之后,再发送到数据库执行,这样就可能执行修改过的语句。
        * */
        //如果查询的是一条数据,不需要while
        //使用if判断
        if(rs.next()){
            System.out.println("登录成功!");
        }else{
            System.out.println("登录失败!");
        }
        JDBCUtils.closeAll(conn,stmt,rs);
    }

    //模拟用户登录操作
    //使用预编译对象进行改造
    @Test
    public void login2() throws SQLException {
        /*
         * 1、如果用户登录成功,提示登录成功
         * 2、如果登录失败,提示登录失败
         * */
        Scanner input = new Scanner(System.in);
        System.out.println("请输入用户名:");
        String username =  input.nextLine();
        System.out.println("请输入密码:");
        String userpwd =  input.nextLine();
        //根据输入的用户名和密码去数据库查询
        Connection conn = JDBCUtils.getConn();
        //创建SQL语句
        String sql = "select * from users where username = ? and  userpwd = ?";;
        //创建预编译的对象
        PreparedStatement ps = conn.prepareStatement(sql);
        //给占位符设置值
        //语法:set数据类型(占位符的位置,占位符的值);
        ps.setString(1,username);
        ps.setString(2,userpwd);
        //执行查询
        //注意:这里不能再添加sql参数了!
        ResultSet rs = ps.executeQuery();

        System.out.println("sql:"+sql);

        /*
        * 预编译对象解决SQL注入问题:
        * 1)使用占位符? 来创建SQL语句,当创建预编译对象的时候,就提前把SQL语句发送到数据库保存(缓存)
        *    数据库获取到该SQL语句的结构,无法再修改。
        * 2)执行查询的时候,发送的不是SQL语句,而是占位符的值!!!
        * */

        //如果查询的是一条数据,不需要while
        //使用if判断
        if(rs.next()){
            System.out.println("登录成功!");
        }else{
            System.out.println("登录失败!");
        }
        JDBCUtils.closeAll(conn,ps,rs);
    }

线程池技术

jdbc java.sql.*这个包

DataSource javax.sql.* 也是一个接口,表示是一个标准是一个规范 连接池

连接池:集合,中保存了100个连接

连接Connection java程序 sql connection 数据库

连接池的实现 dbcp 连接池 c3p0 …

1.增加c3p0支持jar

2.在src中增加c3p0-config.xml文件

package com.kgc.utils;

import com.mchange.v2.c3p0.ComboPooledDataSource;

import javax.sql.DataSource;

public class DataSourcePooled {
    //构造DataSource对象作为返回值对象
    private  static  DataSource dataSource;
    //创建无参构造
    private  DataSourcePooled(){}
    //new ComboPooledDataSource();对象连接线程池
    static {
        //创建一个连接池的对象,读取src下的那个连接文件
        dataSource=new ComboPooledDataSource();
    }
    
    public static DataSource getDataSource(){
        return dataSource;
    }
}

c3p0

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
    <!-- 默认配置,如果没有指定则使用这个配置 -->
    <default-config>
        <property name="user">root</property>
        <property name="password">root</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/test</property>
        <property name="driverClass">com.mysql.jdbc.Driver</property>
    </default-config>

</c3p0-config>

DBUtils组件

DBUtils组件所提供的API

QueryRunner类

​ query() 完成查询的方法

​ update() 增加删除修改的方法,

需要提供DataSource或Connection就对象

ResultSetHandler 查询的API

Serializable 8 个包装类+String 都实现了

​ 将查询结果集中每一行映射成一个类型的对象

​ 自动匹配【字段的值 赋给对象的属性】要求,表中字段的名称与属性名相同

​ new BeanHandler(Student.class) 将查询出来一条记录映射成Student类的对象 返回

new BeanListHandler<Student>(Student.class)  将查询出来一条记录映射成Student类的对象 返回
QueryRunner queryRunner=new QueryRunner(datasource);
queryRunner.update(sql,objs[])
  runner.update(sql,Object ... parms});
  runner.query(sql,new BeanHandler<Student>(Student.class),new Object[]{1,2,3})
   runner.query(sql,new BeanListHandler<Student>(Student.class),new Object[]{1,2,3})
   select count(*) from student;
三层架构
Dao层
父接口Dao

命名规范:Dao

import java.io.Serializable;
import java.util.List;

public interface Dao <T>{
    /**
     * 增加
     */
    public void insert(T t);

    /**
     * 删
     */
    public void delete(T t);

    /**
     * 改
     */
    public void update(T t);

    /**
     * 查
     */

    //public void select(Serializable serializable);
    List<T>findAll();

    T findById(Serializable id);

继承接口

命名规范:实体名+Dao

import day15.entity.Student;

import java.util.List;

public interface StudentDao extends Dao<Student> {
    public Student login(String name,String pwd);

    /**
     * 用于分页查询
     * @param page
     * @param size
     * @return
     */
    List<Student>findByPage(int page,int size);
}
impl实现类

命名规范:实体名+Dao+Impl

import day15.dao.StudentDao;
import day15.entity.Student;
import day15.utils.DataSourcePooled;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.List;

public class StudentDaoImpl implements StudentDao {
    //utils提供的方法==简化了SQL查询功能
    QueryRunner runner = new QueryRunner(DataSourcePooled.getDataSource());


    @Override
    public Student login(String name, String pwd) {
        String sql="select * from student where name=? and pwd=?";
        Student student = null;

        try {
            //通过反射得到user对象,new BeanHandler<Student>获取一个目标对象;
            //          new BeanListHandler<Student>获取多个目标对象的集合;
            runner.query(sql,new BeanHandler<Student>(Student.class));
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return student;
    }

    @Override
    public List<Student> findByPage(int page, int size) {
        String sql="select * from tbl_user where name=? and pwd=?";
        List<Student> list = null;

        try {
            list = runner.query(sql,new BeanListHandler<Student>(Student.class));
        } catch (SQLException e) {

        }

        return list;
    }

    @Override
    public void insert(Student student) {
        String sql = "insert into student values(null,?,?,?,?)";
        int i= 0;
        try {
            i = runner.update(sql, student.getSname(), student.getSex(), student.getBirthday(), student.getS_class());
        } catch (SQLException e) {
            e.printStackTrace();
        }
        if (i>0) {
            System.out.println("成功添加了" + i + "条记录");
        }else {
            System.out.println("添加失败!");
        }
    }

    @Override
    public void delete(Student student) {
        String sql = "delete from student where stuid=?";
        int i =0;
        try {
            i = runner.update(sql, student.getStuid());
        } catch (SQLException e) {
            e.printStackTrace();
        }
        if (i>0) {
            System.out.println("成功删除了" + i + "条记录");
        }else {
            System.out.println("删除失败!");
        }
    }

    @Override
    public void update(Student student) {
        String sql = "update student set sname = ? ,sex = ? ,birthday = ? , s_class = ? where stuid= ?";
        int i =0;
        Object[] params=new  Object[]{
               student.getSname(), student.getSex(),student.getBirthday(),student.getS_class(),student.getStuid()

        };
        try {
            i = runner.update(sql, params);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        if (i>0) {
            System.out.println("成功修改了" + i + "条记录");
        }else {
            System.out.println("修改失败!");
        }
    }

    @Override
    public List<Student> findAll() {
        String sql = "select * from student";
        List<Student> list = null;

        try {
            list = runner.query(sql,new BeanListHandler<Student>(Student.class));
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return list;
    }

    @Override
    public Student findById(Serializable id) {
        String sql = "select * from student";
        Student student = null;

        try {
            student = runner.query(sql,new BeanHandler<Student>(Student.class));
        } catch (SQLException e) {
            e.printStackTrace();
        }


        return student;
    }


}
entity层
实体类

命名规范:跟表名一直,属性名也要一直

public class Student {
    private Integer stuid;
    private String sname;
    private String sex;
    private String birthday;
    private String s_class;

    public Student(Integer stuid) {
        this.stuid = stuid;
    }
    public Student(){

    }

    public Student(Integer stuid, String sname, String sex, String birthday, String s_class) {
        this.stuid = stuid;
        this.sname = sname;
        this.sex = sex;
        this.birthday = birthday;
        this.s_class = s_class;
    }

    public Integer getStuid() {
        return stuid;
    }

    public void setStuid(Integer stuid) {
        this.stuid = stuid;
    }

    public String getSname() {
        return sname;
    }

    public void setSname(String sname) {
        this.sname = sname;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getBirthday() {
        return birthday;
    }

    public void setBirthday(String birthday) {
        this.birthday = birthday;
    }

    public String getS_class() {
        return s_class;
    }

    public void setS_class(String s_class) {
        this.s_class = s_class;
    }

    @Override
    public String toString() {
        return "Student{" +
                "stuid=" + stuid +
                ", s
            name='" + sname + '\'' +
                ", sex='" + sex + '\'' +
                ", birthday='" + birthday + '\'' +
                ", s_class='" + s_class + '\'' +
                '}';
    }
}  
utils层
工具类
import com.mchange.v2.c3p0.ComboPooledDataSource;

import javax.sql.DataSource;

public class DataSourcePooled {
    private static DataSource dataSource;

    public DataSourcePooled() {
    }

    static {
        //utils提供的连接线程池方法
        dataSource = new ComboPooledDataSource();
    }

    public static DataSource getDataSource(){
        return dataSource;
    }
}

Tomcat

url地址语法格式

​ http : //ip地址 : 端口号/项目名/资源路径?参数=值

目录结构

​ bin : 放的是启动tomcat的程序:startup.bat shutdown.bat

​ conf : 放的是配置文件 : server.xml tomcat- user.xml web.xml

​ webapps : 放的是所有的资源文件(web项目)

​ work : 动态资源文件编译之后存放的位置

​ lib : 存放tomcat启动的jar包,和第3方jar包

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ijQ0WzaU-1603283389750)(java封装源码.assets/1599229762205.png)]

01)Tomcat启动和访问

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WA3CBcUQ-1603283389754)(java封装源码.assets/1599229784689.png)]

使用cmd来启动和关闭tomcat:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Fblfltys-1603283389756)(java封装源码.assets/1599229804725.png)]

02)端口占用问题

步骤:

1)在DOS下键入netstat -ano|findstr 8080查看占用8080端口的

配置文件都在 conf 文件夹下面 ,可以关掉相关进程

1、 修改端口号:修改server.xml

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rCQVL63s-1603283389757)(java封装源码.assets/1599229997207.png)]

1、 配置用户名和密码:修改tomcat-users.xml

<user username="zhaojing" password="123456" roles="manager-gui"/>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iUJqi2b7-1603283389759)(java封装源码.assets/1599230111188.png)]

03)设置资源同步tomcat

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ODmR6wk1-1603283389760)(java封装源码.assets/1599802369510.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tAQhUclk-1603283389760)(java封装源码.assets/1599802382104.png)]

JSP

01)jsp技术连接数据库

dao文件代码

public class UserDaoImpl implements UserDao {
    //创建 QueryRunner对象 连接线程池
    QueryRunner runner = new QueryRunner(DataSourcePooled.getDataSource());
    @Override
    //查找的方法
    public User login(String u_name, String u_pwd) {
        String sql = "select * from s_user where u_name =? and u_pwd = ? ";
        User user = null;
        try {
            user = runner.query(sql,new BeanHandler<User>(User.class),u_name,u_pwd);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return user;
    }
}

登录页面代码

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>用户登录</title>
</head>
<body>
	//yanzheng.jsp   验证的jsp文件
    <form method="post" action="yanzheng.jsp">
        账号:<input type="text" name="amin"/> <br/>
        密码:<input type="password" name="pwd"/><br/>
        <input type="submit" value="提交"/>
    </form>
</body>

</html>

验证jsp代码

<%
    User user = new User();
    UserDaoImpl userDao = new UserDaoImpl();
	//通过request.getParameter方法得到value的值
    String amin = request.getParameter("amin");
    String pwd = request.getParameter("pwd");

   //如果返回的对象为空则数据库没有
    if (userDao.login(amin,pwd)!=null ){
        response.sendRedirect("register.jsp");
    }else {
        //window.location.href='amids.jsp';如果密码错误回到登录页面
        out.print("<script>alert('账号或密码不正确!');window.location.href='amids.jsp'; </script>");
    }

%>

02)Web程序的结构

工程名 myweb

​ src 源码目录

​ web 目录 根目录 通过浏览器访问的是这个目录下的文件

​ WEB-INF 这个目录是web程序的私有目录,外部不能不能直接访问

​ web.xml web程序的描述文件 完成程序的注册

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>hello.jsp</welcome-file>
    </welcome-file-list>

发一个请求http://localhost:8080/index.jsp

​ lib目录 存放第三方jar包 c3p0 mysql…

​ classes目录 存放src目录下所有源码编译后的字节码文件 class文件

03)jsp执行原理

​ java server page java服务器端的页面

​ jsp=html+java代码 html可以使用浏览器直接打开 java 要有java运行的环境 浏览器不能直接打开jsp文件

jsp 运行环境 tomcat

1.转译 index.jsp----转译—index_jsp.java文件

2.编译 -index_jsp.java 编译成 -index_jsp.class 字节码

3.执行这个字节码全部生成html标签

4.浏览器就可以打开这个html标签

第一次通过tomcat来访问jsp,经过上面这个流程

04)jsp指令

page import taglib uri prefix include file

指令<% @ 指令名 属性="" 属性=“”%>

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

1) page:设置页面属性导包

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
 <%@ page import ="com.kgc.entity.*,com.kgc.dao.*"%>   
  <%@ page import ="com.kgc.utils.*"%>   

2)taglib指令 导入标签库 jstl

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

3)index.jsp index_jsp.java

index.jsp   index_jsp.java
<%@ include file="table.jsp"%>   静态包含  默诵与编译不生新文件,只有一个文件   index_jsp.java

…未完待续

05)JSP内置对象

对象名作用作用域
out输出对象 类型是PrintWriter打印流,在页面输出把文本输出到客户端 : out.write()
response响应对象一次请求中有效
session会话对象在一次会话中有效
application应用程序对象在整个tomcat运行期间有效
page当前页面对象 跟this同理
pageContext上下文对象,通过这个对象可以得到其它8内置jsp的对象在当前页面有效
config配置对象
exception异常对象
response
session
application
pageContext
//四个内置对象都具有以下共同方法
getAttribute()  
setAttribute()    
removeAttribute()

06)JS常用API

方法名作用
request.getHeaderNames();返回所有请求头的名称
request.getHeader(name);根据请求头的名称来得到它的值
request.getParameter(“name”);返回对象的value的值

代码块 jsp中加java代码

<table width="500px" border="1px">
    <tr>
        <th>编号</th>  <th>姓名</th>  <th>年龄</th>
    </tr>
<%
      for(int i=10;i<100;i+=10) {

%>
    <tr>
        <td>101</td><td>张三</td><td>23</td>
    </tr>
<%}
 %>

</table>
<%
    Date date=new Date();
    SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
    String rq=sdf.format(date);
    out.print(rq);
    out.print("<br/>")
    out.prnt("<hr width=200px/>")//out.print()会内容输出在网页面上

%>

表达式:计算并输出计算结果

<%=表达式 %>  在jsp的当前位置输出这个表达式的结果
name=<%=name %>   变量表达式后没有;
name=<%out.print(name);%>

<%=变量名/10+100 %>

07)表达式

脚本代码片段作用
Java语句<% 内容%>方法的范围:方法中可以写啥,这里就可以写啥
Java表达式<%= 内容 %>Systerm.out.println() 中可以写啥,这里就可以写啥
Java定义类成员<%! 内容%>类的范围,类中可以写啥,这里就可以写啥

08)转发

<%--转发--%>
    <%--<% request.getRequestDispatcher("/test04.jsp").forward(request,response); %>--%>

<%--使用动作标签进行转发--%>
<%--
    注意:
    1)如果不加参数:不能换行写,只能这么写:<jsp:forward page="/test04.jsp"></jsp:forward>
    2)如果加了参数,参数不能写任何注释
--%>
<%--设置request请求中文编码--%>
<%request.setCharacterEncoding("utf-8");%>

<jsp:forward page="/test04.jsp">
    <jsp:param name="username" value="郭德纲"></jsp:param>
</jsp:forward>

可通过转发功能简化打开登录界面的步骤

<%--通过jsp转发功能简化访问的步骤--%>
  <jsp:forward page="pages/main.jsp"></jsp:forward>

Servlet

Servlet的Web.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
		  http://java.sun.com/xml/ns/javaee/web-app_4_0.xsd"
           version="4.0">
<servlet>
    <!--servlet的名字-->
    <servlet-name>ServletDemo</servlet-name>

    <!--servlet的全路径-->
    <servlet-class>cn.kgc.ServletDemo</servlet-class>
    <!--设置初始化参数-->
    <init-param>
        <param-name>code</param-name>
        <param-value>utf-8</param-value>
    </init-param>
    <!--servlet加载的优先级,配置之后,当tomcat一启动,就创建servlet对象==不过这个一般情况不配置!!!-->
    <!--里面的数字表示如果有多个配置存在的话,执行的顺序,1代表第一个,2代表第二个-->
    <load-on-startup>1</load-on-startup>


</servlet>


    <!--映射配置-->
    <servlet-mapping>
        <!--servlet的名字,必须要跟servlet-name标签中的完全一致!-->
        <servlet-name>ServletDemo</servlet-name>

        <!--url的虚拟路径-->
        <url-pattern>/ServletDemo</url-pattern>
    </servlet-mapping>
</web-app>

01)实现Servlet的方式

1) 实现javax.servlet.Servlet接口

2) 继承javax.servlet.GenericServlet类

3) 继承javax.servlet.http.HttpServlet类 = 常用的方式

1)实现Servlet接口

Servlet接口相关类型:

接口名作用
ServletRequest表示请求对象,请求对象里面保存的就是浏览器发送的请求数据
ServletResponse表示响应对象,响应对象里面保存的就是服务器返回给浏览器的响应数据
ServletConfig它表示Servlet配置对象,它对应Servlet的配置信息
ServletConfig对象一般用来获取项目配置的初始化信息
2)继承GenericServlet类

(范围太大,需要强转,比较麻烦)

3)继承HttpServlet类==常用

继承自GenericServlet类

ctrl+o重写doGet和doPost方法

01)实现添加的代码
package cn.kgc.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 MyServlervlet02 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        UserDaoImpl userDao = new UserDaoImpl();
        //处理中文乱码问题
        req.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");
        //接收请求
        String name = req.getParameter("name");
        String pwd = req.getParameter("pwd");
        String pwd2 = req.getParameter("pwd2");
        //处理请求
        if (pwd.equals(pwd2)){
            if (userDao.login(name,pwd) == null) {
                User user = new User(name,pwd);
                String insert = userDao.insert(user);
                //返回响应
                resp.getWriter().write("<script>alert('成功添加"+insert+"条记录'); window.location.href='amids.jsp'; </script>");

            }else {
                resp.getWriter().write("<script>alert('您注册的账号已存在,请更换用户名!');window.location.href='amids.jsp'; </script>");
            }
        }else {
            resp.getWriter().write("<script>alert('两次输入密码不一致!'); window.location.href='amids.jsp'; </script>");
        }
    }   
    }
	//在一个方法里调用另外一个方法可以让所有都在doPost或者doGet内执行
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}
02)实现查找的代码
//可代替xml配置   @WebServlet(urlPatterns = "/SelectServlet")
@WebServlet(urlPatterns = "/SelectServlet")
public class SelectServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        UserDaoImpl userDao = new UserDaoImpl();
        //实现Dao层封装的查找方法
        List<User> list = userDao.findAll();
        //request.getSession();得到一个会话对象:session
        HttpSession session = request.getSession();
        //通过list可自定义,通过此方法可传递对象到jsp中
        session.setAttribute("list",list);
		//完成响应,作出跳转
        response.sendRedirect("jsp/listUser.jsp");
    }
}
03)JSP中的代码
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h2>用户浏览信息</h2>
<%
    //从session中取出list属性
    List<User>list = (List<User>)session.getAttribute("list");
    //使用java中的命名list取出对象的值
    Object list1 = session.getAttribute("list");
    //得到的是一个Object类型,所以需要强制转换
    List<User>list2 = (List<User>)list1;
%>
<table width="500px" border="1">
    <tr>
        <th>用户</th><th>密码</th>
    </tr>
    <%
        if (list != null){
        for (User user : list) {
    %>
    <tr>
        <td><%=user.getU_name()%></td>
        <td><%=user.getU_pwd()%></td>
    </tr>
        <%}}%>
</table>
</body>
</html>
04)登录界面代码
<html>
<head>
    <title>用户登录</title>
</head>
<body>
    <div>
        //通过java配置   @WebServlet(urlPatterns = "/SelectServlet")之后   		     //action="SelectServlet"可以直接写类名调用
        <form method="post" action="SelectServlet">
            <input type="submit" value="显示所有用户数据"/>
        </form>
    </div>
    <div>
        <h1>验证用户登录</h1>
        <form method="post" action="jsp/yanzheng.jsp">
            账号:<input type="text" name="amin"/> <br/>
            密码:<input type="password" name="pwd"/><br/>
            <input type="submit" value="提交"/>
        </form>
    </div>
    <div>
        <h1>添加用户数据</h1>
        <form method="post" action="HttpServletUser">
            用户名:<input type="text" name="name"><br/>
            密码: <input type="text" name="pwd"><br/>
            确密码:<input type="text" name="pwd2"><br/>
            <input type="submit" value="提交"/>
        </form>
    </div>
    <div>
        <h1>删除用户数据</h1>
        
        <form method="post" action="DeleteServlet">
            删除的用户名:<input type="text" name="name"/><br/>
            请输入用户密码:<input type="text" name="pwd"/><br/>
            <input type="submit" value="确认"/>
        </form>
    </div>
    <div>
        //还没实现
        <h1>修改用户数据</h1>
        <form method="post" action="DeleteServlet">
            删除的用户名:<input type="text" name="name"/><br/>
            请输入用户密码:<input type="text" name="pwd"/><br/>
            <input type="submit" value="确认"/>
        </form>
    </div>
</body>
</html>

02)Response对象==响应体

1)Response对象概述(重点)

负责对浏览器进行响应的对象

ServletResponse接口,HttpServletResponse接口继承自ServletResponse 使用的是子接口 HttpServletResponse,此接口对象由Tomcat引擎提供 可以实现对客户端的响应, 响应行,响应头,响应体

2)Response设置响应行(重点)

设置状态码: setStatus(int 状态码)

状态码状态
404找不到资源=路径错误
500程序错误
302重定向
200正确成功响应

一般都是浏览器自动设置好的,浏览器会自动检测,设置合适的状态码

3)Response设置响应头(重点)
返回值方法作用
voidsetHeader(String key,String value)HTTP协议的响应头,数据格式键值对 k:v 包含指导性信息,指导客户端
4)Response设置响应体(重点)

HTTP的响应体,就是页面的正文部分

1)getWriter() :返回值是打印流
resp.getWriter().write("网页输出内容");
2)响应中的中文乱码问题

1、 post请求和响应中文乱码

request.setCharacterEncoding("utf-8"); 
response.setContentType("text/html;charset=utf-8");

2、get请求和响应中文乱码怎么解决==9版本解决方式

在server.xml中加上URIEncoding=“utf-8”

<Connector port="8089" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" URIEncoding="utf-8"/>

03)Request对象==接收请求

1)Request对象获取请求行
返回值类型方法作用
StringgetMethod()获取提交的方式 (GET,POST)
StringgetContextPath()获取WEB应用名称(重点)
StringgetRemoteAddr()返回当前客户端的IP地址
2)Request对象获取请求头(了解)

请求头数据格式键值对, k:v 指导性信息,指导服务器

返回值类型方法作用
StringgetHeader(String key)根据请求头名称,返回请求头的值
EnumerationgetHeaderNames()得到所有的键(请求头),并存在一个Enumeration枚举类型里。
3)Request获取请求参数(重点)

01)数据通过request的请求参数传递到服务器。

返回值类型方法作用
StringgetParameter(“表单中的name值”)获取指定的请求参数
String[]getParameterValues(“表单中的name值”)获取参数中的一键多值
Map<String,String[]>getParameterMap()获取提交的所有参数

02)beanUtils的使用:

//populate:可以直接把map中的数据赋值给实体类的属性!!!
//注意:表单中的name属性的名字必须要跟实体中的属性的名字完全一致!!!
BeanUtils.populate(实体对象,map集合);

03)对象里包含时间日期类型解决方法

//populate:可以直接把map中的数据赋值给实体类的属性!!!
        //注意:表单中的name属性的名字必须要跟实体中的属性的名字完全一致!!!
        UserDemo userdemo = new UserDemo();
        try {

            //需要把String类型的日期转换成Date类型的日期
            //DateConverter:日期转换器
            DateConverter dateConverter = new DateConverter();
            //设置转换格式
            dateConverter.setPatterns(new String[]{"yyyy-MM-dd","yyyy-MM-dd HH:mm:ss"});
            //实现注册转换
            ConvertUtils.register(dateConverter, Date.class);

            BeanUtils.populate(userdemo,parameterMap);

            //爱好单独处理
            userdemo.setChk(Arrays.toString(chks));

        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

        System.out.println(userdemo);
4)Request域对象(重点)
返回值类型方法作用
voidsetArratibute(String key, Object value)域对象存储数据:
ObjectgetAttribute(String key)取出域对象数据
voidremoveAttribute(String key)移除域对象数据

04)重定向(重点)

作用:

1、通过一个servlet访问到另外一个servlet

2、通过一个servlet访问到一个js页面

概念:两次访问和请求:

1、页面先发送请求给A服务器,A服务器给页面响应另外一个服务器B的地址。

2、页面重新访问B服务器完成响应;

//两步合成一步:
//注意:如果有项目名,那么在url中必须写项目名;
response.sendRedirect("文件路径");

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gYQGA19w-1603283389762)(java封装源码.assets/1599611771595.png)]

05)转发(重点)

转发的实现步骤:

1) request对象方法获取转发器 RequestDispatcher getRequestDispatcher(“转发地址”)返回值就是转发器

request.getRequestDispatcher("jsp/UpleUser.jsp").forward(request,response);

2) 使用转发器对象的方法 forward

3) 转发的时候:注意:不需要再写项目名!!

06)转发和重定向区别

1)转发和重定向的区别?

1、 转发是1次请求和响应;重定向2次请求和响应。

2、 转发的URL地址不变;重定向URL地址会发生变化。

3、 转发是发生在服务器的内部;重定向返回了客户端

4、 转发的请求里面的数据一直有效;重定向的请求不会携带数据的。

5、 转发不需要再写应用的名字;重定向是需要写应用的名字。

2)什么时候用转发,什么时候用重定向?

​ 如果你想得到request请求的数据,必须用转发; 如果我们不需要request请求的数据,用重定向。

07)作用域

概念:实现数据通过共享来实现数据的传递

作用域对象范围调用方式
pageContext本页面jsp内置对象
request一个请求中共享数据,生命周期短内置对象,可直接调用
session每用户 购物车 session.invalidate(); 同一个浏览器不同窗口打开文件都可以共享,关闭浏览器销毁;需创建
application每应用程序,tomcat服务器为每一个应用创建一个application对象,这个对象可以供所有用户访问jsp内置对象
//存数据
request.setAttribute(key,value)
//取数据    
request.getAttribute(key,value)   
    
//示例  得到一个会话对象
        HttpSession session = request.getSession();
        session.setAttribute("list",list);
<%
//application对象
//点一次页面num++;
   Object obj=  application.getAttribute("num");
   Integer num=null;
     if(obj==null){
       application.setAttribute("num",new Integer(1));
       num=1;
     }else{
       num=(Integer)obj;
       num++;
       application.setAttribute("num",num);
     }
    %>
    num=2
实现修改功能

1.获取当前点击用户的一个id属性值

2.通过id去数据库查找该行的所有属性值,返回一个对象集合,通过session作用域对象存入

3.从session中取出属性,显示在页面上,在提交给修改的类方法

4.返回修改结果

<html>
<head>
    <title>Title</title>
</head>
<body>
    <h2>用户浏览信息</h2>
<%
    //从session中取出list属性
    List<User> list = (List<User>)session.getAttribute("list");
%>
<table width="500px" border="1">
    <tr>
        <th>用户</th><th>密码</th>
    </tr>
    <%
        if (list != null){
        for (User user : list) {
    %>
    <tr>
        <%--<td><a href="/UpleServlet?u_name=<%=user.getU_name()%>"><%=user.getU_name()%></a></td>--%>
        <td><%=user.getU_name()%></td>
        <td><%=user.getU_pwd()%></td>
    //获取当前属性的name属性值
        <td><a href="../../UpleServlet?u_name=<%=user.getU_name()%>">修改</a></td>
    </tr>
        <%}}%>
</table>
</body>
</html>
@WebServlet(urlPatterns = "/UpleServlet")
public class UpleServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        String name = request.getParameter("u_name");

        UserDaoImpl userDao = new UserDaoImpl();
        User user = userDao.findById(new User(name));

        request.setAttribute("user",user);
        System.out.println(user);
        request.getRequestDispatcher("jsp/UpleUser.jsp").forward(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}
<html>
<head>
    <title>修改</title>
</head>
<body>
<%
    User user = (User) request.getAttribute("user");
%>
<div>
    <h1>修改用户数据</h1>
    <form method="post" action="upServlet">
        更改用户名:<input type="text" name="amid" value="<%=user.getU_name()%>"/><br/>
        更改用户密码:<input type="text" name="pwd" value="<%=user.getU_pwd()%>"/><br/>
        <input type="submit" value="确认"/>
    </form>
</div>
</body>
</html>
@WebServlet(urlPatterns = "/upServlet")
public class upServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");

        String amid = request.getParameter("amid");
        String pwd = request.getParameter("pwd");

        UserDaoImpl userDao = new UserDaoImpl();
        String user = userDao.update(new User(amid, pwd));


        response.getWriter().write("<script>alert('"+user+"');window.location.href='amids.jsp'; </script>");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}

08)Servlet封装

1、Servlet封装
@WebServlet(urlPatterns = "/UserServlet")
        public class UserServlet extends HttpServlet {
            protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                String method = request.getParameter("method");

                if (method.equals("doList")){
                    this.dofindAll(request,response);
                }else if (method.equals("insert")){
                    this.doInsert(request,response);
                }else if (method.equals("doEnter")){
                    this.doEnter(request,response);
                }else if (method.equals("doDelete")){
                    this.doDelete(request,response);
                }else if (method.equals("doUpdate")){
                    this.doUpdate(request,response);
                }else if (method.equals("doUpdateUser")){
                    this.doUpdateUser(request,response);
                }else {
                    this.doList(request,response);
                }
            }

            protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                doPost(request,response);
            }

            //验证登录
            protected void doEnter(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                UserDaoImpl userDao = new UserDaoImpl();
                //处理中文乱码问题
                req.setCharacterEncoding("utf-8");
                resp.setContentType("text/html;charset=utf-8");
                //接收请求
                String name = req.getParameter("amin");
                String pwd = req.getParameter("pwd");
                String mm = req.getParameter("mm");
                User login = userDao.login(name, pwd);

        Cookie cookiename = null;
        Cookie cookiepwd = null;

        if (login != null){
            /*if (mm.equals("1")){
                cookiename = new Cookie("name",name);
                cookiepwd = new Cookie("pwd",pwd);
                cookiename.setMaxAge(60*60*60);
                cookiepwd.setMaxAge(60*60*60);
                System.out.println(cookiename.getName()+"---"+cookiepwd);
            }*/

            HttpSession session = req.getSession();
            session.setAttribute("amin",name);
            doList(req, resp);
            /*resp.sendRedirect("jsp/listUser.jsp");
            req.getRequestDispatcher("jsp/listUser.jsp").forward(req,resp);*/
        }else {
            resp.getWriter().write("<script>alert('账号或密码不正确!');" +
                    "window.location.href='Enter.jsp'; </script>");
        }

    }
    //用户注册
    protected void doInsert(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        UserDaoImpl userDao = new UserDaoImpl();
        //处理中文乱码问题
        req.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");
        //接收请求
        String amin = req.getParameter("amin");
        System.out.println(amin);
        String pwd = req.getParameter("pwd");
        String pwd2 = req.getParameter("pwd2");
        //处理请求
        User byId = userDao.findById(new User(amin));
        System.out.println(byId);
        if (byId == null){
           if (pwd.equals(pwd2)){
               userDao.insert(new User(amin,pwd));
               resp.getWriter().write("<script>alert('注册成功!'); " +
                       "window.location.href='Enter.jsp'; </script>");
           }else {
               resp.getWriter().write("<script>alert('两次输入密码不一致!'); " +
                       "window.location.href='Enter.jsp'; </script>");
           }
        }else {
            resp.getWriter().write("<script>alert('您注册的账号已存在,请更换用户名!');" +
                    "window.location.href='UserLogin.jsp'; </script>");
        }


    }
    //用户浏览
    protected void doList(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        List<User> list = null;
          String amd = request.getParameter("amd");
          String pw = request.getParameter("pw");
//        List<User> list= null;

        UserDao userDao=new UserDaoImpl();
        //List<User> list = userDao.findAllwhere(new User(amd, pw));
        if (amd==null && pw ==null){
            list = userDao.findAll();
        }else {
            list = userDao.findAllwhere(new User(amd,pw));
        }

        //得到一个会话对象
        HttpSession session = request.getSession();
        session.setAttribute("list",list);


        request.getRequestDispatcher("jsp/listUser2.jsp").forward(request,response);


    }
    //删除用户
    protected void doDelete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        UserDaoImpl userDao = new UserDaoImpl();

        //获取请求
        String name = request.getParameter("u_name");
        System.out.println(name);

        User byId = userDao.findById(new User(name));
        System.out.println(byId);

            userDao.delete(new User(name));
            System.out.println("调用删除的方法");
            //response.sendRedirect("jsp/listUser.jsp");
            doList(request,response);
           /* request.getRequestDispatcher("jsp/listUser.jsp").forward(request,response);*/

    }
    //修改用户
    protected void doUpdate(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        String amid = request.getParameter("amid");
        String pwd = request.getParameter("pwd");

        UserDaoImpl userDao = new UserDaoImpl();
        userDao.update(new User(amid,pwd));
        response.getWriter().write("<script>alert('数据已更新!');" +
                "window.location.href='Enter.jsp'; </script>");
        doList(request,response);


    }
    //修改用户传值
    protected void doUpdateUser(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        String amid = request.getParameter("u_name");


        UserDaoImpl userDao = new UserDaoImpl();
        User user = userDao.findById(new User(amid));
        System.out.println("这组数据是:"+user);
        request.setAttribute("user",user);
        request.getRequestDispatcher("jsp/UpleUser.jsp").forward(request,response);
    }

}

2、传值表达式
servlet获取name属性值的同时还传递一个当前的对象属性值过去
语法:url地址?提交的name名=提交的name值&传递的当前需要获取的属性名=属性值
<a href="../../UserServlet?method=doUpdateUser&u_name=<%=user.getU_name()%>">修改</a>
3、jsp的代码
<h1>欢迎登陆User管理系统</h1>
    <form method="POST" action="UserServlet">
        <!--method传递的name名,doEnter对应的name值,通过这个值到servlet判断当前执行的操作
			hidden通过隐藏域的形式传递	-->
        <input type="hidden" name="method" value="doEnter">
        用户名:<input type="text" name="amin"><br/>
        密码:&nbsp;&nbsp;&nbsp;<input type="text" name="pwd"><br/><br/>
        <input type="submit" value="登录">
        <input type="reset">
        <input type="radio" value="1" name="mm">记住我
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
        <a href="Userlogin.jsp">立即注册</a>
    </form>

09)模糊查询

UserDaoImpl

 @Override
    public List<User> findAll(User user) {
        List<User>  list=null;
        //1.sql语句
        String sql="select * from tbl_user  where 1=1";
        if(user.getName()!=null){//表示用户提交了一个name的查询条件
            sql=sql+ " and name like '%"+user.getName()+"%'";
        }
       if(user.getAge()!=null){
           sql=sql+" and age="+user.getAge();
       }
       

        try {
            list=runner.query(sql,new BeanListHandler<User>(User.class));
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return list;
    }

查询

protected void doList(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        List<User> list = null;
          String amd = request.getParameter("amd");
          String pw = request.getParameter("pw");
//        List<User> list= null;

        UserDao userDao=new UserDaoImpl();
        //List<User> list = userDao.findAllwhere(new User(amd, pw));
    //根据查询条件创建查询对象
        if (amd==null && pw ==null){
            list = userDao.findAll();
        }else {
            list = userDao.findAllwhere(new User(amd,pw));
        }
        //得到一个会话对象
        HttpSession session = request.getSession();
        session.setAttribute("list",list);
        request.getRequestDispatcher("jsp/listUser2.jsp").forward(request,response);
    }

常见问题

1.检查数据库是否开启状态

2.地址问题,注意引用路径

3.jsp表达式出错也可能导致页面不显示

Cookie技术

概念

保存客户端浏览器中一组小文件

Cookie 是存储在客户端计算机上的文本文件,并保留了各种跟踪信息。Java Servlet 显然支持 HTTP Cookie。

识别返回用户包括三个步骤:

服务器脚本向浏览器发送一组 Cookie。例如:姓名、年龄或识别号码等。
浏览器将这些信息存储在本地计算机上,以备将来使用。
当下一次浏览器向 Web 服务器发送任何请求时,浏览器会把这些 Cookie 信息发送到服务器,服务器将使用这些信息来识别用户。

案例:将用户提交的name与pwd保存到 cookie中

response.addCookie(cookie),将cookie的内容写以浏览器中

发请求,request对象会自动带上cookie的值

request.getCookies(); 得到这个一个服务器在这个浏览器上保存所有 cookie

写cookie

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

         String rem= req.getParameter("rem");

        //1.取数据,从request对象中取
        String name=req.getParameter("name");
        String pwd=req.getParameter("pwd");
        System.out.println(name+","+pwd);
        Cookie cookieName = new Cookie("name", name);
        Cookie cookiePwd = new Cookie("pwd", pwd);
        if("1".equals(rem)) {
            //构造一个cookie对象,这个对象的保存的key是name  值是admin
            cookieName.setMaxAge(60 * 60 * 24);
             cookiePwd.setMaxAge(60 * 60 * 24);
            //将cooke写到客户端

        }else{
            cookieName.setMaxAge(0);
            cookiePwd.setMaxAge(0);
        }
        resp.addCookie(cookieName);
        resp.addCookie(cookiePwd);
        resp.sendRedirect("index.jsp");

    }

读取cookie

  <%
//取cookie
      Cookie[] cookies=request.getCookies();
      for(Cookie cookie:cookies){
          out.print(cookie.getName()+":"+cookie.getValue());
      }

   %>


<%
    String name="";
    String pwd="";
    Cookie[] cookies=request.getCookies();
    for(Cookie cookie:cookies){
        if("name".equals(cookie.getName()))
            name=cookie.getValue();
        if("pwd".equals(cookie.getName()))
            pwd=cookie.getValue();
    }
%>
<form action="UserServlet" method="get">
    <input type="hidden" name="method" value="login"/>
    用户名:<input type="text" name="name" value="<%=name %>"/><br/>
    密码:<input type="password" name="pwd"  value="<%=pwd %>"/><br/>
<input type="checkbox" name="rem" value="1"/>记住我<br/>
    <input type="submit" value="提交"/>

</form>

MVC模式

概念

mvc模式 是一种 模型

​ 一种编程经验,解决一类问题的方法的总结;

(类似的23种设计模式)

​ mvc是为web程序结构定义一种模式 springmvc struts1.x struts2.x 都实现了mvc模式

M:Model 模型 dao层数据访问对象 UserDaoImpl

V: View 视图 提供用户操作的界面,提供数据输入与输出 view提供输入,输入的数据提交给Controller来处理

​ 视图要为用户展示数据,也由Controller来提供

C:Controller 控制器 接受用户浏览器的请求,为请求产生响应 Servlet mode2 mode1

EL表达式&jstl

EL表达式

EL表达式是jsp2.0中的一个标准,它的主作用取作用域对象中的值 在jsp页面上输入或计算后再输出 4个

request sessjon applicaiton

01)语法
如果jsp页面中直接使用${属性名}方式 如${name}
相于先在pageContext这个作用域对象中找它的name属性值,找到就输出,没有找开,找request session application
02)获取文件的绝对路径
获取文件的根路径
${pageContext.request.contextPath}
示例:
<img src="${pageContext.request.contextPath}/images/c2.jpg">

EL中有4跟作用域有关内置对象

pageScope requestScope sessionScope applicationScope

sessionName:${sessionScope.name}  指定输入指作用域对象中的属性值

调用 user对象的get方法

${user.name}${user.pwd}${user.addr}  调用 user对象的get方法
$(user.name) user.getName();  getAddr();同上,两个方法的效果一样
getName1  将get去   首字母小写name1

pageContext对象

${pageContext.request.contextPath}  通过El表达得到当前应用的根目录

作运算

Age=${user.age+10}
${a>b?1:2}

JSTL java标准标签库

在jsp页面通过标签形式来完成java代码的功能

​ jsp=html+java代码 html+jstl形式 EL集成使用

​ 导入jstl1.2.jar

c.tld文件中c标签的描述文件,c是jstl的核心标签库

01)引用jstl
在html标签上面引入
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
02)声明变量
定义一个变量,变量名是name   值为 admin   放到request作有域对象中
jstl写法
<c:set var="name" value="admin" scope="request"/>


jsp写法
<%
   request.setAttribute("name",admin)
%>


EL写法
Name=${reqeuestScope.name}
03)if判断
if的test是一个条件判断,test=“"写EL表达式  将判断的结果给到stat
<c:if test="${user==null}" var="stat"scope="request">
    user不存在!
</c:if>
<!--相当于else,直接取反-->
<c:if test="${!stat}" >
    user存在!
</c:if>
04)for循环
将list循环遍历 每一个值都赋值给obj
<c:forEach items="${list}" var="obj">
    
</c:forEach>
for(User user:list){}

CURD操作(含分页查询)

utils层

PageBean==分页查询属性
**
 * 封装分页的数据
 * */
public class PageBean {
    private int pageSize =  5;//定义每一页显示的行数
    private int totalPage;//总的页面数
    private int currPage;//当前页面号
    private int totalRows;//总行数
    private List<?>list;//用于封装当前页面的数据

    public int getPageSize() {
        return pageSize;
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    public int getTotalPage() {
        return totalPage;
    }

    public void setTotalPage(int totalPage) {
        this.totalPage = totalPage;
    }

    public int getCurrPage() {
        return currPage;
    }
    //对要显示的当前页面做判断
    public void setCurrPage(int currPage) {
        if (currPage<1){
            this.currPage=1;
        }else if (currPage>this.totalPage){
            this.currPage=this.totalPage;
        }else {
            this.currPage = currPage;
        }
    }

    public int getTotalRows() {
        return totalRows;
    }
    //设置总行数,根据总行数计算出总页面数
    public void setTotalRows(int totalRows) {
        this.totalRows = totalRows;
        if (totalRows % this.pageSize == 0){
            this.totalPage = totalRows/pageSize;
        }else {
            this.totalPage = totalRows/pageSize+1;
        }
    }

    public List<?> getList() {
        return list;
    }

    public void setList(List<?> list) {
        this.list = list;
    }

    @Override
    public String toString() {
        return "PageBean{" +
                "pageSize=" + pageSize +
                ", totalPage=" + totalPage +
                ", currPage=" + currPage +
                ", totalRows=" + totalRows +
                ", list=" + list +
                '}';
    }
}

GoodLike==封装的查询条件类

/**
 * 封装的条件查询
 */
public class GoodLike {
    private Integer typeId;//商品品种
    private Integer priceBetween ;//商品价格最小范围
    private Integer priceAnd ;//商品价格最大范围


    public GoodLike() {
    }

    public GoodLike(Integer priceBetween, Integer priceAnd) {
        this.priceBetween = priceBetween;
        this.priceAnd = priceAnd;
    }

    public GoodLike(Integer typeId, Integer priceBetween, Integer priceAnd) {
        this.typeId = typeId;
        this.priceBetween = priceBetween;
        this.priceAnd = priceAnd;
    }

    public Integer getTypeId() {
        return typeId;
    }

    public void setTypeId(Integer typeId) {
        this.typeId = typeId;
    }

    public Integer getPriceBetween() {
        return priceBetween;
    }

    public void setPriceBetween(Integer priceBetween) {
        this.priceBetween = priceBetween;
    }

    public Integer getPriceAnd() {
        return priceAnd;
    }

    public void setPriceAnd(Integer priceAnd) {
        this.priceAnd = priceAnd;
    }

    @Override
    public String toString() {
        return "GoodLike{" +
                "typeId=" + typeId +
                ", priceBetween=" + priceBetween +
                ", priceAnd=" + priceAnd +
                '}';
    }
}

Empty==判断是否为空
import java.util.Collection;
import java.util.Map;

/**
 * <p>判断是否是空的 工具类</p>
 * @author zzshang
 * @version v1.0
 * @since 2015/5/5
 */
public class EmptyUtils {
    //判空
    public static boolean isEmpty(Object obj){
        if (obj == null)
            return true;
        if (obj instanceof CharSequence)
            return ((CharSequence) obj).length() == 0;
        if (obj instanceof Collection)
            return ((Collection) obj).isEmpty();
        if (obj instanceof Map)
            return ((Map) obj).isEmpty();
        if (obj instanceof Object[]) {
            Object[] object = (Object[]) obj;
            if (object.length == 0) {
                return true;
            }
            boolean empty = true;
            for (int i = 0; i < object.length; i++) {
                if (!isEmpty(object[i])) {
                    empty = false;
                    break;
                }
            }
            return empty;
        }
        return false;
    }
    public static boolean isNotEmpty(Object obj){
        return !isEmpty(obj);
    }



    private boolean validPropertyEmpty(Object ...args) {
        for (int i = 0; i < args.length; i++) {
            if(EmptyUtils.isEmpty(args[i])){
                return true;
            }
        }
        return false;
    }
}

StringUtils==生成随机数

用于文件上传!

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;
import java.util.Random;
import java.util.UUID;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;



public class StringUtils {
    private static String[] binaryArray =   
        {"0000","0001","0010","0011",  
        "0100","0101","0110","0111",  
        "1000","1001","1010","1011",  
        "1100","1101","1110","1111"};  
//    private static String[] chineseDigits = new String[] { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"};
    public static String[] chineseDigits = new String[] { "零", "一", "二", "三", "四", "五", "六", "七", "八", "九"};
	
    private static final char[] charBytes = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9','a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
		'i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
    
    private static final char[] numberBytes = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
    
    /**
     * 生成指定位数的随机数子.
     * @param number
     * @return
     */
    public static String randomNumbers(int number) {
    	int count = 0; //生成的密码的长度
    	int i; //生成的随机数
    	final int maxNum = numberBytes.length;
    	StringBuffer randomStr = new StringBuffer("");
        Random r = new Random();
        while(count < number){
        	 //生成随机数,取绝对值,防止生成负数,
	         i = Math.abs(r.nextInt(maxNum)); //生成的数最大为36-1
	         if (i >= 0 && i < numberBytes.length) {
	        	 randomStr.append(numberBytes[i]);
	          count ++;
	         }
        }
        return randomStr.toString();
    }
    
    
    
    public static String randomStrByNumber(int number) {
    	int count = 0; //生成的密码的长度
    	int i; //生成的随机数
    	final int maxNum = charBytes.length;
    	StringBuffer randomStr = new StringBuffer("");
        Random r = new Random();
        while(count < number){
        	 //生成随机数,取绝对值,防止生成负数,
	         i = Math.abs(r.nextInt(maxNum)); //生成的数最大为36-1
	         if (i >= 0 && i < charBytes.length) {
	        	 randomStr.append(charBytes[i]);
	          count ++;
	         }
        }
        return randomStr.toString();
    }
    
    
    public static String randomUUID() {
		UUID uuid = UUID.randomUUID();
		return uuid.toString().replace("-", "").toUpperCase();
	}
	public static String digitsTochinese(int i){
		//大于10的需要重写
		return chineseDigits[i];
	}
	public static String toAllUpperCase(String uuid) {
		StringBuffer buffer = new StringBuffer();

		for (int i = 0; i < uuid.length(); i++) {
			char c = uuid.charAt(i);
			if (Character.isLowerCase(c)) {
				buffer.append(Character.toUpperCase(c));
			} else {
				buffer.append(c);
			}
		}
		return buffer.toString();
	}
	

	
	// 十六进制字符串转byte数组
		public static byte[] hexStringToBytes(String hexString) {
			if (hexString == null || hexString.equals("")) {
				return null;
			}
			hexString = hexString.toUpperCase();
			int length = hexString.length() / 2;
			char[] hexChars = hexString.toCharArray();
			byte[] d = new byte[length];
			for (int i = 0; i < length; i++) {
				int pos = i * 2;
				d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
			}
			return d;
		}

		private static byte charToByte(char c) {
			return (byte) "0123456789ABCDEF".indexOf(c);
		}

		// 数组转字符串、以空格间隔
		public static String bytesToHexString(byte[] src) {
			StringBuilder stringBuilder = new StringBuilder("");
			if (src == null || src.length <= 0) {
				return null;
			}
			for (int i = 0; i < src.length; i++) {
				int v = src[i] & 0xFF;
				String hv = Integer.toHexString(v);
				if (hv.length() < 2) {
					stringBuilder.append(0);
				}
				if (i == src.length - 1) {
					stringBuilder.append(hv);
				} else {
					stringBuilder.append(hv);
				}
			}
			return stringBuilder.toString();
		}
		
		
		public static String bytesToHexStringNoAppendBit(byte[] src) {
			StringBuilder stringBuilder = new StringBuilder("");
			if (src == null || src.length <= 0) {
				return null;
			}
			for (int i = 0; i < src.length; i++) {
				int v = src[i] & 0xFF;
				String hv = Integer.toHexString(v);
				/*if (hv.length() < 2) {
					stringBuilder.append(0);
				}*/
				if (i == src.length - 1) {
					stringBuilder.append(hv);
				} else {
					stringBuilder.append(hv);
				}
			}
			return stringBuilder.toString();
		}
		
		
		public static String bytesToString(byte[] src, String split) {
			StringBuilder stringBuilder = new StringBuilder("");
			if (src == null || src.length <= 0) {
				return null;
			}
			for (int i = 0; i < src.length; i++) {
				int v = src[i] & 0xFF;
				String hv = String.valueOf(v);
				if (i == src.length - 1) {
					stringBuilder.append(hv);
				} else {
					stringBuilder.append(hv + split);
				}
			}
			return stringBuilder.toString();
		}
		

		public static String generateHexString(int paramInt) {
			StringBuffer localStringBuffer = new StringBuffer();
			Random localRandom = new Random();
			int i = 16;
			for (int j = 0; j < paramInt; j++) {
				if (j % 2 == 0) {
					localStringBuffer.append("0123456789ABCDEF".charAt(localRandom
							.nextInt(i)));
				} else {
					localStringBuffer.append("0123456789ABCDEF".charAt(localRandom
							.nextInt(i)) + " ");
				}
			}
			return localStringBuffer.toString();
		}

		public static byte[] decodeTripleDES(byte[] data, byte[] key)
				throws NoSuchAlgorithmException, NoSuchPaddingException,
				InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
			byte[] keys;
			if (key.length == 16) {
				keys = new byte[24];
				System.arraycopy(key, 0, keys, 0, 16);
				System.arraycopy(key, 0, keys, 16, 8);
			} else {
				keys = key;
			}

			Cipher cipher = Cipher.getInstance("DESede/ECB/NoPadding");
			SecretKey secretKey = new SecretKeySpec(keys, "DESede");
			cipher.init(Cipher.DECRYPT_MODE, secretKey);
			return cipher.doFinal(data);
		}

		public static boolean equals(byte[] b1, byte[] b2) {
			if (b1.length != b2.length) {
				return false;
			}
			for (int i = 0; i < b1.length; i++) {
				if (b1[i] != b2[i]) {
					return false;
				}
			}
			return true;
		}
	/** 
     *  
     * @return 转换为二进制字符串
     */  
    public static String bytes2BinaryStr(byte[] bArray){  
        String outStr = "";  
        int pos = 0;  
        for(byte b:bArray){  
            //高四位  
            pos = (b&0xF0)>>4;  
            outStr+=binaryArray[pos];  
            //低四位  
            pos=b&0x0F;  
            outStr+=binaryArray[pos];  
        }  
        return outStr;  
    }
    /**将二进制转换成16进制
    * @param buf
    * @return
    */
    public static String binaryToHexString(byte[] bytes) {
   		StringBuffer sb = new StringBuffer();
   		for (int i = 0; i < bytes.length; i++) {
   			String hex = Integer.toHexString(bytes[i] & 0xFF);
    	 	if (hex.length() == 1) {
    	 		hex = '0' + hex;
    	 	}
    	 	sb.append(hex.toUpperCase());
   		}
   		return sb.toString();
    }
    /**将16进制转换为二进制
    * @param hexStr
    * @return
    */
	public static byte[] hexStringToBinary(String hexStr) {
		if (hexStr.length() < 1)
			return null;
		byte[] result = new byte[hexStr.length()/2];
		for (int i = 0;i< hexStr.length()/2; i++) {
			int high = Integer.parseInt(hexStr.substring(i*2, i*2+1), 16);
			int low = Integer.parseInt(hexStr.substring(i*2+1, i*2+2), 16);
			result[i] = (byte) (high * 16 + low);
		}
		return result;
	}
	
	//十六进制转为字符
	public static String hexStringToString(String s) {
		byte[] baKeyword = new byte[s.length() / 2];
		for (int i = 0; i < baKeyword.length; i++) {
			try {
				baKeyword[i] = (byte) (0xff & Integer.parseInt(
						s.substring(i * 2, i * 2 + 2), 16));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		try {
			s = new String(baKeyword, "utf-8");// UTF-16le:Not
		} catch (Exception e1) {
			e1.printStackTrace();
		}
		return s;
	}

	/**
	 * 给某个日期加几天后的日期 eg:2013-06-28号+1天是 2013-06-29 ,+3天是2013-07-01
	 * @param date 日期
	 * @param dump 数字
	 * @return
	 */
	public static String getDateByAddSomeDay(Date date,int dump){
		Calendar ca=Calendar.getInstance();
        SimpleDateFormat sm = new SimpleDateFormat("yyyy-MM-dd");  //构造任意格式
        String today = sm.format(date);
        String[] timeArray= today.split("-");
        ca.set(Calendar.YEAR,Integer.parseInt(timeArray[0]));
        ca.set(Calendar.MONTH, Integer.parseInt(timeArray[1])-1);
        ca.set(Calendar.DAY_OF_MONTH,Integer.parseInt(timeArray[2]));
        ca.add(Calendar.DAY_OF_MONTH, dump);
        String someDay = sm.format(ca.getTime());
        return someDay;
	}
	
	/**
	 * 生成公钥
	 * @param pubkey
	 * @return
	 * add by yaoyuan
	 */
	public static String generatePublicKey(String pubkey) {
//		BASE64Encoder base64en = new BASE64Encoder();
//		String encode = base64en.encode(hexStringToBinary(pubkey));
//		encode = "-----BEGIN RSA PUBLIC KEY-----" + encode + "-----END RSA PUBLIC KEY-----";
//		if (encode.getBytes().length < 256) {
//			encode = org.apache.commons.lang.StringUtils.rightPad(encode, 256, "0");
//		}
//		return encode;
		return null;
	}
	
	/**
	 * 获取当前时间 精确到毫秒
	 */
	public static String getCurrentTime(){
		 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
		 String currentTime = sdf.format(new Date());
		 return currentTime;
	}
	/** 
     * @功能: BCD码转为10进制串(阿拉伯数据) 
     * @参数: BCD码 
     * @结果: 10进制串 
     */  
    public static String bcd2Str(byte[] bytes) {  
        StringBuffer temp = new StringBuffer(bytes.length * 2);  
        for (int i = 0; i < bytes.length; i++) {  
            temp.append((byte) ((bytes[i] & 0xf0) >>> 4));  
            temp.append((byte) (bytes[i] & 0x0f));  
        }  
        return temp.toString().substring(0, 1).equalsIgnoreCase("0") ? temp  
                .toString().substring(1) : temp.toString();  
    }  
  
    /** 
     * @功能: 10进制串转为BCD码 
     * @参数: 10进制串 
     * @结果: BCD码 
     */  
    public static byte[] str2Bcd(String asc) {  
        int len = asc.length();  
        int mod = len % 2;  
        if (mod != 0) {  
            asc = "0" + asc;  
            len = asc.length();  
        }  
        byte abt[] = new byte[len];  
        if (len >= 2) {  
            len = len / 2;  
        }  
        byte bbt[] = new byte[len];  
        abt = asc.getBytes();  
        int j, k;  
        for (int p = 0; p < asc.length() / 2; p++) {  
            if ((abt[2 * p] >= '0') && (abt[2 * p] <= '9')) {  
                j = abt[2 * p] - '0';  
            } else if ((abt[2 * p] >= 'a') && (abt[2 * p] <= 'z')) {  
                j = abt[2 * p] - 'a' + 0x0a;  
            } else {  
                j = abt[2 * p] - 'A' + 0x0a;  
            }  
            if ((abt[2 * p + 1] >= '0') && (abt[2 * p + 1] <= '9')) {  
                k = abt[2 * p + 1] - '0';  
            } else if ((abt[2 * p + 1] >= 'a') && (abt[2 * p + 1] <= 'z')) {  
                k = abt[2 * p + 1] - 'a' + 0x0a;  
            } else {  
                k = abt[2 * p + 1] - 'A' + 0x0a;  
            }  
            int a = (j << 4) + k;  
            byte b = (byte) a;  
            bbt[p] = b;  
        }  
        return bbt;  
    }
    /**
     * 去除字符串中的符合${}形式的子串.
     * @param
     * @return 去除${}的字符串
     */
    public static String escape$String(String input) {
        return input.replaceAll("\\$\\{[^}]*\\}", "");
    }

    public static String replace$String(String input, String newStr) {
        return input.replaceAll("\\$\\{[^}]*\\}", newStr);
    }

    public static String replace$SpecifyString(String input, String str,
            String newStr) {
    	if(input != null){
    		input = input.replaceAll("\\$\\{" + str + "\\}", newStr);
    	}
        return input;
    }
    
    public static String replace$String(Map<String, Object> map, String src) {
    	if (src != null && map != null) {
    		for (String key : map.keySet()) {
				String value = String.valueOf(map.get(key));
				src = replace$SpecifyString(src, key, value);
			}
    	}
    	return src;
    	
    }
	/**
	 * 生成验证码
	 * @return
	 */
	public static String createValidateCode(){
		String str = "0,1,2,3,4,5,6,7,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,8,9,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D";
		String str2[] = str.split(",");//将字符串以,分割
		String code="";
		for(int i=0;i<4;i++){
			int a=(int)(Math.random()*36);
			code=code+str2[a];
		}
		return code;
	}
	/**
	 * 根据身份证计算年龄
	 * @param idNumber
	 * @return
	 */
	public static int calculateAgeByIdNumber(String idNumber){
		int leh = idNumber.length();
		int years =0;
		if (leh == 18) {
			years=Integer.parseInt(idNumber.substring(6, 10));
		}else {
			years = Integer.parseInt("19" + idNumber.substring(6, 8));
		}
		Calendar a=Calendar.getInstance();
		return a.get(Calendar.YEAR)-years;
	}
	/**
	 * 根据身份证计算性别
	 * @param idNumber
	 * @return
	 */
	public static int calculateSexByIdNumber(String idNumber){
		int leh = idNumber.length();
		int se =0;
		if (leh == 18) {
			se=Integer.valueOf(idNumber.substring(16,17)) % 2;
		}
		return (se==1?1:2);
	}
	
	/**
	 * 查找数字在数组中得区间.
	 * @param sortedData 排序数组
	 * @param findValue
	 * @return
	 */
	public static int searchValueSectionInArr(Integer[] sortedData,int findValue) {
		int start = 0;
		int end = 0;
		for (int i = 0; i < sortedData.length; i++) {
			if (findValue >= sortedData[i]) {
				start = i;
			} else {
				end = i;
				break;
			}
		}
		return start;
	}
	
	/** 
     * 循环二分查找数组区间,返回第一次出现该值的位置 
     * @param sortedData    已排序的数组 
     * @param findValue     需要找的值 
     * @return 值在数组中的位置,从0开始。找不到返回-1 
     */  
    public static int binarySearch(Integer[] sortedData,int findValue)  {  
        int start=0;  
        int end=sortedData.length-1;  
          
        while(start<=end)  {  
            //中间位置  
            int middle=(start+end)>>1;    //相当于(start+end)/2
     //   System.out.println("middle==>>" + middle);
            //中值  
            int middleValue=sortedData[middle];  

             if(findValue < middleValue)  {
                //小于中值时在中值前面找  
                end = middle-1;
                //如果小于前边的值 和前 前边的值  则继续下一次查找
                if (end >= 0) {
                	int end_v =sortedData[end];
                    if (findValue >= end_v) {
                    	return end;
                    }
                } else {
                	return middle;
                }
            }  
            else   {  
                //大于中值在中值后面找  
                start=middle+1;
                if (start <= sortedData.length -1) {
                	int end_v = sortedData[start];
                    if (findValue < end_v) {
                    	return middle;
                    }
                } else {
                	return middle;
                }
            }  
        }  
        //找不到  
        return -1;  
    }  
	
	

    public static void main(String[] args) {
		/*Integer age=calculateAgeByIdNumber("133022198201242396");
		Integer sex=calculateSexByIdNumber("133022198201242396");
		System.out.println("age"+age+">>>>>>sex>>>>>>>>>"+sex);*/
		String oldFileName="c101.jpg";
		//取上传文件的扩展名
		String suff=oldFileName.substring(oldFileName.lastIndexOf("."));
		System.out.println(StringUtils.randomUUID()+suff);

	}
}
DataSourcePooled==连接池
import com.mchange.v2.c3p0.ComboPooledDataSource;

import javax.sql.DataSource;

public class DataSourcePooled {
    private static DataSource dataSource;

    public DataSourcePooled() {
    }

    static {
        //utils提供的连接线程池方法
        dataSource = new ComboPooledDataSource();
    }

    public static DataSource getDataSource(){
        return dataSource;
    }

    public static void main(String[] args) {
        System.out.println(dataSource);
    }
}

Dao层===模型

Dao的父类接口
package com.kgc.dao;

import java.io.Serializable;
import java.util.List;

/**
 * 定义一个Dao类型对象的规范 ,要求所有Dao对象要实现这个接口中的方法
 * @param <T>  T是一个参数化的数据类型
 */
public interface Dao<T> {
    //增加
    void insert(T t);
    //修改
    void update(T t);
    //删除
    void delete(Serializable id);
    //查询
    List<T> findAll();
    //通过id查询
    T findById(Serializable id);
}

Dao的子类接口
package com.kgc.dao;

import com.kgc.entity.Goods;
import com.kgc.utils.GoodLike;

import java.util.List;

public interface GoodsDao extends Dao<Goods> {
    /*不带查询条件的分页*/
    List<Goods>LikeGoodsAll(int currentPage, int pageSize);
    /*带查询条件的分页*/
    List<Goods>LikeGoodsAll(GoodLike goodLike, int currentPage, int pageSize);


    /*不带条件的记录数*/
    Long getRows();
    /*根据条件查询记录数*/
    int getRows(GoodLike goodLike);
package com.kgc.dao;

import com.kgc.entity.Goods;
import com.kgc.entity.GoodsType;

import java.util.List;

public interface GoodsTypeDao extends Dao<GoodsType> {
    /*把页面的类型换成名称*/
    List<Goods> GoodTypeAll();
}
Dao的实现类impl
package com.kgc.dao.impl;

import com.kgc.dao.GoodsDao;
import com.kgc.entity.Goods;
import com.kgc.utils.DataSourcePooled;
import com.kgc.utils.EmptyUtils;
import com.kgc.utils.GoodLike;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;


import java.io.Serializable;
import java.sql.SQLException;

import java.util.List;

public class GoodsDaoImpl implements GoodsDao {
    QueryRunner runner = new QueryRunner(DataSourcePooled.getDataSource());
    @Override
    public void insert(Goods goods) {
        String sql = "insert into goods values(null,?,?,?,?)";
        Object[]obj = new Object[]{goods.getName(),goods.getTypeId(),goods.getPrice(),goods.getCreateTime()};
        try {
            runner.update(sql,obj);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void update(Goods goods) {
        String sql = "update goods set name=?,typeId=?,price=?,createTime=? where id=?";
        Object[]obj = new Object[]{goods.getName(),goods.getTypeId(),goods.getPrice(),goods.getCreateTime(),goods.getId()};
        try {
            runner.update(sql,obj);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void delete(Serializable id) {
        String sql = "delete from goods where id=?";
        try {
            runner.update(sql,id);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    @Override
    public List<Goods> findAll() {
        String sql = "select * from goods";
        try {
            return runner.query(sql,new BeanListHandler<Goods>(Goods.class));
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public Goods findById(Serializable id) {
        String sql = "select id,name,typeId,price,createTime from goods  where id=?";
        try {
            return runner.query(sql,new BeanHandler<Goods>(Goods.class),id);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }


    @Override
    public List<Goods> LikeGoodsAll(int currentPage, int pageSize) {
        String sql = "select goods.*,goodstype.`name` as typename from goods,goodstype where goods.`typeId`=goodstype.`id`  limit ?,?";
        try {
            return runner.query(sql,new BeanListHandler<Goods>(Goods.class),(currentPage-1)*pageSize,pageSize);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public List<Goods> LikeGoodsAll(GoodLike goodLike, int currentPage, int pageSize) {
        System.out.println("传入的sql值是"+goodLike);
        String sql = "select goods.*,goodstype.`name` as typename from goods,goodstype where goods.`typeId`=goodstype.`id`";
        if (EmptyUtils.isNotEmpty(goodLike.getTypeId()) && goodLike.getTypeId() != -1){
            sql = sql+" and typeId="+goodLike.getTypeId();
        }
        if (EmptyUtils.isNotEmpty(goodLike.getPriceAnd()) &&
                EmptyUtils.isNotEmpty(goodLike.getPriceBetween())){
            sql = sql+"  and price between "+goodLike.getPriceBetween()+" and "+goodLike.getPriceAnd();
        }
        sql = sql+" limit ?,?";
        System.out.println("执行分页查询的sql语句"+sql);
        try {
            return runner.query(sql,new BeanListHandler<Goods>(Goods.class),(currentPage-1)*pageSize,pageSize);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public Long getRows() {
        String sql = "select count(*) from goods";
        try {
            return runner.query(sql,new ScalarHandler<Long>());
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public int getRows(GoodLike goodLike) {
        String sql = "select count(*) from goods where 1=1 ";
        Long num = 0L;
        if (EmptyUtils.isNotEmpty(goodLike.getTypeId()) && goodLike.getTypeId() != -1) {
            sql = sql+" and typeId = "+goodLike.getTypeId();
        }else if (EmptyUtils.isNotEmpty(goodLike.getPriceAnd()) && EmptyUtils.isNotEmpty(goodLike.getPriceBetween())){
            sql = sql+"and price between "+goodLike.getPriceBetween()+" and  "+goodLike.getPriceAnd();
        }
        try {
            num =  runner.query(sql,new ScalarHandler<Long>());
        } catch (SQLException e) {
            e.printStackTrace();
        }
        //Long类型转换为int类型返回
        return num.intValue();
    }
}

package com.kgc.dao.impl;

import com.kgc.dao.GoodsTypeDao;
import com.kgc.entity.Goods;
import com.kgc.entity.GoodsType;
import com.kgc.utils.DataSourcePooled;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.List;

public class GoodsTypeDaoImpl implements GoodsTypeDao {
    QueryRunner runner = new QueryRunner(DataSourcePooled.getDataSource());
    @Override
    public void insert(GoodsType goodsType) {
        String sql = "insert into goodstype values(null,?)";
        Object[]obj = new Object[]{goodsType.getName()};
        try {
            runner.update(sql,obj);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void update(GoodsType goodsType) {
        String sql = "update goodstype set name=? where id=?";
        Object[]obj = new Object[]{goodsType.getName(),goodsType.getId()};
        try {
            runner.update(sql,obj);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void delete(Serializable id) {
        String sql = "delete from goodstype where id=?";
        try {
            runner.update(sql,id);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    @Override
    public List<GoodsType> findAll() {
        String sql = "select * from goodstype";
        try {
            return runner.query(sql,new BeanListHandler<GoodsType>(GoodsType.class));
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public GoodsType findById(Serializable id) {
        String sql = "select * from goodstype  where id=?";
        try {
            return runner.query(sql,new BeanHandler<GoodsType>(GoodsType.class),id);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }
    /*两个表的查询*/
    @Override
    public List<Goods> GoodTypeAll() {
        String sql = "select * from goods,goodstype where goods.`typeId`=goodstype.`id`";
        try {
            return runner.query(sql,new BeanListHandler<Goods>(Goods.class));
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }
}
分页查询的运算逻辑
//分页查询 实现类代码
    @Override
    public List<Book_info> findPageAll(int curentPage, int pageSize) {
        String sql = "select book_code,book_name,book_type," +
                " book_author,pubish_press ,publish_date,is_borrow from book_info  limit ?,?";
        try {
            return runner.query(sql,new BeanListHandler<Book_info>(Book_info.class),(curentPage-1)*pageSize,pageSize);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }
//工具类封装代码

/**
 * 封装分页的数据
 * */
public class PageBean {
    private int pageSize=3;//定义每一页面显示的行数
    private int totalPage;//总的页面数
    private int currPage;//当前页面号
    private int totalRows;//总行数
    private List<?> list;//用于封装当前页面的数据

    public int getPageSize() {
        return pageSize;
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    public int getTotalPage() {
        return totalPage;
    }

    public void setTotalPage(int totalPage) {
        this.totalPage = totalPage;
    }

    public int getCurrPage() {
        return currPage;
    }
    //对要显示的当前页面作判断
    public void setCurrPage(int currPage) {
        if(currPage<1)
            this.currPage=1;
        else if(currPage>this.totalPage)
            this.currPage=this.totalPage;
        else
           this.currPage = currPage;
    }

    public int getTotalRows() {
        return totalRows;
    }

    //设置总行数,根据总行数计算出总页面数
    public void setTotalRows(int totalRows) {
        this.totalRows = totalRows;
        if(totalRows % this.pageSize==0)
            this.totalPage=totalRows/pageSize;
        else
            this.totalPage=totalRows/pageSize+1;
    }

    public List<?> getList() {
        return list;
    }

    public void setList(List<?> list) {
        this.list = list;
    }
}

Service层

定义一个接口一个实现类==方法跟Controller类似,通过这一层直接访问Dao层,

Service层主要负责逻辑运算,让Controller层更简化,只负责取、调、转让代码更便于维护

01接口
public interface GoodsServic {
    //增加
    void insert(Goods goods);
    //修改
    void update(Goods goods);
    //删除
    void delete(Serializable id);
    //查询
    List<Goods> findAll();
    //通过id查询
    Goods findById(Serializable id);
    //查询所有的类型
    List<GoodsType>findAllType();


    /*带查询条件的分页  通过serviet把获取的值传递过来在进行转换,简化serviet,把判断复杂的操作在此层执行*/
    PageBean LikeGoodsAll(String page,String type, String price1, String price2);

}
02)实现类
public class GoodServic implements GoodsServic{
    private GoodsDaoImpl goodsDao = new GoodsDaoImpl();
    private GoodsTypeDaoImpl goodsTypeDao = new GoodsTypeDaoImpl();
    @Override
    public void insert(Goods goods) {
        goodsDao.insert(goods);
    }

    @Override
    public void update(Goods goods) {
        goodsDao.update(goods);
    }

    @Override
    public void delete(Serializable id) {
        goodsDao.delete(id);
    }

    @Override
    public List<Goods> findAll() {
        List<Goods> all = goodsDao.findAll();
        return all;
    }

    @Override
    public Goods findById(Serializable id) {
        Goods byId = goodsDao.findById(id);
        return byId;
    }

    @Override
    public List<GoodsType> findAllType() {
        List<GoodsType> all = goodsTypeDao.findAll();
        return all;
    }

    /*返回满足条件的分页查询集合*/
    @Override
    public PageBean LikeGoodsAll(String page,String type, String price1, String price2) {
        //判断page是否为空===此方法EmptyUtils提供
        if (EmptyUtils.isEmpty(page)){
            page="1";
        }
        //当前默认页面号
        int currentPage = Integer.parseInt(page);
        PageBean pageBean = new PageBean();//封装分页的实体类
        GoodLike goodLike = new GoodLike();//封装查询条件的实体类

        //判断查询的id类型是否为空,如果不为空,则强转后放入对象实体
        if (EmptyUtils.isNotEmpty(type)){
            goodLike.setTypeId(Integer.parseInt(type));
        }
        if (EmptyUtils.isNotEmpty(price1) && EmptyUtils.isNotEmpty(price2)){
            goodLike.setPriceBetween(Integer.parseInt(price1));
            goodLike.setPriceAnd(Integer.parseInt(price2));
        }
        System.out.println("查询条件对象的值为"+goodLike);
        //求总行数 pageBean 在service层放入 总行数 跟 当前页面号 求出其他的值
        int rows= goodsDao.getRows(goodLike);
        pageBean.setTotalRows(rows);
        pageBean.setCurrPage(currentPage);
        //把包含条件的数据查出来放入pageBean的集合当中,用于页面调用
        List<Goods> list = goodsDao.LikeGoodsAll(goodLike, pageBean.getCurrPage(), pageBean.getPageSize());
        pageBean.setList(list);
        System.out.println(list);
        return pageBean;
    }
}

Controller层===控制器(Servlet)

doPost&doGet
@WebServlet(urlPatterns = "/GoodServlet")
public class GoodServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /*处理中乱码*/
        //request.setCharacterEncoding("utf-8");
        //response.setContentType("text/html;charset=utf-8");
        /*获取的到的method值判断执行的命令*/
        String method = request.getParameter("method");
        System.out.println("method="+method);
        if ("doList".equals(method))
            this.doList(request,response);
        else if ("doInsert".equals(method))
            this.doList(request,response);//
        else if ("doDelete".equals(method))
            this.doDelete(request,response);
        else if ("doUp".equals(method))
            this.doUp(request,response);
        else if ("doUpdate".equals(method))
            this.doList(request,response);
        else if ("doUpload".equals(method))
            this.doUpload(request,response);
        else if ("doUt".equals(method))
           this.doUt(request,response);
        else
            this.doList(request,response);
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
分页查询
 /*浏览查询*/
    protected void doList(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //取数据
        String page = request.getParameter("page");//当前浏览的页面号
        String type = request.getParameter("type");//商品类型
        String price1 = request.getParameter("price1");//价格区间
        String price2 = request.getParameter("price2");//价格区间

        //调
        GoodServic goodServic = new GoodServic();

        PageBean pageBean = goodServic.LikeGoodsAll(page, type, price1, price2);

        //存
        request.setAttribute("pb",pageBean);

       /*回显的数据*/
        request.setAttribute("types",type);
        request.setAttribute("price1",price1);
        request.setAttribute("price2",price2);



        /*类型同时加载*/
        List<GoodsType> allType = goodServic.findAllType();
        HttpSession session = request.getSession();
        session.setAttribute("allType",allType);

        /*转发*/
        request.getRequestDispatcher("pages/main.jsp").forward(request,response);

    }
   
删除&加载回显
/*删除*/
    protected void doDelete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /*取数据*/
        String id = request.getParameter("goodid");

        /*方法定义的Serializable类型,此类型包含String int 等8个常用数据类型,所以不需要强转*/
        /*调用删除的方法*/
        GoodServic goodServic = new GoodServic();
        goodServic.delete(id);
        /*内部直接调用查看的方法更新数据*/
        doList(request,response);
    }
    /*辅助修改的方法做回显数据*/
    protected void doUp(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String id = request.getParameter("id");

        GoodServic goodServic = new GoodServic();
        Goods byId = goodServic.findById(id);

        request.setAttribute("byId",byId);

        request.getRequestDispatcher("pages/UpdateGoods.jsp").forward(request,response);

    }
增加==文件上传
/*增加===文件上传版*/
    protected void doUpload(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //创建一个FileItemFactory
        DiskFileItemFactory factory=new DiskFileItemFactory();
        //设置缓冲区
        factory.setSizeThreshold(1024*100);
        //构造上传的组件
        ServletFileUpload upload=new ServletFileUpload(factory);
        upload.setHeaderEncoding("utf-8");
        String path=getServletContext().getRealPath("upload").toString();
        File dir=new File(path);
        if(!dir.exists()){
            dir.mkdir();
        }

        String name="";//商品名称
        String price="";//商品价格
        String typeId="";//商品类型
        String createTime="";//商品生产日期
        String fileName="";//商品图片
        boolean isMultipart = ServletFileUpload.isMultipartContent(request);
        if (isMultipart) {
            try {
                //解析请求,将表单中每个输入项封装成一个FileItem对象  5
                List<FileItem> fileItems = upload.parseRequest(request);
                // 迭代表单数据
                for (FileItem fileItem : fileItems) {
                    //判断输入的类型是 普通输入项 还是文件
                    if (fileItem.isFormField()) {
                        if("name".equals(fileItem.getFieldName())){
                            name=fileItem.getString("UTF-8");
                        }
                        if("price".equals(fileItem.getFieldName())){
                            price=fileItem.getString("UTF-8");
                        }
                        if("typeId".equals(fileItem.getFieldName())){
                            typeId=fileItem.getString("UTF-8");
                        }
                        if("createTime".equals(fileItem.getFieldName())){
                            createTime=fileItem.getString("UTF-8");
                        }
                    } else {
                        fileName=fileItem.getName();
                        String ext = fileName.substring(fileName.lastIndexOf("."));
                        fileName = StringUtils.randomUUID()+ext;
                        //在指的目录下构造一个空文件
                        File file = new File(path+"\\"+fileName);
                        fileItem.write(file);
                    }
                }
            } catch (FileUploadException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }else{
            System.out.println("普通表单");
        }

        //用户增加的数据存储到数据库中
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date parse = null;
        try {
            parse = sdf.parse(createTime);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Goods goods=new Goods(name,Integer.parseInt(typeId),Integer.parseInt(price),parse,fileName);
        GoodServic goodServic = new GoodServic();
        goodServic.insert(goods);
        response.sendRedirect("GoodServlet");
    }
    
修改==文件上传
/*修改===文件上传版*/
    protected void doUt(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //创建一个FileItemFactory
        DiskFileItemFactory factory=new DiskFileItemFactory();
        //设置缓冲区
        factory.setSizeThreshold(1024*100);
        //构造上传的组件
        ServletFileUpload upload=new ServletFileUpload(factory);
        upload.setHeaderEncoding("utf-8");
        String path=getServletContext().getRealPath("upload").toString();
        File dir=new File(path);
        if(!dir.exists()){
            dir.mkdir();
        }
        String id ="";
        String name="";//商品名称
        String price="";//商品价格
        String typeId="";//商品类型
        String createTime="";//商品生产日期
        String fileName="";//商品图片
        boolean isMultipart = ServletFileUpload.isMultipartContent(request);
        if (isMultipart) {
            try {
                //解析请求,将表单中每个输入项封装成一个FileItem对象  5
                List<FileItem> fileItems = upload.parseRequest(request);
                // 迭代表单数据
                for (FileItem fileItem : fileItems) {
                    //判断输入的类型是 普通输入项 还是文件
                    if (fileItem.isFormField()) {
                        if("id".equals(fileItem.getFieldName())){
                            id=fileItem.getString("UTF-8");
                        }
                        if("name".equals(fileItem.getFieldName())){
                            name=fileItem.getString("UTF-8");
                        }
                        if("price".equals(fileItem.getFieldName())){
                            price=fileItem.getString("UTF-8");
                        }
                        if("typeId".equals(fileItem.getFieldName())){
                            typeId=fileItem.getString("UTF-8");
                        }
                        if("createTime".equals(fileItem.getFieldName())){
                            createTime=fileItem.getString("UTF-8");
                        }
                    } else {
                        fileName=fileItem.getName();
                        String ext = fileName.substring(fileName.lastIndexOf("."));
                        fileName = StringUtils.randomUUID()+ext;
                        System.out.println("fileName"+fileName);
                        //在指的目录下构造一个空文件
                        File file = new File(path+"\\"+fileName);
                        fileItem.write(file);
                    }
                }
            } catch (FileUploadException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }else{
            System.out.println("普通表单");
        }

        //用户增加的数据存储到数据库中
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date prase = null;
        try {
            prase = sdf.parse(createTime);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Goods goods=new Goods(Integer.parseInt(id),name,Integer.parseInt(typeId),Integer.parseInt(price),prase,fileName);
        System.out.println(goods);
        GoodServic goodServic = new GoodServic();
        goodServic.update(goods);
        response.sendRedirect("GoodServlet");
    }

模板==只需要改三处,其余套用即可
增加

代码处标记1/2/3/4

//完成文件上传  完成增加的功能  带上传
    protected void doUpload(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //创建一个FileItemFactory
        DiskFileItemFactory factory=new DiskFileItemFactory();
        //设置缓冲区
        factory.setSizeThreshold(1024*100);
        //构造上传的组件
        ServletFileUpload upload=new ServletFileUpload(factory);
        upload.setHeaderEncoding("utf-8");
        String path=getServletContext().getRealPath("upload").toString();
        File dir=new File(path);
        if(!dir.exists()){
            dir.mkdir();
        }
		/*1.第一处*/
        String name="";
        String price="";
        String typeId="";
        String createTime="";
        String fileName="";
        boolean isMultipart = ServletFileUpload.isMultipartContent(request);
        if (isMultipart) {
            try {
                //解析请求,将表单中每个输入项封装成一个FileItem对象  5
                List<FileItem> fileItems = upload.parseRequest(request);
                // 迭代表单数据
                for (FileItem fileItem : fileItems) {
                    //判断输入的类型是 普通输入项 还是文件
                    if (fileItem.isFormField()) {
                        
                        
                        /*2.第二处*/
                       if("name".equals(fileItem.getFieldName())){
                           name=fileItem.getString("UTF-8");
                       }
                        if("price".equals(fileItem.getFieldName())){
                            price=fileItem.getString("UTF-8");
                        }
                        if("typeId".equals(fileItem.getFieldName())){
                            typeId=fileItem.getString("UTF-8");
                        }
                        if("createTime".equals(fileItem.getFieldName())){
                            createTime=fileItem.getString("UTF-8");
                        }
                    } else {
                        fileName=fileItem.getName();
                        String ext = fileName.substring(fileName.lastIndexOf("."));
                        fileName = StringUtils.randomUUID()+ext;
                        //在指的目录下构造一个空文件
                        File file = new File(path+"\\"+fileName);
                        fileItem.write(file);
                    }
                }
            } catch (FileUploadException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }else{
            System.out.println("普通表单");
        }
        //用户增加的数据存储到数据库中
        /*3.第三处*/
        Goods goods=new Goods(name,Integer.parseInt(price),createTime,fileName,Integer.parseInt(typeId));
        /*4.第四处*/
        goodsService.insertGooods(goods);
        response.sendRedirect("GoodsServlet");
    }
修改

加上id、更改dom层方法即可

//完成修改
    protected void doUpdate(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //创建一个FileItemFactory
        DiskFileItemFactory factory=new DiskFileItemFactory();
        //设置缓冲区
        factory.setSizeThreshold(1024*100);
        //构造上传的组件
        ServletFileUpload upload=new ServletFileUpload(factory);
        upload.setHeaderEncoding("utf-8");
        String path=getServletContext().getRealPath("upload").toString();
        File dir=new File(path);
        if(!dir.exists()){
            dir.mkdir();
        }
        String id="";
        String name="";
        String price="";
        String typeId="";
        String createTime="";
        String fileName="";
        boolean isMultipart = ServletFileUpload.isMultipartContent(request);
        if (isMultipart) {
            try {
                //解析请求,将表单中每个输入项封装成一个FileItem对象  5
                List<FileItem> fileItems = upload.parseRequest(request);
                // 迭代表单数据
                for (FileItem fileItem : fileItems) {
                    //判断输入的类型是 普通输入项 还是文件
                    if (fileItem.isFormField()) {
                        if("id".equals(fileItem.getFieldName())){
                            id=fileItem.getString("UTF-8");
                        }
                        if("name".equals(fileItem.getFieldName())){
                            name=fileItem.getString("UTF-8");
                        }
                        if("price".equals(fileItem.getFieldName())){
                            price=fileItem.getString("UTF-8");
                        }
                        if("typeId".equals(fileItem.getFieldName())){
                            typeId=fileItem.getString("UTF-8");
                        }
                        if("createTime".equals(fileItem.getFieldName())){
                            createTime=fileItem.getString("UTF-8");
                        }
                    } else {
                        fileName=fileItem.getName();
                        String ext = fileName.substring(fileName.lastIndexOf("."));
                        fileName = StringUtils.randomUUID()+ext;
                        //在指的目录下构造一个空文件
                        File file = new File(path+"\\"+fileName);
                        fileItem.write(file);
                    }
                }
            } catch (FileUploadException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }else{
            System.out.println("普通表单");
        }
        //用户增加的数据存储到数据库中
        Goods goods=new Goods(name,Integer.parseInt(price),createTime,fileName,Integer.parseInt(typeId));
        goods.setId(Integer.parseInt(id));
        goodsService.udpateBook(goods);
        response.sendRedirect("GoodsServlet");
    }

pages===视图

01)浏览首页
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>首页</title>
</head>
<body>
    <center>
        <h2>商品信息列表</h2>
        <a href="pages/InsertGoods.jsp">添加商品</a>
        <form action="GoodServlet" method="post">
        <input hidden name="method" value="doList">
        商品类型:
            <select name="type">
                    <option value="-1">全部类型</option>
                <c:forEach items="${sessionScope.allType}" var="ty">
                    <option value="${ty.id}"
                    <c:if test="${requestScope.types == ty.id}">
                        selected="selected"
                    </c:if>
                        >${ty.name}</option>

                </c:forEach>
            </select>
        价格:
            <input type="text" name="price1" value="${requestScope.price1}">
            到
            <input type="text" name="price2" value="${requestScope.price2}">
            <input type="submit" value="查询">
        </form>
        <table border="1" width="800">
            <tr>
                <td>商品编号</td>
                <td>商品名称</td>
                <td>商品类型</td>
                <td>价格</td>
                <td>生产日期</td>
                <td>删除</td>
                <td>修改</td>
                <td>详情</td>
            </tr>
            <c:forEach items="${requestScope.pb.list}" var="list">
                <tr>
                    <td>${list.id}</td>
                    <td>${list.name}</td>
                    <td>${list.typename}</td>
                    <td>${list.price}</td>
                    <td>${list.createTime}</td>
                    <td><a href="javascript:deleteGood(${list.id})">删除</a></td>
                    <td><a href="GoodServlet?method=doUp&id=${list.id}">修改</a></td>
                    <td><a href="#">详情</a></td>
                </tr>
            </c:forEach>
                <tr>
                    <td colspan="2"><a href="GoodServlet?method=doList&page=1">首页</a></td>
                    <td><a href="GoodServlet?method=doList&page=${requestScope.pb.currPage-1}">上一页</a></td>
                    <td><a href="GoodServlet?method=doList&page=${requestScope.pb.currPage+1}">下一页</a></td>
                    <td><a href="GoodServlet?method=doList&page=${requestScope.pb.totalPage}">尾页</a></td>
                    <td><a href="#">总行数${requestScope.pb.totalRows}</a></td>
                    <td><a href="#">总页面数${requestScope.pb.totalPage}</a></td>
                    <td><a href="#">当前第${requestScope.pb.currPage}页</a></td>
                </tr>
        </table>

    </center>
</body>
        <script>
            function deleteGood(id) {
                if(confirm("是否要删除?")){
                    window.location.href="GoodServlet?method=doDelete&goodid="+id;
                }
            }
        </script>
</html>

02)修改页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>修改页面</title>
</head>
<body>
    <center>
       <form action="GoodServlet?method=doUt" method="post" enctype="multipart/form-data">
           
            <input type="hidden" name="id" value="${byId.id}">
            <h2>修改商品</h2>
            <table border="1" width="300">
                <tr>
                    <td>商品名称</td>
                    <td><input type="text" name="name" value="${byId.name}"></td>
                </tr>
                <tr>

                    <td>商品类型</td>
                    <%--动态数据--%>
                    <td>
                        <select name="type">
                            <c:forEach items="${sessionScope.allType}" var="ty">
                                <option value="${ty.id}"
                                        <c:if test="${ty.id==byId.id}">
                                            selected="selected"
                                        </c:if>
                                >${ty.name}
                                </option>
                            </c:forEach>
                        </select>
                    </td>
                </tr>
                <tr>
                    <td>价格</td>
                    <td><input type="text" name="price" value="${byId.price}"></td>
                </tr>
                <tr>
                    <td>生产时间</td>
                    <td><input type="text" name="createTime" value="${byId.createTime}"></td>
                </tr>
                <tr>
                    <td colspan="2">
                        <input type="submit" value="添加">
                        <input type="reset" value="重置">
                    </td>
                </tr>
            </table>
        </form>
    </center>

</body>
</html>
03)添加页码
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>添加商品</title>
</head>
<body>

    <form method="post" action="/GoodServlet">
        <input type="hidden" name="method" value="doInsert">
        <h2>添加商品</h2>
        <table border="1" width="300">
            <tr>
                <td>商品名称</td>
                <td><input type="text" name="name"></td>
            </tr>
            <tr>

                <td>商品类型</td>
                <%--动态数据--%>
                <td>
                    <select name="type">
                        <c:forEach items="${sessionScope.allType}" var="ty">
                            <option value="${ty.id}">${ty.name}</option>
                        </c:forEach>
                    </select>
                </td>
            </tr>
            <tr>
                <td>价格</td>
                <td><input type="text" name="price"></td>
            </tr>
            <tr>
                <td>生产时间</td>
                <td><input type="text" name="createTime"></td>
            </tr>
            <tr>
                <td colspan="2">
                    <input type="submit" value="添加">
                    <input type="reset" value="重置">
                </td>
            </tr>
        </table>
    </form>
</body>
</html>

常见问题

1.sql语句如果确定没错的话就检查一下空格,此类问题容易解决

2.单引号问题,一般不需要加单引号。如果加的话要成对加,sql语句报错的话如果报错行检查没问题,就顺延往上检查

3.选择器一定要用if-else,常量放在前面,不然重定向必须带参数,不然空指针,或者出现重复转发现象

4.文件上传如果传递值是空的话检查一下构造方法,打印出来看下有没有在赋值的过程出现错误,导致传参失败!

5.sql语句的判断每一层都要检查,分页查询的返回记录数方法跟dao层的方法判断要一致并且要经过测试排除问题

6.如果是带文件上传一定要在form表单加上传的代码,否则报错

7.报错行不一定是问题出现的行,排查问题要从实体类的构造方法→dao层→service层→servlet层→页面显示层,逐一判断

8.条件分页查询的判断要注意跟查询记录数的方法一致

Filter过滤器

概念

  • 是一个特殊的Servlet[特殊Java类,受容器管理,容器负责创建调用销毁,取调转]
  • 过滤功能,接受用户所有请求,对每一个请求进行过滤[权限]
  • filter工作在浏览器与服务器之间,来过滤所有请求/*,过滤指定的请求/login

任务

  • 字符编码的转换

  • 权限控制[没有登录不能访问[页面]

实现一个过滤器

实现一个Filter的接口

public class MyFilter implements Filter {
    public void destroy() {
    }
// 过滤器链
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        //保证请求经过这个过滤器后正常向下执行
        chain.doFilter(req, resp);
    }

    public void init(FilterConfig config) throws ServletException {

    }

}

配置Filter

web.xml配置这个过滤器
    <filter>
        <filter-name>myFilter</filter-name>
        <filter-class>com.kgc.filter.MyFilter</filter-class>
    </filter>
<filter-mapping>
    <filter-name>myFilter</filter-name>
    <!--向服务器发出所有请求,先要经过这个filter  执行doFilter方法-->
    <url-pattern>/*</url-pattern>
</filter-mapping>

@WebFilter(urlPatterns = {"/login","/LoginServlet"})
接受所有请求,用户向服务发出来的每一个请求都要先经过过滤器
@WebFilter(urlPatterns = {"/*"})

权限控制

1.登录成功将User存放到session

2.sesion中是否有user就一个判断用户是否登录过的一个条件

3.一个资源一个组件,需要先登录才能访问

4.实现只有登录过的用户才能访问BookInfoServlet

Filter过滤重定向,转发不经过滤器

package com.kgc.filter;

import com.kgc.entity.User;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
//login.jsp LoginServlet
@WebFilter(urlPatterns = "/*")
public class PermissionFilter implements Filter {
    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        //当前发请求的用户是否登录过
        HttpServletRequest request=(HttpServletRequest)req;
        HttpServletResponse response=(HttpServletResponse)resp;
        HttpSession session=request.getSession();

        //当前用户发请求的,请求字符串  http://localhost:8080/index.jsp
       String uri=request.getRequestURI();///index.jsp
       //String url=request.getRequestURL().toString();// http://localhost:8080/index.jsp
       if(uri.indexOf("login.jsp")>0){
           chain.doFilter(req, resp);
           return; 
       }

        if(uri.indexOf("LoginServlet")>0){
            chain.doFilter(req, resp);
            return;
        }
        
        
        if(request.getRequestURI().indexOf("BookInfoServlet")>0) {

            User user = (User) session.getAttribute("user");
            if (user != null) {//当前发请求的用户登录过了
                chain.doFilter(req, resp);
                return;
            } else {
                response.sendRedirect("login.jsp");
                return;
            }
        }else{
            chain.doFilter(req, resp);
        }
    }

    public void init(FilterConfig config) throws ServletException {

    }

}

Listener监听器

HttpSessionListener 监听session 的创建与销毁

HttpSessionAttributeListener setAttribute(key,value)

当服务创建一个session,HttpSessionListener 就会触发一个事件sessionCreated,这个方法就被调用

服务器销毁一个session对象,HttpSessionListener中的sessionDestroyed,会被 调用

jQuery

01)html标签内写js方法

可通过a标签href调用传值事件触发js效果

html代码
<td><a href="javascript:deleteGood(${list.id})">删除</a></td>
    
    
<script>
    function deleteGood(id) {
    if(confirm("是否要删除?")){
        window.location.href="GoodServlet?method=doDelete&goodid="+id;
    }
}
</script>

02)jQuery使用步骤

01)导入文件

<script type="text/javascript" src="js/jquery-3.2.1.js"></script>

02)声明js文件或导入js文件路径

<script type="text/javascript" >
            $(function(){
                $("td").click(function(){
                    alert($(this).text());

                });

            });
        </script>

03)声明jquery部分

声明==将dom对象包装成jQuery对象
$(function(){
	内容
                $("td").click(function(){
                    alert($(this).text());

                });

03)获得一个标签对象

js语法:
得到一个dom类型的对象,通过el就可以调用dom所提供的api
val el=document.getElementById("a1");
el.value="张三"

jquery语法:
$("#a1");
$("#a1").val("张三");

代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>jQuery</title>
    <style>
        .c1{
            color: red;
            font-size: 66px;
        }
    </style>
</head>
<body>
    <form action="#" method="POST">
        <h1>学生系统</h1>
        姓名:<input type="text" id="">
        性别:<input type="text" id="">
        <hr/>
        <table border="1" width="800">
            <tr>
                <th>姓名</th><th>年龄</th><th>性别</th>
            </tr>
            <tr>
                <td>张三</td><td>26</td><td></td>
            </tr>
            <tr>
                <td>李四</td><td>27</td><td></td>
            </tr>
            <tr>
                <td>王五</td><td>28</td><td></td>
            </tr>
            <tr>
                <td>赵六</td><td>29</td><td></td>
            </tr>

        </table>
        <img id="image1" src="img/bdlogo.gif">
    </form>
</body>
        <script type="text/javascript" src="js/jquery-3.2.1.js"></script>
        <script type="text/javascript" >
            $(function(){
                $("td").click(function(){
                    // 获取对象的值
                    alert($(this).text());
                    // 给对象赋值
                    $(this).text("小李")
                    // 给当前对象增加css属性
                    $(this).css("color","red")
                    // 链式选择器==结合多种功能的语法
                    $(this).css("color","red").text("abc")
                    // 语法2
                    $(this).css({"color":"red","font-size":"30px"})
                    // 在当前对象中增加class="c1" 使其对象增加c1中css样式
                    $("td").addClass("c1")
                     $(this).addClass("c1")
                    // 删除c1中属性
                     $(this).removeClass("c1");
                    // 触发事件写一个html标签
                    $(this).html("<h1>孙悟空</h1>");
                });

                // 给标签增加属性  
                // attr操作可使用的属性
                // prop操作这个对象本身就有的属性 
                $("#image1").click(function(){
                    // 点击这个对象替换src的属性
                   // $(this).attr("src","img/相机.png");
                    
                    $(this).prop("src","img/相机.png");
                });

            });
        </script>
</html>

04)选择器

id选择器

语法

得到jquery类型的对象
$("#id名");

取这个表单元素的value属性值,表单元素的值
$("#t1").val()  

为表单元素赋值
$("#t1").val("新值")

非表单元素的取文本

类选择器

语法同上,但获得的是一个数组

标签选择器

同类选择器

05)常用API

函数作用
text()操作标签文本
html()操作标签
css()操作样式
addClass()在标签中增加class属性
removeClass()删除标签中的class属性
attr(k,v)修改标签属性值==任何属性值
prop(k,v)修改标签属性值==标签内存在的属性值
val()获取属性值或赋值
push()数组中添加元素
父元素.append(子元素)给当前元素增加子元素
子元素.appendTo(父元素)给当前元素增加父级元素
parent()得到当前元素的父节点
parents()得到当前元素的父节点的父节点
remove()删除元素

06)循环遍历

$("#revm").click(function(){
                    // 定义一个数组
                    var ids=[];
                    // 循环遍历方式一:index表示索引,data表示对象
                    $("td :checked").each(function(index,data){
                        console.log($(data).val())
                        //把值存入数组
                        ids.push($(data).val())
                    });
                    // 循环遍历方式二:
                    $.each( $("td :checked"),function(index,data){
                        console.log($(data).val())
                        ids.push($(data).val())
                    });

                
            });

07)隔行变色

$(function(){                                 
    // 隔行换色  :odd奇数行,:even匹配所有索引值为偶数的元素,从 0 开始计数
    $("tr:odd").css("background-color","mediumturquoise");
    console.info($("td[style]").text());                             
            });

08)删除选中的项

<h1>学生系统</h1>
        姓名:<input type="text" id="">
        性别:<input type="text" id="">
        <hr/>
        <table border="1" width="600">
            <tr>
                <th><input type="checkbox"  id="all">全选</th><th>姓名</th><th>年龄</th><th>性别</th><td>操作</td>
            </tr>
            <tr>
                <td><input type="checkbox" name="ids"  value="1"></td><td>张三</td><td>26</td><td></td>
                <td><button class="rem">删除</button></td>
            </tr>
            <tr>
                <td><input type="checkbox" name="ids"  value="2"></td><td>李四</td><td>27</td><td></td>
                <td><button class="rem">删除</button></td>
            </tr>
            <tr>
                <td><input type="checkbox" name="ids"  value="3"></td><td>王五</td><td>28</td><td></td>
                <td><button class="rem">删除</button></td>
            </tr>
            <tr>
                <td><input type="checkbox" name="ids"  value="4"></td><td>赵六</td><td>29</td><td></td>
                <td><button class="rem">删除</button></td>
            </tr>

        </table>
        <button id="revm">删除</button>
        <br/>
        <img id="image1" src="img/bdlogo.gif">





$(function(){
             
                // 全选
                $("#all").click(function(){
                    $("#all").prop("checked")
                    $("td :checkbox[name='ids']").prop("checked",$("#all").prop("checked"))
                });

                
                // 获取勾选对象值
                $("#revm").click(function(){
                   //判断当前是否有选中值                   
                    if($("td :checked").length == 0){
                        alert("请先选择要删除的项!")
                        return;
                    }
                    // 循环遍历方式一:删除勾选中项
 					// 定义一个数组
 					var ids=[];
                    $("td :checked").each(function(index,data){                   
                        //把值存入数组
                        //ids.push($(data).val())
                        $(data).parents("tr").remove();
                    });      
                });
				//删除当前点击的
                $(".rem").click(function(e){                        
                    $(this).parents("tr").remove();
                });
            });

Ajax

jQuery发送Ajax请求

$.post(url,{key:value,key:value},function(result){});
$.get(url,{key:value,key:value},function(result){});
$.ajax();// $.get $.post都是$.ajax简化版
$.ajax({
  type: "GET",//请求的类型get /post
  url: "test.js",//向服务器那个controller发请求
  dataType: "json",//返回结果的类型
  data:key=value&key=value,
  success:function(reslt0{}),服务器返回成功,就执行success方法
  error:function(){} 
});

代码示例

/*输一个id  在前台显示这个用户信息*/
            /*不输入,在前参显示所有信息*/
            $("#all").click(function () {
            var userIdValue = $("#userId").val();
                $.ajax({
                    type:"post",
                    url:"../AjaxServlet?op=doAll",
                    data:"userId="+userIdValue,
                    dataType:"json",
                    success:function (resule) {                  
                        $("#ids").text(resule.userId);
                        $("#names").text(resule.userName);
                        $("#pwds").text(resule.userPwd);
                    }
                })
            });

常用API

方法说明
open(String method,String url,boolean async,String user ,String password)

Ajax交互数据库

js方式
<html>
<head>
    <title>用户登录</title>
</head>
<body>
    <form action="#" method="post">
        <table border="0" width="500">
            <tr>
                <th colspan="2"><h1>论坛注册</h1></th>
            </tr>
            <tr>
                <td>用户名:</td>
                <td><input type="text" name="userName" id="userName" onblur="chank()"><span id="info"></span></td>
            </tr>
            <tr>
                <td>密码:</td>
                <td><input type="text" name="userPwd"></td>
            </tr>
            <tr>
                <td>确认密码:</td>
                <td><input type="text" name="userPwd"></td>
            </tr>
            <tr>
                <td colspan="2"><input type="button" value="提交"></td>
            </tr>
        </table>
    </form>
    <script type="text/javascript">
        var xmlHttpRequest;
        function chank() {
            //得到要发给服务器的值
            var userName = document.getElementById("userName").value;
            //得到xmlHttpRequest这个对象,这个对象可以发ajxk请求 createXmlRequse 自定义的函数
            xmlHttpRequest = createXmlRequse();
            //调回调函数  这个callback函数处理服务器返回的结果  callback 自定义的函数
            xmlHttpRequest.onreadystatechange= callback;
            //初始化
            xmlHttpRequest.open("post","../AjaxServlet?op=doBoor&userName="+userName,true);
            //发请求
            xmlHttpRequest.send(null)
        }        
        function callback() {
            if(xmlHttpRequest.readyState == 4){       //判断交互是否成功
                if(xmlHttpRequest.status == 200){         //获取服务器返回的数据         
                    //获取纯文本数据
                    //得到服务器返回的结果
                    var responseText =xmlHttpRequest.responseText;
                    document.getElementById("info").innerHTML = responseText;
                }
            }
        }
        function createXmlRequse(){
            var xmlHttp;
            if(window.XMLHttpRequest) {//非IE
                xmlHttp = new XMLHttpRequest();
                if(xmlHttp.overrideMimeType) {
                    xmlHttp.overrideMimeType("text/xml");
                }
            } else if(window.ActiveXobject) {//
                var activeName = ["MSXML2.XMLHTTP", "Microsoft.XMLHTTP"];
                for (var i = 0; i < activeName.length; i++) {
                    try {
                        xmlHttp = new ActiveXobject(activeName[i]);
                        break;
                    } catch (e) {
                    }
                }
            }
            return xmlHttp;
        }

    </script>
</body>
</html>

jquery方式
<html>
<head>
    <title>用户登录</title>
</head>
<body>
        <table border="1" width="500">
            <tr>
                <th colspan="2"><h1>论坛注册</h1></th>
            </tr>

            <tr>
                <td>用户名:</td>
                <td><input type="text" name="userName" id="userName" ><span id="info"></span></td>
            </tr>
            <tr>
                <td>密码:</td>
                <td><input type="text" name="userPwd"></td>
            </tr>
            <tr>
                <td>确认密码:</td>
                <td><input type="text" name="userPwd"></td>
            </tr>
            <tr>
                <td colspan="2"><input type="button" value="提交"></td>
            </tr>
        </table>
        <div id="allText">
            <table border="1" width="500">
                <tr>
                    <td>用户查询:</td>
                    <td><input type="text" id="userId"></td>
                    <td><button id="all">查询</button></td>
                </tr>
                <tr>
                    <th>用户编号</th>
                    <th>用户账号</th>
                    <th>用户密码</th>
                </tr>
                <tr>
                    <td ><span id="ids"></span></td>
                    <td id="names"></td>
                    <td id="pwds"></td>
                </tr>
            </table>
        </div>
    <script type="text/javascript" src="../js/jquery-3.2.1.js" ></script>
    <script type="text/javascript">
        $(function () {
            /*查询用户名是否存在数据库*/
           $("#userName").blur(function () {

               var userNameValue = $("#userName").val();

               $.ajax({
                   type:"post",
                   url:"../AjaxServlet?op=doBoor",
                   data:"userName="+userNameValue,
                   success:function (resule) {
                       $("#info").text(resule);
                   }
               })
           })
            /*输一个id  在前台显示这个用户信息*/
            /*不输入,在前参显示所有信息*/
            $("#all").click(function () {
            var userIdValue = $("#userId").val();
                $.ajax({
                    type:"post",
                    url:"../AjaxServlet?op=doAll",
                    data:"userId="+userIdValue,
                    dataType:"json",
                    success:function (resule) {
                        //$("#ids").html(resule.userId);
                        $("#ids").text(resule.userId);
                        $("#names").text(resule.userName);
                        $("#pwds").text(resule.userPwd);
                    }
                })
            });
            //失去焦点显示所有对象
            $("#userId").blur(function () {
                $.ajax({
                    type:"post",
                    url:"../AjaxServlet?op=doAllSum",
                    success:function (resule) {
                        $("#ids").text(resule);
                    }
                })
            });
        });

    </script>
</body>
</html>
Servlet后台代码
@WebServlet(urlPatterns = "/AjaxServlet")
public class AjaxServlet extends HttpServlet {
    private UserDaoImpl userDao = new UserDaoImpl();
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");

        String op = request.getParameter("op");
        System.out.println(op);
        if ("doAll".equals(op))
            this.doAll(request,response);
        else if ("doBoor".equals(op))
            this.doBoor(request,response);
        else if ("doAllSum".equals(op))
            this.doAllSum(request,response);
        else
            this.doAllSum(request,response);
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request,response);
    }
    protected void doAllSum(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获得打印对象
        PrintWriter out = response.getWriter();
        //查询结果集
        List<User> all = userDao.findAll();
        //通过gson转换格式
        Gson gson = new Gson();
        String s = gson.toJson(all);
        out.print(s);
    }
    //查询单条数据
    protected void doAll(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        PrintWriter out = response.getWriter();
        String userId = request.getParameter("userId");
        User byId = userDao.findById(userId);
        Gson gson = new Gson();
        String s = gson.toJson(byId);
        out.print(s);
    }
    //向后台发送账号,检查是否存在
    protected void doBoor(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        PrintWriter out = response.getWriter();
        String userName = request.getParameter("userName");
        //向后台发送账号,检查是否存在
        if (userDao.isName(new User(userName))){
            out.print("该账户已被占用,请更换!");
        }else {
            out.print("该账户可以正常注册!");
        }
    }
}

参数说明

参数类型说明
urlString必选,发送请求的地址
dataPlainobject或 String发送到服务器的数据
successFunction( PlainObject result , String textStatus,jqXHR jqxhr )请求成功后调用的函数,
参数result:可选,由服务器返回的数据
dataTypeString预期服务器返回的数据类型,
包括:XML、HTML.Script
$.get()方法的使用

$.get(url,data,function(result){
    //省略服务器返回的数据显示到页面的代码
});

Maven

云仓配置

<mirrors>  
    <!--复制以下代码放入mirrors中后,项目需要的jar包如果没有将会在阿里云自动下载-->
	 <mirror>
      <!--This sends everything else to /public -->
      <id>nexus</id>
      <mirrorOf>*</mirrorOf> 
      <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
    </mirror>
    <mirror>
      
      <id>nexus-public-snapshots</id>
      <mirrorOf>public-snapshots</mirrorOf> 
      <url>http://maven.aliyun.com/nexus/content/repositories/snapshots/</url>
    </mirror>	
	<mirror>   
        <id>Central</id>   
        <url>http://repo1.maven.org/maven2</url>   
        <mirrorOf>central</mirrorOf>   
    </mirror>  
  </mirrors> 

th>









```
Servlet后台代码
@WebServlet(urlPatterns = "/AjaxServlet")
public class AjaxServlet extends HttpServlet {
    private UserDaoImpl userDao = new UserDaoImpl();
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");

        String op = request.getParameter("op");
        System.out.println(op);
        if ("doAll".equals(op))
            this.doAll(request,response);
        else if ("doBoor".equals(op))
            this.doBoor(request,response);
        else if ("doAllSum".equals(op))
            this.doAllSum(request,response);
        else
            this.doAllSum(request,response);
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request,response);
    }
    protected void doAllSum(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获得打印对象
        PrintWriter out = response.getWriter();
        //查询结果集
        List<User> all = userDao.findAll();
        //通过gson转换格式
        Gson gson = new Gson();
        String s = gson.toJson(all);
        out.print(s);
    }
    //查询单条数据
    protected void doAll(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        PrintWriter out = response.getWriter();
        String userId = request.getParameter("userId");
        User byId = userDao.findById(userId);
        Gson gson = new Gson();
        String s = gson.toJson(byId);
        out.print(s);
    }
    //向后台发送账号,检查是否存在
    protected void doBoor(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        PrintWriter out = response.getWriter();
        String userName = request.getParameter("userName");
        //向后台发送账号,检查是否存在
        if (userDao.isName(new User(userName))){
            out.print("该账户已被占用,请更换!");
        }else {
            out.print("该账户可以正常注册!");
        }
    }
}

参数说明

参数类型说明
urlString必选,发送请求的地址
dataPlainobject或 String发送到服务器的数据
successFunction( PlainObject result , String textStatus,jqXHR jqxhr )请求成功后调用的函数,
参数result:可选,由服务器返回的数据
dataTypeString预期服务器返回的数据类型,
包括:XML、HTML.Script
$.get()方法的使用

$.get(url,data,function(result){
    //省略服务器返回的数据显示到页面的代码
});

Maven

云仓配置

<mirrors>  
    <!--复制以下代码放入mirrors中后,项目需要的jar包如果没有将会在阿里云自动下载-->
	 <mirror>
      <!--This sends everything else to /public -->
      <id>nexus</id>
      <mirrorOf>*</mirrorOf> 
      <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
    </mirror>
    <mirror>
      
      <id>nexus-public-snapshots</id>
      <mirrorOf>public-snapshots</mirrorOf> 
      <url>http://maven.aliyun.com/nexus/content/repositories/snapshots/</url>
    </mirror>	
	<mirror>   
        <id>Central</id>   
        <url>http://repo1.maven.org/maven2</url>   
        <mirrorOf>central</mirrorOf>   
    </mirror>  
  </mirrors> 

maven用骨架创建web.xml文件需要改

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我也不想摸鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值