jdbc工具类的封装,以及表单验证数据提交后台

Posted zs-book1

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了jdbc工具类的封装,以及表单验证数据提交后台相关的知识,希望对你有一定的参考价值。

在之前已经写过了jdbc的工具类,不过最近学习了新的方法,所以在这里重新写一遍,为后面的javaEE做铺垫;

首先我们要了解javaEE项目中,文件构成,新建一个javaEE项目,在项目中,有一个web文件夹,在web文件夹下有WEB-INF文件夹,我们的web.xml文件放在这个文件夹下,同时我们要新建两个文件夹,一个是classes文件夹,一个lib文件夹;技术图片

classes文件夹:我们做出来的程序,都是先编译成class文件,然后再jvm中运行class文件,所以运行时,并不需要java‘文件,因此要把编译好的class文件放在classes文件夹下,然后直接将web文件夹放在tomcat的webapps文件夹下就可以运行了。

这里写一下怎样将class文件放入classes文件夹:

技术图片

 

我们先建四个包:

技术图片

然后以建一个student表:

技术图片

我们一这个表为基础,来模拟一次业务;

首先在entity中创建student表的实例化对象类Student:

技术图片
package com.zs.entity;
/**
 * 创建实例化是对象类Student
 * 生成get和set方法,
 * 空参及带参构造方法
 * tostring方法*/
public class Student {
//    1定义成员变量
    private int id;
    private String sname;
    private int age;

    public Student() {
        super();
    }

    public Student(int id, String sname, int age) {
        this.id = id;
        this.sname = sname;
        this.age = age;
    }

    public int getId() {
        return id;
    }

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

    public String getSname() {
        return sname;
    }

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

    public int getAge() {
        return age;
    }

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

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", sname=‘" + sname + ‘‘‘ +
                ", age=" + age +
                ‘}‘;
    }
}
View Code

然后我们在util包创建jdbc的工具类:

技术图片
package com.zs.util;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;

/**
 * 1.导jar包,需要用到druid-1.0.9.jar,
 *                  mysql-connector-java-5.1.45-bin.jar,
 *                  servlet-api.jar
 *  需要用到阿里的连接池,所以需要配置文件,配置文件放在src文件夹下,配置文件的内容之前有介绍
 */

public class DBUtils {
    private static DataSource ds;
//    1.创建静态代码块读druid.properites配置文件,创建链接池
    static {
        Properties p = new Properties();
        InputStream in = DBUtils.class.getClassLoader().getResourceAsStream("druid.properties");
        try {
            p.load(in);
            ds = DruidDataSourceFactory.createDataSource(p);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

//    2.创建获得连接对象的静态方法
    public static Connection getConnection() throws SQLException {
        return ds.getConnection();
    }

//    3.创建增删改的方法,并返回布尔类型,使用可变参数来传递占位符的值
    public static boolean executeUpdate(String sql,Object... args){
        Connection conn = null;
        PreparedStatement ps = null;
        try {
            conn= getConnection();
            ps = conn.prepareStatement(sql);
//            通过for循环来给占位符赋值
            for (int i = 0; i < args.length; i++) {
                ps.setObject(i+1,args[i]);
            }
//            执行sql语句
            int i = ps.executeUpdate();
            return i>0;
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            close(conn,ps);
        }
        return false;
    }

    //    创建查询的方法,并返回list集合
    public static List<Map<String, Object>> executeQuery(String sql, Object... args) {
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            conn=getConnection();
            ps = conn.prepareStatement(sql);
//            遍历可变数组传递占位符值
            for (int i = 0; i < args.length; i++) {
               ps.setObject(i+1,args[i]);
            }
            rs = ps.executeQuery();
            List<Map<String,Object>> list=new ArrayList<>();
            while (rs.next()) {
                Map<String, Object> map = new LinkedHashMap<>();
/**这里可能会有问题,为什么是String,Object类型,因为我们通过rs.next只能获得一行结果,这一行结果,我们如果直接存入集合中的的化就是一个一个的值
 * 我们无法识别哪儿个值是那儿一列的,所以用想到用map集合来装结果,key为列名,所以用String,因为一行中有多种数据类型,所以用obj来保存,用linkedHashMap
 * 是因为map集合出来的结果是无序的,所以用linkedHashMap是有序的*/
//                rs.getMetaData().getColumnCount();方法获得当前结果集的列数
                for (int i = 0; i <rs.getMetaData().getColumnCount(); i++) {
//                    通过列的索引获得列名,i+1是因为没有第0列,从第一列开始
                    String key = rs.getMetaData().getColumnLabel(i + 1);
//                    通过键名来获得值
                    Object value = rs.getObject(key);
                    map.put(key, value);
                }
                list.add(map);
            }
            return  list;
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            close(conn,ps,rs);
        }
        return  null;
    }
//    创建关闭流的方法
    private static void close(Connection conn) {
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
//    重载
    private static void close(Connection conn, PreparedStatement ps) {
        if (ps != null) {
            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }finally {
                close(conn);
            }
        }
    }
//    重载
    private static void close(Connection conn, PreparedStatement ps, ResultSet rs) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }finally {
                close(conn,ps);
            }
        }
    }
}
View Code

然后我们写dao层的类:

技术图片
package com.zs.dao;

import com.zs.entity.Student;

import java.util.List;
import java.util.Map;

/**我们首先在dao层下面创建接口,因为我们需要一个多态的特征,所以在接口中写抽象方法,方便后期的修改和维护
 * 为什么要用多态,为了程序解耦,接触程序的耦合性,在创建后期修改时,如果我们要修改某一个方法,那就看可能会导致其他的方法不能运行,
 * 程序之间的联系就是耦合性,就像藕断丝连,越是复杂的程序,之间的联系就越多,而多态就是为了解耦*/
public interface IStudentDAO {
    /**
     *  在这里我们传递的参数为Student 对象
     *  为什么要用student对象?
     *  因为在实际开发中,我们的表中的数据可能有很多列,我们不能把所有的列都当参数来传递,那样太麻烦了,而且不方便后期的修改和维护和,
     *  比如说,我们突然要删除一列,那么我们就要找到所有于该方法有关的方法,删除参数列表中相应的参数,这样太麻烦了,传递对象,我们通过get方法来获得参数*/
    boolean add(Student s);
    boolean upd(Student s);
    boolean del(int id);
    List<Map<String,Object>> getStudentById(int id);
    List<Map<String,Object>> getAllStudent();

}
View Code
技术图片
package com.zs.dao.impl;
/**
 * 在创建完接口后,我们在dao层的下面新建一个impl文件夹,用来存放接口的实现类*/
import com.zs.dao.IStudentDAO;
import com.zs.entity.Student;
import com.zs.util.DBUtils;

import java.util.List;
import java.util.Map;

public class StudentImpl implements IStudentDAO {
    @Override
    public boolean add(Student s) {
        String sql="insert into student(sname,age) value (?,?)";
//        通过get方法来传递占位符的值
        return DBUtils.executeUpdate(sql, s.getSname(), s.getAge());
    }

    @Override
    public boolean upd(Student s) {
        String sql = "update student set sname=? ,age=? where id=?";
        return DBUtils.executeUpdate(sql, s.getSname(), s.getAge(), s.getId());
    }

    @Override
    public boolean del(int id) {
        String sql = "delete from student where id=?";
        return DBUtils.executeUpdate(sql, id);
    }

    @Override
    public List<Map<String, Object>> getStudentById(int id) {
        String sql = "select * from student where id=?";
        return DBUtils.executeQuery(sql, id);
    }

    @Override
    public List<Map<String, Object>> getAllStudent() {
        String sql = "select * from student";
        return DBUtils.executeQuery(sql);
    }
}
View Code

然后我们在servlet包中建测试类来测试工具类:

技术图片
package com.zs.servlet;

import com.zs.dao.IStudentDAO;
import com.zs.dao.impl.StudentImpl;
import com.zs.entity.Student;
import com.zs.util.DBUtils;
import org.junit.Test;

import java.util.List;
import java.util.Map;

public class StudentServlet {
    IStudentDAO is=new StudentImpl();
    @Test
    public void add(){
        Student stu = new Student(1, "张三", 20);
//        这里这个 1 可能会有疑问,可以看一下dao层,我们插入语句中并没有用导id;写1是为了使用带参构造
        boolean b = is.add(stu);
        if (b) {
            System.out.println("插入成功");
        } else {
            System.out.println("插入失败");
        }
    }
    @Test
    public void upd(){
        Student stu = new Student(1, "张三", 20);
        boolean b = is.upd(stu);
        if (b) {
            System.out.println("修改成功");
        } else {
            System.out.println("修改失败");
        }
    }
    @Test
    public void del(){
        boolean b = is.del(1);
        if (b) {
            System.out.println("删除成功");
        } else {
            System.out.println("删除失败");
        }
    }
    @Test
    public void sel(){
        List<Map<String, Object>> list = is.getStudentById(2);
        if (list.size() > 0) {
            System.out.println(list);
        } else {
            System.out.println("该学生不存在");
        }
    }
    @Test
    public void selAll(){
        List<Map<String, Object>> list = is.getAllStudent();
        System.out.println(list);
    }
}
View Code

 上面完成后,我们下面写一个页面,完成简单的表单验证,点击提交后,数据提交到后台,然后后台调用dao层,数据对比:

首先创建一个login表:

技术图片

然后我们在dao层中创建ilogin接口:

package com.zs.dao;

public interface ILoginDAO {
    boolean login(String username, String password);
}

然后在impl文件夹中创建实现类:

package com.zs.dao.impl;

import com.zs.dao.ILoginDAO;
import com.zs.util.DBUtils;

import java.util.List;
import java.util.Map;

public class LoginImpl implements ILoginDAO {

    @Override
    public boolean login(String username, String password) {
        String sql = "select * from login where sname=? and pwd=?";
        List<Map<String, Object>> list = DBUtils.executeQuery(sql, username, password);
        return list.size()>0;
    }
}

然后我们写一个简单的html页面,html页面放在web文件夹下;

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录界面</title>
</head>
<body>
    <form action="/zs/login" method="post">
        <input type="text" name="username" placeholder="请输入用户名"><br>
        <input type="password" name="password" placeholder="请输入密码"><br>
        <input type="submit" value="登录">
    </form>
</body>
</html>

下面写登陆的后台Servlet:

package com.zs.servlet;

import com.zs.dao.ILoginDAO;
import com.zs.dao.impl.LoginImpl;

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

@WebServlet(name = "LoginServlet")
public class LoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//        将请求的数据转为utf-8的格式,没有这句话的话,会出现登录中文用户名失败
        request.setCharacterEncoding("utf-8");
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        ILoginDAO lo=new LoginImpl();
        boolean b = lo.login(username, password);
        if (b) {
            System.out.println("登录成功");
//            成功跳转页面方法与下面一样,这里没有写可以跳转的页面
        } else {
            System.out.println("登陆失败");
//            失败返回登录页面
            response.sendRedirect("Login.html");
        }
    }

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

配置tomcat的方法再之前写过,然后直接启动tomcat就好了

 

以上是关于jdbc工具类的封装,以及表单验证数据提交后台的主要内容,如果未能解决你的问题,请参考以下文章

javascprit form表单提交前验证以及ajax返回json

代码记录

封装表单自定义错误信息。(阻止默认错误信息提示,添加自定义错误信息提示)

vue获取form表单file

thinkPHP3.2.3利用Ajax前台实现验证码验证,但通过form表单的按钮提交后,验证码一直错误!如何解决?

AJAX表单提交以及数据接收